Skip to content

Commit b535029

Browse files
frinyvonnicklaura-bergoens
authored andcommitted
feat(api): add method to get campaign skill ids for campaign participations in campaign API
1 parent b737f27 commit b535029

File tree

6 files changed

+157
-22
lines changed

6 files changed

+157
-22
lines changed

api/src/prescription/campaign/application/api/campaigns-api.js

+13
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,16 @@ export const findAllForOrganization = async (payload) => {
137137

138138
return { models: campaignsList, meta };
139139
};
140+
141+
/**
142+
* @function
143+
* @name findCampaignSkillIdsForCampaignParticipations
144+
*
145+
* @param {Array<Number>} campaignParticipationIds
146+
* @returns {Promise<Array<Number>>}
147+
*/
148+
export const findCampaignSkillIdsForCampaignParticipations = async (campaignParticipationIds) => {
149+
return usecases.findCampaignSkillIdsForCampaignParticipations({
150+
campaignParticipationIds,
151+
});
152+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
const findCampaignSkillIdsForCampaignParticipations = async function ({
2+
campaignParticipationIds,
3+
campaignRepository,
4+
}) {
5+
return campaignRepository.findSkillIdsByCampaignParticipationIds({ campaignParticipationIds });
6+
};
7+
8+
export { findCampaignSkillIdsForCampaignParticipations };

api/src/prescription/campaign/infrastructure/repositories/campaign-repository.js

+26-21
Original file line numberDiff line numberDiff line change
@@ -78,27 +78,43 @@ const getCampaignIdByCampaignParticipationId = async function (campaignParticipa
7878

7979
const findSkillIds = async function ({ campaignId, filterByStatus = 'operative' }) {
8080
if (filterByStatus === 'all') {
81-
return _findSkillIds({ campaignId });
81+
return _findSkillIds([campaignId]);
8282
}
83-
const skills = await this.findSkills({ campaignId, filterByStatus });
83+
const skills = await findSkills({ campaignId, filterByStatus });
8484
return skills.map(({ id }) => id);
8585
};
8686

87-
const findSkills = function ({ campaignId, filterByStatus }) {
88-
return _findSkills({ campaignId, filterByStatus });
87+
const findSkills = async function ({ campaignId, filterByStatus }) {
88+
const skillIds = await _findSkillIds([campaignId]);
89+
switch (filterByStatus) {
90+
case 'operative':
91+
return skillRepository.findOperativeByIds(skillIds);
92+
case 'all':
93+
return skillRepository.findByRecordIds(skillIds);
94+
default:
95+
throw new TypeError(`unknown filterByStatus value "${filterByStatus}", use "operative" or "all"`);
96+
}
8997
};
9098

9199
const findSkillsByCampaignParticipationId = async function ({ campaignParticipationId }) {
92100
const knexConn = DomainTransaction.getConnection();
93101
const [campaignId] = await knexConn('campaign-participations')
94102
.where({ id: campaignParticipationId })
95103
.pluck('campaignId');
96-
return this.findSkills({ campaignId });
104+
return findSkills({ campaignId });
105+
};
106+
107+
const findSkillIdsByCampaignParticipationIds = async function ({ campaignParticipationIds }) {
108+
const knexConn = DomainTransaction.getConnection();
109+
const campaignIds = await knexConn('campaign-participations')
110+
.whereIn('id', campaignParticipationIds)
111+
.pluck('campaignId');
112+
const skillIds = await _findSkillIds(campaignIds);
113+
return [...new Set(skillIds)];
97114
};
98115

99116
const findSkillIdsByCampaignParticipationId = async function ({ campaignParticipationId }) {
100-
const skills = await this.findSkillsByCampaignParticipationId({ campaignParticipationId });
101-
return skills.map(({ id }) => id);
117+
return findSkillIdsByCampaignParticipationIds({ campaignParticipationIds: [campaignParticipationId] });
102118
};
103119

104120
const findTubes = async function ({ campaignId }) {
@@ -123,6 +139,7 @@ export {
123139
findAllSkills,
124140
findSkillIds,
125141
findSkillIdsByCampaignParticipationId,
142+
findSkillIdsByCampaignParticipationIds,
126143
findSkills,
127144
findSkillsByCampaignParticipationId,
128145
findTubes,
@@ -132,19 +149,7 @@ export {
132149
getCampaignIdByCampaignParticipationId,
133150
};
134151

135-
async function _findSkills({ campaignId, filterByStatus = 'operative' }) {
136-
const skillIds = await _findSkillIds({ campaignId });
137-
switch (filterByStatus) {
138-
case 'operative':
139-
return skillRepository.findOperativeByIds(skillIds);
140-
case 'all':
141-
return skillRepository.findByRecordIds(skillIds);
142-
default:
143-
throw new TypeError(`unknown filterByStatus value "${filterByStatus}", use "operative" or "all"`);
144-
}
145-
}
146-
147-
async function _findSkillIds({ campaignId }) {
152+
async function _findSkillIds(campaignIds) {
148153
const knexConn = DomainTransaction.getConnection();
149-
return knexConn('campaign_skills').where({ campaignId }).pluck('skillId');
154+
return knexConn('campaign_skills').whereIn('campaignId', campaignIds).pluck('skillId');
150155
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { usecases } from '../../../../../../src/prescription/campaign/domain/usecases/index.js';
2+
import { databaseBuilder, expect } from '../../../../../test-helper.js';
3+
4+
describe('Integration | UseCase | find-campaign-skill-ids-for-campaign-participations', function () {
5+
it('should return campaign skill ids for campaign participations', async function () {
6+
// given
7+
const campaignId1 = databaseBuilder.factory.buildCampaign().id;
8+
databaseBuilder.factory.buildCampaignSkill({ skillId: 'skillId1', campaignId: campaignId1 });
9+
const campaignId2 = databaseBuilder.factory.buildCampaign().id;
10+
databaseBuilder.factory.buildCampaignSkill({ skillId: 'skillId2', campaignId: campaignId2 });
11+
12+
const campaignParticipationIds = [
13+
databaseBuilder.factory.buildCampaignParticipation({ campaignId: campaignId1 }).id,
14+
databaseBuilder.factory.buildCampaignParticipation({ campaignId: campaignId2 }).id,
15+
];
16+
await databaseBuilder.commit();
17+
18+
// when
19+
const skillIds = await usecases.findCampaignSkillIdsForCampaignParticipations({ campaignParticipationIds });
20+
21+
// then
22+
expect(skillIds).to.have.lengthOf(2);
23+
expect(skillIds).to.have.members(['skillId1', 'skillId2']);
24+
});
25+
});

api/tests/prescription/campaign/integration/infrastructure/repositories/campaign-repository_test.js

+70
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,76 @@ describe('Integration | Repository | Campaign', function () {
3939
});
4040
});
4141

42+
describe('#findSkillIdsByCampaignParticipationIds', function () {
43+
it('should return empty array', async function () {
44+
const skillIds = await campaignRepository.findSkillIdsByCampaignParticipationIds({
45+
campaignParticipationIds: [123, 456],
46+
});
47+
48+
// then
49+
expect(skillIds).to.have.lengthOf(0);
50+
});
51+
52+
it('should return the skillIds for the campaign participations', async function () {
53+
// given
54+
const campaignId1 = databaseBuilder.factory.buildCampaign().id;
55+
databaseBuilder.factory.buildCampaignSkill({ skillId: 'skillId1', campaignId: campaignId1 });
56+
databaseBuilder.factory.buildCampaignSkill({ skillId: 'skillId2', campaignId: campaignId1 });
57+
const campaignId2 = databaseBuilder.factory.buildCampaign().id;
58+
databaseBuilder.factory.buildCampaignSkill({ skillId: 'skillId1', campaignId: campaignId2 });
59+
databaseBuilder.factory.buildCampaignSkill({ skillId: 'skillId3', campaignId: campaignId2 });
60+
61+
const campaignParticipationIds = [
62+
databaseBuilder.factory.buildCampaignParticipation({ campaignId: campaignId1 }).id,
63+
databaseBuilder.factory.buildCampaignParticipation({ campaignId: campaignId2 }).id,
64+
];
65+
await databaseBuilder.commit();
66+
67+
// when
68+
const skillIds = await campaignRepository.findSkillIdsByCampaignParticipationIds({ campaignParticipationIds });
69+
70+
// then
71+
expect(skillIds).to.have.lengthOf(3);
72+
expect(skillIds).to.have.members(['skillId1', 'skillId2', 'skillId3']);
73+
});
74+
});
75+
76+
describe('#findSkillIdsByCampaignParticipationId', function () {
77+
it('should return empty array', async function () {
78+
const skillIds = await campaignRepository.findSkillIdsByCampaignParticipationId({
79+
campaignParticipationId: 123,
80+
});
81+
82+
// then
83+
expect(skillIds).to.have.lengthOf(0);
84+
});
85+
86+
it('should return the skillIds for the campaign participation', async function () {
87+
// given
88+
const campaignId1 = databaseBuilder.factory.buildCampaign().id;
89+
databaseBuilder.factory.buildCampaignSkill({ skillId: 'skillId1', campaignId: campaignId1 });
90+
databaseBuilder.factory.buildCampaignSkill({ skillId: 'skillId2', campaignId: campaignId1 });
91+
const campaignId2 = databaseBuilder.factory.buildCampaign().id;
92+
databaseBuilder.factory.buildCampaignSkill({ skillId: 'skillId1', campaignId: campaignId2 });
93+
databaseBuilder.factory.buildCampaignSkill({ skillId: 'skillId3', campaignId: campaignId2 });
94+
95+
const campaignParticipationIds = [
96+
databaseBuilder.factory.buildCampaignParticipation({ campaignId: campaignId1 }).id,
97+
databaseBuilder.factory.buildCampaignParticipation({ campaignId: campaignId2 }).id,
98+
];
99+
await databaseBuilder.commit();
100+
101+
// when
102+
const skillIds = await campaignRepository.findSkillIdsByCampaignParticipationId({
103+
campaignParticipationId: campaignParticipationIds[0],
104+
});
105+
106+
// then
107+
expect(skillIds).to.have.lengthOf(2);
108+
expect(skillIds).to.have.members(['skillId1', 'skillId2']);
109+
});
110+
});
111+
42112
describe('#findTubes', function () {
43113
it('should return the tubes for the campaign', async function () {
44114
// given

api/tests/prescription/campaign/unit/application/api/campaigns-api_test.js

+15-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import { UserNotAuthorizedToCreateCampaignError } from '../../../../../../src/pr
33
import { Campaign } from '../../../../../../src/prescription/campaign/domain/models/Campaign.js';
44
import { usecases } from '../../../../../../src/prescription/campaign/domain/usecases/index.js';
55
import { CampaignReport } from '../../../../../../src/shared/domain/read-models/CampaignReport.js';
6-
import { catchErr, expect, sinon } from '../../../../../test-helper.js';
6+
import { catchErr, expect, preventStubsToBeCalledUnexpectedly, sinon } from '../../../../../test-helper.js';
77
import { domainBuilder } from '../../../../../tooling/domain-builder/domain-builder.js';
88

99
describe('Unit | API | Campaigns', function () {
@@ -189,6 +189,20 @@ describe('Unit | API | Campaigns', function () {
189189
});
190190
});
191191

192+
describe('#findCampaignSkillIdsForCampaignPartipicipations', function () {
193+
it('should return an array of campaign skill ids for campaign participations', async function () {
194+
const skillIds = Symbol('skillIds');
195+
const campaignParticipationIds = [123, 456];
196+
const usecaseStub = sinon.stub(usecases, 'findCampaignSkillIdsForCampaignParticipations');
197+
preventStubsToBeCalledUnexpectedly([usecaseStub]);
198+
usecaseStub.withArgs({ campaignParticipationIds }).resolves(skillIds);
199+
200+
const result = await campaignApi.findCampaignSkillIdsForCampaignParticipations(campaignParticipationIds);
201+
202+
expect(result).to.equal(skillIds);
203+
});
204+
});
205+
192206
describe('#findAllForOrganization', function () {
193207
it('should return paginated campaign list from organizationId', async function () {
194208
const organizationId = Symbol('organizationId');

0 commit comments

Comments
 (0)