diff --git a/.env.example b/.env.example index ad219648..c6baa0d8 100644 --- a/.env.example +++ b/.env.example @@ -15,3 +15,4 @@ RABBITMQ_DEFAULT_USER=app RABBITMQ_DEFAULT_PASS=rabbit_app RABBITMQ_EVENTS_QUEUE='events_queue' RABBITMQ_HOST="amqp://${RABBITMQ_DEFAULT_USER}:${RABBITMQ_DEFAULT_PASS}@rabbitmq:5672" +SERVER_URL=http://localhost:4000 diff --git a/.env.test b/.env.test index 7816764c..3cf89f74 100644 --- a/.env.test +++ b/.env.test @@ -15,3 +15,4 @@ RABBITMQ_DEFAULT_USER=app RABBITMQ_DEFAULT_PASS=rabbit_app RABBITMQ_EVENTS_QUEUE='events_queue' RABBITMQ_HOST="amqp://app:rabbit_app@localhost:5672" +SERVER_URL=http://localhost:4000 diff --git a/src/languages/_dependencyInjection/repositories.ts b/src/languages/_dependencyInjection/repositories.ts index 5207cecb..356d2fc9 100644 --- a/src/languages/_dependencyInjection/repositories.ts +++ b/src/languages/_dependencyInjection/repositories.ts @@ -2,6 +2,8 @@ import { COUNTRY_REPOSITORY } from '@src/languages/domain/country/countryReposit import { TERM_REPOSITORY } from '@src/languages/domain/term/termRepository'; import MikroOrmCountryRepository from '../infrastructure/persistence/mikroOrm/repositories/mikroOrmCountryRepository'; import MikroOrmTermRepository from '../infrastructure/persistence/mikroOrm/repositories/mikroOrmTermRepository'; +import { COLLABORATOR_REPOSITORY } from '@src/languages/domain/collaborator/collaboratorRepository'; +import { TranslatingCollaboratorRepository } from '@src/languages/infrastructure/persistence/http/TranslatingCollaboratorRepository'; export const repositories = [ { @@ -12,4 +14,8 @@ export const repositories = [ provide: TERM_REPOSITORY, useClass: MikroOrmTermRepository, }, + { + provide: COLLABORATOR_REPOSITORY, + useClass: TranslatingCollaboratorRepository, + }, ]; diff --git a/src/languages/_dependencyInjection/services.ts b/src/languages/_dependencyInjection/services.ts new file mode 100644 index 00000000..0b35a596 --- /dev/null +++ b/src/languages/_dependencyInjection/services.ts @@ -0,0 +1,5 @@ +import { HttpCollaboratorAdapter } from '@src/languages/infrastructure/persistence/http/httpCollaboratorAdapter'; + +export const services = [ + HttpCollaboratorAdapter +]; \ No newline at end of file diff --git a/src/languages/application/term/command/addLikeTermCommandHandler.ts b/src/languages/application/term/command/addLikeTermCommandHandler.ts index 22137a51..9b9ebd0d 100644 --- a/src/languages/application/term/command/addLikeTermCommandHandler.ts +++ b/src/languages/application/term/command/addLikeTermCommandHandler.ts @@ -1,32 +1,34 @@ import { CommandHandler, ICommandHandler } from '@src/shared/domain/bus/commandBus/commandHandler'; import AddLikeTermCommand from '@src/languages/application/term/command/addLikeTermCommand'; import TermId from '@src/languages/domain/term/termId'; -import UserId from '@src/account/domain/user/userId'; import { Inject } from '@src/shared/domain/injector/inject.decorator'; import TermRepository, { TERM_REPOSITORY } from '@src/languages/domain/term/termRepository'; import Term from '@src/languages/domain/term/term'; import TermDoesNotExistsException from '@src/languages/domain/term/termDoesNotExistsException'; -import UserRepository, { USER_REPOSITORY } from '@src/account/domain/user/userRepository'; -import UserDoesNotExistsException from '@src/account/domain/user/userDoesNotExistsException'; -import User from '@src/account/domain/user/user'; import { ASYNC_EVENT_BUS, EventBus } from '@src/shared/domain/bus/eventBus/eventBus'; +import CollaboratorRepository, { + COLLABORATOR_REPOSITORY, +} from '@src/languages/domain/collaborator/collaboratorRepository'; +import CollaboratorId from '@src/languages/domain/collaborator/collaboratorId'; +import Collaborator from '@src/languages/domain/collaborator/collaborator'; +import CollaboratorDoesNotExistsException from '@src/languages/domain/collaborator/collaboratorDoesNotExistsException'; @CommandHandler(AddLikeTermCommand) export default class AddLikeTermCommandHandler implements ICommandHandler { constructor( @Inject(TERM_REPOSITORY) private readonly termRepository: TermRepository, - @Inject(USER_REPOSITORY) private readonly userRepository: UserRepository, + @Inject(COLLABORATOR_REPOSITORY) private readonly collaboratorRepository: CollaboratorRepository, @Inject(ASYNC_EVENT_BUS) private readonly eventBus: EventBus, ) {} async execute(command: AddLikeTermCommand): Promise { const termId = TermId.of(command.termId); - const userId = UserId.of(command.userId); + const collaboratorId = CollaboratorId.of(command.userId); const term = await this.getTerm(termId); - const user = await this.getUser(userId); + const collaborator = await this.getCollaborator(collaboratorId); - term.addLike(userId, user.getName(), user.getPhoto()); + term.addLike(collaboratorId, collaborator.getName(), collaborator.getPhoto()); this.termRepository.save(term); @@ -42,12 +44,12 @@ export default class AddLikeTermCommandHandler implements ICommandHandler { - const user = await this.userRepository.findById(userId); - if (!user) { - throw new UserDoesNotExistsException(userId.toString()); + private async getCollaborator(collaboratorId: CollaboratorId): Promise { + const collaborator = await this.collaboratorRepository.findById(collaboratorId); + if (!collaborator) { + throw new CollaboratorDoesNotExistsException(collaboratorId.toString()); } - return user; + return collaborator; } } diff --git a/src/languages/application/term/command/dislikeTermCommandHandler.ts b/src/languages/application/term/command/dislikeTermCommandHandler.ts index 43efacdf..786bd100 100644 --- a/src/languages/application/term/command/dislikeTermCommandHandler.ts +++ b/src/languages/application/term/command/dislikeTermCommandHandler.ts @@ -1,32 +1,34 @@ import { CommandHandler, ICommandHandler } from '@src/shared/domain/bus/commandBus/commandHandler'; import TermId from '@src/languages/domain/term/termId'; -import UserId from '@src/account/domain/user/userId'; import DislikeTermCommand from '@src/languages/application/term/command/dislikeTermCommand'; import Term from '@src/languages/domain/term/term'; import TermDoesNotExistsException from '@src/languages/domain/term/termDoesNotExistsException'; -import User from '@src/account/domain/user/user'; -import UserDoesNotExistsException from '@src/account/domain/user/userDoesNotExistsException'; import { Inject } from '@src/shared/domain/injector/inject.decorator'; import TermRepository, { TERM_REPOSITORY } from '@src/languages/domain/term/termRepository'; -import UserRepository, { USER_REPOSITORY } from '@src/account/domain/user/userRepository'; import { ASYNC_EVENT_BUS, EventBus } from '@src/shared/domain/bus/eventBus/eventBus'; +import CollaboratorRepository, { + COLLABORATOR_REPOSITORY, +} from '@src/languages/domain/collaborator/collaboratorRepository'; +import Collaborator from '@src/languages/domain/collaborator/collaborator'; +import CollaboratorId from '@src/languages/domain/collaborator/collaboratorId'; +import CollaboratorDoesNotExistsException from '@src/languages/domain/collaborator/collaboratorDoesNotExistsException'; @CommandHandler(DislikeTermCommand) export default class DislikeTermCommandHandler implements ICommandHandler { constructor( @Inject(TERM_REPOSITORY) private readonly termRepository: TermRepository, - @Inject(USER_REPOSITORY) private readonly userRepository: UserRepository, + @Inject(COLLABORATOR_REPOSITORY) private readonly collaboratorRepository: CollaboratorRepository, @Inject(ASYNC_EVENT_BUS) private readonly eventBus: EventBus, ) {} async execute(command: DislikeTermCommand): Promise { const termId = TermId.of(command.termId); - const userId = UserId.of(command.userId); + const collaboratorId = CollaboratorId.of(command.userId); const term = await this.getTerm(termId); - const user = await this.getUser(userId); + const collaborator = await this.getCollaborator(collaboratorId); - term.dislike(userId, user.getName(), user.getPhoto()); + term.dislike(collaboratorId, collaborator.getName(), collaborator.getPhoto()); this.termRepository.save(term); @@ -42,12 +44,12 @@ export default class DislikeTermCommandHandler implements ICommandHandler { - const user = await this.userRepository.findById(userId); - if (!user) { - throw new UserDoesNotExistsException(userId.toString()); + private async getCollaborator(collaboratorId: CollaboratorId): Promise { + const collaborator = await this.collaboratorRepository.findById(collaboratorId); + if (!collaborator) { + throw new CollaboratorDoesNotExistsException(collaboratorId.toString()); } - return user; + return collaborator; } } diff --git a/src/languages/domain/collaborator/collaborator.ts b/src/languages/domain/collaborator/collaborator.ts new file mode 100644 index 00000000..d4fcac8d --- /dev/null +++ b/src/languages/domain/collaborator/collaborator.ts @@ -0,0 +1,36 @@ +import { AggregateRoot } from '@src/shared/domain/aggregate/aggregateRoot'; +import CollaboratorId from '@src/languages/domain/collaborator/collaboratorId'; + +export type CollaboratorPrimitives = { + id: string; + name: string; + photo: string; + interests: string[]; +}; + +export default class Collaborator extends AggregateRoot { + constructor(private id: CollaboratorId, private name: string, private photo: string, private interests: string[]) { + super(); + } + + public getName(): string { + return this.name; + } + + public getPhoto(): string { + return this.photo; + } + + public getInterests(): string[] { + return this.interests; + } + + toPrimitives(): CollaboratorPrimitives { + return { + id: this.id.toString(), + name: this.name, + photo: this.photo, + interests: this.interests, + }; + } +} diff --git a/src/languages/domain/collaborator/collaboratorDoesNotExistsException.ts b/src/languages/domain/collaborator/collaboratorDoesNotExistsException.ts new file mode 100644 index 00000000..4958d91d --- /dev/null +++ b/src/languages/domain/collaborator/collaboratorDoesNotExistsException.ts @@ -0,0 +1,7 @@ +import NotFoundException from '@src/shared/domain/exceptions/notFoundException'; + +export default class CollaboratorDoesNotExistsException extends NotFoundException { + constructor(collaboratorId: string) { + super(`Collaborator ${collaboratorId} does not exists`, 'collaborator_does_not_exists'); + } +} diff --git a/src/languages/domain/collaborator/collaboratorId.ts b/src/languages/domain/collaborator/collaboratorId.ts new file mode 100644 index 00000000..f4d9fc47 --- /dev/null +++ b/src/languages/domain/collaborator/collaboratorId.ts @@ -0,0 +1,11 @@ +import { Uuid } from '@src/shared/domain/valueObjects/uuid'; + +export default class CollaboratorId extends Uuid { + static of(value: string): CollaboratorId { + return super.of(value) as CollaboratorId; + } + + static fromPrimitives(value: string): CollaboratorId { + return super.fromPrimitives(value) as CollaboratorId; + } +} diff --git a/src/languages/domain/collaborator/collaboratorRepository.ts b/src/languages/domain/collaborator/collaboratorRepository.ts new file mode 100644 index 00000000..9d17c701 --- /dev/null +++ b/src/languages/domain/collaborator/collaboratorRepository.ts @@ -0,0 +1,10 @@ +import Collaborator from '@src/languages/domain/collaborator/collaborator'; +import CollaboratorId from '@src/languages/domain/collaborator/collaboratorId'; + +interface CollaboratorRepository { + findById(id: CollaboratorId): Promise; +} + +export default CollaboratorRepository; + +export const COLLABORATOR_REPOSITORY = Symbol('CollaboratorRepository'); diff --git a/src/languages/infrastructure/persistence/http/TranslatingCollaboratorRepository.ts b/src/languages/infrastructure/persistence/http/TranslatingCollaboratorRepository.ts new file mode 100644 index 00000000..801124fa --- /dev/null +++ b/src/languages/infrastructure/persistence/http/TranslatingCollaboratorRepository.ts @@ -0,0 +1,14 @@ +import CollaboratorRepository from '@src/languages/domain/collaborator/collaboratorRepository'; +import Collaborator from '@src/languages/domain/collaborator/collaborator'; +import CollaboratorId from '@src/languages/domain/collaborator/collaboratorId'; +import { Injectable } from '@nestjs/common'; +import { HttpCollaboratorAdapter } from '@src/languages/infrastructure/persistence/http/httpCollaboratorAdapter'; + +@Injectable() +export class TranslatingCollaboratorRepository implements CollaboratorRepository { + constructor(private readonly httpCollaboratorAdapter: HttpCollaboratorAdapter) {} + + async findById(id: CollaboratorId): Promise { + return this.httpCollaboratorAdapter.toCollaborator(id); + } +} diff --git a/src/languages/infrastructure/persistence/http/collaboratorTranslator.ts b/src/languages/infrastructure/persistence/http/collaboratorTranslator.ts new file mode 100644 index 00000000..e608cbff --- /dev/null +++ b/src/languages/infrastructure/persistence/http/collaboratorTranslator.ts @@ -0,0 +1,9 @@ +import Collaborator from '@src/languages/domain/collaborator/collaborator'; +import { AxiosResponse } from 'axios'; + +export class CollaboratorTranslator { + static toCollaborator(collaboratorResponse: AxiosResponse): Collaborator { + const collaborator = collaboratorResponse.data; + return new Collaborator(collaborator.id, collaborator.name, collaborator.photo, collaborator.interests); + } +} diff --git a/src/languages/infrastructure/persistence/http/httpCollaboratorAdapter.ts b/src/languages/infrastructure/persistence/http/httpCollaboratorAdapter.ts new file mode 100644 index 00000000..26322082 --- /dev/null +++ b/src/languages/infrastructure/persistence/http/httpCollaboratorAdapter.ts @@ -0,0 +1,18 @@ +import { Injectable } from '@nestjs/common'; +import { HttpService } from '@nestjs/axios'; +import { firstValueFrom } from 'rxjs'; +import CollaboratorId from '@src/languages/domain/collaborator/collaboratorId'; +import Collaborator from '@src/languages/domain/collaborator/collaborator'; +import { CollaboratorTranslator } from '@src/languages/infrastructure/persistence/http/collaboratorTranslator'; + +@Injectable() +export class HttpCollaboratorAdapter { + URL = '/users/{id}'; + constructor(private readonly httpService: HttpService) {} + + async toCollaborator(id: CollaboratorId): Promise { + const { data } = await firstValueFrom(this.httpService.get(this.URL.replace('{id}', id.toString))); + + return CollaboratorTranslator.toCollaborator(data); + } +} diff --git a/src/languages/infrastructure/persistence/mongo/readModels/mongoFindSuggestionsTermReadModel.ts b/src/languages/infrastructure/persistence/mongo/readModels/mongoFindSuggestionsTermReadModel.ts index fa5c1df6..68df87e0 100644 --- a/src/languages/infrastructure/persistence/mongo/readModels/mongoFindSuggestionsTermReadModel.ts +++ b/src/languages/infrastructure/persistence/mongo/readModels/mongoFindSuggestionsTermReadModel.ts @@ -1,26 +1,29 @@ import FindSuggestionsTermReadModel from '@src/languages/application/term/query/findSuggestionsTermReadModel'; import UserId from '@src/account/domain/user/userId'; import { TermView } from '@src/languages/application/term/query/termView'; -import UserRepository, { USER_REPOSITORY } from '@src/account/domain/user/userRepository'; import { Inject } from '@src/shared/domain/injector/inject.decorator'; import { Document } from 'mongodb'; import MongoConnection, { MONGO_CLIENT } from '@src/shared/infrastructure/persistence/mongo/mongoConnection'; -import User from '@src/account/domain/user/user'; -import UserDoesNotExistsException from '@src/account/domain/user/userDoesNotExistsException'; +import CollaboratorRepository, { + COLLABORATOR_REPOSITORY, +} from '@src/languages/domain/collaborator/collaboratorRepository'; +import Collaborator from '@src/languages/domain/collaborator/collaborator'; +import CollaboratorDoesNotExistsException from '@src/languages/domain/collaborator/collaboratorDoesNotExistsException'; +import CollaboratorId from '@src/languages/domain/collaborator/collaboratorId'; export default class MongoFindSuggestionsTermReadModel implements FindSuggestionsTermReadModel { constructor( @Inject(MONGO_CLIENT) private readonly mongo: MongoConnection, - @Inject(USER_REPOSITORY) private readonly userRepository: UserRepository, + @Inject(COLLABORATOR_REPOSITORY) private readonly collaboratorRepository: CollaboratorRepository, ) {} async find(userId: UserId): Promise { - const user = await this.getUser(userId); + const collaborator = await this.getCollaborator(userId); const result = await this.mongo.db .collection('terms') .find({ - $or: [{ hashtags: user.getInterests() }], + $or: [{ hashtags: collaborator.getInterests() }], }) .project({ _id: 0 }) .sort(['createdAt', -1]) @@ -43,12 +46,12 @@ export default class MongoFindSuggestionsTermReadModel implements FindSuggestion }); } - async getUser(userId: UserId): Promise { - const user = await this.userRepository.findById(userId); - if (null === user) { - throw new UserDoesNotExistsException(userId.toString()); + async getCollaborator(collaboratorId: CollaboratorId): Promise { + const collaborator = await this.collaboratorRepository.findById(collaboratorId); + if (null === collaborator) { + throw new CollaboratorDoesNotExistsException(collaboratorId.toString()); } - return user; + return collaborator; } } diff --git a/src/languages/language.module.ts b/src/languages/language.module.ts index 839056fb..9048f804 100644 --- a/src/languages/language.module.ts +++ b/src/languages/language.module.ts @@ -9,11 +9,26 @@ import { readModels } from '@src/languages/_dependencyInjection/readModels'; import { MikroOrmModule } from '@mikro-orm/nestjs'; import { entitySchemas } from '@src/languages/_dependencyInjection/entitySchemas'; import mikroOrmConfiguration from './infrastructure/persistence/mikroOrm/config'; +import { HttpModule } from '@nestjs/axios'; +import { ConfigModule, ConfigService } from '@nestjs/config'; +import { services } from '@src/languages/_dependencyInjection/services'; @Module({ - imports: [MikroOrmModule.forRoot(mikroOrmConfiguration), MikroOrmModule.forFeature(entitySchemas)], + imports: [ + MikroOrmModule.forRoot(mikroOrmConfiguration), + MikroOrmModule.forFeature(entitySchemas), + ConfigModule.forRoot(), + HttpModule.registerAsync({ + imports: [ConfigModule], + inject: [ConfigService], + useFactory: (configService: ConfigService) => ({ + baseURL: configService.get('SERVER_URL'), + timeout: 5000, + }), + }), + ], exports: [], controllers: [...controllers], - providers: [...commands, ...queries, ...events, ...projections, ...repositories, ...readModels], + providers: [...commands, ...queries, ...events, ...projections, ...services, ...repositories, ...readModels], }) export class LanguageModule {} diff --git a/test/unit/languages/application/term/command/addLikeTermCommandHandler.test.ts b/test/unit/languages/application/term/command/addLikeTermCommandHandler.test.ts index a5e4c2e5..f4aedc2e 100644 --- a/test/unit/languages/application/term/command/addLikeTermCommandHandler.test.ts +++ b/test/unit/languages/application/term/command/addLikeTermCommandHandler.test.ts @@ -6,42 +6,42 @@ import InvalidArgumentException from '@src/shared/domain/exceptions/invalidArgum import { TermRepositoryMock } from '@test/unit/languages/domain/term/termRepositoryMock'; import WordMother from '@test/unit/languages/domain/term/word/wordMother'; import TermDoesNotExistsException from '@src/languages/domain/term/termDoesNotExistsException'; -import { UserRepositoryMock } from '@test/unit/account/domain/user/userRepositoryMock'; -import UserDoesNotExistsException from '@src/account/domain/user/userDoesNotExistsException'; import { TermIdMother } from '@test/unit/languages/domain/term/termIdMother'; -import { UserMother } from '@test/unit/account/domain/user/userMother'; -import { UserIdMother } from '@test/unit/account/domain/user/userIdMother'; import { EventBusMock } from '@test/unit/shared/domain/buses/eventBus/eventBusMock'; import { TermLikeAddedEventMother } from '@test/unit/languages/domain/term/termLikeAddedEventMother'; import TermLikeMother from '@test/unit/languages/domain/term/termLikeMother'; import Word from '@src/languages/domain/term/word/word'; import { TermLikeIdMother } from '@test/unit/languages/domain/term/termLikeIdMother'; +import { CollaboratorRepositoryMock } from '@test/unit/languages/domain/collaborator/collaboratorRepositoryMock'; +import { CollaboratorMother } from '@test/unit/languages/domain/collaborator/collaboratorMother'; +import { CollaboratorIdMother } from '@test/unit/languages/domain/collaborator/collaboratorIdMother'; +import CollaboratorDoesNotExistsException from '@src/languages/domain/collaborator/collaboratorDoesNotExistsException'; describe('Given a AddLikeTermCommandHandler to handle', () => { let termRepository: TermRepositoryMock; - let userRepository: UserRepositoryMock; + let collaboratorRepository: CollaboratorRepositoryMock; let eventBus: EventBusMock; let handler: AddLikeTermCommandHandler; - const USER_ID = '0a8008d5-ab68-4c10-8476-668b5b540e0f'; + const COLLABORATOR_ID = '0a8008d5-ab68-4c10-8476-668b5b540e0f'; const TERM_ID = '7abe3a96-d603-4e87-b69e-e9fb372294de'; const TERM_LIKE_ID = '98d173b4-8b60-5cde-8688-8cc8dd9f07b8'; const prepareDependencies = () => { termRepository = new TermRepositoryMock(); - userRepository = new UserRepositoryMock(); + collaboratorRepository = new CollaboratorRepositoryMock(); eventBus = new EventBusMock(); }; const initHandler = () => { - handler = new AddLikeTermCommandHandler(termRepository, userRepository, eventBus); + handler = new AddLikeTermCommandHandler(termRepository, collaboratorRepository, eventBus); jest.useFakeTimers(); }; const clean = () => { termRepository.clean(); - userRepository.clean(); + collaboratorRepository.clean(); eventBus.clean(); }; @@ -81,7 +81,7 @@ describe('Given a AddLikeTermCommandHandler to handle', () => { }); }); - describe('When the user id is invalid ', () => { + describe('When the collaborator id is invalid ', () => { let command: AddLikeTermCommand; function startScenario() { @@ -135,11 +135,11 @@ describe('Given a AddLikeTermCommandHandler to handle', () => { }); }); - describe('When the user does not exists ', () => { + describe('When the collaborator does not exists ', () => { let command: AddLikeTermCommand; function startScenario() { - command = AddLikeTermCommandMother.random({ termId: TERM_ID, userId: USER_ID }); + command = AddLikeTermCommandMother.random({ termId: TERM_ID, userId: COLLABORATOR_ID }); const term = WordMother.random({ id: TermIdMother.random(TERM_ID) }); termRepository.add(term); @@ -148,7 +148,7 @@ describe('Given a AddLikeTermCommandHandler to handle', () => { beforeEach(startScenario); it('then should thrown an exception', async () => { - await expect(handler.execute(command)).rejects.toThrowError(UserDoesNotExistsException); + await expect(handler.execute(command)).rejects.toThrowError(CollaboratorDoesNotExistsException); }); it('then should not add the like', async () => { @@ -165,28 +165,28 @@ describe('Given a AddLikeTermCommandHandler to handle', () => { }); }); - describe('When an user add a like to a term that already exists', () => { + describe('When an collaborator add a like to a term that already exists', () => { let command: AddLikeTermCommand; let term: Word; function startScenario() { - command = AddLikeTermCommandMother.random({ termId: TERM_ID, userId: USER_ID }); + command = AddLikeTermCommandMother.random({ termId: TERM_ID, userId: COLLABORATOR_ID }); term = WordMother.random({ id: TermIdMother.random(TERM_ID), likes: [ TermLikeMother.random({ id: TermLikeIdMother.random(TERM_LIKE_ID), - userId: UserIdMother.random(USER_ID), + userId: CollaboratorIdMother.random(COLLABORATOR_ID), termId: TermIdMother.random(TERM_ID), name: 'test', photo: '', }), ], }); - const user = UserMother.random({ id: UserIdMother.random(USER_ID) }); + const collaborator = CollaboratorMother.random({ id: CollaboratorIdMother.random(COLLABORATOR_ID) }); termRepository.add(term); - userRepository.add(user); + collaboratorRepository.add(collaborator); } beforeEach(startScenario); @@ -208,22 +208,26 @@ describe('Given a AddLikeTermCommandHandler to handle', () => { }); }); - describe('When an user add a like to a term ', () => { + describe('When an collaborator add a like to a term ', () => { let command: AddLikeTermCommand; let term: Word; const NAME = 'Name test'; const PHOTO = 'http://link'; function startScenario() { - command = AddLikeTermCommandMother.random({ termId: TERM_ID, userId: USER_ID }); + command = AddLikeTermCommandMother.random({ termId: TERM_ID, userId: COLLABORATOR_ID }); term = WordMother.random({ id: TermIdMother.random(TERM_ID), likes: [], }); - const user = UserMother.random({ id: UserIdMother.random(USER_ID), name: NAME, photo: PHOTO }); + const user = CollaboratorMother.random({ + id: CollaboratorIdMother.random(COLLABORATOR_ID), + name: NAME, + photo: PHOTO, + }); termRepository.add(term); - userRepository.add(user); + collaboratorRepository.add(user); } beforeEach(startScenario); @@ -243,7 +247,7 @@ describe('Given a AddLikeTermCommandHandler to handle', () => { expect(eventBus.domainEvents()).toHaveLength(1); expect(eventBus.domainEvents()[0]).toEqual({ - ...TermLikeAddedEventMother.random({ termId: TERM_ID, userId: USER_ID, name: NAME, photo: PHOTO }), + ...TermLikeAddedEventMother.random({ termId: TERM_ID, userId: COLLABORATOR_ID, name: NAME, photo: PHOTO }), }); }); }); diff --git a/test/unit/languages/application/term/command/dislikeTermCommandHandler.test.ts b/test/unit/languages/application/term/command/dislikeTermCommandHandler.test.ts index 8bb99a8d..b52df675 100644 --- a/test/unit/languages/application/term/command/dislikeTermCommandHandler.test.ts +++ b/test/unit/languages/application/term/command/dislikeTermCommandHandler.test.ts @@ -4,44 +4,44 @@ import DislikeTermCommandHandler from '@src/languages/application/term/command/d import { DislikeTermCommandMother } from '@test/unit/languages/application/term/command/dislikeTermCommandMother'; import DislikeTermCommand from '@src/languages/application/term/command/dislikeTermCommand'; import { TermRepositoryMock } from '@test/unit/languages/domain/term/termRepositoryMock'; -import { UserRepositoryMock } from '@test/unit/account/domain/user/userRepositoryMock'; import TermDoesNotExistsException from '@src/languages/domain/term/termDoesNotExistsException'; import WordMother from '@test/unit/languages/domain/term/word/wordMother'; import { TermIdMother } from '@test/unit/languages/domain/term/termIdMother'; -import UserDoesNotExistsException from '@src/account/domain/user/userDoesNotExistsException'; -import { UserMother } from '@test/unit/account/domain/user/userMother'; -import { UserIdMother } from '@test/unit/account/domain/user/userIdMother'; import { EventBusMock } from '@test/unit/shared/domain/buses/eventBus/eventBusMock'; import { TermDislikedEventMother } from '@test/unit/languages/domain/term/termDislikedEventMother'; import Word from '@src/languages/domain/term/word/word'; import TermLikeMother from '@test/unit/languages/domain/term/termLikeMother'; import { TermLikeIdMother } from '@test/unit/languages/domain/term/termLikeIdMother'; +import { CollaboratorRepositoryMock } from '@test/unit/languages/domain/collaborator/collaboratorRepositoryMock'; +import CollaboratorDoesNotExistsException from '@src/languages/domain/collaborator/collaboratorDoesNotExistsException'; +import { CollaboratorIdMother } from '@test/unit/languages/domain/collaborator/collaboratorIdMother'; +import { CollaboratorMother } from '@test/unit/languages/domain/collaborator/collaboratorMother'; describe('Given a DislikeTermCommandHandler to handle', () => { let termRepository: TermRepositoryMock; - let userRepository: UserRepositoryMock; + let collaboratorRepository: CollaboratorRepositoryMock; let eventBus: EventBusMock; let handler: DislikeTermCommandHandler; - const USER_ID = '0a8008d5-ab68-4c10-8476-668b5b540e0f'; + const COLLABORATOR_ID = '0a8008d5-ab68-4c10-8476-668b5b540e0f'; const TERM_ID = '7abe3a96-d603-4e87-b69e-e9fb372294de'; const TERM_LIKE_ID = '98d173b4-8b60-5cde-8688-8cc8dd9f07b8'; const prepareDependencies = () => { termRepository = new TermRepositoryMock(); - userRepository = new UserRepositoryMock(); + collaboratorRepository = new CollaboratorRepositoryMock(); eventBus = new EventBusMock(); }; const initHandler = () => { - handler = new DislikeTermCommandHandler(termRepository, userRepository, eventBus); + handler = new DislikeTermCommandHandler(termRepository, collaboratorRepository, eventBus); jest.useFakeTimers(); }; const clean = () => { termRepository.clean(); - userRepository.clean(); + collaboratorRepository.clean(); eventBus.clean(); }; @@ -81,7 +81,7 @@ describe('Given a DislikeTermCommandHandler to handle', () => { }); }); - describe('When the user id is invalid ', () => { + describe('When the collaborator id is invalid ', () => { let command: DislikeTermCommand; function startScenario() { @@ -135,11 +135,11 @@ describe('Given a DislikeTermCommandHandler to handle', () => { }); }); - describe('When the user does not exists ', () => { + describe('When the collaborator does not exists ', () => { let command: DislikeTermCommand; function startScenario() { - command = DislikeTermCommandMother.random({ termId: TERM_ID, userId: USER_ID }); + command = DislikeTermCommandMother.random({ termId: TERM_ID, userId: COLLABORATOR_ID }); const term = WordMother.random({ id: TermIdMother.random(TERM_ID) }); termRepository.add(term); @@ -148,7 +148,7 @@ describe('Given a DislikeTermCommandHandler to handle', () => { beforeEach(startScenario); it('then should thrown an exception', async () => { - await expect(handler.execute(command)).rejects.toThrowError(UserDoesNotExistsException); + await expect(handler.execute(command)).rejects.toThrowError(CollaboratorDoesNotExistsException); }); it('then should not dislike the term', async () => { @@ -165,27 +165,27 @@ describe('Given a DislikeTermCommandHandler to handle', () => { }); }); - describe('When an user dislike a term that the like does not exist', () => { + describe('When an collaborator dislike a term that the like does not exist', () => { let command: DislikeTermCommand; let term: Word; function startScenario() { - command = DislikeTermCommandMother.random({ termId: TERM_ID, userId: USER_ID }); + command = DislikeTermCommandMother.random({ termId: TERM_ID, userId: COLLABORATOR_ID }); term = WordMother.random({ id: TermIdMother.random(TERM_ID), likes: [ TermLikeMother.random({ - userId: UserIdMother.random('1cee3a96-d603-4e88-b69e-e9fb372294da'), + userId: CollaboratorIdMother.random('1cee3a96-d603-4e88-b69e-e9fb372294da'), termId: TermIdMother.random(TERM_ID), name: 'test', photo: '', }), ], }); - const user = UserMother.random({ id: UserIdMother.random(USER_ID) }); + const collaborator = CollaboratorMother.random({ id: CollaboratorIdMother.random(COLLABORATOR_ID) }); termRepository.add(term); - userRepository.add(user); + collaboratorRepository.add(collaborator); } beforeEach(startScenario); @@ -207,27 +207,27 @@ describe('Given a DislikeTermCommandHandler to handle', () => { }); }); - describe('When an user dislike a term that the like exist', () => { + describe('When an collaborator dislike a term that the like exist', () => { let command: DislikeTermCommand; let term: Word; function startScenario() { - command = DislikeTermCommandMother.random({ termId: TERM_ID, userId: USER_ID }); + command = DislikeTermCommandMother.random({ termId: TERM_ID, userId: COLLABORATOR_ID }); term = WordMother.random({ id: TermIdMother.random(TERM_ID), likes: [ TermLikeMother.random({ id: TermLikeIdMother.random(TERM_LIKE_ID), - userId: UserIdMother.random(USER_ID), + userId: CollaboratorIdMother.random(COLLABORATOR_ID), termId: TermIdMother.random(TERM_ID), name: 'test', }), ], }); - const user = UserMother.random({ id: UserIdMother.random(USER_ID) }); + const collaborator = CollaboratorMother.random({ id: CollaboratorIdMother.random(COLLABORATOR_ID) }); termRepository.add(term); - userRepository.add(user); + collaboratorRepository.add(collaborator); } beforeEach(startScenario); @@ -247,7 +247,7 @@ describe('Given a DislikeTermCommandHandler to handle', () => { expect(eventBus.domainEvents()).toHaveLength(1); expect(eventBus.domainEvents()[0]).toEqual({ - ...TermDislikedEventMother.random({ termId: TERM_ID, userId: USER_ID }), + ...TermDislikedEventMother.random({ termId: TERM_ID, userId: COLLABORATOR_ID }), }); }); }); diff --git a/test/unit/languages/domain/collaborator/collaboratorIdMother.ts b/test/unit/languages/domain/collaborator/collaboratorIdMother.ts new file mode 100644 index 00000000..1b092e78 --- /dev/null +++ b/test/unit/languages/domain/collaborator/collaboratorIdMother.ts @@ -0,0 +1,8 @@ +import faker from 'faker'; +import CollaboratorId from '@src/languages/domain/collaborator/collaboratorId'; + +export class CollaboratorIdMother { + static random(id?: string): CollaboratorId { + return CollaboratorId.of(id ?? faker.datatype.uuid()); + } +} diff --git a/test/unit/languages/domain/collaborator/collaboratorMother.ts b/test/unit/languages/domain/collaborator/collaboratorMother.ts new file mode 100644 index 00000000..3712a007 --- /dev/null +++ b/test/unit/languages/domain/collaborator/collaboratorMother.ts @@ -0,0 +1,24 @@ +import faker from 'faker'; +import CollaboratorId from '@src/languages/domain/collaborator/collaboratorId'; +import Collaborator from '@src/languages/domain/collaborator/collaborator'; +import { CollaboratorIdMother } from '@test/unit/languages/domain/collaborator/collaboratorIdMother'; + +interface CollaboratorMotherProps { + id?: CollaboratorId; + name?: string; + photo?: string; + interests?: string[]; +} + +export class CollaboratorMother { + static random(props?: CollaboratorMotherProps): Collaborator { + const { id, name, photo, interests } = props ?? {}; + + return new Collaborator( + id ?? CollaboratorIdMother.random(), + name ?? faker.name.findName(), + photo ?? faker.image.imageUrl(), + interests ?? ['test'], + ); + } +} diff --git a/test/unit/languages/domain/collaborator/collaboratorRepositoryMock.ts b/test/unit/languages/domain/collaborator/collaboratorRepositoryMock.ts new file mode 100644 index 00000000..53c0718d --- /dev/null +++ b/test/unit/languages/domain/collaborator/collaboratorRepositoryMock.ts @@ -0,0 +1,25 @@ +import CollaboratorRepository from '@src/languages/domain/collaborator/collaboratorRepository'; +import Collaborator from '@src/languages/domain/collaborator/collaborator'; +import CollaboratorId from '@src/languages/domain/collaborator/collaboratorId'; + +export class CollaboratorRepositoryMock implements CollaboratorRepository { + private collaborators: Collaborator[]; + + constructor() { + this.collaborators = []; + } + + add(collaborator: Collaborator): void { + this.collaborators.push(collaborator); + } + + clean(): void { + this.collaborators = []; + } + + async findById(_id: CollaboratorId): Promise { + const collaborator = this.collaborators.length > 0 ? this.collaborators[0] : null; + + return Promise.resolve(collaborator); + } +}