Skip to content

Commit

Permalink
tech(api): refacto quest eligibility computing to handle various comb…
Browse files Browse the repository at this point in the history
…inations

Co-authored-by: Yvonnick Frin <[email protected]>
Co-authored-by: Xavier Carron <[email protected]>
  • Loading branch information
3 people committed Feb 6, 2025
1 parent 13907dd commit ff963f9
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 53 deletions.
23 changes: 5 additions & 18 deletions api/src/quest/domain/models/Eligibility.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,44 +5,31 @@ export const TYPES = {
};

export class Eligibility {
#campaignParticipations;

constructor({ organizationLearner, organization, campaignParticipations = [] }) {
this.organizationLearner = {
id: organizationLearner?.id,
MEFCode: organizationLearner?.MEFCode,
};
this.organization = organization;
this.#campaignParticipations = campaignParticipations;
}

get campaignParticipations() {
return {
targetProfileIds: this.#campaignParticipations.map(({ targetProfileId }) => targetProfileId),
};
}

set campaignParticipations(campaignParticipations) {
this.#campaignParticipations = campaignParticipations;
this.campaignParticipations = campaignParticipations;
}

hasCampaignParticipation(campaignParticipationId) {
return Boolean(
this.#campaignParticipations.find(
(campaignParticipation) => campaignParticipation.id === campaignParticipationId,
),
this.campaignParticipations.find((campaignParticipation) => campaignParticipation.id === campaignParticipationId),
);
}

hasCampaignParticipationForTargetProfileId(targetProfileId) {
return Boolean(
this.#campaignParticipations.find(
this.campaignParticipations.find(
(campaignParticipation) => campaignParticipation.targetProfileId === targetProfileId,
),
);
}

getTargetProfileForCampaignParticipation(campaignParticipationId) {
const campaignParticipation = this.#campaignParticipations.find(
const campaignParticipation = this.campaignParticipations.find(
(campaignParticipation) => campaignParticipation.id === campaignParticipationId,
);

Expand Down
36 changes: 28 additions & 8 deletions api/src/quest/domain/models/Quest.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,37 @@ class Quest {
);
}

#checkCriterion({ criterion, eligibilityData }) {
if (Array.isArray(criterion)) {
if (Array.isArray(eligibilityData)) {
return criterion.every((valueToTest) => eligibilityData.includes(valueToTest));
}
return criterion.some((valueToTest) => valueToTest === eligibilityData);
}
return eligibilityData === criterion;
}

#checkRequirement(eligibilityRequirement, eligibility) {
const comparaisonFunction = eligibilityRequirement.comparison === COMPARISON.ONE_OF ? 'some' : 'every';
const comparisonFunction = eligibilityRequirement.comparison === COMPARISON.ONE_OF ? 'some' : 'every';

return Object.keys(eligibilityRequirement.data)[comparaisonFunction]((key) => {
const eligibilityData = eligibility[eligibilityRequirement.type][key];
const criterion = eligibilityRequirement.data[key];
if (Array.isArray(eligibility[eligibilityRequirement.type])) {
return eligibility[eligibilityRequirement.type].some((item) => {
return Object.keys(eligibilityRequirement.data)[comparisonFunction]((key) => {
// TODO: Dés que les quêtes ont été mises à jour il faudra retirer cette ligne
const alterKey = key === 'targetProfileIds' ? 'targetProfileId' : key;
return this.#checkCriterion({
criterion: eligibilityRequirement.data[key],
eligibilityData: item[alterKey],
});
});
});
}

if (Array.isArray(criterion)) {
return criterion.every((valueToTest) => eligibilityData.includes(valueToTest));
}
return eligibilityData === criterion;
return Object.keys(eligibilityRequirement.data)[comparisonFunction]((key) => {
return this.#checkCriterion({
criterion: eligibilityRequirement.data[key],
eligibilityData: eligibility[eligibilityRequirement.type][key],
});
});
}

Expand Down
26 changes: 0 additions & 26 deletions api/tests/quest/unit/domain/models/Eligibility_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,6 @@ import { Eligibility } from '../../../../../src/quest/domain/models/Eligibility.
import { expect } from '../../../../test-helper.js';

describe('Quest | Unit | Domain | Models | Eligibility ', function () {
describe('#campaignParticipations', function () {
it('Should return an object with targetProfileIds property', function () {
// given
const campaignParticipations = [{ targetProfileId: 1 }, { targetProfileId: 2 }];
const eligiblity = new Eligibility({ campaignParticipations });

// when
const result = eligiblity.campaignParticipations;

// then
expect(result.targetProfileIds).to.deep.equal([1, 2]);
});

it('Should return an empty array on targetProfileIds property', function () {
// given
const campaignParticipations = [];
const eligiblity = new Eligibility({ campaignParticipations });

// when
const result = eligiblity.campaignParticipations;

// then
expect(result.targetProfileIds).to.deep.equal([]);
});
});

describe('#hasCampaignParticipation', function () {
it('Should return true if campaign participation exists', function () {
// given
Expand Down
58 changes: 57 additions & 1 deletion api/tests/quest/unit/domain/models/Quest_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ describe('Quest | Unit | Domain | Models | Quest ', function () {
let quest;
let userTargetProfileId;

before(function () {
beforeEach(function () {
// given
const eligibleTargetProfileId = 1000;
userTargetProfileId = eligibleTargetProfileId;
Expand Down Expand Up @@ -177,6 +177,62 @@ describe('Quest | Unit | Domain | Models | Quest ', function () {
// then
expect(quest.isEligible(eligibilityData)).to.equal(false);
});

it('should return true if all eligibility requirements of a same type are met', function () {
// given
const organization = { type: 'SCO', isManagingStudents: true, tags: ['AEFE'] };
const organizationLearner = { MEFCode: '10010012110' };
const campaignParticipations = [{ targetProfileId: 1 }, { targetProfileId: 2 }];
const eligibilityData = new Eligibility({ organization, organizationLearner, campaignParticipations });
const eligibilityRequirements = [
{
type: TYPES.CAMPAIGN_PARTICIPATIONS,
data: {
targetProfileIds: [1],
},
comparison: COMPARISON.ALL,
},
{
type: TYPES.CAMPAIGN_PARTICIPATIONS,
data: {
targetProfileIds: [2, 3],
},
comparison: COMPARISON.ALL,
},
];
quest = new Quest({ eligibilityRequirements });

// then
expect(quest.isEligible(eligibilityData)).to.equal(true);
});

it('should return false if one of eligibility requirement of a same type is not eligible', function () {
// given
const organization = { type: 'SCO', isManagingStudents: true, tags: ['AEFE'] };
const organizationLearner = { MEFCode: '10010012110' };
const campaignParticipations = [{ targetProfileId: 1 }, { targetProfileId: 4 }];
const eligibilityData = new Eligibility({ organization, organizationLearner, campaignParticipations });
const eligibilityRequirements = [
{
type: TYPES.CAMPAIGN_PARTICIPATIONS,
data: {
targetProfileIds: [1],
},
comparison: COMPARISON.ALL,
},
{
type: TYPES.CAMPAIGN_PARTICIPATIONS,
data: {
targetProfileIds: [2, 3],
},
comparison: COMPARISON.ALL,
},
];
quest = new Quest({ eligibilityRequirements });

// then
expect(quest.isEligible(eligibilityData)).to.equal(false);
});
});
});

Expand Down

0 comments on commit ff963f9

Please sign in to comment.