refactor: email API rest compliant

This commit is contained in:
Ravinou 2025-04-12 19:20:30 +02:00
commit 0ee771f64a
No known key found for this signature in database
GPG key ID: EEEE670C40F6A4D7
7 changed files with 174 additions and 198 deletions

View file

@ -1,97 +0,0 @@
import { getServerSession } from 'next-auth/next';
import { createMocks } from 'node-mocks-http';
import handler from '~/pages/api/account/getEmailAlert';
import { ConfigService } from '~/services';
vi.mock('next-auth/next');
vi.mock('~/services');
describe('Get Email Alert API', () => {
beforeEach(() => {
vi.clearAllMocks();
vi.spyOn(console, 'log').mockImplementation(() => {});
});
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 () => {
vi.mocked(getServerSession).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 () => {
vi.mocked(getServerSession).mockResolvedValue({
user: { name: 'nonexistent' },
});
vi.mocked(ConfigService.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);
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 () => {
vi.mocked(getServerSession).mockResolvedValue({
user: { name: 'testuser' },
});
vi.mocked(ConfigService.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);
expect(res._getStatusCode()).toBe(200);
expect(res._getJSONData()).toEqual({
emailAlert: true,
});
});
it('should return 500 if there is an error reading the file', async () => {
vi.mocked(getServerSession).mockResolvedValue({
user: { name: 'testuser' },
});
vi.mocked(ConfigService.getUsersList).mockImplementation(() => {
throw new Error();
});
const { req, res } = createMocks({ method: 'GET' });
await handler(req, res);
expect(res._getStatusCode()).toBe(500);
expect(res._getJSONData()).toEqual({
status: 500,
message: 'API error, contact the administrator',
});
});
});

View file

@ -1,44 +0,0 @@
import { NextApiRequest, NextApiResponse } from 'next';
import { getServerSession } from 'next-auth/next';
import { ConfigService } from '~/services';
import { authOptions } from '../auth/[...nextauth]';
import { EmailAlertDTO, ErrorResponse } from '~/types';
export default async function handler(
req: NextApiRequest,
res: NextApiResponse<EmailAlertDTO | ErrorResponse>
) {
if (req.method !== 'GET') {
res.status(405).json({ message: 'Bad request on API' });
return;
}
//Verify that the user is logged in.
const session = await getServerSession(req, res, authOptions);
if (!session) {
res.status(401).json({ message: 'You must be logged in.' });
return;
}
try {
const usersList = await ConfigService.getUsersList();
//Verify that the user of the session exists
const user = usersList.find((u) => u.username === session.user?.name);
if (!user) {
res.status(400).json({
message: 'User is incorrect. Please, logout to update your session.',
});
return;
}
res.status(200).json({ emailAlert: user.emailAlert });
} catch (error: any) {
console.log(error);
const errorMessage =
error.code === 'ENOENT'
? 'No such file or directory'
: 'API error, contact the administrator';
res.status(500).json({ status: 500, message: errorMessage });
}
}

View file

@ -1,52 +0,0 @@
import { ConfigService } from '~/services';
import { authOptions } from '../auth/[...nextauth]';
import { getServerSession } from 'next-auth/next';
import { NextApiRequest, NextApiResponse } from 'next';
import { EmailAlertDTO, ErrorResponse } from '~/types';
export default async function handler(
req: NextApiRequest & { body: EmailAlertDTO },
res: NextApiResponse<ErrorResponse>
) {
if (req.method !== 'PUT') {
return res.status(405);
}
const session = await getServerSession(req, res, authOptions);
if (!session) {
return res.status(401);
}
const { emailAlert } = req.body;
if (typeof emailAlert !== 'boolean') {
return res.status(422).json({ message: 'Unexpected data' });
}
try {
const usersList = await ConfigService.getUsersList();
const userIndex = usersList.findIndex((u) => u.username === session.user?.name);
if (userIndex === -1) {
return res
.status(400)
.json({ message: 'User is incorrect. Please, logout to update your session.' });
}
const updatedUsersList = usersList.map((user, index) =>
index === userIndex ? { ...user, emailAlert } : user
);
await ConfigService.updateUsersList(updatedUsersList);
return res.status(200).json({ message: 'Successful API send' });
} catch (error: any) {
console.log(error);
return res.status(500).json({
status: 500,
message:
error.code === 'ENOENT'
? 'No such file or directory'
: 'API error, contact the administrator',
});
}
}

View file

@ -1,12 +1,104 @@
import { createMocks } from 'node-mocks-http';
import handler from '~/pages/api/account/updateEmailAlert';
import { getServerSession } from 'next-auth/next';
import { createMocks } from 'node-mocks-http';
import handler from '~/pages/api/notif/email/alert';
import { ConfigService } from '~/services';
vi.mock('next-auth/next');
vi.mock('~/services');
describe('PUT /api/account/updateEmailAlert', () => {
describe('Get Email Alert API', () => {
beforeEach(() => {
vi.clearAllMocks();
vi.spyOn(console, 'log').mockImplementation(() => {});
});
it('should return 405 if the method is not GET', async () => {
vi.mocked(getServerSession).mockResolvedValue({
user: { name: 'testuser' },
});
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 () => {
vi.mocked(getServerSession).mockResolvedValue(null);
const { req, res } = createMocks({ method: 'GET' });
await handler(req, res);
expect(res._getStatusCode()).toBe(401);
});
it('should return 400 if the user does not exist', async () => {
vi.mocked(getServerSession).mockResolvedValue({
user: { name: 'nonexistent' },
});
vi.mocked(ConfigService.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);
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 () => {
vi.mocked(getServerSession).mockResolvedValue({
user: { name: 'testuser' },
});
vi.mocked(ConfigService.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);
expect(res._getStatusCode()).toBe(200);
expect(res._getJSONData()).toEqual({
emailAlert: true,
});
});
it('should return 500 if there is an error reading the file', async () => {
vi.mocked(getServerSession).mockResolvedValue({
user: { name: 'testuser' },
});
vi.mocked(ConfigService.getUsersList).mockImplementation(() => {
throw new Error();
});
const { req, res } = createMocks({ method: 'GET' });
await handler(req, res);
expect(res._getStatusCode()).toBe(500);
expect(res._getJSONData()).toEqual({
status: 500,
message: 'API error, contact the administrator',
});
});
});
describe('Update email Alert API', () => {
beforeEach(() => {
vi.clearAllMocks();
vi.spyOn(console, 'log').mockImplementation(() => {});
@ -22,6 +114,9 @@ describe('PUT /api/account/updateEmailAlert', () => {
});
it('should return 405 if method is not PUT', async () => {
vi.mocked(getServerSession).mockResolvedValue({
user: { name: 'testuser' },
});
const { req, res } = createMocks({ method: 'POST' });
await handler(req, res);

View file

@ -0,0 +1,74 @@
import { NextApiRequest, NextApiResponse } from 'next';
import { getServerSession } from 'next-auth/next';
import { ConfigService } from '~/services';
import { authOptions } from '../../auth/[...nextauth]';
import { EmailAlertDTO, ErrorResponse } from '~/types';
import ApiResponse from '~/helpers/functions/apiResponse';
export default async function handler(
req: NextApiRequest & { body: EmailAlertDTO },
res: NextApiResponse<EmailAlertDTO | ErrorResponse>
) {
const session = await getServerSession(req, res, authOptions);
if (!session) {
return ApiResponse.unauthorized(res);
}
if (req.method == 'GET') {
try {
const usersList = await ConfigService.getUsersList();
//Verify that the user of the session exists
const user = usersList.find((u) => u.username === session.user?.name);
if (!user) {
res.status(400).json({
message: 'User is incorrect. Please, logout to update your session.',
});
return;
}
res.status(200).json({ emailAlert: user.emailAlert });
} catch (error: any) {
console.log(error);
const errorMessage =
error.code === 'ENOENT'
? 'No such file or directory'
: 'API error, contact the administrator';
res.status(500).json({ status: 500, message: errorMessage });
}
} else if (req.method == 'PUT') {
const { emailAlert } = req.body;
if (typeof emailAlert !== 'boolean') {
return res.status(422).json({ message: 'Unexpected data' });
}
try {
const usersList = await ConfigService.getUsersList();
const userIndex = usersList.findIndex((u) => u.username === session.user?.name);
if (userIndex === -1) {
return res
.status(400)
.json({ message: 'User is incorrect. Please, logout to update your session.' });
}
const updatedUsersList = usersList.map((user, index) =>
index === userIndex ? { ...user, emailAlert } : user
);
await ConfigService.updateUsersList(updatedUsersList);
return res.status(200).json({ message: 'Successful API send' });
} catch (error: any) {
console.log(error);
return res.status(500).json({
status: 500,
message:
error.code === 'ENOENT'
? 'No such file or directory'
: 'API error, contact the administrator',
});
}
} else {
return ApiResponse.methodNotAllowed(res);
}
}

View file

@ -1,5 +1,5 @@
import { createMocks } from 'node-mocks-http';
import handler from '~/pages/api/account/sendTestEmail';
import handler from '~/pages/api/notif/email/send-test';
import { getServerSession } from 'next-auth/next';
vi.mock('next-auth/next');

View file

@ -1,4 +1,4 @@
import { authOptions } from '../auth/[...nextauth]';
import { authOptions } from '../../auth/[...nextauth]';
import { getServerSession } from 'next-auth/next';
import { NextApiRequest, NextApiResponse } from 'next';
import emailTest from '~/helpers/templates/emailTest';