Skip to content

Commit ea33528

Browse files
frinyvonnickxav-car
authored andcommitted
refactor(api): add model DataForQuest that aggregates Eligibility and Success models
1 parent adc6b2c commit ea33528

File tree

5 files changed

+108
-35
lines changed

5 files changed

+108
-35
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
export class DataForQuest {
2+
#success;
3+
#eligibility;
4+
5+
constructor({ eligibility, success = null }) {
6+
this.#success = success;
7+
this.#eligibility = eligibility;
8+
}
9+
10+
get eligibility() {
11+
return Object.freeze(this.#eligibility);
12+
}
13+
14+
get success() {
15+
return Object.freeze(this.#success);
16+
}
17+
18+
set success(value) {
19+
this.#success = value;
20+
}
21+
22+
/*
23+
* Eligibility
24+
*/
25+
26+
get organizationLearner() {
27+
return this.#eligibility.organizationLearner;
28+
}
29+
30+
get organization() {
31+
return this.#eligibility.organization;
32+
}
33+
34+
get campaignParticipations() {
35+
return this.#eligibility.campaignParticipations;
36+
}
37+
38+
buildDataForQuestScopedByCampaignParticipationId(...args) {
39+
const eligibility = this.#eligibility.buildEligibilityScopedByCampaignParticipationId(...args);
40+
return new DataForQuest({ eligibility, success: this.#success });
41+
}
42+
43+
hasCampaignParticipation(...args) {
44+
return this.#eligibility.hasCampaignParticipation(...args);
45+
}
46+
47+
/*
48+
* Success
49+
*/
50+
51+
get knowledgeElements() {
52+
return this.#success.knowledgeElements;
53+
}
54+
55+
getMasteryPercentageForSkills(...args) {
56+
return this.#success.getMasteryPercentageForSkills(...args);
57+
}
58+
}

api/src/quest/domain/models/Quest.js

+11-14
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ import {
55
TYPES as _REQUIREMENT_TYPES,
66
} from './Requirement.js';
77
/**
8-
* @typedef {import ('./Eligibility.js').Eligibility} Eligibility
9-
* @typedef {import ('./Success.js').Success} Success
8+
* @typedef {import ('./DataForQuest.js').DataForQuest} DataForQuest
109
*/
1110

1211
export const REQUIREMENT_COMPARISONS = _REQUIREMENT_COMPARISONS;
@@ -34,22 +33,20 @@ class Quest {
3433
});
3534
}
3635

37-
// je crois que ce getter sert à rien
3836
get eligibilityRequirements() {
3937
return this.#eligibilityRequirements.data;
4038
}
4139

42-
// je crois que ce getter sert à rien
4340
get successRequirements() {
4441
return this.#successRequirements.data;
4542
}
4643

4744
/**
48-
* @param {Eligibility} eligibility
45+
* @param {DataForQuest} data
4946
* @param {number} campaignParticipationId
5047
*/
51-
isCampaignParticipationContributingToQuest({ eligibility, campaignParticipationId }) {
52-
const scopedEligibility = eligibility.buildEligibilityScopedByCampaignParticipationId({ campaignParticipationId });
48+
isCampaignParticipationContributingToQuest({ data, campaignParticipationId }) {
49+
const scopedData = data.buildDataForQuestScopedByCampaignParticipationId({ campaignParticipationId });
5350

5451
const campaignParticipationRequirements = this.#flattenRequirementsByType(
5552
this.#eligibilityRequirements.data,
@@ -61,24 +58,24 @@ class Quest {
6158
data: campaignParticipationRequirements,
6259
comparison: REQUIREMENT_COMPARISONS.ONE_OF,
6360
});
64-
return a.isFulfilled(scopedEligibility);
61+
return a.isFulfilled(scopedData);
6562
}
6663

6764
return false;
6865
}
6966

7067
/**
71-
* @param {Eligibility} eligibility
68+
* @param {DataForQuest} data
7269
*/
73-
isEligible(eligibility) {
74-
return this.#eligibilityRequirements.isFulfilled(eligibility);
70+
isEligible(data) {
71+
return this.#eligibilityRequirements.isFulfilled(data);
7572
}
7673

7774
/**
78-
* @param {Success} success
75+
* @param {DataForQuest} data
7976
*/
80-
isSuccessful(success) {
81-
return this.#successRequirements.isFulfilled(success);
77+
isSuccessful(data) {
78+
return this.#successRequirements.isFulfilled(data);
8279
}
8380

8481
toDTO() {

api/src/quest/domain/usecases/get-quest-results-for-campaign-participation.js

+9-6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { DataForQuest } from '../models/DataForQuest.js';
2+
13
export const getQuestResultsForCampaignParticipation = async ({
24
userId,
35
campaignParticipationId,
@@ -12,20 +14,21 @@ export const getQuestResultsForCampaignParticipation = async ({
1214
}
1315

1416
const eligibilities = await eligibilityRepository.find({ userId });
15-
const eligibility = eligibilities.find((eligibility) =>
16-
eligibility.hasCampaignParticipation(campaignParticipationId),
17-
);
18-
if (!eligibility) {
17+
const dataForQuest = eligibilities
18+
.map((eligibility) => new DataForQuest({ eligibility }))
19+
.find((dataForQuest) => dataForQuest.hasCampaignParticipation(campaignParticipationId));
20+
21+
if (!dataForQuest) {
1922
return [];
2023
}
2124

2225
const questsRelatedToCampaignParticipation = quests.filter((q) =>
23-
q.isCampaignParticipationContributingToQuest({ eligibility, campaignParticipationId }),
26+
q.isCampaignParticipationContributingToQuest({ data: dataForQuest, campaignParticipationId }),
2427
);
2528

2629
const questResults = [];
2730
for (const quest of questsRelatedToCampaignParticipation) {
28-
const isEligible = quest.isEligible(eligibility);
31+
const isEligible = quest.isEligible(dataForQuest);
2932
if (!isEligible) continue;
3033
const questResult = await rewardRepository.getByQuestAndUserId({ userId, quest });
3134
questResults.push(questResult);

api/src/quest/domain/usecases/reward-user.js

+8-3
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { DataForQuest } from '../models/DataForQuest.js';
2+
13
export const rewardUser = async ({
24
userId,
35
questRepository,
@@ -20,9 +22,11 @@ export const rewardUser = async ({
2022
const rewardIds = rewards.map((reward) => reward.rewardId);
2123

2224
for (const quest of quests) {
23-
const isEligibleForQuest = eligibilities.some((eligibility) => quest.isEligible(eligibility));
25+
const dataForQuest = eligibilities
26+
.map((eligibility) => new DataForQuest({ eligibility }))
27+
.find((dataForQuest) => quest.isEligible(dataForQuest));
2428

25-
if (!isEligibleForQuest) {
29+
if (!dataForQuest) {
2630
continue;
2731
}
2832

@@ -31,7 +35,8 @@ export const rewardUser = async ({
3135
}
3236

3337
const success = await successRepository.find({ userId });
34-
const userHasSucceedQuest = quest.isSuccessful(success);
38+
dataForQuest.success = success;
39+
const userHasSucceedQuest = quest.isSuccessful(dataForQuest);
3540

3641
if (userHasSucceedQuest) {
3742
await rewardRepository.reward({ userId, rewardId: quest.rewardId });

api/tests/quest/unit/domain/models/Quest_test.js

+22-12
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { DataForQuest } from '../../../../../src/quest/domain/models/DataForQuest.js';
12
import { Eligibility } from '../../../../../src/quest/domain/models/Eligibility.js';
23
import {
34
CRITERION_COMPARISONS,
@@ -29,8 +30,9 @@ describe('Quest | Unit | Domain | Models | Quest ', function () {
2930
});
3031

3132
const eligibility = new Eligibility({ organization: { type: 'SCO' } });
33+
const data = new DataForQuest({ eligibility });
3234

33-
expect(quest.isEligible(eligibility)).to.be.true;
35+
expect(quest.isEligible(data)).to.be.true;
3436
});
3537

3638
it('return false', function () {
@@ -51,8 +53,9 @@ describe('Quest | Unit | Domain | Models | Quest ', function () {
5153
});
5254

5355
const eligibility = new Eligibility({ organization: { type: 'PRO' } });
56+
const data = new DataForQuest({ eligibility });
5457

55-
expect(quest.isEligible(eligibility)).to.be.false;
58+
expect(quest.isEligible(data)).to.be.false;
5659
});
5760
});
5861

@@ -71,8 +74,9 @@ describe('Quest | Unit | Domain | Models | Quest ', function () {
7174
{ status: KnowledgeElement.StatusType.VALIDATED, skillId: 'skillD' },
7275
],
7376
});
77+
const data = new DataForQuest({ success });
7478

75-
expect(quest.isSuccessful(success)).to.be.true;
79+
expect(quest.isSuccessful(data)).to.be.true;
7680
});
7781

7882
it('returns true when all requirements are met', function () {
@@ -104,8 +108,9 @@ describe('Quest | Unit | Domain | Models | Quest ', function () {
104108
{ status: KnowledgeElement.StatusType.VALIDATED, skillId: 'skillD' },
105109
],
106110
});
111+
const data = new DataForQuest({ success });
107112

108-
expect(quest.isSuccessful(success)).to.be.true;
113+
expect(quest.isSuccessful(data)).to.be.true;
109114
});
110115

111116
it('returns false when at least one requirement is not met', function () {
@@ -137,8 +142,9 @@ describe('Quest | Unit | Domain | Models | Quest ', function () {
137142
{ status: KnowledgeElement.StatusType.VALIDATED, skillId: 'skillD' },
138143
],
139144
});
145+
const data = new DataForQuest({ success });
140146

141-
expect(quest.isSuccessful(success)).to.be.false;
147+
expect(quest.isSuccessful(data)).to.be.false;
142148
});
143149

144150
it('returns false when none of the requirements are met', function () {
@@ -170,8 +176,9 @@ describe('Quest | Unit | Domain | Models | Quest ', function () {
170176
{ status: KnowledgeElement.StatusType.INVALIDATED, skillId: 'skillD' },
171177
],
172178
});
179+
const data = new DataForQuest({ success });
173180

174-
expect(quest.isSuccessful(success)).to.be.false;
181+
expect(quest.isSuccessful(data)).to.be.false;
175182
});
176183
});
177184

@@ -219,12 +226,13 @@ describe('Quest | Unit | Domain | Models | Quest ', function () {
219226
{ id: 10, targetProfileId: 1 },
220227
{ id: 11, targetProfileId: 3 },
221228
];
222-
const eligibilityData = new Eligibility({ organization, organizationLearner, campaignParticipations });
229+
const eligibility = new Eligibility({ organization, organizationLearner, campaignParticipations });
230+
const data = new DataForQuest({ eligibility });
223231
const campaignParticipationIdToCheck = 11;
224232

225233
// when
226234
const isContributing = quest.isCampaignParticipationContributingToQuest({
227-
eligibility: eligibilityData,
235+
data,
228236
campaignParticipationId: campaignParticipationIdToCheck,
229237
});
230238

@@ -271,12 +279,13 @@ describe('Quest | Unit | Domain | Models | Quest ', function () {
271279
{ id: 10, targetProfileId: 1 },
272280
{ id: 11, targetProfileId: 3 },
273281
];
274-
const eligibilityData = new Eligibility({ organization, organizationLearner, campaignParticipations });
282+
const eligibility = new Eligibility({ organization, organizationLearner, campaignParticipations });
283+
const data = new DataForQuest({ eligibility });
275284
const campaignParticipationIdToCheck = 10;
276285

277286
// when
278287
const isContributing = quest.isCampaignParticipationContributingToQuest({
279-
eligibility: eligibilityData,
288+
data,
280289
campaignParticipationId: campaignParticipationIdToCheck,
281290
});
282291

@@ -312,12 +321,13 @@ describe('Quest | Unit | Domain | Models | Quest ', function () {
312321
];
313322
const quest = new Quest({ eligibilityRequirements, successRequirements: [] });
314323
const campaignParticipations = [{ id: 10 }, { id: 11 }];
315-
const eligibilityData = new Eligibility({ organization, organizationLearner, campaignParticipations });
324+
const eligibility = new Eligibility({ organization, organizationLearner, campaignParticipations });
325+
const data = new DataForQuest({ eligibility });
316326
const campaignParticipationIdToCheck = 10;
317327

318328
// when
319329
const isContributing = quest.isCampaignParticipationContributingToQuest({
320-
eligibility: eligibilityData,
330+
data,
321331
campaignParticipationId: campaignParticipationIdToCheck,
322332
});
323333

0 commit comments

Comments
 (0)