mirror of
https://github.com/Ravinou/borgwarehouse
synced 2026-03-14 14:25:46 +01:00
test: ✅ migration from Jest to Vitest
This commit is contained in:
parent
9e2ae9f0fa
commit
52d8bca2ad
39 changed files with 4238 additions and 6479 deletions
6
.eslintrc.json
Normal file
6
.eslintrc.json
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"extends": [
|
||||
"next/core-web-vitals",
|
||||
"next/typescript"
|
||||
]
|
||||
}
|
||||
12
helpers/functions/__mocks__/apiResponse.ts
Normal file
12
helpers/functions/__mocks__/apiResponse.ts
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
const ApiResponse = {
|
||||
success: vi.fn(),
|
||||
badRequest: vi.fn(),
|
||||
unauthorized: vi.fn(),
|
||||
forbidden: vi.fn(),
|
||||
notFound: vi.fn(),
|
||||
methodNotAllowed: vi.fn(),
|
||||
validationError: vi.fn(),
|
||||
serverError: vi.fn(),
|
||||
};
|
||||
|
||||
export default ApiResponse;
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
import type { JestConfigWithTsJest } from 'ts-jest';
|
||||
|
||||
const config: JestConfigWithTsJest = {
|
||||
testEnvironment: 'node',
|
||||
transform: {
|
||||
'^.+\\.tsx?$': ['ts-jest', {}],
|
||||
},
|
||||
moduleNameMapper: {
|
||||
'^~/(.*)$': '<rootDir>/$1',
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
5430
package-lock.json
generated
5430
package-lock.json
generated
File diff suppressed because it is too large
Load diff
11
package.json
11
package.json
|
|
@ -6,9 +6,8 @@
|
|||
"dev": "next dev",
|
||||
"build": "next build",
|
||||
"start": "next start",
|
||||
"test": "jest",
|
||||
"test:watch": "jest --watch",
|
||||
"lint": "next lint",
|
||||
"test": "vitest",
|
||||
"setup": "npm install && npm run setup:hooks",
|
||||
"setup:hooks": "npx husky install",
|
||||
"format": "prettier --write \"{Components,Containers,helpers,pages,styles}/**/*.{js,jsx,ts,tsx,json,css,scss,md}\""
|
||||
|
|
@ -37,19 +36,15 @@
|
|||
"@commitlint/cli": "^19.7.1",
|
||||
"@commitlint/config-conventional": "^19.7.1",
|
||||
"@types/bcryptjs": "^2.4.6",
|
||||
"@types/jest": "^29.5.14",
|
||||
"@types/node": "^22.10.2",
|
||||
"@types/nodemailer": "^6.4.17",
|
||||
"@types/react": "^18.3.18",
|
||||
"@types/supertest": "^6.0.2",
|
||||
"eslint-config-next": "^15.1.6",
|
||||
"husky": "^9.1.7",
|
||||
"jest": "^29.7.0",
|
||||
"node-mocks-http": "^1.16.2",
|
||||
"prettier": "^3.5.1",
|
||||
"supertest": "^7.0.0",
|
||||
"ts-jest": "^29.3.0",
|
||||
"ts-node": "^10.9.2",
|
||||
"typescript": "^5.7.2"
|
||||
"typescript": "^5.7.2",
|
||||
"vitest": "^3.1.1"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,15 +3,15 @@ import { createMocks } from 'node-mocks-http';
|
|||
import { getUsersList } from '~/services';
|
||||
import handler from '~/pages/api/account/getAppriseAlert';
|
||||
|
||||
jest.mock('next-auth/next');
|
||||
jest.mock('~/services', () => ({
|
||||
getUsersList: jest.fn(),
|
||||
vi.mock('next-auth/next');
|
||||
vi.mock('~/services', () => ({
|
||||
getUsersList: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('Get Apprise Alert API', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
vi.clearAllMocks();
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return 405 if the method is not GET', async () => {
|
||||
|
|
@ -21,7 +21,7 @@ describe('Get Apprise Alert API', () => {
|
|||
});
|
||||
|
||||
it('should return 401 if the user is not authenticated', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(401);
|
||||
|
|
@ -29,11 +29,20 @@ describe('Get Apprise Alert API', () => {
|
|||
});
|
||||
|
||||
it('should return 400 if the user does not exist', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'nonexistent' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockResolvedValue([{ username: 'testuser', appriseAlert: true }]);
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
email: 'testuser@example.com',
|
||||
appriseAlert: true,
|
||||
},
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
|
@ -45,11 +54,20 @@ describe('Get Apprise Alert API', () => {
|
|||
});
|
||||
|
||||
it('should return appriseAlert value if the user exists', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockResolvedValue([{ username: 'testuser', appriseAlert: true }]);
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
email: 'testuser@example.com',
|
||||
appriseAlert: true,
|
||||
},
|
||||
]);
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
||||
|
|
@ -58,11 +76,11 @@ describe('Get Apprise Alert API', () => {
|
|||
});
|
||||
|
||||
it('should return 500 if there is an error reading the file', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockImplementation(() => {
|
||||
vi.mocked(getUsersList).mockImplementation(() => {
|
||||
throw new Error();
|
||||
});
|
||||
|
||||
|
|
@ -2,16 +2,17 @@ import { getServerSession } from 'next-auth/next';
|
|||
import { createMocks } from 'node-mocks-http';
|
||||
import { getUsersList } from '~/services';
|
||||
import handler from '~/pages/api/account/getAppriseMode';
|
||||
import { AppriseModeEnum } from '~/types/domain/config.types';
|
||||
|
||||
jest.mock('next-auth/next');
|
||||
jest.mock('~/services', () => ({
|
||||
getUsersList: jest.fn(),
|
||||
vi.mock('next-auth/next');
|
||||
vi.mock('~/services', () => ({
|
||||
getUsersList: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('Get Apprise Mode API', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
vi.clearAllMocks();
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return 405 if the method is not GET', async () => {
|
||||
|
|
@ -21,7 +22,7 @@ describe('Get Apprise Mode API', () => {
|
|||
});
|
||||
|
||||
it('should return 401 if the user is not authenticated', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(401);
|
||||
|
|
@ -29,14 +30,18 @@ describe('Get Apprise Mode API', () => {
|
|||
});
|
||||
|
||||
it('should return 400 if the user does not exist', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'nonexistent' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
appriseMode: 'stateless',
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
email: 'testuser@example.com',
|
||||
appriseMode: AppriseModeEnum.STATELESS,
|
||||
appriseStatelessURL: 'https://example.com',
|
||||
},
|
||||
]);
|
||||
|
|
@ -51,14 +56,18 @@ describe('Get Apprise Mode API', () => {
|
|||
});
|
||||
|
||||
it('should return appriseMode and appriseStatelessURL if the user exists', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
appriseMode: 'stateless',
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
email: 'testuser@example.com',
|
||||
appriseMode: AppriseModeEnum.STATELESS,
|
||||
appriseStatelessURL: 'https://example.com',
|
||||
},
|
||||
]);
|
||||
|
|
@ -74,11 +83,11 @@ describe('Get Apprise Mode API', () => {
|
|||
});
|
||||
|
||||
it('should return 500 if there is an error reading the file', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockImplementation(() => {
|
||||
vi.mocked(getUsersList).mockImplementation(() => {
|
||||
throw new Error();
|
||||
});
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
|
|
@ -3,15 +3,15 @@ import { createMocks } from 'node-mocks-http';
|
|||
import { getUsersList } from '~/services';
|
||||
import handler from '~/pages/api/account/getAppriseServices';
|
||||
|
||||
jest.mock('next-auth/next');
|
||||
jest.mock('~/services', () => ({
|
||||
getUsersList: jest.fn(),
|
||||
vi.mock('next-auth/next');
|
||||
vi.mock('~/services', () => ({
|
||||
getUsersList: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('Get Apprise Services API', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
vi.clearAllMocks();
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return 405 if the method is not GET', async () => {
|
||||
|
|
@ -21,7 +21,7 @@ describe('Get Apprise Services API', () => {
|
|||
});
|
||||
|
||||
it('should return 401 if the user is not authenticated', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(401);
|
||||
|
|
@ -29,12 +29,19 @@ describe('Get Apprise Services API', () => {
|
|||
});
|
||||
|
||||
it('should return 400 if the user does not exist', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'nonexistent' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockResolvedValue([
|
||||
{ username: 'testuser', appriseServices: ['service1', 'service2'] },
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
email: 'testuser@example.com',
|
||||
appriseServices: ['service1', 'service2'],
|
||||
},
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
|
|
@ -47,12 +54,19 @@ describe('Get Apprise Services API', () => {
|
|||
});
|
||||
|
||||
it('should return appriseServices if the user exists', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockResolvedValue([
|
||||
{ username: 'testuser', appriseServices: ['service1', 'service2'] },
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
email: 'testuser@example.com',
|
||||
appriseServices: ['service1', 'service2'],
|
||||
},
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
|
|
@ -65,11 +79,11 @@ describe('Get Apprise Services API', () => {
|
|||
});
|
||||
|
||||
it('should return 500 if there is an error reading the file', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockImplementation(() => {
|
||||
vi.mocked(getUsersList).mockImplementation(() => {
|
||||
throw new Error();
|
||||
});
|
||||
|
||||
|
|
@ -1,19 +1,17 @@
|
|||
import { getServerSession } from 'next-auth/next';
|
||||
import { createMocks } from 'node-mocks-http';
|
||||
import handler from '~/pages/api/account/getEmailAlert';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { promises as fs } from 'fs';
|
||||
import path from 'path';
|
||||
import { getUsersList } from '~/services';
|
||||
|
||||
jest.mock('next-auth/next');
|
||||
jest.mock('~/services', () => ({
|
||||
getUsersList: jest.fn(),
|
||||
vi.mock('next-auth/next');
|
||||
vi.mock('~/services', () => ({
|
||||
getUsersList: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('Get Email Alert API', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
vi.clearAllMocks();
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return 405 if the method is not GET', async () => {
|
||||
|
|
@ -23,7 +21,7 @@ describe('Get Email Alert API', () => {
|
|||
});
|
||||
|
||||
it('should return 401 if the user is not authenticated', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(401);
|
||||
|
|
@ -31,11 +29,20 @@ describe('Get Email Alert API', () => {
|
|||
});
|
||||
|
||||
it('should return 400 if the user does not exist', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'nonexistent' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockResolvedValue([{ username: 'testuser', emailAlert: true }]);
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
email: 'testuser@example.com',
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
emailAlert: true,
|
||||
},
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
|
@ -47,11 +54,20 @@ describe('Get Email Alert API', () => {
|
|||
});
|
||||
|
||||
it('should return emailAlert if the user exists', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockResolvedValue([{ username: 'testuser', emailAlert: true }]);
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
email: 'testuser@example.com',
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
emailAlert: true,
|
||||
},
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
|
@ -63,11 +79,11 @@ describe('Get Email Alert API', () => {
|
|||
});
|
||||
|
||||
it('should return 500 if there is an error reading the file', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockImplementation(() => {
|
||||
vi.mocked(getUsersList).mockImplementation(() => {
|
||||
throw new Error();
|
||||
});
|
||||
|
||||
|
|
@ -2,7 +2,7 @@ import { createMocks } from 'node-mocks-http';
|
|||
import handler from '~/pages/api/account/getWizardEnv';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
|
||||
jest.mock('next-auth/next');
|
||||
vi.mock('next-auth/next');
|
||||
|
||||
describe('Get Wizard Env API', () => {
|
||||
it('should return 405 if the method is not GET', async () => {
|
||||
|
|
@ -12,14 +12,14 @@ describe('Get Wizard Env API', () => {
|
|||
});
|
||||
|
||||
it('should return 401 if the user is not authenticated', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(401);
|
||||
});
|
||||
|
||||
it('should return 200 with wizardEnv if the user is authenticated', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testuser' } });
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' } });
|
||||
|
||||
process.env.UNIX_USER = 'borgwarehouse';
|
||||
process.env.FQDN = 'localhost';
|
||||
|
|
@ -2,34 +2,26 @@ import { createMocks } from 'node-mocks-http';
|
|||
import handler from '~/pages/api/account/sendTestEmail';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
|
||||
jest.mock('next-auth', () => {
|
||||
return jest.fn(() => {
|
||||
return {
|
||||
auth: { session: {} },
|
||||
GET: jest.fn(),
|
||||
POST: jest.fn(),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
jest.mock('next-auth/next', () => ({
|
||||
getServerSession: jest.fn(),
|
||||
}));
|
||||
jest.mock('~/helpers/functions/nodemailerSMTP', () => ({
|
||||
vi.mock('next-auth/next', () => ({
|
||||
__esModule: true,
|
||||
default: jest.fn(() => ({
|
||||
sendMail: jest.fn().mockResolvedValue({ messageId: 'fake-message-id' }),
|
||||
getServerSession: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('~/helpers/functions/nodemailerSMTP', () => ({
|
||||
__esModule: true,
|
||||
default: vi.fn(() => ({
|
||||
sendMail: vi.fn().mockResolvedValue({ messageId: 'fake-message-id' }),
|
||||
})),
|
||||
}));
|
||||
|
||||
describe('Email API', () => {
|
||||
beforeEach(() => {
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return 401 if not authenticated', async () => {
|
||||
// Mock unauthenticated session
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
|
||||
// Simulate a POST request
|
||||
const { req, res } = createMocks({ method: 'POST' });
|
||||
|
|
@ -41,7 +33,7 @@ describe('Email API', () => {
|
|||
|
||||
it('should send an email if authenticated', async () => {
|
||||
// Mock unauthenticated session
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { email: 'ada-lovelace@example.com', name: 'Lovelace' },
|
||||
});
|
||||
|
||||
208
pages/api/account/tokenManager.test.ts
Normal file
208
pages/api/account/tokenManager.test.ts
Normal file
|
|
@ -0,0 +1,208 @@
|
|||
import handler from '~/pages/api/account/tokenManager';
|
||||
import { createMocks } from 'node-mocks-http';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { getUsersList, updateUsersList } from '~/services';
|
||||
import ApiResponse from '~/helpers/functions/apiResponse';
|
||||
|
||||
vi.mock('next-auth/next', () => ({
|
||||
__esModule: true,
|
||||
getServerSession: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('~/services', () => ({
|
||||
getUsersList: vi.fn(),
|
||||
updateUsersList: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('~/helpers/functions/apiResponse');
|
||||
|
||||
describe('Token Manager API', () => {
|
||||
afterEach(() => {
|
||||
vi.clearAllMocks();
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return unauthorized if session is not found', async () => {
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
body: {
|
||||
name: 'testToken',
|
||||
permissions: { create: true, read: true, update: true, delete: true },
|
||||
},
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(ApiResponse.unauthorized).toHaveBeenCalledWith(res);
|
||||
});
|
||||
|
||||
it('should create a new token if valid data is provided', async () => {
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testUser' } });
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testUser',
|
||||
password: 'hashedPassword',
|
||||
email: 'testUser@example.com',
|
||||
roles: ['user'],
|
||||
tokens: [],
|
||||
},
|
||||
]);
|
||||
vi.mocked(updateUsersList).mockResolvedValue();
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
body: {
|
||||
name: 'testToken',
|
||||
permissions: { create: true, read: true, update: true, delete: true },
|
||||
},
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
const responseData = JSON.parse(res._getData());
|
||||
expect(responseData).toHaveProperty('token');
|
||||
expect(updateUsersList).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return bad request if token name already exists', async () => {
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testUser' } });
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testUser',
|
||||
password: 'hashedPassword',
|
||||
email: 'testUser@example.com',
|
||||
roles: ['user'],
|
||||
tokens: [
|
||||
{
|
||||
token: 'sampleToken123',
|
||||
name: 'testToken',
|
||||
permissions: { create: true, read: true, update: true, delete: true },
|
||||
creation: 123,
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
body: {
|
||||
name: 'testToken',
|
||||
permissions: { create: true, read: true, update: true, delete: true },
|
||||
},
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(ApiResponse.badRequest).toHaveBeenCalledWith(res, 'Token name already exists');
|
||||
});
|
||||
|
||||
it('should return token list for GET request', async () => {
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testUser' } });
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testUser',
|
||||
password: 'hashedPassword',
|
||||
email: 'testUser@example.com',
|
||||
roles: ['user'],
|
||||
tokens: [
|
||||
{
|
||||
token: 'sampleToken1',
|
||||
name: 'token1',
|
||||
permissions: { create: false, read: false, update: false, delete: false },
|
||||
creation: 123,
|
||||
},
|
||||
{
|
||||
token: 'sampleToken2',
|
||||
name: 'token2',
|
||||
permissions: { create: false, read: false, update: false, delete: false },
|
||||
creation: 456,
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
const responseData = JSON.parse(res._getData());
|
||||
expect(responseData).toEqual([
|
||||
{
|
||||
name: 'token1',
|
||||
permissions: { create: false, read: false, update: false, delete: false },
|
||||
creation: 123,
|
||||
},
|
||||
{
|
||||
name: 'token2',
|
||||
permissions: { create: false, read: false, update: false, delete: false },
|
||||
creation: 456,
|
||||
},
|
||||
]);
|
||||
});
|
||||
|
||||
it('should delete a token for DELETE request', async () => {
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testUser' } });
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testUser',
|
||||
password: 'hashedPassword',
|
||||
email: 'testUser@example.com',
|
||||
roles: ['user'],
|
||||
tokens: [
|
||||
{
|
||||
token: 'sampleToken1',
|
||||
name: 'token1',
|
||||
permissions: { create: false, read: false, update: false, delete: false },
|
||||
creation: 123,
|
||||
},
|
||||
{
|
||||
token: 'sampleToken2',
|
||||
name: 'token2',
|
||||
permissions: { create: false, read: false, update: false, delete: false },
|
||||
creation: 456,
|
||||
},
|
||||
],
|
||||
},
|
||||
]);
|
||||
vi.mocked(updateUsersList).mockResolvedValue();
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'DELETE',
|
||||
body: { name: 'token1' },
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(ApiResponse.success).toHaveBeenCalledWith(res, 'Token deleted');
|
||||
expect(updateUsersList).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return bad request if token name is missing in DELETE request', async () => {
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testUser' } });
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'DELETE',
|
||||
body: {},
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(ApiResponse.badRequest).toHaveBeenCalledWith(res, 'Missing token name');
|
||||
});
|
||||
|
||||
it('should return method not allowed for unsupported HTTP methods', async () => {
|
||||
const { req, res } = createMocks({ method: 'PUT' });
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(ApiResponse.methodNotAllowed).toHaveBeenCalledWith(res);
|
||||
});
|
||||
});
|
||||
|
|
@ -3,7 +3,7 @@ import { getServerSession } from 'next-auth/next';
|
|||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { IntegrationTokenType, TokenPermissionsType } from '~/types/api/integration.types';
|
||||
import ApiResponse from '~/helpers/functions/apiResponse';
|
||||
import { getUsersList, updateUsersList } from '~/helpers/functions';
|
||||
import { getUsersList, updateUsersList } from '~/services';
|
||||
import { getUnixTime } from 'date-fns';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { BorgWarehouseApiResponse } from '~/types/api/error.types';
|
||||
|
|
|
|||
|
|
@ -3,19 +3,19 @@ import handler from '~/pages/api/account/updateAppriseAlert';
|
|||
import { getServerSession } from 'next-auth/next';
|
||||
import { getUsersList, updateUsersList } from '~/services';
|
||||
|
||||
jest.mock('next-auth/next');
|
||||
jest.mock('~/services', () => ({
|
||||
vi.mock('next-auth/next');
|
||||
vi.mock('~/services', () => ({
|
||||
__esModule: true,
|
||||
getUsersList: jest.fn(),
|
||||
updateUsersList: jest.fn(),
|
||||
getUsersList: vi.fn(),
|
||||
updateUsersList: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('Notifications API', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.resetModules();
|
||||
jest.resetAllMocks();
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
vi.clearAllMocks();
|
||||
vi.resetModules();
|
||||
vi.resetAllMocks();
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return 405 if the method is not PUT', async () => {
|
||||
|
|
@ -25,7 +25,7 @@ describe('Notifications API', () => {
|
|||
});
|
||||
|
||||
it('should return 401 if the user is not authenticated', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
|
||||
const { req, res } = createMocks({ method: 'PUT', body: { appriseAlert: true } });
|
||||
await handler(req, res);
|
||||
|
|
@ -33,7 +33,7 @@ describe('Notifications API', () => {
|
|||
});
|
||||
|
||||
it('should return 422 if the request body is invalid', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
|
|
@ -44,11 +44,20 @@ describe('Notifications API', () => {
|
|||
});
|
||||
|
||||
it('should return 400 if the user does not exist', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'nonexistent' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockResolvedValue([{ username: 'testuser', appriseAlert: false }]);
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
email: 'testuser@example.com',
|
||||
appriseAlert: false,
|
||||
},
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({ method: 'PUT', body: { appriseAlert: true } });
|
||||
await handler(req, res);
|
||||
|
|
@ -59,26 +68,44 @@ describe('Notifications API', () => {
|
|||
});
|
||||
|
||||
it('should update appriseAlert and return 200 if everything is correct', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockResolvedValue([{ username: 'testuser', appriseAlert: false }]);
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
email: 'testuser@example.com',
|
||||
appriseAlert: false,
|
||||
},
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({ method: 'PUT', body: { appriseAlert: true } });
|
||||
await handler(req, res);
|
||||
|
||||
expect(updateUsersList).toHaveBeenCalledWith([{ username: 'testuser', appriseAlert: true }]);
|
||||
expect(updateUsersList).toHaveBeenCalledWith([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
email: 'testuser@example.com',
|
||||
appriseAlert: true,
|
||||
},
|
||||
]);
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
expect(res._getJSONData()).toEqual({ message: 'Successful API send' });
|
||||
});
|
||||
|
||||
it('should return 500 if there is an error reading users file', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockRejectedValue({ code: 'ENOENT' });
|
||||
vi.mocked(getUsersList).mockRejectedValue({ code: 'ENOENT' });
|
||||
|
||||
const { req, res } = createMocks({ method: 'PUT', body: { appriseAlert: true } });
|
||||
await handler(req, res);
|
||||
|
|
@ -2,11 +2,12 @@ import { createMocks } from 'node-mocks-http';
|
|||
import handler from '~/pages/api/account/updateAppriseMode';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { getUsersList, updateUsersList } from '~/services';
|
||||
import { AppriseModeEnum } from '~/types/domain/config.types';
|
||||
|
||||
jest.mock('next-auth/next');
|
||||
jest.mock('~/services', () => ({
|
||||
getUsersList: jest.fn(),
|
||||
updateUsersList: jest.fn(),
|
||||
vi.mock('next-auth/next');
|
||||
vi.mock('~/services', () => ({
|
||||
getUsersList: vi.fn(),
|
||||
updateUsersList: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('Apprise Mode API', () => {
|
||||
|
|
@ -17,7 +18,7 @@ describe('Apprise Mode API', () => {
|
|||
});
|
||||
|
||||
it('should return 401 if not authenticated', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
|
||||
const { req, res } = createMocks({ method: 'PUT' });
|
||||
await handler(req, res);
|
||||
|
|
@ -26,7 +27,7 @@ describe('Apprise Mode API', () => {
|
|||
});
|
||||
|
||||
it('should return 422 if invalid data is provided', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testuser' } });
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' } });
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'PUT',
|
||||
|
|
@ -38,9 +39,16 @@ describe('Apprise Mode API', () => {
|
|||
});
|
||||
|
||||
it('should return 400 if user does not exist', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'unknownuser' } });
|
||||
(getUsersList as jest.Mock).mockResolvedValue([
|
||||
{ username: 'testuser', appriseMode: 'package' },
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'unknownuser' } });
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
email: 'testuser@example.com',
|
||||
appriseMode: AppriseModeEnum.PACKAGE,
|
||||
},
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
|
|
@ -53,11 +61,18 @@ describe('Apprise Mode API', () => {
|
|||
});
|
||||
|
||||
it('should update user settings and return 200', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testuser' } });
|
||||
(getUsersList as jest.Mock).mockResolvedValue([
|
||||
{ username: 'testuser', appriseMode: 'package' },
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'testuser' } });
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
email: 'testuser@example.com',
|
||||
appriseMode: AppriseModeEnum.PACKAGE,
|
||||
},
|
||||
]);
|
||||
(updateUsersList as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(updateUsersList).mockResolvedValue();
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'PUT',
|
||||
|
|
@ -68,8 +83,12 @@ describe('Apprise Mode API', () => {
|
|||
|
||||
expect(updateUsersList).toHaveBeenCalledWith([
|
||||
{
|
||||
id: 1,
|
||||
username: 'testuser',
|
||||
appriseMode: 'stateless',
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
email: 'testuser@example.com',
|
||||
appriseMode: AppriseModeEnum.STATELESS,
|
||||
appriseStatelessURL: 'https://example.com',
|
||||
},
|
||||
]);
|
||||
|
|
@ -3,24 +3,23 @@ import handler from '~/pages/api/account/updateAppriseServices';
|
|||
import { getServerSession } from 'next-auth/next';
|
||||
import { getUsersList, updateUsersList } from '~/services';
|
||||
|
||||
// Mock imports
|
||||
jest.mock('next-auth/next');
|
||||
jest.mock('~/services', () => ({
|
||||
getUsersList: jest.fn(),
|
||||
updateUsersList: jest.fn(),
|
||||
vi.mock('next-auth/next');
|
||||
vi.mock('~/services', () => ({
|
||||
getUsersList: vi.fn(),
|
||||
updateUsersList: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('PUT /api/account/updateAppriseURLs', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.resetModules();
|
||||
jest.resetAllMocks();
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
vi.clearAllMocks();
|
||||
vi.resetModules();
|
||||
vi.resetAllMocks();
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return 401 if not authenticated', async () => {
|
||||
// Mock unauthenticated session
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
|
||||
const { req, res } = createMocks({ method: 'PUT' });
|
||||
await handler(req, res);
|
||||
|
|
@ -37,11 +36,19 @@ describe('PUT /api/account/updateAppriseURLs', () => {
|
|||
|
||||
it('should return 400 if user is not found in the users list', async () => {
|
||||
// Mock authenticated session
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'Lovelace' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockResolvedValue([{ username: 'Ada' }]);
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'Ada',
|
||||
password: 'securepassword',
|
||||
roles: ['user'],
|
||||
email: 'ada@example.com',
|
||||
},
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'PUT',
|
||||
|
|
@ -56,12 +63,21 @@ describe('PUT /api/account/updateAppriseURLs', () => {
|
|||
});
|
||||
|
||||
it('should return 200 and successfully update the appriseURLs', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'Lovelace' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockResolvedValue([{ username: 'Lovelace', appriseServices: [] }]);
|
||||
(updateUsersList as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
username: 'Lovelace',
|
||||
password: 'securepassword',
|
||||
roles: ['user'],
|
||||
email: 'lovelace@example.com',
|
||||
appriseServices: [],
|
||||
},
|
||||
]);
|
||||
vi.mocked(updateUsersList).mockResolvedValue();
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'PUT',
|
||||
|
|
@ -74,11 +90,11 @@ describe('PUT /api/account/updateAppriseURLs', () => {
|
|||
});
|
||||
|
||||
it('should return 500 if there is an error reading the users file', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'Lovelace' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockRejectedValue({ code: 'ENOENT' });
|
||||
vi.mocked(getUsersList).mockRejectedValue({ code: 'ENOENT' });
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'PUT',
|
||||
|
|
@ -94,11 +110,11 @@ describe('PUT /api/account/updateAppriseURLs', () => {
|
|||
});
|
||||
|
||||
it('should return 500 if there is an API error', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'Lovelace' },
|
||||
});
|
||||
|
||||
(getUsersList as jest.Mock).mockRejectedValue({ code: 'UNKNOWN_ERROR' });
|
||||
vi.mocked(getUsersList).mockRejectedValue({ code: 'UNKNOWN_ERROR' });
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'PUT',
|
||||
137
pages/api/account/updateEmail.test.ts
Normal file
137
pages/api/account/updateEmail.test.ts
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
import { describe, it, expect, vi } from 'vitest';
|
||||
import handler from './updateEmail';
|
||||
import { getUsersList, updateUsersList } from '~/services';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
|
||||
vi.mock('~/services', () => ({
|
||||
getUsersList: vi.fn(),
|
||||
updateUsersList: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('next-auth/next', () => ({
|
||||
getServerSession: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('updateEmail API handler', () => {
|
||||
const mockReq = {
|
||||
method: 'PUT',
|
||||
body: { email: 'newemail@example.com' },
|
||||
} as unknown as NextApiRequest;
|
||||
|
||||
const mockRes = {
|
||||
status: vi.fn().mockReturnThis(),
|
||||
json: vi.fn(),
|
||||
} as unknown as NextApiResponse;
|
||||
|
||||
it('should return 405 if method is not PUT', async () => {
|
||||
mockReq.method = 'GET';
|
||||
await handler(mockReq, mockRes);
|
||||
expect(mockRes.status).toHaveBeenCalledWith(405);
|
||||
});
|
||||
|
||||
it('should return 401 if session is not found', async () => {
|
||||
vi.mocked(getServerSession).mockResolvedValueOnce(null);
|
||||
await handler(mockReq, mockRes);
|
||||
expect(mockRes.status).toHaveBeenCalledWith(401);
|
||||
});
|
||||
|
||||
it('should return 422 if email is not provided', async () => {
|
||||
mockReq.body = {};
|
||||
vi.mocked(getServerSession).mockResolvedValueOnce({ user: { name: 'testuser' } });
|
||||
await handler(mockReq, mockRes);
|
||||
expect(mockRes.status).toHaveBeenCalledWith(422);
|
||||
expect(mockRes.json).toHaveBeenCalledWith({ message: 'Unexpected data' });
|
||||
});
|
||||
|
||||
it('should return 400 if user is not found in users list', async () => {
|
||||
vi.mocked(getServerSession).mockResolvedValueOnce({ user: { name: 'testuser' } });
|
||||
vi.mocked(getUsersList).mockResolvedValueOnce([]);
|
||||
await handler(mockReq, mockRes);
|
||||
expect(mockRes.status).toHaveBeenCalledWith(400);
|
||||
expect(mockRes.json).toHaveBeenCalledWith({
|
||||
message: 'User is incorrect. Please, logout to update your session.',
|
||||
});
|
||||
});
|
||||
|
||||
it('should return 400 if email already exists', async () => {
|
||||
vi.mocked(getServerSession).mockResolvedValueOnce({ user: { name: 'testuser' } });
|
||||
vi.mocked(getUsersList).mockResolvedValueOnce([
|
||||
{
|
||||
username: 'testuser',
|
||||
email: 'oldemail@example.com',
|
||||
id: 1,
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
},
|
||||
{
|
||||
username: 'otheruser',
|
||||
email: 'newemail@example.com',
|
||||
id: 2,
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
},
|
||||
]);
|
||||
await handler(mockReq, mockRes);
|
||||
expect(mockRes.status).toHaveBeenCalledWith(400);
|
||||
expect(mockRes.json).toHaveBeenCalledWith({ message: 'Email already exists' });
|
||||
});
|
||||
|
||||
it('should update email and return 200 on success', async () => {
|
||||
vi.mocked(getServerSession).mockResolvedValueOnce({ user: { name: 'testuser' } });
|
||||
vi.mocked(getUsersList).mockResolvedValueOnce([
|
||||
{
|
||||
username: 'testuser',
|
||||
email: 'oldemail@example.com',
|
||||
id: 1,
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
},
|
||||
{
|
||||
username: 'otheruser',
|
||||
email: 'otheremail@example.com',
|
||||
id: 2,
|
||||
password: 'hashedpassword',
|
||||
roles: ['user'],
|
||||
},
|
||||
]);
|
||||
vi.mocked(updateUsersList).mockResolvedValueOnce(undefined);
|
||||
|
||||
await handler(mockReq, mockRes);
|
||||
|
||||
expect(mockRes.status).toHaveBeenCalledWith(200);
|
||||
expect(mockRes.json).toHaveBeenCalledWith({ message: 'Successful API send' });
|
||||
expect(updateUsersList).toHaveBeenCalledWith([
|
||||
{ username: 'testuser', email: 'newemail@example.com' },
|
||||
{ username: 'otheruser', email: 'otheremail@example.com' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should return 500 if an unexpected error occurs', async () => {
|
||||
vi.mocked(getServerSession).mockResolvedValueOnce({ user: { name: 'testuser' } });
|
||||
vi.mocked(getUsersList).mockRejectedValueOnce(new Error('Unexpected error'));
|
||||
|
||||
await handler(mockReq, mockRes);
|
||||
|
||||
expect(mockRes.status).toHaveBeenCalledWith(500);
|
||||
expect(mockRes.json).toHaveBeenCalledWith({
|
||||
status: 500,
|
||||
message: 'API error, contact the administrator',
|
||||
});
|
||||
});
|
||||
|
||||
it('should return 500 with specific message if ENOENT error occurs', async () => {
|
||||
vi.mocked(getServerSession).mockResolvedValueOnce({ user: { name: 'testuser' } });
|
||||
const enoentError = new Error('No such file or directory');
|
||||
(enoentError as any).code = 'ENOENT';
|
||||
vi.mocked(getUsersList).mockRejectedValueOnce(enoentError);
|
||||
|
||||
await handler(mockReq, mockRes);
|
||||
|
||||
expect(mockRes.status).toHaveBeenCalledWith(500);
|
||||
expect(mockRes.json).toHaveBeenCalledWith({
|
||||
status: 500,
|
||||
message: 'No such file or directory',
|
||||
});
|
||||
});
|
||||
});
|
||||
0
pages/api/account/updateEmailAlert.test.ts
Normal file
0
pages/api/account/updateEmailAlert.test.ts
Normal file
0
pages/api/account/updatePasssword.test.ts
Normal file
0
pages/api/account/updatePasssword.test.ts
Normal file
|
|
@ -1,5 +1,6 @@
|
|||
import { getUsersList, updateUsersList, hashPassword, verifyPassword } from '~/helpers/functions';
|
||||
import { hashPassword, verifyPassword } from '~/helpers/functions';
|
||||
import { authOptions } from '../auth/[...nextauth]';
|
||||
import { getUsersList, updateUsersList } from '~/services';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { ErrorResponse } from '~/types/api/error.types';
|
||||
|
|
|
|||
0
pages/api/account/updateUsername.test.ts
Normal file
0
pages/api/account/updateUsername.test.ts
Normal file
|
|
@ -1,4 +1,4 @@
|
|||
import { getUsersList, updateUsersList } from '~/helpers/functions';
|
||||
import { getUsersList, updateUsersList } from '~/services';
|
||||
import { authOptions } from '../auth/[...nextauth]';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { UsernameSettingDTO } from '~/types/api/setting.types';
|
||||
|
|
|
|||
|
|
@ -3,33 +3,33 @@ import handler from '~/pages/api/cronjob/checkStatus';
|
|||
import { getRepoList, getUsersList, updateRepoList } from '~/services';
|
||||
import { getLastSaveListShell } from '~/helpers/functions/shell.utils';
|
||||
import nodemailerSMTP from '~/helpers/functions/nodemailerSMTP';
|
||||
import { AppriseModeEnum } from '~/types/domain/config.types';
|
||||
|
||||
jest.mock('~/services', () => ({
|
||||
getRepoList: jest.fn(),
|
||||
getUsersList: jest.fn(),
|
||||
updateRepoList: jest.fn(),
|
||||
vi.mock('~/services', () => ({
|
||||
getRepoList: vi.fn(),
|
||||
getUsersList: vi.fn(),
|
||||
updateRepoList: vi.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/helpers/functions/shell.utils', () => ({
|
||||
getLastSaveListShell: jest.fn(),
|
||||
vi.mock('~/helpers/functions/shell.utils', () => ({
|
||||
getLastSaveListShell: vi.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/helpers/functions/nodemailerSMTP', () => ({
|
||||
__esModule: true,
|
||||
default: jest.fn(() => ({
|
||||
sendMail: jest.fn().mockResolvedValue({ messageId: 'fake-message-id' }),
|
||||
vi.mock('~/helpers/functions/nodemailerSMTP', () => ({
|
||||
default: vi.fn(() => ({
|
||||
sendMail: vi.fn().mockResolvedValue({ messageId: 'fake-message-id' }),
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('~/helpers/templates/emailAlertStatus', () =>
|
||||
jest.fn(() => ({
|
||||
vi.mock('~/helpers/templates/emailAlertStatus', () => ({
|
||||
default: vi.fn(() => ({
|
||||
subject: 'Alert',
|
||||
text: 'Alert text',
|
||||
}))
|
||||
);
|
||||
})),
|
||||
}));
|
||||
|
||||
jest.mock('node:child_process', () => ({
|
||||
exec: jest.fn(
|
||||
vi.mock('node:child_process', () => ({
|
||||
exec: vi.fn(
|
||||
(
|
||||
command: string,
|
||||
callback: (err: Error | null, result: { stdout: string; stderr: string }) => void
|
||||
|
|
@ -42,9 +42,9 @@ jest.mock('node:child_process', () => ({
|
|||
describe('Cronjob API Handler', () => {
|
||||
beforeEach(() => {
|
||||
process.env.CRONJOB_KEY = 'test-key';
|
||||
jest.clearAllMocks();
|
||||
jest.resetModules();
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
vi.clearAllMocks();
|
||||
vi.resetModules();
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return 401 if no authorization header', async () => {
|
||||
|
|
@ -72,10 +72,8 @@ describe('Cronjob API Handler', () => {
|
|||
});
|
||||
|
||||
it('should return 200 with message if no repository to check (empty repoList)', async () => {
|
||||
(getRepoList as jest.Mock).mockResolvedValue([]);
|
||||
(getLastSaveListShell as jest.Mock).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', lastSave: 123 },
|
||||
]);
|
||||
vi.mocked(getRepoList).mockResolvedValue([]);
|
||||
vi.mocked(getLastSaveListShell).mockResolvedValue([{ repositoryName: 'repo1', lastSave: 123 }]);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
|
|
@ -91,10 +89,21 @@ describe('Cronjob API Handler', () => {
|
|||
});
|
||||
|
||||
it('should return 200 with message if no repository to check (empty lastSaveList)', async () => {
|
||||
(getRepoList as jest.Mock).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', alert: 100, alias: 'Repo1' },
|
||||
vi.mocked(getRepoList).mockResolvedValue([
|
||||
{
|
||||
repositoryName: 'repo1',
|
||||
alert: 100,
|
||||
alias: 'Repo1',
|
||||
id: 1,
|
||||
status: true,
|
||||
lastSave: 0,
|
||||
storageSize: 0,
|
||||
storageUsed: 0,
|
||||
sshPublicKey: '',
|
||||
comment: '',
|
||||
},
|
||||
]);
|
||||
(getLastSaveListShell as jest.Mock).mockResolvedValue([]);
|
||||
vi.mocked(getLastSaveListShell).mockResolvedValue([]);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
|
|
@ -111,14 +120,25 @@ describe('Cronjob API Handler', () => {
|
|||
|
||||
it('should execute successfully without alerts if all repositories are OK', async () => {
|
||||
const currentTime = Math.floor(Date.now() / 1000);
|
||||
(getRepoList as jest.Mock).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', alert: 1000, alias: 'Repo1', status: true },
|
||||
vi.mocked(getRepoList).mockResolvedValue([
|
||||
{
|
||||
repositoryName: 'repo1',
|
||||
alert: 1000,
|
||||
alias: 'Repo1',
|
||||
status: true,
|
||||
id: 1,
|
||||
lastSave: 0,
|
||||
storageSize: 0,
|
||||
storageUsed: 0,
|
||||
sshPublicKey: '',
|
||||
comment: '',
|
||||
},
|
||||
]);
|
||||
(getLastSaveListShell as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getLastSaveListShell).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', lastSave: currentTime },
|
||||
]);
|
||||
(updateRepoList as jest.Mock).mockResolvedValue(undefined);
|
||||
(getUsersList as jest.Mock).mockResolvedValue([]);
|
||||
vi.mocked(updateRepoList).mockResolvedValue(undefined);
|
||||
vi.mocked(getUsersList).mockResolvedValue([]);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
|
|
@ -135,7 +155,7 @@ describe('Cronjob API Handler', () => {
|
|||
});
|
||||
|
||||
it('should return 500 if an error occurs', async () => {
|
||||
(getRepoList as jest.Mock).mockRejectedValue(new Error('Test error'));
|
||||
vi.mocked(getRepoList).mockRejectedValue(new Error('Test error'));
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
|
|
@ -153,19 +173,33 @@ describe('Cronjob API Handler', () => {
|
|||
it('should not send email alert if emailAlert is false', async () => {
|
||||
const currentTime = Math.floor(Date.now() / 1000);
|
||||
|
||||
(getRepoList as jest.Mock).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', alert: 100, alias: 'Repo1' },
|
||||
vi.mocked(getRepoList).mockResolvedValue([
|
||||
{
|
||||
repositoryName: 'repo1',
|
||||
alert: 100,
|
||||
alias: 'Repo1',
|
||||
id: 1,
|
||||
status: true,
|
||||
lastSave: 0,
|
||||
storageSize: 0,
|
||||
storageUsed: 0,
|
||||
sshPublicKey: '',
|
||||
comment: '',
|
||||
},
|
||||
]);
|
||||
(getLastSaveListShell as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getLastSaveListShell).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', lastSave: currentTime - 200 },
|
||||
]);
|
||||
// User has disabled email alert but enabled Apprise alert
|
||||
(getUsersList as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
password: 'hashed-password',
|
||||
roles: ['user'],
|
||||
emailAlert: false,
|
||||
appriseAlert: true,
|
||||
appriseServices: ['http://example.com'],
|
||||
appriseMode: 'package',
|
||||
appriseMode: AppriseModeEnum.PACKAGE,
|
||||
appriseStatelessURL: 'http://example.com',
|
||||
email: 'test@example.com',
|
||||
username: 'testuser',
|
||||
|
|
@ -183,19 +217,33 @@ describe('Cronjob API Handler', () => {
|
|||
|
||||
it('should not send apprise alert if appriseAlert is false', async () => {
|
||||
const currentTime = Math.floor(Date.now() / 1000);
|
||||
(getRepoList as jest.Mock).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', alert: 100, alias: 'Repo1' },
|
||||
vi.mocked(getRepoList).mockResolvedValue([
|
||||
{
|
||||
repositoryName: 'repo1',
|
||||
alert: 100,
|
||||
alias: 'Repo1',
|
||||
id: 1,
|
||||
status: true,
|
||||
lastSave: 0,
|
||||
storageSize: 0,
|
||||
storageUsed: 0,
|
||||
sshPublicKey: '',
|
||||
comment: '',
|
||||
},
|
||||
]);
|
||||
(getLastSaveListShell as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getLastSaveListShell).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', lastSave: currentTime - 200 },
|
||||
]);
|
||||
// User has disabled Apprise alert but enabled email alert
|
||||
(getUsersList as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
password: 'hashed-password',
|
||||
roles: ['user'],
|
||||
emailAlert: true,
|
||||
appriseAlert: false,
|
||||
appriseServices: ['http://example.com'],
|
||||
appriseMode: 'package',
|
||||
appriseMode: AppriseModeEnum.PACKAGE,
|
||||
appriseStatelessURL: 'http://example.com',
|
||||
email: 'test@example.com',
|
||||
username: 'testuser',
|
||||
|
|
@ -203,7 +251,7 @@ describe('Cronjob API Handler', () => {
|
|||
]);
|
||||
|
||||
// Spy on exec to check if it is called
|
||||
const execSpy = jest.spyOn(require('node:child_process'), 'exec');
|
||||
const execSpy = vi.spyOn(require('node:child_process'), 'exec');
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
headers: { authorization: 'Bearer test-key' },
|
||||
|
|
@ -216,46 +264,68 @@ describe('Cronjob API Handler', () => {
|
|||
|
||||
it('should not send alert if alert is disabled on repo (repo.alert === 0)', async () => {
|
||||
const currentTime = Math.floor(Date.now() / 1000);
|
||||
(getRepoList as jest.Mock).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', alert: 0, alias: 'Repo1' },
|
||||
vi.mocked(getRepoList).mockResolvedValue([
|
||||
{
|
||||
repositoryName: 'repo1',
|
||||
alert: 0,
|
||||
alias: 'Repo1',
|
||||
id: 1,
|
||||
status: false,
|
||||
lastSave: 0,
|
||||
storageSize: 0,
|
||||
storageUsed: 0,
|
||||
sshPublicKey: '',
|
||||
comment: '',
|
||||
},
|
||||
]);
|
||||
(getLastSaveListShell as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getLastSaveListShell).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', lastSave: currentTime - 1000 },
|
||||
]);
|
||||
(getUsersList as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
password: 'hashed-password',
|
||||
roles: ['user'],
|
||||
emailAlert: true,
|
||||
appriseAlert: true,
|
||||
appriseServices: ['http://example.com'],
|
||||
appriseMode: 'package',
|
||||
appriseMode: AppriseModeEnum.PACKAGE,
|
||||
appriseStatelessURL: 'http://example.com',
|
||||
email: 'test@example.com',
|
||||
username: 'testuser',
|
||||
},
|
||||
]);
|
||||
|
||||
// Spy on exec to check if it is called
|
||||
const nodemailerSpy = jest.spyOn(require('~/helpers/functions/nodemailerSMTP'), 'default');
|
||||
const execSpy = jest.spyOn(require('node:child_process'), 'exec');
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
headers: { authorization: 'Bearer test-key' },
|
||||
});
|
||||
await handler(req, res);
|
||||
|
||||
expect(nodemailerSpy).not.toHaveBeenCalled();
|
||||
expect(execSpy).not.toHaveBeenCalled();
|
||||
expect(nodemailerSMTP).not.toHaveBeenCalled();
|
||||
|
||||
nodemailerSpy.mockRestore();
|
||||
execSpy.mockRestore();
|
||||
const childProcess = await import('node:child_process');
|
||||
expect(childProcess.exec).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should not update lastStatusAlertSend or add to repoListToSendAlert if repo status is OK', async () => {
|
||||
(getRepoList as jest.Mock).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', status: true, alert: 100 },
|
||||
vi.mocked(getRepoList).mockResolvedValue([
|
||||
{
|
||||
repositoryName: 'repo1',
|
||||
status: true,
|
||||
alert: 100,
|
||||
id: 1,
|
||||
alias: 'Repo1',
|
||||
lastSave: 0,
|
||||
storageSize: 0,
|
||||
storageUsed: 0,
|
||||
sshPublicKey: '',
|
||||
comment: '',
|
||||
lastStatusAlertSend: 1000,
|
||||
},
|
||||
]);
|
||||
(getLastSaveListShell as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(updateRepoList).mockResolvedValue(undefined);
|
||||
vi.mocked(getLastSaveListShell).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', lastSave: Math.floor(Date.now() / 1000) },
|
||||
]);
|
||||
|
||||
|
|
@ -271,7 +341,14 @@ describe('Cronjob API Handler', () => {
|
|||
repositoryName: 'repo1',
|
||||
status: true,
|
||||
alert: 100,
|
||||
id: 1,
|
||||
alias: 'Repo1',
|
||||
lastSave: expect.any(Number),
|
||||
storageSize: 0,
|
||||
storageUsed: 0,
|
||||
sshPublicKey: '',
|
||||
comment: '',
|
||||
lastStatusAlertSend: 1000,
|
||||
},
|
||||
]);
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
|
|
@ -279,19 +356,32 @@ describe('Cronjob API Handler', () => {
|
|||
|
||||
it('should update lastStatusAlertSend if repo is down and alert is enabled', async () => {
|
||||
const currentTime = 1741535661;
|
||||
(getRepoList as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getRepoList).mockResolvedValue([
|
||||
{
|
||||
repositoryName: 'repo1',
|
||||
alias: 'Repo1',
|
||||
status: false,
|
||||
alert: 100,
|
||||
id: 1,
|
||||
lastSave: 0,
|
||||
storageSize: 0,
|
||||
storageUsed: 0,
|
||||
sshPublicKey: '',
|
||||
comment: '',
|
||||
},
|
||||
]);
|
||||
(getLastSaveListShell as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getLastSaveListShell).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', lastSave: currentTime - 200 },
|
||||
]);
|
||||
(getUsersList as jest.Mock).mockResolvedValue([
|
||||
{ emailAlert: true, email: 'test@example.com', username: 'TestUser' },
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
password: 'hashed-password',
|
||||
roles: ['user'],
|
||||
emailAlert: true,
|
||||
email: 'test@example.com',
|
||||
username: 'TestUser',
|
||||
},
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
|
|
@ -307,8 +397,13 @@ describe('Cronjob API Handler', () => {
|
|||
alias: 'Repo1',
|
||||
status: false,
|
||||
alert: 100,
|
||||
id: 1,
|
||||
lastSave: currentTime - 200,
|
||||
lastStatusAlertSend: expect.any(Number),
|
||||
lastSave: expect.any(Number),
|
||||
storageSize: 0,
|
||||
storageUsed: 0,
|
||||
sshPublicKey: '',
|
||||
comment: '',
|
||||
},
|
||||
]);
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
|
|
@ -316,16 +411,22 @@ describe('Cronjob API Handler', () => {
|
|||
|
||||
it('should not update lastStatusAlertSend or send alerts if alert is disabled', async () => {
|
||||
const currentTime = Math.floor(Date.now() / 1000);
|
||||
(getRepoList as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getRepoList).mockResolvedValue([
|
||||
{
|
||||
repositoryName: 'repo1',
|
||||
alias: 'Repo1',
|
||||
status: false,
|
||||
alert: 0,
|
||||
lastStatusAlertSend: null,
|
||||
lastStatusAlertSend: undefined,
|
||||
id: 1,
|
||||
lastSave: 0,
|
||||
storageSize: 0,
|
||||
storageUsed: 0,
|
||||
sshPublicKey: '',
|
||||
comment: '',
|
||||
},
|
||||
]);
|
||||
(getLastSaveListShell as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getLastSaveListShell).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', lastSave: currentTime - 200 },
|
||||
]);
|
||||
|
||||
|
|
@ -342,8 +443,13 @@ describe('Cronjob API Handler', () => {
|
|||
alias: 'Repo1',
|
||||
status: false,
|
||||
alert: 0,
|
||||
lastStatusAlertSend: null,
|
||||
lastStatusAlertSend: undefined,
|
||||
id: 1,
|
||||
lastSave: currentTime - 200,
|
||||
storageSize: 0,
|
||||
storageUsed: 0,
|
||||
sshPublicKey: '',
|
||||
comment: '',
|
||||
},
|
||||
]);
|
||||
expect(nodemailerSMTP).not.toHaveBeenCalled();
|
||||
|
|
@ -352,20 +458,33 @@ describe('Cronjob API Handler', () => {
|
|||
|
||||
it('should update lastStatusAlertSend only if the last alert was sent more than 90000 seconds ago', async () => {
|
||||
const currentTime = Math.floor(Date.now() / 1000);
|
||||
(getRepoList as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getRepoList).mockResolvedValue([
|
||||
{
|
||||
repositoryName: 'repo1',
|
||||
alias: 'Repo1',
|
||||
status: false,
|
||||
alert: 100,
|
||||
lastStatusAlertSend: currentTime - 80000,
|
||||
id: 1,
|
||||
lastSave: 0,
|
||||
storageSize: 0,
|
||||
storageUsed: 0,
|
||||
sshPublicKey: '',
|
||||
comment: '',
|
||||
},
|
||||
]);
|
||||
(getLastSaveListShell as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getLastSaveListShell).mockResolvedValue([
|
||||
{ repositoryName: 'repo1', lastSave: currentTime - 200 },
|
||||
]);
|
||||
(getUsersList as jest.Mock).mockResolvedValue([
|
||||
{ emailAlert: true, email: 'test@example.com', username: 'TestUser' },
|
||||
vi.mocked(getUsersList).mockResolvedValue([
|
||||
{
|
||||
id: 1,
|
||||
password: 'hashed-password',
|
||||
roles: ['user'],
|
||||
emailAlert: true,
|
||||
email: 'test@example.com',
|
||||
username: 'TestUser',
|
||||
},
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
|
|
@ -382,7 +501,12 @@ describe('Cronjob API Handler', () => {
|
|||
status: false,
|
||||
alert: 100,
|
||||
lastStatusAlertSend: expect.any(Number),
|
||||
id: 1,
|
||||
lastSave: currentTime - 200,
|
||||
storageSize: 0,
|
||||
storageUsed: 0,
|
||||
sshPublicKey: '',
|
||||
comment: '',
|
||||
},
|
||||
]);
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
|
|
@ -1,23 +1,21 @@
|
|||
import handler from '~/pages/api/cronjob/getStorageUsed';
|
||||
import { createMocks } from 'node-mocks-http';
|
||||
import { getRepoList, updateRepoList } from '~/helpers/functions';
|
||||
import { getRepoList, updateRepoList } from '~/services';
|
||||
import { getStorageUsedShell } from '~/helpers/functions/shell.utils';
|
||||
|
||||
jest.mock('~/helpers/functions', () => ({
|
||||
getRepoList: jest.fn(),
|
||||
updateRepoList: jest.fn(),
|
||||
vi.mock('~/services', () => ({
|
||||
getRepoList: vi.fn(),
|
||||
updateRepoList: vi.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/helpers/functions/shell.utils', () => ({
|
||||
getStorageUsedShell: jest.fn(),
|
||||
vi.mock('~/helpers/functions/shell.utils', () => ({
|
||||
getStorageUsedShell: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('GET /api/cronjob/getStorageUsed', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.resetModules();
|
||||
jest.resetAllMocks();
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
vi.clearAllMocks();
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
const CRONJOB_KEY = 'test-cronjob-key';
|
||||
|
|
@ -47,7 +45,7 @@ describe('GET /api/cronjob/getStorageUsed', () => {
|
|||
});
|
||||
|
||||
it('should return success if no repositories are found', async () => {
|
||||
(getRepoList as jest.Mock).mockResolvedValue([]);
|
||||
vi.mocked(getRepoList).mockResolvedValue([]);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
|
|
@ -72,9 +70,9 @@ describe('GET /api/cronjob/getStorageUsed', () => {
|
|||
{ name: 'repo2', size: 200 },
|
||||
];
|
||||
|
||||
(getRepoList as jest.Mock).mockResolvedValue(mockRepoList);
|
||||
(getStorageUsedShell as jest.Mock).mockResolvedValue(mockStorageUsed);
|
||||
(updateRepoList as jest.Mock).mockResolvedValue(undefined);
|
||||
vi.mocked(getRepoList).mockResolvedValue(mockRepoList);
|
||||
vi.mocked(getStorageUsedShell).mockResolvedValue(mockStorageUsed);
|
||||
vi.mocked(updateRepoList).mockResolvedValue(undefined);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
|
|
@ -94,7 +92,7 @@ describe('GET /api/cronjob/getStorageUsed', () => {
|
|||
});
|
||||
|
||||
it('should return server error if an exception occurs', async () => {
|
||||
(getRepoList as jest.Mock).mockRejectedValue(new Error('Test error'));
|
||||
vi.mocked(getRepoList).mockRejectedValue(new Error('Test error'));
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
|
|
@ -115,9 +113,9 @@ describe('GET /api/cronjob/getStorageUsed', () => {
|
|||
];
|
||||
const mockStorageUsed = [{ name: 'repo1', size: 100 }];
|
||||
|
||||
(getRepoList as jest.Mock).mockResolvedValue(mockRepoList);
|
||||
(getStorageUsedShell as jest.Mock).mockResolvedValue(mockStorageUsed);
|
||||
(updateRepoList as jest.Mock).mockResolvedValue(undefined);
|
||||
vi.mocked(getRepoList).mockResolvedValue(mockRepoList);
|
||||
vi.mocked(getStorageUsedShell).mockResolvedValue(mockStorageUsed);
|
||||
vi.mocked(updateRepoList).mockResolvedValue(undefined);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { getRepoList, updateRepoList } from '~/helpers/functions';
|
||||
import { getRepoList, updateRepoList } from '~/services';
|
||||
import ApiResponse from '~/helpers/functions/apiResponse';
|
||||
import { getStorageUsedShell } from '~/helpers/functions/shell.utils';
|
||||
import { BorgWarehouseApiResponse } from '~/types/api/error.types';
|
||||
|
|
|
|||
|
|
@ -1,45 +1,34 @@
|
|||
import { createMocks } from 'node-mocks-http';
|
||||
import handler from '~/pages/api/repo/add';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import {
|
||||
getRepoList,
|
||||
updateRepoList,
|
||||
tokenController,
|
||||
isSshPubKeyDuplicate,
|
||||
} from '~/helpers/functions';
|
||||
import { tokenController, isSshPubKeyDuplicate } from '~/helpers/functions';
|
||||
import { getRepoList, updateRepoList } from '~/services';
|
||||
import { createRepoShell } from '~/helpers/functions/shell.utils';
|
||||
|
||||
jest.mock('next-auth', () => {
|
||||
return jest.fn(() => {
|
||||
return {
|
||||
auth: { session: {} },
|
||||
GET: jest.fn(),
|
||||
POST: jest.fn(),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
jest.mock('next-auth/next', () => ({
|
||||
getServerSession: jest.fn(),
|
||||
vi.mock('next-auth/next', () => ({
|
||||
getServerSession: vi.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/helpers/functions', () => ({
|
||||
getRepoList: jest.fn(),
|
||||
updateRepoList: jest.fn(),
|
||||
tokenController: jest.fn(),
|
||||
isSshPubKeyDuplicate: jest.fn(),
|
||||
vi.mock('~/helpers/functions', () => ({
|
||||
tokenController: vi.fn(),
|
||||
isSshPubKeyDuplicate: vi.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/helpers/functions/shell.utils', () => ({
|
||||
createRepoShell: jest.fn(),
|
||||
vi.mock('~/services', () => ({
|
||||
getRepoList: vi.fn(),
|
||||
updateRepoList: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('~/helpers/functions/shell.utils', () => ({
|
||||
createRepoShell: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('POST /api/repo/add', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.resetModules();
|
||||
jest.resetAllMocks();
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
vi.clearAllMocks();
|
||||
vi.resetModules();
|
||||
vi.resetAllMocks();
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return 405 if method is not POST', async () => {
|
||||
|
|
@ -55,8 +44,8 @@ describe('POST /api/repo/add', () => {
|
|||
});
|
||||
|
||||
it('should return 401 if API key is invalid', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
(tokenController as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
vi.mocked(tokenController).mockResolvedValue(null);
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
headers: { authorization: 'Bearer INVALID_API_KEY' },
|
||||
|
|
@ -66,8 +55,8 @@ describe('POST /api/repo/add', () => {
|
|||
});
|
||||
|
||||
it('should return 403 if API key does not have create permissions', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
(tokenController as jest.Mock).mockResolvedValue({ create: false });
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
vi.mocked(tokenController).mockResolvedValue({ create: false });
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
headers: { authorization: 'Bearer API_KEY' },
|
||||
|
|
@ -77,9 +66,9 @@ describe('POST /api/repo/add', () => {
|
|||
});
|
||||
|
||||
it('should return 409 if SSH key is duplicated', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
(getRepoList as jest.Mock).mockResolvedValue([{ id: 1, sshPublicKey: 'duplicate-key' }]);
|
||||
(isSshPubKeyDuplicate as jest.Mock).mockReturnValue(true);
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getRepoList).mockResolvedValue([{ id: 1, sshPublicKey: 'duplicate-key' }]);
|
||||
(isSshPubKeyDuplicate as vi.Mock).mockReturnValue(true);
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
body: { alias: 'repo1', sshPublicKey: 'duplicate-key', storageSize: 10 },
|
||||
|
|
@ -89,9 +78,9 @@ describe('POST /api/repo/add', () => {
|
|||
});
|
||||
|
||||
it('should return 500 if createRepoShell fails', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
(getRepoList as jest.Mock).mockResolvedValue([]);
|
||||
(createRepoShell as jest.Mock).mockResolvedValue({ stderr: 'Error' });
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getRepoList).mockResolvedValue([]);
|
||||
(createRepoShell as vi.Mock).mockResolvedValue({ stderr: 'Error' });
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
body: { alias: 'repo1', sshPublicKey: 'valid-key', storageSize: 10 },
|
||||
|
|
@ -101,10 +90,10 @@ describe('POST /api/repo/add', () => {
|
|||
});
|
||||
|
||||
it('should successfully create a repository with a session', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
(getRepoList as jest.Mock).mockResolvedValue([]);
|
||||
(createRepoShell as jest.Mock).mockResolvedValue({ stdout: 'new-repo' });
|
||||
(updateRepoList as jest.Mock).mockResolvedValue(true);
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getRepoList).mockResolvedValue([]);
|
||||
(createRepoShell as vi.Mock).mockResolvedValue({ stdout: 'new-repo' });
|
||||
vi.mocked(updateRepoList).mockResolvedValue(true);
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
body: { alias: 'repo1', sshPublicKey: 'valid-key', storageSize: 10 },
|
||||
|
|
@ -115,10 +104,10 @@ describe('POST /api/repo/add', () => {
|
|||
});
|
||||
|
||||
it('should add missing optional properties with default values and update repo list correctly', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
(getRepoList as jest.Mock).mockResolvedValue([]);
|
||||
(createRepoShell as jest.Mock).mockResolvedValue({ stdout: 'new-repo' });
|
||||
(updateRepoList as jest.Mock).mockResolvedValue(true);
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getRepoList).mockResolvedValue([]);
|
||||
(createRepoShell as vi.Mock).mockResolvedValue({ stdout: 'new-repo' });
|
||||
vi.mocked(updateRepoList).mockResolvedValue(true);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
|
|
@ -153,16 +142,16 @@ describe('POST /api/repo/add', () => {
|
|||
});
|
||||
|
||||
it('should assign the correct ID based on existing repositories', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
|
||||
(getRepoList as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getRepoList).mockResolvedValue([
|
||||
{ id: 0, alias: 'repo0', sshPublicKey: 'key0', storageSize: 10 },
|
||||
{ id: 1, alias: 'repo1', sshPublicKey: 'key1', storageSize: 20 },
|
||||
{ id: 3, alias: 'repo3', sshPublicKey: 'key3', storageSize: 30 },
|
||||
]);
|
||||
|
||||
(createRepoShell as jest.Mock).mockResolvedValue({ stdout: 'new-repo' });
|
||||
(updateRepoList as jest.Mock).mockResolvedValue(true);
|
||||
(createRepoShell as vi.Mock).mockResolvedValue({ stdout: 'new-repo' });
|
||||
vi.mocked(updateRepoList).mockResolvedValue(true);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
|
|
@ -1,16 +1,12 @@
|
|||
import { authOptions } from '../auth/[...nextauth]';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import {
|
||||
getRepoList,
|
||||
updateRepoList,
|
||||
tokenController,
|
||||
isSshPubKeyDuplicate,
|
||||
} from '~/helpers/functions';
|
||||
import { tokenController, isSshPubKeyDuplicate } from '~/helpers/functions';
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import ApiResponse from '~/helpers/functions/apiResponse';
|
||||
import { Repository } from '~/types/domain/config.types';
|
||||
import { createRepoShell } from '~/helpers/functions/shell.utils';
|
||||
import { getUnixTime } from 'date-fns';
|
||||
import { getRepoList, updateRepoList } from '~/services';
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest & { body: Partial<Repository> },
|
||||
|
|
|
|||
|
|
@ -2,39 +2,33 @@ import { createMocks } from 'node-mocks-http';
|
|||
import handler from '~/pages/api/repo/id/[slug]/delete';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { deleteRepoShell } from '~/helpers/functions/shell.utils';
|
||||
import { getRepoList, tokenController, updateRepoList } from '~/helpers/functions';
|
||||
import { getRepoList, updateRepoList } from '~/services';
|
||||
import { tokenController } from '~/helpers/functions';
|
||||
|
||||
jest.mock('next-auth', () => {
|
||||
return jest.fn(() => {
|
||||
return {
|
||||
auth: { session: {} },
|
||||
GET: jest.fn(),
|
||||
POST: jest.fn(),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
jest.mock('next-auth/next', () => ({
|
||||
getServerSession: jest.fn(),
|
||||
vi.mock('next-auth/next', () => ({
|
||||
getServerSession: vi.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/helpers/functions', () => ({
|
||||
getRepoList: jest.fn(),
|
||||
updateRepoList: jest.fn(),
|
||||
tokenController: jest.fn(),
|
||||
vi.mock('~/helpers/functions', () => ({
|
||||
tokenController: vi.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/helpers/functions/shell.utils', () => {
|
||||
vi.mock('~/services', () => ({
|
||||
getRepoList: vi.fn(),
|
||||
updateRepoList: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('~/helpers/functions/shell.utils', () => {
|
||||
return {
|
||||
deleteRepoShell: jest.fn(),
|
||||
deleteRepoShell: vi.fn(),
|
||||
};
|
||||
});
|
||||
|
||||
describe('DELETE /api/repo/id/[slug]/delete', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.resetModules();
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
vi.clearAllMocks();
|
||||
vi.resetModules();
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return 405 if method is not DELETE', async () => {
|
||||
|
|
@ -51,7 +45,7 @@ describe('DELETE /api/repo/id/[slug]/delete', () => {
|
|||
|
||||
it('should return 403 if deletion is disabled via environment variable', async () => {
|
||||
process.env.DISABLE_DELETE_REPO = 'true';
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'USER' },
|
||||
});
|
||||
const { req, res } = createMocks({ method: 'DELETE' });
|
||||
|
|
@ -65,7 +59,7 @@ describe('DELETE /api/repo/id/[slug]/delete', () => {
|
|||
});
|
||||
|
||||
it('should return 400 if slug is missing or malformed', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'USER' },
|
||||
});
|
||||
const { req, res } = createMocks({
|
||||
|
|
@ -81,14 +75,14 @@ describe('DELETE /api/repo/id/[slug]/delete', () => {
|
|||
});
|
||||
|
||||
it('should return 404 if repository is not found', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'USER' },
|
||||
});
|
||||
const { req, res } = createMocks({
|
||||
method: 'DELETE',
|
||||
query: { slug: '123' },
|
||||
});
|
||||
(getRepoList as jest.Mock).mockResolvedValue([]);
|
||||
vi.mocked(getRepoList).mockResolvedValue([]);
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(404);
|
||||
expect(res._getJSONData()).toEqual({
|
||||
|
|
@ -98,15 +92,15 @@ describe('DELETE /api/repo/id/[slug]/delete', () => {
|
|||
});
|
||||
|
||||
it('should return 500 if deleteRepo fails', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'USER' },
|
||||
});
|
||||
const { req, res } = createMocks({
|
||||
method: 'DELETE',
|
||||
query: { slug: '123' },
|
||||
});
|
||||
(getRepoList as jest.Mock).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]);
|
||||
(deleteRepoShell as jest.Mock).mockResolvedValue({ stderr: 'Error' });
|
||||
vi.mocked(getRepoList).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]);
|
||||
vi.mocked(deleteRepoShell).mockResolvedValue({ stderr: 'Error' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(500);
|
||||
expect(res._getJSONData()).toEqual({
|
||||
|
|
@ -117,16 +111,16 @@ describe('DELETE /api/repo/id/[slug]/delete', () => {
|
|||
});
|
||||
|
||||
it('should delete the repository and return 200 on success with a session', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
vi.mocked(getServerSession).mockResolvedValue({
|
||||
user: { name: 'USER' },
|
||||
});
|
||||
const { req, res } = createMocks({
|
||||
method: 'DELETE',
|
||||
query: { slug: '1234' },
|
||||
});
|
||||
(getRepoList as jest.Mock).mockResolvedValue([{ id: 1234, repositoryName: 'test-repo' }]);
|
||||
(deleteRepoShell as jest.Mock).mockResolvedValue({ stderr: null });
|
||||
(updateRepoList as jest.Mock).mockResolvedValue(true);
|
||||
vi.mocked(getRepoList).mockResolvedValue([{ id: 1234, repositoryName: 'test-repo' }]);
|
||||
vi.mocked(deleteRepoShell).mockResolvedValue({ stderr: null });
|
||||
vi.mocked(updateRepoList).mockResolvedValue(true);
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
expect(res._getJSONData()).toEqual({
|
||||
|
|
@ -137,8 +131,8 @@ describe('DELETE /api/repo/id/[slug]/delete', () => {
|
|||
});
|
||||
|
||||
it('should delete the repository and return 200 on success with an API key', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
(tokenController as jest.Mock).mockResolvedValue({ delete: true });
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
vi.mocked(tokenController).mockResolvedValue({ delete: true });
|
||||
const { req, res } = createMocks({
|
||||
method: 'DELETE',
|
||||
query: { slug: '12345' },
|
||||
|
|
@ -146,9 +140,9 @@ describe('DELETE /api/repo/id/[slug]/delete', () => {
|
|||
authorization: 'Bearer API_KEY',
|
||||
},
|
||||
});
|
||||
(getRepoList as jest.Mock).mockResolvedValue([{ id: 12345, repositoryName: 'test-repo2' }]);
|
||||
(deleteRepoShell as jest.Mock).mockResolvedValue({ stderr: null });
|
||||
(updateRepoList as jest.Mock).mockResolvedValue(true);
|
||||
vi.mocked(getRepoList).mockResolvedValue([{ id: 12345, repositoryName: 'test-repo2' }]);
|
||||
vi.mocked(deleteRepoShell).mockResolvedValue({ stderr: null });
|
||||
vi.mocked(updateRepoList).mockResolvedValue(true);
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
expect(res._getJSONData()).toEqual({
|
||||
|
|
@ -159,8 +153,8 @@ describe('DELETE /api/repo/id/[slug]/delete', () => {
|
|||
});
|
||||
|
||||
it('should return 401 if the API key is invalid', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
(tokenController as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
vi.mocked(tokenController).mockResolvedValue(null);
|
||||
const { req, res } = createMocks({
|
||||
method: 'DELETE',
|
||||
query: { slug: '12345' },
|
||||
|
|
@ -177,8 +171,8 @@ describe('DELETE /api/repo/id/[slug]/delete', () => {
|
|||
});
|
||||
|
||||
it('should return 403 if the API key does not have delete permissions', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
(tokenController as jest.Mock).mockResolvedValue({ delete: false });
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
vi.mocked(tokenController).mockResolvedValue({ delete: false });
|
||||
const { req, res } = createMocks({
|
||||
method: 'DELETE',
|
||||
query: { slug: '12345' },
|
||||
|
|
@ -1,7 +1,8 @@
|
|||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { getRepoList, updateRepoList, tokenController } from '~/helpers/functions';
|
||||
import { tokenController } from '~/helpers/functions';
|
||||
import { deleteRepoShell } from '~/helpers/functions/shell.utils';
|
||||
import { getRepoList, updateRepoList } from '~/services';
|
||||
|
||||
import ApiResponse from '~/helpers/functions/apiResponse';
|
||||
import { BorgWarehouseApiResponse } from '~/types/api/error.types';
|
||||
|
|
|
|||
|
|
@ -2,44 +2,34 @@ import { createMocks } from 'node-mocks-http';
|
|||
import handler from '~/pages/api/repo/id/[slug]/edit';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { updateRepoShell } from '~/helpers/functions/shell.utils';
|
||||
import {
|
||||
getRepoList,
|
||||
updateRepoList,
|
||||
tokenController,
|
||||
isSshPubKeyDuplicate,
|
||||
} from '~/helpers/functions';
|
||||
import { tokenController, isSshPubKeyDuplicate } from '~/helpers/functions';
|
||||
import { getRepoList, updateRepoList } from '~/services';
|
||||
|
||||
jest.mock('next-auth', () => {
|
||||
return jest.fn(() => {
|
||||
return {
|
||||
auth: { session: {} },
|
||||
GET: jest.fn(),
|
||||
POST: jest.fn(),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
jest.mock('next-auth/next', () => ({
|
||||
getServerSession: jest.fn(),
|
||||
vi.mock('next-auth/next', () => ({
|
||||
__esModule: true,
|
||||
getServerSession: vi.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/helpers/functions', () => ({
|
||||
getRepoList: jest.fn(),
|
||||
updateRepoList: jest.fn(),
|
||||
tokenController: jest.fn(),
|
||||
isSshPubKeyDuplicate: jest.fn(),
|
||||
vi.mock('~/helpers/functions', () => ({
|
||||
tokenController: vi.fn(),
|
||||
isSshPubKeyDuplicate: vi.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/helpers/functions/shell.utils', () => ({
|
||||
updateRepoShell: jest.fn(),
|
||||
vi.mock('~/helpers/functions/shell.utils', () => ({
|
||||
updateRepoShell: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('~/services', () => ({
|
||||
getRepoList: vi.fn(),
|
||||
updateRepoList: vi.fn(),
|
||||
}));
|
||||
|
||||
describe('PATCH /api/repo/id/[slug]/edit', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.resetModules();
|
||||
jest.resetAllMocks();
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
vi.clearAllMocks();
|
||||
vi.resetModules();
|
||||
vi.resetAllMocks();
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return 405 if method is not PATCH', async () => {
|
||||
|
|
@ -55,8 +45,8 @@ describe('PATCH /api/repo/id/[slug]/edit', () => {
|
|||
});
|
||||
|
||||
it('should return 401 if API key is invalid', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
(tokenController as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
vi.mocked(tokenController).mockResolvedValue(null);
|
||||
const { req, res } = createMocks({
|
||||
method: 'PATCH',
|
||||
headers: { authorization: 'Bearer INVALID_API_KEY' },
|
||||
|
|
@ -66,8 +56,8 @@ describe('PATCH /api/repo/id/[slug]/edit', () => {
|
|||
});
|
||||
|
||||
it('should return 403 if API key does not have update permissions', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
(tokenController as jest.Mock).mockResolvedValue({ update: false });
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
vi.mocked(tokenController).mockResolvedValue({ update: false });
|
||||
const { req, res } = createMocks({
|
||||
method: 'PATCH',
|
||||
headers: { authorization: 'Bearer API_KEY' },
|
||||
|
|
@ -77,24 +67,24 @@ describe('PATCH /api/repo/id/[slug]/edit', () => {
|
|||
});
|
||||
|
||||
it('should return 400 if slug is missing or malformed', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
const { req, res } = createMocks({ method: 'PATCH', query: { slug: undefined } });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(400);
|
||||
});
|
||||
|
||||
it('should return 404 if repository is not found', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
(getRepoList as jest.Mock).mockResolvedValue([]);
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getRepoList).mockResolvedValue([]);
|
||||
const { req, res } = createMocks({ method: 'PATCH', query: { slug: '123' } });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(404);
|
||||
});
|
||||
|
||||
it('should return 409 if SSH key is duplicated', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
(getRepoList as jest.Mock).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]);
|
||||
(isSshPubKeyDuplicate as jest.Mock).mockReturnValue(true);
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getRepoList).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]);
|
||||
(isSshPubKeyDuplicate as vi.Mock).mockReturnValue(true);
|
||||
const { req, res } = createMocks({
|
||||
method: 'PATCH',
|
||||
query: { slug: '123' },
|
||||
|
|
@ -105,9 +95,9 @@ describe('PATCH /api/repo/id/[slug]/edit', () => {
|
|||
});
|
||||
|
||||
it('should return 500 if updateRepoShell fails', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
(getRepoList as jest.Mock).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]);
|
||||
(updateRepoShell as jest.Mock).mockResolvedValue({ stderr: 'Error' });
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getRepoList).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]);
|
||||
(updateRepoShell as vi.Mock).mockResolvedValue({ stderr: 'Error' });
|
||||
const { req, res } = createMocks({
|
||||
method: 'PATCH',
|
||||
query: { slug: '123' },
|
||||
|
|
@ -118,10 +108,10 @@ describe('PATCH /api/repo/id/[slug]/edit', () => {
|
|||
});
|
||||
|
||||
it('should successfully update repository with a session', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
(getRepoList as jest.Mock).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]);
|
||||
(updateRepoShell as jest.Mock).mockResolvedValue({ stderr: null });
|
||||
(updateRepoList as jest.Mock).mockResolvedValue(true);
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getRepoList).mockResolvedValue([{ id: 123, repositoryName: 'test-repo' }]);
|
||||
(updateRepoShell as vi.Mock).mockResolvedValue({ stderr: null });
|
||||
vi.mocked(updateRepoList).mockResolvedValue(true);
|
||||
const { req, res } = createMocks({
|
||||
method: 'PATCH',
|
||||
query: { slug: '123' },
|
||||
|
|
@ -133,11 +123,11 @@ describe('PATCH /api/repo/id/[slug]/edit', () => {
|
|||
});
|
||||
|
||||
it('should successfully update repository with API key', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
(tokenController as jest.Mock).mockResolvedValue({ update: true });
|
||||
(getRepoList as jest.Mock).mockResolvedValue([{ id: 456, repositoryName: 'repo-key' }]);
|
||||
(updateRepoShell as jest.Mock).mockResolvedValue({ stderr: null });
|
||||
(updateRepoList as jest.Mock).mockResolvedValue(true);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
vi.mocked(tokenController).mockResolvedValue({ update: true });
|
||||
vi.mocked(getRepoList).mockResolvedValue([{ id: 456, repositoryName: 'repo-key' }]);
|
||||
(updateRepoShell as vi.Mock).mockResolvedValue({ stderr: null });
|
||||
vi.mocked(updateRepoList).mockResolvedValue(true);
|
||||
const { req, res } = createMocks({
|
||||
method: 'PATCH',
|
||||
query: { slug: '456' },
|
||||
|
|
@ -150,8 +140,8 @@ describe('PATCH /api/repo/id/[slug]/edit', () => {
|
|||
});
|
||||
|
||||
it('should only update the provided fields, keep the rest unchanged and history the modification.', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
(getRepoList as jest.Mock).mockResolvedValue([
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getRepoList).mockResolvedValue([
|
||||
{
|
||||
id: 123,
|
||||
repositoryName: 'test-repo',
|
||||
|
|
@ -161,8 +151,8 @@ describe('PATCH /api/repo/id/[slug]/edit', () => {
|
|||
lanCommand: false,
|
||||
},
|
||||
]);
|
||||
(updateRepoShell as jest.Mock).mockResolvedValue({ stderr: null });
|
||||
(updateRepoList as jest.Mock).mockResolvedValue(true);
|
||||
(updateRepoShell as vi.Mock).mockResolvedValue({ stderr: null });
|
||||
vi.mocked(updateRepoList).mockResolvedValue(true);
|
||||
const { req, res } = createMocks({
|
||||
method: 'PATCH',
|
||||
query: { slug: '123' },
|
||||
|
|
@ -1,15 +1,11 @@
|
|||
import { authOptions } from '../../../auth/[...nextauth]';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import {
|
||||
getRepoList,
|
||||
updateRepoList,
|
||||
tokenController,
|
||||
isSshPubKeyDuplicate,
|
||||
} from '~/helpers/functions';
|
||||
import { tokenController, isSshPubKeyDuplicate } from '~/helpers/functions';
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import ApiResponse from '~/helpers/functions/apiResponse';
|
||||
import { Repository } from '~/types/domain/config.types';
|
||||
import { updateRepoShell } from '~/helpers/functions/shell.utils';
|
||||
import { getRepoList, updateRepoList } from '~/services';
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest & { body: Partial<Repository> },
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ import { getServerSession } from 'next-auth/next';
|
|||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { BorgWarehouseApiResponse } from '~/types/api/error.types';
|
||||
import ApiResponse from '~/helpers/functions/apiResponse';
|
||||
import { getRepoList, tokenController } from '~/helpers/functions';
|
||||
import { tokenController } from '~/helpers/functions';
|
||||
import { Repository } from '~/types/domain/config.types';
|
||||
import { getRepoList } from '~/services';
|
||||
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
|
|
|
|||
|
|
@ -1,26 +1,20 @@
|
|||
import { createMocks } from 'node-mocks-http';
|
||||
import handler from '~/pages/api/repo/id/[slug]';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { getRepoList, tokenController } from '~/helpers/functions';
|
||||
import { tokenController } from '~/helpers/functions';
|
||||
import { getRepoList } from '~/services';
|
||||
import { Repository } from '~/types/domain/config.types';
|
||||
|
||||
jest.mock('next-auth', () => {
|
||||
return jest.fn(() => {
|
||||
return {
|
||||
auth: { session: {} },
|
||||
GET: jest.fn(),
|
||||
POST: jest.fn(),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
jest.mock('next-auth/next', () => ({
|
||||
getServerSession: jest.fn(),
|
||||
vi.mock('next-auth/next', () => ({
|
||||
getServerSession: vi.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/helpers/functions', () => ({
|
||||
getRepoList: jest.fn(),
|
||||
tokenController: jest.fn(),
|
||||
vi.mock('~/helpers/functions', () => ({
|
||||
tokenController: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('~/services', () => ({
|
||||
getRepoList: vi.fn(),
|
||||
}));
|
||||
|
||||
const mockRepoList: Repository[] = [
|
||||
|
|
@ -58,9 +52,9 @@ const mockRepoList: Repository[] = [
|
|||
|
||||
describe('GET /api/repo/id/[slug]', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.resetModules();
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
vi.clearAllMocks();
|
||||
vi.resetModules();
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return 405 if method is not GET', async () => {
|
||||
|
|
@ -76,8 +70,8 @@ describe('GET /api/repo/id/[slug]', () => {
|
|||
});
|
||||
|
||||
it('should return 401 if API key is invalid', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
(tokenController as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
vi.mocked(tokenController).mockResolvedValue(null);
|
||||
const { req, res } = createMocks({
|
||||
method: 'GET',
|
||||
headers: { authorization: 'Bearer INVALID_API_KEY' },
|
||||
|
|
@ -87,8 +81,8 @@ describe('GET /api/repo/id/[slug]', () => {
|
|||
});
|
||||
|
||||
it('should return 403 if API key does not have read permissions', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
(tokenController as jest.Mock).mockResolvedValue({ read: false });
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
vi.mocked(tokenController).mockResolvedValue({ read: false });
|
||||
const { req, res } = createMocks({
|
||||
method: 'GET',
|
||||
headers: { authorization: 'Bearer API_KEY' },
|
||||
|
|
@ -98,23 +92,23 @@ describe('GET /api/repo/id/[slug]', () => {
|
|||
});
|
||||
|
||||
it('should return 400 if slug is missing or malformed', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
const { req, res } = createMocks({ method: 'GET', query: { slug: undefined } });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(400);
|
||||
});
|
||||
|
||||
it('should return 404 if repository is not found', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
(getRepoList as jest.Mock).mockResolvedValue([]);
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getRepoList).mockResolvedValue([]);
|
||||
const { req, res } = createMocks({ method: 'GET', query: { slug: '3' } });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(404);
|
||||
});
|
||||
|
||||
it('should return 200 and the repository data if found', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
(getRepoList as jest.Mock).mockResolvedValue(mockRepoList);
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getRepoList).mockResolvedValue(mockRepoList);
|
||||
const { req, res } = createMocks({ method: 'GET', query: { slug: '1' } });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
|
|
@ -3,7 +3,8 @@ import { getServerSession } from 'next-auth/next';
|
|||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { BorgWarehouseApiResponse } from '~/types/api/error.types';
|
||||
import ApiResponse from '~/helpers/functions/apiResponse';
|
||||
import { getRepoList, tokenController } from '~/helpers/functions';
|
||||
import { tokenController } from '~/helpers/functions';
|
||||
import { getRepoList } from '~/services';
|
||||
import { Repository } from '~/types/domain/config.types';
|
||||
|
||||
export default async function handler(
|
||||
|
|
|
|||
|
|
@ -1,26 +1,20 @@
|
|||
import { createMocks } from 'node-mocks-http';
|
||||
import handler from '~/pages/api/repo';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { getRepoList, tokenController } from '~/helpers/functions';
|
||||
import { tokenController } from '~/helpers/functions';
|
||||
import { getRepoList } from '~/services';
|
||||
import { Repository } from '~/types/domain/config.types';
|
||||
|
||||
jest.mock('next-auth', () => {
|
||||
return jest.fn(() => {
|
||||
return {
|
||||
auth: { session: {} },
|
||||
GET: jest.fn(),
|
||||
POST: jest.fn(),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
jest.mock('next-auth/next', () => ({
|
||||
getServerSession: jest.fn(),
|
||||
vi.mock('next-auth/next', () => ({
|
||||
getServerSession: vi.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/helpers/functions', () => ({
|
||||
getRepoList: jest.fn(),
|
||||
tokenController: jest.fn(),
|
||||
vi.mock('~/helpers/functions', () => ({
|
||||
tokenController: vi.fn(),
|
||||
}));
|
||||
|
||||
vi.mock('~/services', () => ({
|
||||
getRepoList: vi.fn(),
|
||||
}));
|
||||
|
||||
const mockRepoList: Repository[] = [
|
||||
|
|
@ -58,9 +52,9 @@ const mockRepoList: Repository[] = [
|
|||
|
||||
describe('GET /api/repo/id/[slug]', () => {
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.resetModules();
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
vi.clearAllMocks();
|
||||
vi.resetModules();
|
||||
vi.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return 405 if method is not GET', async () => {
|
||||
|
|
@ -76,8 +70,8 @@ describe('GET /api/repo/id/[slug]', () => {
|
|||
});
|
||||
|
||||
it('should return 401 if API key is invalid', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
(tokenController as jest.Mock).mockResolvedValue(null);
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
vi.mocked(tokenController).mockResolvedValue(null);
|
||||
const { req, res } = createMocks({
|
||||
method: 'GET',
|
||||
headers: { authorization: 'Bearer INVALID_API_KEY' },
|
||||
|
|
@ -87,8 +81,8 @@ describe('GET /api/repo/id/[slug]', () => {
|
|||
});
|
||||
|
||||
it('should return 403 if API key does not have read permissions', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
(tokenController as jest.Mock).mockResolvedValue({ read: false });
|
||||
vi.mocked(getServerSession).mockResolvedValue(null);
|
||||
vi.mocked(tokenController).mockResolvedValue({ read: false });
|
||||
const { req, res } = createMocks({
|
||||
method: 'GET',
|
||||
headers: { authorization: 'Bearer API_KEY' },
|
||||
|
|
@ -98,8 +92,8 @@ describe('GET /api/repo/id/[slug]', () => {
|
|||
});
|
||||
|
||||
it('should return 200 and the repoList data if found', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'USER' } });
|
||||
(getRepoList as jest.Mock).mockResolvedValue(mockRepoList);
|
||||
vi.mocked(getServerSession).mockResolvedValue({ user: { name: 'USER' } });
|
||||
vi.mocked(getRepoList).mockResolvedValue(mockRepoList);
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
|
|
@ -1,7 +1,3 @@
|
|||
## BATS tests against bash scripts
|
||||
|
||||
From `tests/bats`, launch `docker compose up --build`
|
||||
|
||||
## supertest (Jest) is used to test API endpoints
|
||||
|
||||
Launch `npm test`
|
||||
|
|
|
|||
|
|
@ -1,164 +0,0 @@
|
|||
import handler from '~/pages/api/account/tokenManager';
|
||||
import { createMocks } from 'node-mocks-http';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { getUsersList, updateUsersList } from '~/helpers/functions';
|
||||
import ApiResponse from '~/helpers/functions/apiResponse';
|
||||
|
||||
jest.mock('next-auth', () => {
|
||||
return jest.fn(() => {
|
||||
return {
|
||||
auth: { session: {} },
|
||||
GET: jest.fn(),
|
||||
POST: jest.fn(),
|
||||
};
|
||||
});
|
||||
});
|
||||
|
||||
jest.mock('next-auth/next', () => ({
|
||||
getServerSession: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/helpers/functions', () => ({
|
||||
getUsersList: jest.fn(),
|
||||
updateUsersList: jest.fn(),
|
||||
}));
|
||||
|
||||
jest.mock('~/helpers/functions/apiResponse', () => ({
|
||||
unauthorized: jest.fn(),
|
||||
badRequest: jest.fn(),
|
||||
serverError: jest.fn(),
|
||||
methodNotAllowed: jest.fn(),
|
||||
success: jest.fn(),
|
||||
}));
|
||||
|
||||
describe('Token Manager API', () => {
|
||||
afterEach(() => {
|
||||
jest.clearAllMocks();
|
||||
jest.spyOn(console, 'log').mockImplementation(() => {});
|
||||
});
|
||||
|
||||
it('should return unauthorized if session is not found', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
body: {
|
||||
name: 'testToken',
|
||||
permissions: { create: true, read: true, update: true, delete: true },
|
||||
},
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(ApiResponse.unauthorized).toHaveBeenCalledWith(res);
|
||||
});
|
||||
|
||||
it('should create a new token if valid data is provided', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testUser' } });
|
||||
(getUsersList as jest.Mock).mockResolvedValue([{ username: 'testUser', tokens: [] }]);
|
||||
(updateUsersList as jest.Mock).mockResolvedValue(true);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
body: {
|
||||
name: 'testToken',
|
||||
permissions: { create: true, read: true, update: true, delete: true },
|
||||
},
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
const responseData = JSON.parse(res._getData());
|
||||
expect(responseData).toHaveProperty('token');
|
||||
expect(updateUsersList).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return bad request if token name already exists', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testUser' } });
|
||||
(getUsersList as jest.Mock).mockResolvedValue([
|
||||
{ username: 'testUser', tokens: [{ name: 'testToken', permissions: {}, creation: 123 }] },
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'POST',
|
||||
body: {
|
||||
name: 'testToken',
|
||||
permissions: { create: true, read: true, update: true, delete: true },
|
||||
},
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(ApiResponse.badRequest).toHaveBeenCalledWith(res, 'Token name already exists');
|
||||
});
|
||||
|
||||
it('should return token list for GET request', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testUser' } });
|
||||
(getUsersList as jest.Mock).mockResolvedValue([
|
||||
{
|
||||
username: 'testUser',
|
||||
tokens: [
|
||||
{ name: 'token1', permissions: {}, creation: 123 },
|
||||
{ name: 'token2', permissions: {}, creation: 456 },
|
||||
],
|
||||
},
|
||||
]);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
const responseData = JSON.parse(res._getData());
|
||||
expect(responseData).toEqual([
|
||||
{ name: 'token1', permissions: {}, creation: 123 },
|
||||
{ name: 'token2', permissions: {}, creation: 456 },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should delete a token for DELETE request', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testUser' } });
|
||||
(getUsersList as jest.Mock).mockResolvedValue([
|
||||
{
|
||||
username: 'testUser',
|
||||
tokens: [
|
||||
{ name: 'token1', permissions: {}, creation: 123 },
|
||||
{ name: 'token2', permissions: {}, creation: 456 },
|
||||
],
|
||||
},
|
||||
]);
|
||||
(updateUsersList as jest.Mock).mockResolvedValue(true);
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'DELETE',
|
||||
body: { name: 'token1' },
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(ApiResponse.success).toHaveBeenCalledWith(res, 'Token deleted');
|
||||
expect(updateUsersList).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should return bad request if token name is missing in DELETE request', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({ user: { name: 'testUser' } });
|
||||
|
||||
const { req, res } = createMocks({
|
||||
method: 'DELETE',
|
||||
body: {},
|
||||
});
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(ApiResponse.badRequest).toHaveBeenCalledWith(res, 'Missing token name');
|
||||
});
|
||||
|
||||
it('should return method not allowed for unsupported HTTP methods', async () => {
|
||||
const { req, res } = createMocks({ method: 'PUT' });
|
||||
|
||||
await handler(req, res);
|
||||
|
||||
expect(ApiResponse.methodNotAllowed).toHaveBeenCalledWith(res);
|
||||
});
|
||||
});
|
||||
|
|
@ -16,7 +16,8 @@
|
|||
"moduleResolution": "node",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true,
|
||||
"jsx": "preserve"
|
||||
"jsx": "preserve",
|
||||
"types": ["vitest/globals"] // Auto import vitest types
|
||||
},
|
||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
|
||||
"exclude": ["node_modules"]
|
||||
|
|
|
|||
19
vitest.config.ts
Normal file
19
vitest.config.ts
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
// vitest.config.ts
|
||||
import { defineConfig } from 'vitest/config';
|
||||
import path from 'path';
|
||||
|
||||
export default defineConfig({
|
||||
test: {
|
||||
environment: 'node',
|
||||
coverage: {
|
||||
provider: 'v8',
|
||||
reporter: ['text', 'json', 'html'],
|
||||
},
|
||||
globals: true,
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'~': path.resolve(__dirname, './'),
|
||||
},
|
||||
},
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue