Skip to content

Commit 1b88c0a

Browse files
committed
test: Added unit test for list use-cases
1 parent 364fd24 commit 1b88c0a

15 files changed

+485
-9
lines changed

api/src/application/use-cases/list/CheckProjectMembershipByListUseCase.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,14 @@ class CheckProjectMembershipByListUseCase {
66
}
77

88
async execute(userId, listId) {
9+
if (!userId) throw new Error('userId was not provided');
10+
if (!listId) throw new Error('listId was not provided');
11+
912
const list = await this.listRepository.checkProjectMembershipByList(
1013
userId,
1114
listId,
1215
);
13-
return new ListDto(list);
16+
return list?.id ? new ListDto(list) : {};
1417
}
1518
}
1619

api/src/application/use-cases/list/CreateListUseCase.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,16 @@ class CreateListUseCase {
77
}
88

99
async execute(listData) {
10+
if (!listData?.projectId) {
11+
throw new Error('projectId was not provided');
12+
}
13+
1014
const listEntity = new ListEntity(listData);
1115

1216
const createdList = await this.listRepository.create(listEntity);
17+
if (!createdList?.id) {
18+
throw new Error('Something went wrong creating the list');
19+
}
1320

1421
return new ListDto(createdList);
1522
}

api/src/application/use-cases/list/DeleteListUseCase.js

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,18 @@ class DeleteListUseCase {
44
}
55

66
async execute(projectId, listId) {
7-
return this.listRepository.delete(projectId, listId);
7+
if (!projectId) throw new Error('projectId was not provided');
8+
if (!listId) throw new Error('listId was not provided');
9+
10+
const result = await this.listRepository.delete(projectId, listId);
11+
12+
if (result === 0) {
13+
throw new Error(
14+
'Something went wrong deleting the list. Maybe the list does not exist',
15+
);
16+
}
17+
18+
return result;
819
}
920
}
1021

api/src/application/use-cases/list/GetAllListsUseCase.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@ class GetAllListsUseCase {
66
}
77

88
async execute(projectId) {
9+
if (!projectId) throw new Error('projectId was not provided');
10+
911
const lists = await this.listRepository.findAll(projectId);
10-
return lists.map((list) => new ListDto(list));
12+
return lists?.length > 0 ? lists.map((list) => new ListDto(list)) : [];
1113
}
1214
}
1315

api/src/application/use-cases/list/GetListUseCase.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,12 @@ class GetListUseCase {
66
}
77

88
async execute(projectId, listId) {
9+
if (!projectId) throw new Error('projectId was not provided');
10+
if (!listId) throw new Error('listId was not provided');
11+
912
const list = await this.listRepository.findOneById(projectId, listId);
10-
if (!list?.id) return {};
11-
return new ListDto(list);
13+
14+
return list?.id ? new ListDto(list) : {};
1215
}
1316
}
1417

api/src/application/use-cases/list/GetProjectByListUseCase.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,11 @@ class GetProjectByListUseCase {
44
}
55

66
async execute(listId) {
7+
if (!listId) throw new Error('listId was not provided');
8+
79
const listIWithItsProject =
810
await this.listRepository.getProjectByList(listId);
11+
912
return listIWithItsProject?.id ? listIWithItsProject : {};
1013
}
1114
}

api/src/application/use-cases/list/UpdateListUseCase.js

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,22 @@ class UpdateListUseCase {
77
}
88

99
async execute(listId, newName) {
10+
if (!listId) throw new Error('listId was not provided');
11+
1012
const listUpdateEntity = new ListName(newName).value;
1113

12-
const [[updatedList]] = await this.listRepository.update(listId, {
13-
name: listUpdateEntity,
14-
});
14+
const [affectedRows, [updatedList]] = await this.listRepository.update(
15+
listId,
16+
{
17+
name: listUpdateEntity,
18+
},
19+
);
20+
21+
if (affectedRows === 0) {
22+
throw new Error(
23+
'Something went wrong updating the list. Maybe the list does not exist',
24+
);
25+
}
1526

1627
return new ListDto(updatedList);
1728
}

api/src/domain/value-objects/listName.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@ class ListName {
88
this.#value = value;
99
}
1010

