Skip to content

Commit 7572116

Browse files
committed
tests: Added unit test for checklist use-cases
1 parent bed5f57 commit 7572116

16 files changed

+740
-4
lines changed

api/src/application/use-cases/checklist/CreateChecklistByCopyingItemsUseCase.js

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,42 @@ class CreateChecklistByCopyingItemsUseCase {
99
}
1010

1111
async execute(checklistData, checklistWithItems) {
12+
if (!checklistData?.cardId) throw new Error('cardId was not provided');
13+
if (!checklistData?.name) {
14+
throw new Error('the checklist name was not provided');
15+
}
16+
if (!checklistWithItems?.id) {
17+
throw new Error(
18+
'The checklist does not exist or does not belong to the card',
19+
);
20+
}
21+
if (checklistWithItems.items?.length === 0) {
22+
throw new Error('The selected checklist has no items to copy');
23+
}
24+
1225
const checklistEntity = new ChecklistEntity(checklistData);
1326
const itemEntities = checklistWithItems.items.map(
1427
(item) =>
1528
new ChecklistItemEntity({ ...item, checklistId: checklistEntity.id }),
1629
);
1730

1831
const newChecklist = await this.checklistRepository.create(checklistEntity);
19-
const formattedNewChecklist = newChecklist.get({ plain: true });
32+
33+
if (!newChecklist?.id) {
34+
throw new Error('Something went wrong creating the checklist');
35+
}
36+
37+
const formattedNewChecklist = newChecklist?.get
38+
? newChecklist.get({ plain: true })
39+
: newChecklist;
2040

2141
const newItems =
2242
await this.checklistItemRepository.bulkCreate(itemEntities);
2343

44+
if (newItems?.length === 0) {
45+
throw new Error('Something went wrong creating the checklist items');
46+
}
47+
2448
return new ChecklistDto({ ...formattedNewChecklist, items: newItems });
2549
}
2650
}

api/src/application/use-cases/checklist/CreateChecklistUseCase.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,14 @@ class CreateChecklistUseCase {
88
}
99

1010
async execute(checklistData) {
11+
if (!checklistData?.name) throw new Error('name was not provided');
12+
if (!checklistData?.cardId) throw new Error('cardId was not provided');
13+
1114
const checklistEntity = new ChecklistEntity(checklistData);
1215

1316
const newChecklist = await this.checklistRepository.create(checklistEntity);
1417
if (!newChecklist?.id)
15-
throw boom.badRequest('Something went wront creating the checklist');
18+
throw boom.badRequest('Something went wrong creating the checklist');
1619

1720
return new ChecklistDto(newChecklist);
1821
}

api/src/application/use-cases/checklist/DeleteChecklistUseCase.js

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,15 @@ class DeleteChecklistUseCase {
44
}
55

66
async execute(checklistId) {
7-
return this.checklistRepository.delete(checklistId);
7+
if (!checklistId) throw new Error('checklistId was not provided');
8+
9+
const result = await this.checklistRepository.delete(checklistId);
10+
11+
if (result === 0) {
12+
throw new Error('Something went wrong removing the checklist');
13+
}
14+
15+
return result;
816
}
917
}
1018

api/src/application/use-cases/checklist/GetAllChecklistsByCardUseCase.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ class GetAllChecklistsByCardUseCase {
66
}
77

88
async execute(cardId) {
9+
if (!cardId) throw new Error('cardId was not provided');
10+
911
const checklists =
1012
await this.checklistRepository.findChecklistsByCard(cardId);
13+
1114
return checklists?.length > 0
1215
? checklists.map((checklist) => new ChecklistDto(checklist))
1316
: [];

api/src/application/use-cases/checklist/GetAllChecklistsByProjectUseCase.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ class GetAllChecklistsByProjectUseCase {
66
}
77

88
async execute(projectId) {
9+
if (!projectId) throw new Error('projectId was not provided');
10+
911
const project =
1012
await this.checklistRepository.findChecklistsByProject(projectId);
13+
1114
if (!project || !project.lists) return [];
1215

1316
return project.lists.flatMap((list) => {

api/src/application/use-cases/checklist/GetChecklistUseCase.js

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

88
async execute(checklistId) {
9+
if (!checklistId) throw new Error('checklistId was not provided');
10+
911
const checklist = await this.checklistRepository.findOne(checklistId);
10-
return new ChecklistDto(checklist);
12+
return checklist?.id ? new ChecklistDto(checklist) : {};
1113
}
1214
}
1315

api/src/application/use-cases/checklist/GetProjectMemberByChecklistUseCase.js

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

99
async execute(userId, checklistId) {
10+
if (!userId) throw new Error('userId was not provided');
11+
if (!checklistId) throw new Error('checklistId was not provided');
12+
1013
const checklist =
1114
await this.checklistRepository.findOneByIdWithData(checklistId);
15+
16+
if (!checklist?.id) {
17+
throw new Error('checklist was not found');
18+
}
19+
1220
const projectMember =
1321
await this.projectMemberRepository.checkProjectMemberByUser(
1422
userId,
1523
checklist.card.list.projectId,
1624
);
25+
1726
return projectMember?.id ? new ProjectMemberDto(projectMember) : {};
1827
}
1928
}

api/src/application/use-cases/checklist/UpdateChecklistUseCase.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ class UpdateChecklistUseCase {
88
}
99

1010
async execute(checklistId, checklistData) {
11+
if (!checklistId) throw new Error('checklistId was not provided');
12+
if (!checklistData?.newName) throw new Error('newName was not provided');
1113
const updateChecklistEntity = new ChecklistName(checklistData.newName)
1214
.value;
1315

Lines changed: 151 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,151 @@
1+
jest.mock('uuid', () => ({
2+
v4: jest.fn(),
3+
}));
4+
5+
const { v4: uuid } = require('uuid');
6+
7+
const CreateChecklistByCopyingItemsUseCase = require('../../../api/src/application/use-cases/checklist/CreateChecklistByCopyingItemsUseCase');
8+
const ChecklistDto = require('../../../api/src/application/dtos/checklist.dto');
9+
const {
10+
createChecklistItem,
11+
createChecklist,
12+
} = require('../../fake-data/fake-entities');
13+
14+
describe('CreateChecklistByCopyingItemsUseCase', () => {
15+
const fakeChecklistId = 'fake-checklist-uuid';
16+
const fakeChecklistItemId = 'fake-checklist-item-uuid';
17+
18+
let checklistData;
19+
let checklistWithItems;
20+
let createdChecklist;
21+
let createdChecklistItems;
22+
let mockChecklistRepository;
23+
let mockChecklistItemRepository;
24+
let createChecklistByCopyingItemsUseCase;
25+
26+
beforeAll(() => {
27+
uuid
28+
.mockReturnValueOnce(fakeChecklistId)
29+
.mockReturnValueOnce(fakeChecklistItemId);
30+
});
31+
32+
beforeEach(() => {
33+
checklistData = {
34+
name: 'checklist name',
35+
cardId: createChecklist().cardId,
36+
};
37+
checklistWithItems = {
38+
...createChecklist(),
39+
items: [createChecklistItem(), createChecklistItem()],
40+
};
41+
createdChecklist = createChecklist({ id: fakeChecklistId });
42+
createdChecklistItems = [
43+
createChecklistItem({ id: fakeChecklistItemId }),
44+
createChecklistItem({ id: fakeChecklistItemId }),
45+
];
46+
47+
mockChecklistRepository = {
48+
create: jest.fn().mockResolvedValue(createdChecklist),
49+
};
50+
51+
mockChecklistItemRepository = {
52+
bulkCreate: jest.fn().mockResolvedValue(createdChecklistItems),
53+
};
54+
55+
createChecklistByCopyingItemsUseCase =
56+
new CreateChecklistByCopyingItemsUseCase({
57+
checklistRepository: mockChecklistRepository,
58+
checklistItemRepository: mockChecklistItemRepository,
59+
});
60+
});
61+
62+
test('It should return a checklist with the items copied', async () => {
63+
const dbResponse = { ...createdChecklist, items: createdChecklistItems };
64+
65+
const result = await createChecklistByCopyingItemsUseCase.execute(
66+
checklistData,
67+
checklistWithItems,
68+
);
69+
70+
expect(mockChecklistRepository.create).toHaveBeenCalledTimes(1);
71+
expect(mockChecklistItemRepository.bulkCreate).toHaveBeenCalledTimes(1);
72+
expect(result).toMatchObject(new ChecklistDto(dbResponse));
73+
});
74+
75+
test('It should return an error because cardId was not provided', async () => {
76+
checklistData.cardId = null;
77+
78+
await expect(
79+
createChecklistByCopyingItemsUseCase.execute(
80+
checklistData,
81+
checklistWithItems,
82+
),
83+
).rejects.toThrow(/was not provided/);
84+
expect(mockChecklistRepository.create).not.toHaveBeenCalled();
85+
});
86+
87+
test('It should return an error because the checklist name was not provided', async () => {
88+
checklistData.name = null;
89+
90+
await expect(
91+
createChecklistByCopyingItemsUseCase.execute(
92+
checklistData,
93+
checklistWithItems,
94+
),
95+
).rejects.toThrow(/was not provided/);
96+
expect(mockChecklistRepository.create).not.toHaveBeenCalled();
97+
});
98+
99+
test('It should return an error because checklistWithItems to be copied was not provided', async () => {
100+
await expect(
101+
createChecklistByCopyingItemsUseCase.execute(checklistData, {}),
102+
).rejects.toThrow(
103+
'The checklist does not exist or does not belong to the card',
104+
);
105+
expect(mockChecklistRepository.create).not.toHaveBeenCalled();
106+
});
107+
108+
test('It should return an error because the checklistWithItems to be copied have not items', async () => {
109+
checklistWithItems.items = [];
110+
111+
await expect(
112+
createChecklistByCopyingItemsUseCase.execute(
113+
checklistData,
114+
checklistWithItems,
115+
),
116+
).rejects.toThrow(/has no items to copy/);
117+
expect(mockChecklistRepository.create).not.toHaveBeenCalled();
118+
});
119+
120+
test('It should return an error because the create operation failed', async () => {
121+
mockChecklistRepository.create.mockResolvedValue({});
122+
123+
await expect(
124+
createChecklistByCopyingItemsUseCase.execute(
125+
checklistData,
126+
checklistWithItems,
127+
),
128+
).rejects.toThrow(/Something went wrong/);
129+
130+
expect(mockChecklistRepository.create).toHaveBeenCalledTimes(1);
131+
expect(mockChecklistItemRepository.bulkCreate).not.toHaveBeenCalled();
132+
});
133+
134+
test('It should return an error because the bulkCreate operation failed', async () => {
135+
mockChecklistItemRepository.bulkCreate.mockResolvedValue([]);
136+
137+
await expect(
138+
createChecklistByCopyingItemsUseCase.execute(
139+
checklistData,
140+
checklistWithItems,
141+
),
142+
).rejects.toThrow(/Something went wrong/);
143+
144+
expect(mockChecklistRepository.create).toHaveBeenCalledTimes(1);
145+
expect(mockChecklistItemRepository.bulkCreate).toHaveBeenCalledTimes(1);
146+
});
147+
148+
afterEach(() => {
149+
jest.clearAllMocks();
150+
});
151+
});
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
jest.mock('uuid', () => ({
2+
v4: jest.fn(),
3+
}));
4+
5+
const { v4: uuid } = require('uuid');
6+
7+
const CreateChecklistUseCase = require('../../../api/src/application/use-cases/checklist/CreateChecklistUseCase');
8+
const ChecklistDto = require('../../../api/src/application/dtos/checklist.dto');
9+
const { createChecklist } = require('../../fake-data/fake-entities');
10+
11+
describe('CreateChecklistUseCase', () => {
12+
const fakeChecklistId = 'fake-checklist-uuid';
13+
14+
let checklistData;
15+
let createdChecklist;
16+
let mockChecklistRepository;
17+
let createChecklistUseCase;
18+
19+
beforeAll(() => {
20+
uuid.mockReturnValueOnce(fakeChecklistId);
21+
});
22+
23+
beforeEach(() => {
24+
checklistData = {
25+
name: 'checklist name',
26+
cardId: createChecklist().cardId,
27+
};
28+
29+
createdChecklist = createChecklist({ id: fakeChecklistId });
30+
31+
mockChecklistRepository = {
32+
create: jest.fn().mockResolvedValue(createdChecklist),
33+
};
34+
35+
createChecklistUseCase = new CreateChecklistUseCase({
36+
checklistRepository: mockChecklistRepository,
37+
});
38+
});
39+
40+
test('It should return a created checklist', async () => {
41+
const result = await createChecklistUseCase.execute(checklistData);
42+
43+
expect(mockChecklistRepository.create).toHaveBeenCalledTimes(1);
44+
expect(result).toMatchObject(new ChecklistDto(createdChecklist));
45+
});
46+
47+
test('It should return an error because cardId was not provided', async () => {
48+
checklistData.cardId = null;
49+
50+
await expect(createChecklistUseCase.execute(checklistData)).rejects.toThrow(
51+
/was not provided/,
52+
);
53+
expect(mockChecklistRepository.create).not.toHaveBeenCalled();
54+
});
55+
56+
test('It should return an error because the checklist name was not provided', async () => {
57+
checklistData.name = null;
58+
59+
await expect(createChecklistUseCase.execute(checklistData)).rejects.toThrow(
60+
/was not provided/,
61+
);
62+
expect(mockChecklistRepository.create).not.toHaveBeenCalled();
63+
});
64+
65+
test('It should return an error because the create operation failed', async () => {
66+
mockChecklistRepository.create.mockResolvedValue({});
67+
68+
await expect(createChecklistUseCase.execute(checklistData)).rejects.toThrow(
69+
/Something went wrong/,
70+
);
71+
72+
expect(mockChecklistRepository.create).toHaveBeenCalledTimes(1);
73+
});
74+
75+
afterEach(() => {
76+
jest.clearAllMocks();
77+
});
78+
});

0 commit comments

Comments
 (0)