Skip to content

Commit

Permalink
tech(api): save of knowledge-element-snapshot-repository does "upsert…
Browse files Browse the repository at this point in the history
…" now

Co-authored-by: Yvonnick Frin <[email protected]>
Co-authored-by: Xavier Carron <[email protected]>
  • Loading branch information
3 people committed Mar 6, 2025
1 parent b99dbc4 commit b2013e0
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 27 deletions.
Original file line number Diff line number Diff line change
@@ -1,27 +1,32 @@
import { knex } from '../../../../../db/knex-database-connection.js';
import { DomainTransaction } from '../../../../shared/domain/DomainTransaction.js';
import { AlreadyExistingEntityError } from '../../../../shared/domain/errors.js';
import { KnowledgeElement } from '../../../../shared/domain/models/KnowledgeElement.js';
import * as knexUtils from '../../../../shared/infrastructure/utils/knex-utils.js';
import { CampaignParticipationKnowledgeElementSnapshots } from '../../../shared/domain/read-models/CampaignParticipationKnowledgeElementSnapshots.js';

const save = async function ({ userId, snappedAt, snapshot, campaignParticipationId }) {
try {
const knexConn = DomainTransaction.getConnection();
export async function save({ userId, snappedAt, snapshot, campaignParticipationId }) {
const knexConn = DomainTransaction.getConnection();
const existingSnapshot = await knexConn
.select('id')
.from('knowledge-element-snapshots')
.where('campaignParticipationId', campaignParticipationId)
.first();
if (existingSnapshot) {
return await knexConn('knowledge-element-snapshots')
.update({
userId,
snappedAt,
snapshot,
})
.where('campaignParticipationId', campaignParticipationId);
} else {
return await knexConn('knowledge-element-snapshots').insert({
userId,
snappedAt,
snapshot,
campaignParticipationId,
});
} catch (error) {
if (knexUtils.isUniqConstraintViolated(error)) {
throw new AlreadyExistingEntityError(
`A snapshot already exists for the user ${userId} at the datetime ${snappedAt}.`,
);
}
}
};
}

/**
* @function
Expand All @@ -30,7 +35,7 @@ const save = async function ({ userId, snappedAt, snapshot, campaignParticipatio
* @param {number[]} campaignParticipationIds
* @returns {Promise<Array<CampaignParticipationKnowledgeElementSnapshots>>}
*/
const findCampaignParticipationKnowledgeElementSnapshots = async function (campaignParticipationIds) {
export async function findCampaignParticipationKnowledgeElementSnapshots(campaignParticipationIds) {
const knowledgeElementsByCampaignParticipation = await findByCampaignParticipationIds(campaignParticipationIds);
return campaignParticipationIds.map(
(campaignParticipationId) =>
Expand All @@ -39,14 +44,14 @@ const findCampaignParticipationKnowledgeElementSnapshots = async function (campa
campaignParticipationId: campaignParticipationId,
}),
);
};
}

/**
*
* @param {number[]} campaignParticipationIds
* @returns {Object.<number, KnowledgeElement[]>}
*/
const findByCampaignParticipationIds = async function (campaignParticipationIds) {
export async function findByCampaignParticipationIds(campaignParticipationIds) {
const results = await knex
.select('campaignParticipationId', 'snapshot')
.from('knowledge-element-snapshots')
Expand All @@ -60,6 +65,4 @@ const findByCampaignParticipationIds = async function (campaignParticipationIds)
}),
]),
);
};

export { findByCampaignParticipationIds, findCampaignParticipationKnowledgeElementSnapshots, save };
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import * as knowledgeElementSnapshotRepository from '../../../../../../src/prescription/campaign/infrastructure/repositories/knowledge-element-snapshot-repository.js';
import { KnowledgeElementCollection } from '../../../../../../src/prescription/shared/domain/models/KnowledgeElementCollection.js';
import { DomainTransaction } from '../../../../../../src/shared/domain/DomainTransaction.js';
import { AlreadyExistingEntityError } from '../../../../../../src/shared/domain/errors.js';
import { catchErr, databaseBuilder, domainBuilder, expect, knex } from '../../../../../test-helper.js';
import { databaseBuilder, domainBuilder, expect, knex } from '../../../../../test-helper.js';

describe('Integration | Repository | KnowledgeElementSnapshotRepository', function () {
describe('#save', function () {
it('should save knowledge elements snapshot for a userId and a date', async function () {
it('should create a new knowledge elements snapshot when no snapshot exist for given campaignParticipationId', async function () {
// given
const snappedAt = new Date('2019-04-01');
const userId = databaseBuilder.factory.buildUser().id;
Expand Down Expand Up @@ -34,28 +33,56 @@ describe('Integration | Repository | KnowledgeElementSnapshotRepository', functi
const actualUserSnapshot = await knex.select('*').from('knowledge-element-snapshots').first();
expect(actualUserSnapshot.userId).to.deep.equal(userId);
expect(actualUserSnapshot.snappedAt).to.deep.equal(snappedAt);

expect(actualUserSnapshot.snapshot).to.deep.equal(JSON.parse(knowledgeElements.toSnapshot()));
});

it('should throw an error if knowledge elements snapshot already exist for userId and a date', async function () {
it('should update the existing knowledge elements snapshot when snapshot exists for given campaignParticipationId', async function () {
// given
const snappedAt = new Date('2019-04-01');
const userId = databaseBuilder.factory.buildUser().id;
const campaignParticipationId = databaseBuilder.factory.buildCampaignParticipation().id;
databaseBuilder.factory.buildKnowledgeElementSnapshot({ userId, snappedAt, campaignParticipationId });
const knowledgeElement1 = databaseBuilder.factory.buildKnowledgeElement({
userId,
createdAt: new Date('2019-03-01'),
skillId: 'acquis1',
});
const knowledgeElement2 = databaseBuilder.factory.buildKnowledgeElement({
userId,
createdAt: new Date('2019-03-01'),
skillId: 'acquis2',
});
const knowledgeElement3 = databaseBuilder.factory.buildKnowledgeElement({
userId,
createdAt: new Date('2019-03-01'),
skillId: 'acquis3',
});
const knowledgeElementsBefore = new KnowledgeElementCollection([knowledgeElement1, knowledgeElement2]);
databaseBuilder.factory.buildKnowledgeElementSnapshot({
userId,
snappedAt: new Date('2019-01-01'),
campaignParticipationId,
snapshot: knowledgeElementsBefore.toSnapshot(),
});
await databaseBuilder.commit();
const knowledgeElementsAfter = new KnowledgeElementCollection([
knowledgeElement1,
knowledgeElement2,
knowledgeElement3,
]);

// when
const error = await catchErr(knowledgeElementSnapshotRepository.save)({
await knowledgeElementSnapshotRepository.save({
userId,
snappedAt,
snapshot: JSON.stringify([]),
snapshot: knowledgeElementsAfter.toSnapshot(),
campaignParticipationId,
});

// then
expect(error).to.be.instanceOf(AlreadyExistingEntityError);
const actualUserSnapshot = await knex.select('*').from('knowledge-element-snapshots').first();
expect(actualUserSnapshot.userId).to.deep.equal(userId);
expect(actualUserSnapshot.snappedAt).to.deep.equal(snappedAt);
expect(actualUserSnapshot.snapshot).to.deep.equal(JSON.parse(knowledgeElementsAfter.toSnapshot()));
});

context('when a transaction is given transaction', function () {
Expand Down

0 comments on commit b2013e0

Please sign in to comment.