Skip to content

Commit 93edf9f

Browse files
committed
feat(api): record passage started event
by using module content as content hash
1 parent c35b90e commit 93edf9f

File tree

2 files changed

+67
-9
lines changed

2 files changed

+67
-9
lines changed

api/src/devcomp/domain/usecases/create-passage.js

+25-4
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
1+
import { withTransaction } from '../../../shared/domain/DomainTransaction.js';
12
import { NotFoundError } from '../../../shared/domain/errors.js';
23
import { ModuleDoesNotExistError } from '../errors.js';
4+
import { PassageStartedEvent } from '../models/passage-events/passage-events.js';
35

4-
const createPassage = async function ({ moduleId, userId, moduleRepository, passageRepository, userRepository }) {
5-
await _getModule({ moduleId, moduleRepository });
6+
const createPassage = withTransaction(async function ({
7+
moduleId,
8+
userId,
9+
moduleRepository,
10+
passageRepository,
11+
passageEventRepository,
12+
userRepository,
13+
}) {
14+
const module = await _getModule({ moduleId, moduleRepository });
615
if (userId !== null) {
716
await userRepository.get(userId);
817
}
9-
return passageRepository.save({ moduleId, userId });
10-
};
18+
19+
const passage = await passageRepository.save({ moduleId, userId });
20+
await _recordPassageEvent({ module, passage, passageEventRepository });
21+
22+
return passage;
23+
});
1124

1225
async function _getModule({ moduleId, moduleRepository }) {
1326
try {
@@ -20,4 +33,12 @@ async function _getModule({ moduleId, moduleRepository }) {
2033
}
2134
}
2235

36+
async function _recordPassageEvent({ module, passage, passageEventRepository }) {
37+
const { id: passageId, createdAt: occurredAt } = passage;
38+
const contentHash = module.hash();
39+
const passageStartedEvent = new PassageStartedEvent({ contentHash, passageId, occurredAt });
40+
41+
await passageEventRepository.record(passageStartedEvent);
42+
}
43+
2344
export { createPassage };

api/tests/devcomp/unit/domain/usecases/create-passage_test.js

+42-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
import { ModuleDoesNotExistError } from '../../../../../src/devcomp/domain/errors.js';
2+
import { Module } from '../../../../../src/devcomp/domain/models/module/Module.js';
3+
import { Passage } from '../../../../../src/devcomp/domain/models/Passage.js';
4+
import { PassageStartedEvent } from '../../../../../src/devcomp/domain/models/passage-events/passage-events.js';
25
import { createPassage } from '../../../../../src/devcomp/domain/usecases/create-passage.js';
36
import { UserNotFoundError } from '../../../../../src/shared/domain/errors.js';
47
import { NotFoundError } from '../../../../../src/shared/domain/errors.js';
@@ -48,11 +51,38 @@ describe('Unit | Devcomp | Domain | UseCases | create-passage', function () {
4851
});
4952
});
5053

51-
it('should call passage repository to save the passage', async function () {
54+
it('should save the passage and record passage started event', async function () {
5255
// given
5356
const moduleId = Symbol('moduleId');
57+
const passageId = Symbol('passageId');
5458
const userId = Symbol('userId');
55-
const repositoryResult = Symbol('repository-result');
59+
60+
const slug = 'les-adresses-email';
61+
const title = 'Les adresses email';
62+
const isBeta = false;
63+
const grains = [Symbol('text')];
64+
const transitionTexts = [];
65+
const details = Symbol('details');
66+
const hash = 'AZERTY123456';
67+
let module = new Module({ id: moduleId, slug, title, isBeta, grains, details, transitionTexts });
68+
module = {
69+
...module,
70+
hash: sinon.stub().returns(hash),
71+
};
72+
73+
const passageCreatedAt = new Date('2025-03-05');
74+
const passage = new Passage({
75+
id: passageId,
76+
moduleId,
77+
userId,
78+
createdAt: passageCreatedAt,
79+
});
80+
81+
const passageStartedEvent = new PassageStartedEvent({
82+
contentHash: hash,
83+
occurredAt: passageCreatedAt,
84+
passageId,
85+
});
5686

5787
const userRepositoryStub = {
5888
get: sinon.stub(),
@@ -61,17 +91,22 @@ describe('Unit | Devcomp | Domain | UseCases | create-passage', function () {
6191
const moduleRepositoryStub = {
6292
getBySlug: sinon.stub(),
6393
};
64-
moduleRepositoryStub.getBySlug.withArgs({ slug: moduleId }).resolves();
94+
moduleRepositoryStub.getBySlug.withArgs({ slug: moduleId }).resolves(module);
6595
const passageRepositoryStub = {
6696
save: sinon.stub(),
6797
};
68-
passageRepositoryStub.save.resolves(repositoryResult);
98+
passageRepositoryStub.save.resolves(passage);
99+
100+
const passageEventRepositoryStub = {
101+
record: sinon.stub(),
102+
};
69103

70104
// when
71105
const result = await createPassage({
72106
moduleId,
73107
userId,
74108
passageRepository: passageRepositoryStub,
109+
passageEventRepository: passageEventRepositoryStub,
75110
moduleRepository: moduleRepositoryStub,
76111
userRepository: userRepositoryStub,
77112
});
@@ -81,6 +116,8 @@ describe('Unit | Devcomp | Domain | UseCases | create-passage', function () {
81116
moduleId,
82117
userId,
83118
});
84-
expect(result).to.equal(repositoryResult);
119+
expect(module.hash).to.have.been.calledOnce;
120+
expect(passageEventRepositoryStub.record).to.have.been.calledOnceWith(passageStartedEvent);
121+
expect(result).to.equal(passage);
85122
});
86123
});

0 commit comments

Comments
 (0)