Skip to content

Commit

Permalink
tech(api): removed placementProfile
Browse files Browse the repository at this point in the history
  • Loading branch information
alicegoarnisson committed Feb 21, 2025
1 parent 130fe23 commit 24db189
Show file tree
Hide file tree
Showing 4 changed files with 12 additions and 290 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,18 @@ import * as placementProfileService from '../../../../shared/domain/services/pla
import * as areaRepository from '../../../../shared/infrastructure/repositories/area-repository.js';
import * as competenceRepository from '../../../../shared/infrastructure/repositories/competence-repository.js';
import { CampaignProfile } from '../../domain/models/CampaignProfile.js';
import * as campaignParticipationRepository from './campaign-participation-repository.js';

const findProfile = async function ({ campaignId, campaignParticipationId, locale }) {
const profile = await _fetchCampaignProfileAttributesFromCampaignParticipation(campaignId, campaignParticipationId);
const competences = await competenceRepository.listPixCompetencesOnly({ locale });
const allAreas = await areaRepository.list({ locale });
const participation = await campaignParticipationRepository.get(campaignParticipationId);

const { sharedAt, userId } = profile;

const placementProfile = await placementProfileService.getPlacementProfileWithSnapshotting({
userId,
limitDate: sharedAt,
allowExcessPixAndLevels: false,
const placementProfile = await placementProfileService.getPlacementProfilesWithSnapshotting({
participations: [participation],
competences,
campaignParticipationId,
allowExcessPixAndLevels: false,
});

return new CampaignProfile({ ...profile, placementProfile, allAreas });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,7 @@ import * as placementProfileService from '../../../../shared/domain/services/pla
import * as competenceRepository from '../../../../shared/infrastructure/repositories/competence-repository.js';
import * as knowledgeElementSnapshotRepository from '../../../campaign/infrastructure/repositories/knowledge-element-snapshot-repository.js';
import { ParticipantResultsShared } from '../../domain/models/ParticipantResultsShared.js';

function _fetchUserIdAndSharedAt(campaignParticipationId) {
return knex('campaign-participations')
.select('userId', 'sharedAt')
.where('campaign-participations.id', campaignParticipationId)
.first();
}
import * as campaignParticipationRepository from './campaign-participation-repository.js';

const participantResultsSharedRepository = {
async save(participantResultShared) {
Expand All @@ -24,15 +18,13 @@ const participantResultsSharedRepository = {
const knowledgeElements = await knowledgeElementSnapshotRepository.findByCampaignParticipationIds([
campaignParticipationId,
]);
const { userId, sharedAt } = await _fetchUserIdAndSharedAt(campaignParticipationId);
const competences = await competenceRepository.listPixCompetencesOnly();
const participation = await campaignParticipationRepository.get(campaignParticipationId);

const placementProfile = await placementProfileService.getPlacementProfileWithSnapshotting({
userId,
limitDate: sharedAt,
allowExcessPixAndLevels: false,
const placementProfile = await placementProfileService.getPlacementProfilesWithSnapshotting({
participations: [participation],
competences,
campaignParticipationId,
allowExcessPixAndLevels: false,
});

return new ParticipantResultsShared({
Expand Down
34 changes: 1 addition & 33 deletions api/src/shared/domain/services/placement-profile-service.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,38 +164,6 @@ async function getPlacementProfilesWithSnapshotting({ participations, competence
});
}

async function getPlacementProfileWithSnapshotting({
userId,
limitDate,
competences,
allowExcessPixAndLevels = true,
campaignParticipationId,
}) {
const snapshots = await knowledgeElementSnapshotRepository.findByCampaignParticipationIds([campaignParticipationId]);
const knowledgeElements = snapshots[campaignParticipationId];
const knowledgeElementsByCompetence = knowledgeElements
? knowledgeElements.reduce((acc, ke) => {
if (!acc[ke.competenceId]) {
acc[ke.competenceId] = [];
}
acc[ke.competenceId].push(ke);
return acc;
}, {})
: {};

const userCompetences = _createUserCompetencesV2({
knowledgeElementsByCompetence,
competences,
allowExcessPixAndLevels,
});

return new PlacementProfile({
userId,
profileDate: limitDate,
userCompetences,
});
}

function _matchingDirectlyValidatedSkillsForCompetence(knowledgeElementsForCompetence, skillMap) {
const competenceSkills = knowledgeElementsForCompetence
.filter((ke) => ke.isDirectlyValidated())
Expand All @@ -206,4 +174,4 @@ function _matchingDirectlyValidatedSkillsForCompetence(knowledgeElementsForCompe
return competenceSkills.filter(Boolean);
}

export { getPlacementProfile, getPlacementProfilesWithSnapshotting, getPlacementProfileWithSnapshotting };
export { getPlacementProfile, getPlacementProfilesWithSnapshotting };
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
import { KnowledgeElementCollection } from '../../../../../src/prescription/shared/domain/models/KnowledgeElementCollection.js';
import { LOCALE } from '../../../../../src/shared/domain/constants.js';
import {
CampaignParticipationStatuses,
CampaignTypes,
KnowledgeElement,
} from '../../../../../src/shared/domain/models/index.js';
import { CampaignParticipationStatuses, KnowledgeElement } from '../../../../../src/shared/domain/models/index.js';
import * as placementProfileService from '../../../../../src/shared/domain/services/placement-profile-service.js';
import { databaseBuilder, domainBuilder, expect } from '../../../../test-helper.js';

Expand Down Expand Up @@ -667,236 +663,4 @@ describe('Shared | Integration | Domain | Services | Placement Profile Service',
});
});
});

describe('#getPlacementProfileWithSnapshotting', function () {
const competences = [
{
id: 'competenceRecordIdOne',
area: { id: 'areaOne', code: '1' },
areaId: 'areaOne',
name: 'Construire un flipper',
index: '1.1',
skillIds: ['recCitation4', 'recMoteur3', 'recRecherche4'],
},
{
id: 'competenceRecordIdTwo',
area: { id: 'areaOne', code: '1' },
areaId: 'areaOne',
name: 'Adopter un dauphin',
index: '1.2',
skillIds: ['recRemplir2', 'recRemplir4', 'recUrl3', 'recWeb1'],
},
{
id: 'competenceRecordIdThree',
area: { id: 'areaOne', code: '1' },
areaId: 'areaOne',
name: 'Se faire manger par un requin',
index: '1.3',
skillIds: ['recRequin5', 'recRequin8'],
},
];

it('should assign 0 pixScore and level of 0 to user competence when campaign is TO_SHARE', async function () {
// when
const campaign = databaseBuilder.factory.buildCampaign({ type: CampaignTypes.PROFILES_COLLECTION });
const campaignParticipationProfileCollection = databaseBuilder.factory.buildCampaignParticipation({
campaignId: campaign.id,
userId,
status: CampaignParticipationStatuses.TO_SHARE,
});

const actualPlacementProfile = await placementProfileService.getPlacementProfileWithSnapshotting({
userId,
limitDate: new Date(),
competences,
campaignParticipationId: campaignParticipationProfileCollection.id,
});

// then
expect(actualPlacementProfile.userCompetences).to.deep.equal([
{
id: 'competenceRecordIdOne',
index: '1.1',
areaId: 'areaOne',
name: 'Construire un flipper',
skills: [],
pixScore: 0,
estimatedLevel: 0,
},
{
id: 'competenceRecordIdTwo',
index: '1.2',
areaId: 'areaOne',
name: 'Adopter un dauphin',
skills: [],
pixScore: 0,
estimatedLevel: 0,
},
{
id: 'competenceRecordIdThree',
index: '1.3',
areaId: 'areaOne',
name: 'Se faire manger par un requin',
skills: [],
pixScore: 0,
estimatedLevel: 0,
},
]);
});

describe('PixScore by competences', function () {
it('should assign pixScore and level to user competence based on knowledge elements', async function () {
// given
const knowledgeElement = databaseBuilder.factory.buildKnowledgeElement({
competenceId: 'competenceRecordIdTwo',
skillId: 'recRemplir2',
earnedPix: 23,
userId,
assessmentId,
});

databaseBuilder.factory.buildKnowledgeElementSnapshot({
userId,
snappedAt: campaignParticipation.sharedAt,
campaignParticipationId: campaignParticipation.id,
snapshot: JSON.stringify([knowledgeElement]),
});

await databaseBuilder.commit();

// when
const actualPlacementProfile = await placementProfileService.getPlacementProfileWithSnapshotting({
userId,
limitDate: new Date(),
competences,
campaignParticipationId: campaignParticipation.id,
});

// then
expect(actualPlacementProfile.userCompetences[0]).to.include({
id: 'competenceRecordIdOne',
pixScore: 0,
estimatedLevel: 0,
});
expect(actualPlacementProfile.userCompetences[1]).to.include({
id: 'competenceRecordIdTwo',
pixScore: 23,
estimatedLevel: 2,
});
});

it('should include both inferred and direct KnowlegdeElements to compute PixScore', async function () {
// given
const ke1 = databaseBuilder.factory.buildKnowledgeElement({
competenceId: 'competenceRecordIdTwo',
skillId: 'recRemplir2',
earnedPix: 8,
source: KnowledgeElement.SourceType.INFERRED,
userId,
assessmentId,
});

const ke2 = databaseBuilder.factory.buildKnowledgeElement({
competenceId: 'competenceRecordIdTwo',
skillId: 'recRemplir4',
earnedPix: 9,
source: KnowledgeElement.SourceType.DIRECT,
userId,
assessmentId,
});

databaseBuilder.factory.buildKnowledgeElementSnapshot({
userId,
snappedAt: campaignParticipation.sharedAt,
campaignParticipationId: campaignParticipation.id,
snapshot: JSON.stringify([ke1, ke2]),
});

await databaseBuilder.commit();

// when
const actualPlacementProfile = await placementProfileService.getPlacementProfileWithSnapshotting({
userId,
limitDate: new Date(),
competences,
campaignParticipationId: campaignParticipation.id,
});

// then
expect(actualPlacementProfile.userCompetences[1].pixScore).to.equal(17);
});

context('when we dont want to limit pix score', function () {
it('should not limit pixScore and level to the max reachable for user competence based on knowledge elements', async function () {
const ke = databaseBuilder.factory.buildKnowledgeElement({
competenceId: 'competenceRecordIdOne',
earnedPix: 64,
userId,
assessmentId,
});

databaseBuilder.factory.buildKnowledgeElementSnapshot({
userId,
snappedAt: campaignParticipation.sharedAt,
campaignParticipationId: campaignParticipation.id,
snapshot: JSON.stringify([ke]),
});

await databaseBuilder.commit();

// when
const actualPlacementProfile = await placementProfileService.getPlacementProfileWithSnapshotting({
userId,
limitDate: new Date(),
competences,
allowExcessPixAndLevels: true,
campaignParticipationId: campaignParticipation.id,
});

// then
expect(actualPlacementProfile.userCompetences[0]).to.include({
id: 'competenceRecordIdOne',
pixScore: 64,
estimatedLevel: 8,
});
});
});

context('when we want to limit pix score', function () {
it('should limit pixScore to 40 and level to 5', async function () {
const ke = databaseBuilder.factory.buildKnowledgeElement({
competenceId: 'competenceRecordIdOne',
earnedPix: 64,
userId,
assessmentId,
});

databaseBuilder.factory.buildKnowledgeElementSnapshot({
userId,
snappedAt: campaignParticipation.sharedAt,
campaignParticipationId: campaignParticipation.id,
snapshot: JSON.stringify([ke]),
});

await databaseBuilder.commit();

// when
const actualPlacementProfile = await placementProfileService.getPlacementProfileWithSnapshotting({
userId,
limitDate: new Date(),
competences,
allowExcessPixAndLevels: false,
campaignParticipationId: campaignParticipation.id,
});

// then
expect(actualPlacementProfile.userCompetences[0]).to.include({
id: 'competenceRecordIdOne',
pixScore: 40,
estimatedLevel: 5,
});
});
});
});
});
});

0 comments on commit 24db189

Please sign in to comment.