Skip to content

Commit 8136a10

Browse files
authored
refactor: test and add test schema,error,controller (#170)
* refactor: test and add test schema,error,controller * refactor: organizing the description * refactor: fixing delte to delete
1 parent bfa07a4 commit 8136a10

File tree

3 files changed

+86
-30
lines changed

3 files changed

+86
-30
lines changed
Lines changed: 81 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,93 @@
1-
import type { NextFunction, Request, Response } from 'express';
2-
import type { MockProxy } from 'vitest-mock-extended';
3-
import { mock } from 'vitest-mock-extended';
1+
import type { Request, Response } from 'express';
2+
import { mock, mockDeep } from 'vitest-mock-extended';
43

54
import { AccountController } from '@/features/account/controllers/account-controller';
6-
import type { AccountRepository } from '@/features/account/repositories/account-repository/account-repository';
7-
import { DeleteUserAccountsService } from '@/features/account/services/delete-user-accounts-service';
8-
9-
describe('Account Controller', () => {
10-
let accountRepository: MockProxy<AccountRepository>;
11-
let deleteAccountByIdService: DeleteUserAccountsService;
12-
let accountController: AccountController;
13-
14-
beforeEach(() => {
15-
accountRepository = mock<AccountRepository>();
16-
deleteAccountByIdService = new DeleteUserAccountsService(accountRepository);
17-
accountController = new AccountController(deleteAccountByIdService);
5+
import type { DeleteUserAccountsService } from '@/features/account/services/delete-user-accounts-service';
6+
import { accountDeleteBySchema } from '@/features/account/validators/account-find-by-id-schema';
7+
import { HttpError } from '@/shared/errors/http-error';
8+
import { HttpStatusCode } from '@/shared/protocols/http-client';
9+
10+
const makeSut = () => {
11+
const deleteUserAccountServiceMock = mock<DeleteUserAccountsService>({
12+
execute: vi.fn(),
1813
});
1914

20-
it('should be able to delete an account by id', async () => {
21-
const req = mock<Request>();
22-
req.params.id = 'f19c169c-5fa2-406d-8de9-4d2c36dc6529';
15+
const accountController = new AccountController(deleteUserAccountServiceMock);
16+
17+
const req = mockDeep<Request>();
18+
19+
const res = {
20+
send: vi.fn(),
21+
22+
status: vi.fn().mockReturnThis(),
23+
} as unknown as Response;
24+
25+
const next = vi.fn();
26+
27+
return {
28+
accountController,
29+
30+
deleteUserAccountService: deleteUserAccountServiceMock,
2331

24-
const res = mock<Response>();
25-
res.status.mockReturnThis();
26-
res.send.mockReturnThis();
32+
next,
2733

28-
const next = mock<NextFunction>();
34+
req,
35+
36+
res,
37+
};
38+
};
39+
40+
describe('deleteAccountById', () => {
41+
it('should delete an account and return no content status', async () => {
42+
const { accountController, deleteUserAccountService, next, req, res } =
43+
makeSut();
44+
45+
const socialMediaId = '123';
46+
47+
req.params = { id: socialMediaId };
48+
49+
const executeSpy = vi
50+
.spyOn(deleteUserAccountService, 'execute')
51+
.mockResolvedValue();
2952

3053
await accountController.deleteAccountById(req, res, next);
3154

32-
expect(res.status).toHaveBeenCalledWith(204);
55+
expect(executeSpy).toHaveBeenCalledWith({
56+
socialMediaId: Number(socialMediaId),
57+
});
58+
59+
expect(res.status).toHaveBeenCalledWith(HttpStatusCode.noContent);
60+
3361
expect(res.send).toHaveBeenCalled();
62+
63+
expect(next).not.toHaveBeenCalled();
64+
});
65+
66+
it('should call next with an error when service throws', async () => {
67+
const { accountController, deleteUserAccountService, next, req, res } =
68+
makeSut();
69+
70+
const socialMediaId = '123';
71+
req.params = { id: socialMediaId };
72+
73+
const error = new HttpError(HttpStatusCode.badRequest, 'Service error');
74+
75+
vi.spyOn(deleteUserAccountService, 'execute').mockRejectedValueOnce(error);
76+
77+
await accountController.deleteAccountById(req, res, next);
78+
79+
expect(next).toHaveBeenCalledWith(error);
80+
81+
expect(res.status).not.toHaveBeenCalled();
82+
expect(res.send).not.toHaveBeenCalled();
83+
});
84+
85+
describe('accountDeleteByschema', () => {
86+
it('should pass validation when id is a valid number', () => {
87+
const validInput = { id: 123 };
88+
const parsedData = accountDeleteBySchema.parse(validInput);
89+
90+
expect(parsedData).toEqual({ id: validInput.id });
91+
});
3492
});
3593
});

src/features/account/controllers/account-controller.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import type { Controller } from '@/shared/protocols/controller';
33
import type { AsyncRequestHandler } from '@/shared/protocols/handlers';
44
import { HttpStatusCode } from '@/shared/protocols/http-client';
55

6+
import { accountDeleteBySchema } from '../validators/account-find-by-id-schema';
7+
68
export class AccountController implements Controller {
79
deleteAccountById: AsyncRequestHandler = async (req, res, next) => {
810
try {
9-
const accountId = Number(req.params.id);
11+
const { id } = accountDeleteBySchema.parse(req.params);
1012

1113
await this.deleteUserAccountService.execute({
12-
socialMediaId: accountId,
14+
socialMediaId: id,
1315
});
1416

1517
return res.status(HttpStatusCode.noContent).send();
Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
import { z } from 'zod';
22

3-
export const accountDeleteByParamsSchema = z.object({
4-
id: z.string().uuid(),
5-
});
6-
73
export const accountDeleteBySchema = z.object({
8-
params: accountDeleteByParamsSchema,
4+
id: z.coerce.number().min(1),
95
});

0 commit comments

Comments
 (0)