Skip to content

Commit fb3facc

Browse files
committed
♻️ chore(api) reduce bounded context violation
1 parent 0cc443b commit fb3facc

File tree

4 files changed

+39
-71
lines changed

4 files changed

+39
-71
lines changed

api/src/devcomp/domain/usecases/find-tutorials.js

+6-14
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,20 @@
11
import _ from 'lodash';
22

3-
// TODO Bounded context violation
4-
import { Scorecard } from '../../../evaluation/domain/models/Scorecard.js';
5-
import { UserNotAuthorizedToAccessEntityError } from '../../../shared/domain/errors.js';
63
import { KnowledgeElement } from '../../../shared/domain/models/KnowledgeElement.js';
74

85
const findTutorials = async function ({
9-
authenticatedUserId,
10-
scorecardId,
6+
userId,
7+
competenceId,
118
knowledgeElementRepository,
129
skillRepository,
1310
tubeRepository,
1411
tutorialRepository,
1512
locale,
1613
}) {
17-
// TODO replace scorecardId by competenceId
18-
const { userId, competenceId } = Scorecard.parseId(scorecardId);
19-
20-
// TODO refactor to extract this guard to controller
21-
if (parseInt(authenticatedUserId) !== parseInt(userId)) {
22-
throw new UserNotAuthorizedToAccessEntityError();
23-
}
24-
25-
const knowledgeElements = await knowledgeElementRepository.findUniqByUserIdAndCompetenceId({ userId, competenceId });
14+
const knowledgeElements = await knowledgeElementRepository.findUniqByUserIdAndCompetenceId({
15+
userId,
16+
competenceId,
17+
});
2618
const invalidatedDirectKnowledgeElements = _getInvalidatedDirectKnowledgeElements(knowledgeElements);
2719

2820
if (invalidatedDirectKnowledgeElements.length === 0) {

api/src/evaluation/application/scorecards/scorecard-controller.js

+15-9
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,10 @@
22
import { usecases as devCompUsecases } from '../../../devcomp/domain/usecases/index.js';
33
// TODO Bounded context violation
44
import * as tutorialSerializer from '../../../devcomp/infrastructure/serializers/jsonapi/tutorial-serializer.js';
5-
import { evaluationUsecases } from '../../../evaluation/domain/usecases/index.js';
5+
import { UserNotAuthorizedToAccessEntityError } from '../../../shared/domain/errors.js';
66
import * as requestResponseUtils from '../../../shared/infrastructure/utils/request-response-utils.js';
7+
import { Scorecard } from '../../domain/models/Scorecard.js';
8+
import { evaluationUsecases } from '../../domain/usecases/index.js';
79
import * as scorecardSerializer from '../../infrastructure/serializers/jsonapi/scorecard-serializer.js';
810

911
const getScorecard = function (request, h, dependencies = { requestResponseUtils, scorecardSerializer }) {
@@ -20,18 +22,22 @@ const getScorecard = function (request, h, dependencies = { requestResponseUtils
2022
.then(dependencies.scorecardSerializer.serialize);
2123
};
2224

23-
const findTutorials = function (request, h, dependencies = { requestResponseUtils, tutorialSerializer }) {
25+
const findTutorials = async function (request, h, dependencies = { requestResponseUtils, tutorialSerializer }) {
2426
const locale = dependencies.requestResponseUtils.extractLocaleFromRequest(request);
2527
const authenticatedUserId = request.auth.credentials.userId;
2628
const scorecardId = request.params.id;
2729

28-
return devCompUsecases
29-
.findTutorials({
30-
authenticatedUserId,
31-
scorecardId,
32-
locale,
33-
})
34-
.then(dependencies.tutorialSerializer.serialize);
30+
const { userId, competenceId } = await Scorecard.parseId(scorecardId);
31+
if (parseInt(authenticatedUserId) !== parseInt(userId)) {
32+
throw new UserNotAuthorizedToAccessEntityError();
33+
}
34+
const tutorials = await devCompUsecases.findTutorials({
35+
userId,
36+
competenceId,
37+
locale,
38+
});
39+
console.log('tutorials ', tutorials);
40+
return dependencies.tutorialSerializer.serialize(tutorials);
3541
};
3642

3743
const resetScorecard = function (request, h, dependencies = { scorecardSerializer, requestResponseUtils }) {

api/tests/devcomp/unit/domain/usecases/find-tutorials_test.js

+11-42
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
import { findTutorials } from '../../../../../src/devcomp/domain/usecases/find-tutorials.js';
2-
import { Scorecard } from '../../../../../src/evaluation/domain/models/Scorecard.js';
3-
import { UserNotAuthorizedToAccessEntityError } from '../../../../../src/shared/domain/errors.js';
42
import { KnowledgeElement } from '../../../../../src/shared/domain/models/KnowledgeElement.js';
53
import { domainBuilder, expect, sinon } from '../../../../test-helper.js';
64

75
describe('Unit | UseCase | find-tutorials', function () {
8-
let authenticatedUserId;
6+
let userId;
97
let competenceId;
10-
let scorecardId;
11-
let parseIdStub;
128
let knowledgeElementRepository;
139
let skillRepository;
1410
let tubeRepository;
@@ -17,10 +13,8 @@ describe('Unit | UseCase | find-tutorials', function () {
1713
let locale;
1814

1915
beforeEach(function () {
20-
scorecardId = '1_recabC123';
2116
competenceId = 'recABc123';
22-
authenticatedUserId = 1;
23-
parseIdStub = sinon.stub(Scorecard, 'parseId');
17+
userId = 1;
2418
knowledgeElementRepository = { findUniqByUserIdAndCompetenceId: sinon.stub() };
2519
skillRepository = { findActiveByCompetenceId: sinon.stub() };
2620
tubeRepository = { findByNames: sinon.stub() };
@@ -29,19 +23,15 @@ describe('Unit | UseCase | find-tutorials', function () {
2923
});
3024

3125
context('When user is authenticated', function () {
32-
beforeEach(function () {
33-
parseIdStub.withArgs(scorecardId).returns({ competenceId, userId: authenticatedUserId });
34-
});
35-
3626
context('And user asks for tutorials belonging to his scorecard', function () {
3727
it('should resolve', function () {
3828
// given
3929
knowledgeElementRepository.findUniqByUserIdAndCompetenceId.resolves({});
4030

4131
// when
4232
const result = findTutorials({
43-
authenticatedUserId,
44-
scorecardId,
33+
userId,
34+
competenceId,
4535
knowledgeElementRepository,
4636
skillRepository,
4737
tubeRepository,
@@ -101,14 +91,14 @@ describe('Unit | UseCase | find-tutorials', function () {
10191
const inferredTutorialIdList = [inferredTutorial.id];
10292

10393
tutorialRepository.findByRecordIdsForCurrentUser
104-
.withArgs({ ids: tutorialIdList1, userId: authenticatedUserId, locale })
94+
.withArgs({ ids: tutorialIdList1, userId: userId, locale })
10595
.returns([tutorial1, tutorial2]);
10696
tutorialRepository.findByRecordIdsForCurrentUser
107-
.withArgs({ ids: tutorialIdList2, userId: authenticatedUserId, locale })
97+
.withArgs({ ids: tutorialIdList2, userId: userId, locale })
10898
.returns([tutorial3]);
10999

110100
tutorialRepository.findByRecordIdsForCurrentUser
111-
.withArgs({ ids: inferredTutorialIdList, userId: authenticatedUserId })
101+
.withArgs({ ids: inferredTutorialIdList, userId: userId })
112102
.returns([inferredTutorial]);
113103

114104
const skill_1 = domainBuilder.buildSkill({
@@ -227,8 +217,8 @@ describe('Unit | UseCase | find-tutorials', function () {
227217
it('should return the tutorials related to the scorecard', async function () {
228218
// when
229219
const result = await findTutorials({
230-
authenticatedUserId,
231-
scorecardId,
220+
userId,
221+
competenceId,
232222
knowledgeElementRepository,
233223
skillRepository,
234224
tubeRepository,
@@ -267,8 +257,8 @@ describe('Unit | UseCase | find-tutorials', function () {
267257

268258
// when
269259
const result = await findTutorials({
270-
authenticatedUserId,
271-
scorecardId,
260+
userId,
261+
competenceId,
272262
knowledgeElementRepository,
273263
skillRepository,
274264
tubeRepository,
@@ -282,26 +272,5 @@ describe('Unit | UseCase | find-tutorials', function () {
282272
});
283273
});
284274
});
285-
286-
context('And user asks for a scorecard that do not belongs to him', function () {
287-
it('should reject a "UserNotAuthorizedToAccessEntityError" domain error', function () {
288-
// given
289-
const unauthorizedUserId = 42;
290-
291-
// when
292-
const promise = findTutorials({
293-
authenticatedUserId: unauthorizedUserId,
294-
scorecardId,
295-
knowledgeElementRepository,
296-
skillRepository,
297-
tubeRepository,
298-
tutorialRepository,
299-
userSavedTutorialRepository,
300-
});
301-
302-
// then
303-
return expect(promise).to.be.rejectedWith(UserNotAuthorizedToAccessEntityError);
304-
});
305-
});
306275
});
307276
});

api/tests/evaluation/unit/application/scorecards/scorecard-controller_test.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { usecases as devCompUsecases } from '../../../../../src/devcomp/domain/usecases/index.js';
22
import { scorecardController } from '../../../../../src/evaluation/application/scorecards/scorecard-controller.js';
3+
import { Scorecard } from '../../../../../src/evaluation/domain/models/Scorecard.js';
34
import { evaluationUsecases } from '../../../../../src/evaluation/domain/usecases/index.js';
45
import * as requestResponseUtils from '../../../../../src/shared/infrastructure/utils/request-response-utils.js';
56
import { expect, hFake, sinon } from '../../../../test-helper.js';
@@ -54,16 +55,16 @@ describe('Unit | Controller | scorecard-controller', function () {
5455

5556
describe('#findTutorials', function () {
5657
const tutorials = [];
58+
const competenceId = 13;
59+
const userId = authenticatedUserId;
60+
const scorecard = { userId, competenceId };
5761

58-
beforeEach(function () {
62+
it('should call the expected usecase', async function () {
5963
sinon
6064
.stub(devCompUsecases, 'findTutorials')
61-
.withArgs({ authenticatedUserId, scorecardId, locale })
65+
.withArgs({ userId: authenticatedUserId, competenceId, locale })
6266
.resolves(tutorials);
63-
});
64-
65-
it('should call the expected usecase', async function () {
66-
// given
67+
sinon.stub(Scorecard, 'parseId').withArgs(scorecardId).resolves(scorecard);
6768
const tutorialSerializer = {
6869
serialize: sinon.stub(),
6970
};

0 commit comments

Comments
 (0)