11-
// eslint-disable-next-line class-methods-use-this
1211
validate(value) {
1312
if (typeof value !== 'string' || value.trim() === '') {
1413
throw boom.badData('ListName must be a non-empty string.');
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
const CheckProjectMembershipByListUseCase = require('../../../api/src/application/use-cases/list/CheckProjectMembershipByListUseCase');
2+
const ListDto = require('../../../api/src/application/dtos/list.dto');
3+
const { createList, createUser } = require('../../fake-data/fake-entities');
4+
5+
describe('CheckProjectMembershipByListUseCase', () => {
6+
let userId;
7+
let listId;
8+
let dbResponse;
9+
let mockListRepository;
10+
let checkProjectMembershipByListUseCase;
11+
12+
beforeEach(() => {
13+
userId = createUser().id;
14+
listId = createList().id;
15+
dbResponse = createList();
16+
17+
mockListRepository = {
18+
checkProjectMembershipByList: jest.fn().mockResolvedValue(dbResponse),
19+
};
20+
21+
checkProjectMembershipByListUseCase =
22+
new CheckProjectMembershipByListUseCase({
23+
listRepository: mockListRepository,
24+
});
25+
});
26+
27+
test('It should return a list with its project', async () => {
28+
const result = await checkProjectMembershipByListUseCase.execute(
29+
userId,
30+
listId,
31+
);
32+
33+
expect(
34+
mockListRepository.checkProjectMembershipByList,
35+
).toHaveBeenCalledTimes(1);
36+
expect(result).toMatchObject(new ListDto(dbResponse));
37+
});
38+
39+
test('It should return an error because the userId was not provided', async () => {
40+
await expect(
41+
checkProjectMembershipByListUseCase.execute(null, listId),
42+
).rejects.toThrow(/was not provided/);
43+
expect(
44+
mockListRepository.checkProjectMembershipByList,
45+
).not.toHaveBeenCalled();
46+
});
47+
48+
test('It should return an error because the listId was not provided', async () => {
49+
await expect(
50+
checkProjectMembershipByListUseCase.execute(userId, null),
51+
).rejects.toThrow(/was not provided/);
52+
expect(
53+
mockListRepository.checkProjectMembershipByList,
54+
).not.toHaveBeenCalled();
55+
});
56+
57+
test('It should return an empty object because the operation db did not find anything', async () => {
58+
mockListRepository.checkProjectMembershipByList.mockResolvedValue(0);
59+
60+
const result = await checkProjectMembershipByListUseCase.execute(
61+
userId,
62+
listId,
63+
);
64+
expect(
65+
mockListRepository.checkProjectMembershipByList,
66+
).toHaveBeenCalledTimes(1);
67+
expect(result).toEqual({});
68+
});
69+
70+
afterEach(() => {
71+
jest.clearAllMocks();
72+
});
73+
});
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
jest.mock('uuid', () => ({
2+
v4: jest.fn(),
3+
}));
4+
5+
const { v4: uuidv4 } = require('uuid');
6+
7+
const CreateListUseCase = require('../../../api/src/application/use-cases/list/CreateListUseCase');
8+
const ListDto = require('../../../api/src/application/dtos/list.dto');
9+
const { createList } = require('../../fake-data/fake-entities');
10+
11+
describe('CreateListUseCase', () => {
12+
let listData;
13+
let dbResponse;
14+
let mockListRepository;
15+
let createListUseCase;
16+
17+
beforeEach(() => {
18+
dbResponse = createList();
19+
listData = dbResponse;
20+
uuidv4.mockReturnValue(dbResponse.id);
21+
22+
mockListRepository = {
23+
create: jest.fn().mockResolvedValue(dbResponse),
24+
};
25+
26+
createListUseCase = new CreateListUseCase({
27+
listRepository: mockListRepository,
28+
});
29+
});
30+
31+
test('It should return a successfully created list', async () => {
32+
const result = await createListUseCase.execute(listData);
33+
34+
expect(uuidv4).toHaveBeenCalledTimes(1);
35+
expect(mockListRepository.create).toHaveBeenCalledTimes(1);
36+
expect(result).toMatchObject(new ListDto(dbResponse));
37+
});
38+
39+
test('It should return an error because projectId was not provided', async () => {
40+
listData.projectId = null;
41+
42+
await expect(createListUseCase.execute(listData)).rejects.toThrow(
43+
/was not provided/,
44+
);
45+
expect(mockListRepository.create).not.toHaveBeenCalled();
46+
});
47+
48+
test('It should return an error because the provided name is not valid', async () => {
49+
listData.name = 123;
50+
51+
await expect(createListUseCase.execute(listData)).rejects.toThrow(
52+
/must be a non-empty string/,
53+
);
54+
expect(mockListRepository.create).not.toHaveBeenCalled();
55+
});
56+
57+
test('It should return an error because the provided name contains invalid characters', async () => {
58+
listData.name =
59+
'sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss';
60+
61+
await expect(createListUseCase.execute(listData)).rejects.toThrow(
62+
/cannot exceed 80 characters/,
63+
);
64+
expect(mockListRepository.create).not.toHaveBeenCalled();
65+
});
66+
67+
test('It should return an error because the operation db failed', async () => {
68+
mockListRepository.create.mockResolvedValue({});
69+
70+
await expect(createListUseCase.execute(listData)).rejects.toThrow(
71+
/Something went wrong/,
72+
);
73+
expect(mockListRepository.create).toHaveBeenCalledTimes(1);
74+
});
75+
76+
afterEach(() => {
77+
jest.clearAllMocks();
78+
});
79+
});

0 commit comments

Comments
 (0)