mirror of
https://github.com/Ravinou/borgwarehouse
synced 2026-03-14 14:25:46 +01:00
test: ✅ apprise, email and wizard API
This commit is contained in:
parent
b40c7d7343
commit
d753df49a0
7 changed files with 410 additions and 39 deletions
|
|
@ -1,48 +1,45 @@
|
|||
//Lib
|
||||
import { authOptions } from '~/pages/api/auth/[...nextauth]';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { WizardEnvEnum } from '~/types/domain/config.types';
|
||||
import { WizardEnvEnum, WizardEnvType } from '~/types/domain/config.types';
|
||||
import { NextApiRequest, NextApiResponse } from 'next';
|
||||
import { ErrorResponse } from '~/types/api/error.types';
|
||||
|
||||
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
|
||||
if (req.method == 'GET') {
|
||||
//AUTHENTICATION
|
||||
const session = await getServerSession(req, res, authOptions);
|
||||
if (!session) {
|
||||
res.status(401).json({ message: 'You must be logged in.' });
|
||||
return;
|
||||
export default async function handler(
|
||||
req: NextApiRequest,
|
||||
res: NextApiResponse<WizardEnvType | ErrorResponse>
|
||||
) {
|
||||
if (req.method !== 'GET') {
|
||||
return res.status(405);
|
||||
}
|
||||
const session = await getServerSession(req, res, authOptions);
|
||||
if (!session) {
|
||||
return res.status(401);
|
||||
}
|
||||
|
||||
try {
|
||||
function getEnvVariable(envName: WizardEnvEnum, defaultValue = '') {
|
||||
return process.env[envName] || defaultValue;
|
||||
}
|
||||
|
||||
try {
|
||||
function getEnvVariable(envName: WizardEnvEnum, defaultValue = '') {
|
||||
return process.env[envName] || defaultValue;
|
||||
}
|
||||
const wizardEnv: WizardEnvType = {
|
||||
UNIX_USER: getEnvVariable(WizardEnvEnum.UNIX_USER, 'borgwarehouse'),
|
||||
FQDN: getEnvVariable(WizardEnvEnum.FQDN, 'localhost'),
|
||||
SSH_SERVER_PORT: getEnvVariable(WizardEnvEnum.SSH_SERVER_PORT, '22'),
|
||||
FQDN_LAN: getEnvVariable(WizardEnvEnum.FQDN_LAN),
|
||||
SSH_SERVER_PORT_LAN: getEnvVariable(WizardEnvEnum.SSH_SERVER_PORT_LAN),
|
||||
SSH_SERVER_FINGERPRINT_RSA: getEnvVariable(WizardEnvEnum.SSH_SERVER_FINGERPRINT_RSA),
|
||||
SSH_SERVER_FINGERPRINT_ED25519: getEnvVariable(WizardEnvEnum.SSH_SERVER_FINGERPRINT_ED25519),
|
||||
SSH_SERVER_FINGERPRINT_ECDSA: getEnvVariable(WizardEnvEnum.SSH_SERVER_FINGERPRINT_ECDSA),
|
||||
HIDE_SSH_PORT: getEnvVariable(WizardEnvEnum.HIDE_SSH_PORT, 'false'),
|
||||
DISABLE_INTEGRATIONS: getEnvVariable(WizardEnvEnum.DISABLE_INTEGRATIONS, 'false'),
|
||||
DISABLE_DELETE_REPO: getEnvVariable(WizardEnvEnum.DISABLE_DELETE_REPO, 'false'),
|
||||
};
|
||||
|
||||
const wizardEnv = {
|
||||
UNIX_USER: getEnvVariable(WizardEnvEnum.UNIX_USER, 'borgwarehouse'),
|
||||
FQDN: getEnvVariable(WizardEnvEnum.FQDN, 'localhost'),
|
||||
SSH_SERVER_PORT: getEnvVariable(WizardEnvEnum.SSH_SERVER_PORT, '22'),
|
||||
FQDN_LAN: getEnvVariable(WizardEnvEnum.FQDN_LAN),
|
||||
SSH_SERVER_PORT_LAN: getEnvVariable(WizardEnvEnum.SSH_SERVER_PORT_LAN),
|
||||
SSH_SERVER_FINGERPRINT_RSA: getEnvVariable(WizardEnvEnum.SSH_SERVER_FINGERPRINT_RSA),
|
||||
SSH_SERVER_FINGERPRINT_ED25519: getEnvVariable(
|
||||
WizardEnvEnum.SSH_SERVER_FINGERPRINT_ED25519
|
||||
),
|
||||
SSH_SERVER_FINGERPRINT_ECDSA: getEnvVariable(WizardEnvEnum.SSH_SERVER_FINGERPRINT_ECDSA),
|
||||
HIDE_SSH_PORT: getEnvVariable(WizardEnvEnum.HIDE_SSH_PORT, 'false'),
|
||||
DISABLE_INTEGRATIONS: getEnvVariable(WizardEnvEnum.DISABLE_INTEGRATIONS, 'false'),
|
||||
};
|
||||
|
||||
res.status(200).json({ wizardEnv });
|
||||
return;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
res.status(500).json({
|
||||
message: 'API error, contact the administrator',
|
||||
});
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
res.status(405).json({ message: 'Bad request on API' });
|
||||
res.status(200).json(wizardEnv);
|
||||
return;
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return res.status(500);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
76
tests/supertest/getAppriseAlert.test.ts
Normal file
76
tests/supertest/getAppriseAlert.test.ts
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
import { createMocks } from 'node-mocks-http';
|
||||
import handler from '~/pages/api/account/getAppriseAlert';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { promises as fs } from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
jest.mock('next-auth/next');
|
||||
jest.mock('fs', () => ({
|
||||
promises: {
|
||||
readFile: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('Get Apprise Alert API', () => {
|
||||
it('should return 405 if the method is not GET', async () => {
|
||||
const { req, res } = createMocks({ method: 'POST' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(405);
|
||||
});
|
||||
|
||||
it('should return 401 if the user is not authenticated', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(401);
|
||||
expect(res._getJSONData()).toEqual({ message: 'You must be logged in.' });
|
||||
});
|
||||
|
||||
it('should return 400 if the user does not exist', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
user: { name: 'nonexistent' },
|
||||
});
|
||||
|
||||
(fs.readFile as jest.Mock).mockResolvedValue(
|
||||
JSON.stringify([{ username: 'testuser', appriseAlert: true }])
|
||||
);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(400);
|
||||
expect(res._getJSONData()).toEqual({
|
||||
message: 'User is incorrect. Please, logout to update your session.',
|
||||
});
|
||||
});
|
||||
|
||||
it('should return appriseAlert value if the user exists', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(fs.readFile as jest.Mock).mockResolvedValue(
|
||||
JSON.stringify([{ username: 'testuser', appriseAlert: true }])
|
||||
);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
expect(res._getJSONData()).toEqual({ appriseAlert: true });
|
||||
});
|
||||
|
||||
it('should return 500 if there is an error reading the file', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(fs.readFile as jest.Mock).mockRejectedValue({ code: 'ENOENT' });
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(500);
|
||||
expect(res._getJSONData()).toEqual({ status: 500, message: 'No such file or directory' });
|
||||
});
|
||||
});
|
||||
91
tests/supertest/getAppriseMode.test.ts
Normal file
91
tests/supertest/getAppriseMode.test.ts
Normal file
|
|
@ -0,0 +1,91 @@
|
|||
import { createMocks } from 'node-mocks-http';
|
||||
import handler from '~/pages/api/account/getAppriseMode';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { promises as fs } from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
jest.mock('next-auth/next');
|
||||
jest.mock('fs', () => ({
|
||||
promises: {
|
||||
readFile: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('Get Apprise Mode API', () => {
|
||||
it('should return 405 if the method is not GET', async () => {
|
||||
const { req, res } = createMocks({ method: 'POST' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(405);
|
||||
});
|
||||
|
||||
it('should return 401 if the user is not authenticated', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(401);
|
||||
expect(res._getJSONData()).toEqual({ message: 'You must be logged in.' });
|
||||
});
|
||||
|
||||
it('should return 400 if the user does not exist', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
user: { name: 'nonexistent' },
|
||||
});
|
||||
|
||||
(fs.readFile as jest.Mock).mockResolvedValue(
|
||||
JSON.stringify([
|
||||
{
|
||||
username: 'testuser',
|
||||
appriseMode: 'stateless',
|
||||
appriseStatelessURL: 'https://example.com',
|
||||
},
|
||||
])
|
||||
);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(400);
|
||||
expect(res._getJSONData()).toEqual({
|
||||
message: 'User is incorrect. Please, logout to update your session.',
|
||||
});
|
||||
});
|
||||
|
||||
it('should return appriseMode and appriseStatelessURL if the user exists', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(fs.readFile as jest.Mock).mockResolvedValue(
|
||||
JSON.stringify([
|
||||
{
|
||||
username: 'testuser',
|
||||
appriseMode: 'stateless',
|
||||
appriseStatelessURL: 'https://example.com',
|
||||
},
|
||||
])
|
||||
);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
expect(res._getJSONData()).toEqual({
|
||||
appriseMode: 'stateless',
|
||||
appriseStatelessURL: 'https://example.com',
|
||||
});
|
||||
});
|
||||
|
||||
it('should return 500 if there is an error reading the file', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(fs.readFile as jest.Mock).mockRejectedValue({ code: 'ENOENT' });
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(500);
|
||||
expect(res._getJSONData()).toEqual({ status: 500, message: 'No such file or directory' });
|
||||
});
|
||||
});
|
||||
78
tests/supertest/getAppriseServices.test.ts
Normal file
78
tests/supertest/getAppriseServices.test.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
import { createMocks } from 'node-mocks-http';
|
||||
import handler from '~/pages/api/account/getAppriseServices';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { promises as fs } from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
jest.mock('next-auth/next');
|
||||
jest.mock('fs', () => ({
|
||||
promises: {
|
||||
readFile: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('Get Apprise Services API', () => {
|
||||
it('should return 405 if the method is not GET', async () => {
|
||||
const { req, res } = createMocks({ method: 'POST' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(405);
|
||||
});
|
||||
|
||||
it('should return 401 if the user is not authenticated', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(401);
|
||||
expect(res._getJSONData()).toEqual({ message: 'You must be logged in.' });
|
||||
});
|
||||
|
||||
it('should return 400 if the user does not exist', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
user: { name: 'nonexistent' },
|
||||
});
|
||||
|
||||
(fs.readFile as jest.Mock).mockResolvedValue(
|
||||
JSON.stringify([{ username: 'testuser', appriseServices: ['service1', 'service2'] }])
|
||||
);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(400);
|
||||
expect(res._getJSONData()).toEqual({
|
||||
message: 'User is incorrect. Please, logout to update your session.',
|
||||
});
|
||||
});
|
||||
|
||||
it('should return appriseServices if the user exists', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(fs.readFile as jest.Mock).mockResolvedValue(
|
||||
JSON.stringify([{ username: 'testuser', appriseServices: ['service1', 'service2'] }])
|
||||
);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
expect(res._getJSONData()).toEqual({
|
||||
appriseServices: ['service1', 'service2'],
|
||||
});
|
||||
});
|
||||
|
||||
it('should return 500 if there is an error reading the file', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(fs.readFile as jest.Mock).mockRejectedValue({ code: 'ENOENT' });
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(500);
|
||||
expect(res._getJSONData()).toEqual({ status: 500, message: 'No such file or directory' });
|
||||
});
|
||||
});
|
||||
78
tests/supertest/getEmailAlert.test.ts
Normal file
78
tests/supertest/getEmailAlert.test.ts
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
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';
|
||||
|
||||
jest.mock('next-auth/next');
|
||||
jest.mock('fs', () => ({
|
||||
promises: {
|
||||
readFile: jest.fn(),
|
||||
},
|
||||
}));
|
||||
|
||||
describe('Get Email Alert API', () => {
|
||||
it('should return 405 if the method is not GET', async () => {
|
||||
const { req, res } = createMocks({ method: 'POST' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(405);
|
||||
});
|
||||
|
||||
it('should return 401 if the user is not authenticated', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue(null);
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(401);
|
||||
expect(res._getJSONData()).toEqual({ message: 'You must be logged in.' });
|
||||
});
|
||||
|
||||
it('should return 400 if the user does not exist', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
user: { name: 'nonexistent' },
|
||||
});
|
||||
|
||||
(fs.readFile as jest.Mock).mockResolvedValue(
|
||||
JSON.stringify([{ username: 'testuser', emailAlert: true }])
|
||||
);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(400);
|
||||
expect(res._getJSONData()).toEqual({
|
||||
message: 'User is incorrect. Please, logout to update your session.',
|
||||
});
|
||||
});
|
||||
|
||||
it('should return emailAlert if the user exists', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(fs.readFile as jest.Mock).mockResolvedValue(
|
||||
JSON.stringify([{ username: 'testuser', emailAlert: true }])
|
||||
);
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
expect(res._getJSONData()).toEqual({
|
||||
emailAlert: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('should return 500 if there is an error reading the file', async () => {
|
||||
(getServerSession as jest.Mock).mockResolvedValue({
|
||||
user: { name: 'testuser' },
|
||||
});
|
||||
|
||||
(fs.readFile as jest.Mock).mockRejectedValue({ code: 'ENOENT' });
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(500);
|
||||
expect(res._getJSONData()).toEqual({ status: 500, message: 'No such file or directory' });
|
||||
});
|
||||
});
|
||||
51
tests/supertest/getWizardEnv.test.ts
Normal file
51
tests/supertest/getWizardEnv.test.ts
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
import { createMocks } from 'node-mocks-http';
|
||||
import handler from '~/pages/api/account/getWizardEnv';
|
||||
import { getServerSession } from 'next-auth/next';
|
||||
import { WizardEnvEnum } from '~/types/domain/config.types';
|
||||
|
||||
jest.mock('next-auth/next');
|
||||
|
||||
describe('Get Wizard Env API', () => {
|
||||
it('should return 405 if the method is not GET', async () => {
|
||||
const { req, res } = createMocks({ method: 'POST' });
|
||||
await handler(req, res);
|
||||
expect(res._getStatusCode()).toBe(405);
|
||||
});
|
||||
|
||||
it('should return 401 if the user is not authenticated', async () => {
|
||||
(getServerSession as jest.Mock).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' } });
|
||||
|
||||
process.env.UNIX_USER = 'borgwarehouse';
|
||||
process.env.FQDN = 'localhost';
|
||||
process.env.SSH_SERVER_PORT = '22';
|
||||
process.env.HIDE_SSH_PORT = 'false';
|
||||
process.env.DISABLE_INTEGRATIONS = 'false';
|
||||
|
||||
const { req, res } = createMocks({ method: 'GET' });
|
||||
await handler(req, res);
|
||||
|
||||
expect(res._getStatusCode()).toBe(200);
|
||||
expect(res._getJSONData()).toEqual({
|
||||
wizardEnv: {
|
||||
UNIX_USER: 'borgwarehouse',
|
||||
FQDN: 'localhost',
|
||||
SSH_SERVER_PORT: '22',
|
||||
FQDN_LAN: '',
|
||||
SSH_SERVER_PORT_LAN: '',
|
||||
SSH_SERVER_FINGERPRINT_RSA: '',
|
||||
SSH_SERVER_FINGERPRINT_ED25519: '',
|
||||
SSH_SERVER_FINGERPRINT_ECDSA: '',
|
||||
HIDE_SSH_PORT: 'false',
|
||||
DISABLE_INTEGRATIONS: 'false',
|
||||
DISABLE_DELETE_REPO: 'false',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
@ -2,7 +2,7 @@ export type EmailSettingDTO = {
|
|||
email: string;
|
||||
};
|
||||
|
||||
export type UserSettingDTO = {
|
||||
export type UsernameSettingDTO = {
|
||||
username: string;
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue