diff --git a/apps/pathway-design/server/src/test/initialize-pathway/index.feature b/apps/pathway-design/server/src/test/initialize-pathway/index.feature index 3297a0fb..5547a5eb 100644 --- a/apps/pathway-design/server/src/test/initialize-pathway/index.feature +++ b/apps/pathway-design/server/src/test/initialize-pathway/index.feature @@ -9,3 +9,14 @@ Feature: Initialize Pathway in a memory database | title | description | researchField | | My Pathway | A test pathway | biology | Then The pathway should be have a unique identifier + + Scenario: I want to initialize another learning pathway with different data + Given I am authenticated on the platform + When I want to initialize a pathway with these data + | title | description | researchField | + | Arterial stiffness | Understand the role of the arterial stiffness | biomedical | + Then I should retrieve a pathway initialized with its data + | title | description | researchField | + | Arterial stiffness | Understand the role of the arterial stiffness | biomedical | + Then The pathway should be have a unique identifier + \ No newline at end of file diff --git a/apps/pathway-design/server/src/test/initialize-pathway/index.step.ts b/apps/pathway-design/server/src/test/initialize-pathway/index.step.ts index b02dbf0b..0d048f1f 100644 --- a/apps/pathway-design/server/src/test/initialize-pathway/index.step.ts +++ b/apps/pathway-design/server/src/test/initialize-pathway/index.step.ts @@ -1,5 +1,3 @@ -import { strict as assert } from 'node:assert'; -import type { Http2Server } from 'node:http2'; import { PDSPIInitializePathwayPersistenceInfrastructureModule } from '@bewoak/pathway-design-server-pathway-infrastructure'; import { PDSPIAInitializePathwayInterfaceAdaptersModule } from '@bewoak/pathway-design-server-pathway-interface-adapters'; import { PDSPPPathwayPresentersModule } from '@bewoak/pathway-design-server-pathway-presenters'; @@ -8,6 +6,8 @@ import type { INestApplication } from '@nestjs/common'; import { CqrsModule } from '@nestjs/cqrs'; import { Test } from '@nestjs/testing'; import { binding, given, then, when } from 'cucumber-tsflow'; +import { strict as assert } from 'node:assert'; +import type { Http2Server } from 'node:http2'; import request from 'supertest'; @binding() @@ -67,6 +67,7 @@ class ControllerSteps { @then('The pathway should be have a unique identifier') public thenThePathwayIdentifierShouldBeUnique() { assert.notEqual(this.response.body.id, undefined); + assert.notEqual(this.response.body.id, ''); } } diff --git a/libs/pathway-design/server/pathway/application/src/lib/change-title/usecase/change-title-pathway.usecase.step.ts b/libs/pathway-design/server/pathway/application/src/lib/change-title/usecase/change-title-pathway.usecase.step.ts index 8700a9b0..284b0a86 100644 --- a/libs/pathway-design/server/pathway/application/src/lib/change-title/usecase/change-title-pathway.usecase.step.ts +++ b/libs/pathway-design/server/pathway/application/src/lib/change-title/usecase/change-title-pathway.usecase.step.ts @@ -42,7 +42,7 @@ export default class ControllerSteps { @then('I should see the title of the pathway changed to {string}') public thenIShouldSeeTheTitleOfThePathwayChangedTo(title: string) { - assert.strictEqual(this.pDSPBEPathwayEntity?.title?.value, title); + assert.strictEqual(this.pDSPBEPathwayEntity.title, title); } @then('I should see an error message {string} during the title change') diff --git a/libs/pathway-design/server/pathway/application/src/lib/initialize/command/initialize-pathway.command-handler.spec.ts b/libs/pathway-design/server/pathway/application/src/lib/initialize/command/initialize-pathway.command-handler.spec.ts deleted file mode 100644 index 2a128f29..00000000 --- a/libs/pathway-design/server/pathway/application/src/lib/initialize/command/initialize-pathway.command-handler.spec.ts +++ /dev/null @@ -1,145 +0,0 @@ -import { - type PDSPBEPathwayEntity, - type PDSPBPInitializePathwayPersistencePort, - type PDSPBPToJsonPathwayPresenterPort, - type PDSPBPToJsonPathwayPresenterPortOutput, - PDSPBP_INITIALIZE_PATHWAY_PERSISTENCE_PORT, - PDSPBP_TO_JSON_PATHWAY_PRESENTER_PORT, -} from '@bewoak/pathway-design-server-pathway-business'; - -import { beforeEach, describe, expect, spyOn, test } from 'bun:test'; -import { Test } from '@nestjs/testing'; - -import { PDSPAIUInitializePathwayUsecase } from '../usecase/initialize-pathway.usecase'; -import { PDSPAInitializePathwayCommand } from './initialize-pathway.command'; -import { PDSPAInitializePathwayCommandHandler } from './initialize-pathway.command-handler'; - -class InitializePathwayPersistence - implements PDSPBPInitializePathwayPersistencePort -{ - save(pDSPBEPathwayEntity: PDSPBEPathwayEntity) { - return Promise.resolve(pDSPBEPathwayEntity); - } -} -class ToJsonPathwayPresenter implements PDSPBPToJsonPathwayPresenterPort { - present(pDSPBEPathwayEntity: PDSPBEPathwayEntity) { - return { - description: pDSPBEPathwayEntity.description?.value ?? '', - id: pDSPBEPathwayEntity.id?.value ?? '', - researchField: pDSPBEPathwayEntity.researchField?.value ?? '', - title: pDSPBEPathwayEntity.title?.value ?? '', - }; - } -} - -describe('PDSPAInitializePathwayCommandHandler', () => { - let pDSPAInitializePathwayCommandHandler: PDSPAInitializePathwayCommandHandler; - let pDSPAIUInitializePathwayUsecase: PDSPAIUInitializePathwayUsecase; - let initializePathwayPersistence: PDSPBPInitializePathwayPersistencePort; - let toJsonPathwayPresenter: PDSPBPToJsonPathwayPresenterPort; - - beforeEach(async () => { - const module = await Test.createTestingModule({ - providers: [ - InitializePathwayPersistence, - PDSPAInitializePathwayCommandHandler, - { - provide: PDSPBP_INITIALIZE_PATHWAY_PERSISTENCE_PORT, - useExisting: InitializePathwayPersistence, - }, - { - provide: PDSPBP_TO_JSON_PATHWAY_PRESENTER_PORT, - useClass: ToJsonPathwayPresenter, - }, - PDSPAIUInitializePathwayUsecase, - ], - }).compile(); - - pDSPAInitializePathwayCommandHandler = - module.get( - PDSPAInitializePathwayCommandHandler - ); - pDSPAIUInitializePathwayUsecase = - module.get( - PDSPAIUInitializePathwayUsecase - ); - initializePathwayPersistence = - module.get( - PDSPBP_INITIALIZE_PATHWAY_PERSISTENCE_PORT - ); - toJsonPathwayPresenter = module.get( - PDSPBP_TO_JSON_PATHWAY_PRESENTER_PORT - ); - }); - - test('should be defined', () => { - expect(pDSPAInitializePathwayCommandHandler).toBeDefined(); - }); - - describe('I want to initialize a pathway from a command', () => { - const command = new PDSPAInitializePathwayCommand( - 'pathway description', - 'research field', - 'pathway title' - ); - let result: PDSPBPToJsonPathwayPresenterPortOutput; - - beforeEach(async () => { - spyOn(pDSPAIUInitializePathwayUsecase, 'execute'); - result = - await pDSPAInitializePathwayCommandHandler.execute(command); - }); - - test('should call the usecase in order to initiate the pathway', () => { - expect( - pDSPAIUInitializePathwayUsecase.execute - ).toHaveBeenCalledTimes(1); - expect( - pDSPAIUInitializePathwayUsecase.execute - ).toHaveBeenCalledWith( - initializePathwayPersistence, - toJsonPathwayPresenter, - { - title: command.title, - description: command.description, - researchField: command.researchField, - } - ); - }); - - test('should receive the attributes of the pathway', () => { - expect(result).toBeDefined(); - expect(result.title).toBe(command.title); - expect(result.description).toBe(command.description); - expect(result.researchField).toBe(command.researchField); - }); - - test('should send an event in the event bus', () => { - expect(result).toBeDefined(); - expect(result.title).toBe(command.title); - expect(result.description).toBe(command.description); - expect(result.researchField).toBe(command.researchField); - }); - }); - - describe('I want to initialize a pathway from another command', () => { - const command = new PDSPAInitializePathwayCommand( - 'My pathway description', - 'pharmacology', - 'My pathway' - ); - let result: PDSPBPToJsonPathwayPresenterPortOutput; - - beforeEach(async () => { - result = - await pDSPAInitializePathwayCommandHandler.execute(command); - }); - - test('should receive a pathway with its correct attributes', () => { - expect(result).toBeDefined(); - expect(result.title).toBe(command.title); - expect(result.description).toBe(command.description); - expect(result.researchField).toBe(command.researchField); - }); - }); -}); diff --git a/libs/pathway-design/server/pathway/application/src/lib/initialize/service/initialize-pathway.service.spec.ts b/libs/pathway-design/server/pathway/application/src/lib/initialize/service/initialize-pathway.service.spec.ts deleted file mode 100644 index 28140260..00000000 --- a/libs/pathway-design/server/pathway/application/src/lib/initialize/service/initialize-pathway.service.spec.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { beforeEach, describe, expect, mock, test } from 'bun:test'; -import type { PDSPBEPathwayEntity } from '@bewoak/pathway-design-server-pathway-business'; -import { CommandBus } from '@nestjs/cqrs'; -import { Test } from '@nestjs/testing'; -import { PDSPAInitializePathwayCommand } from '../command/initialize-pathway.command'; -import { PDSPAInitializePathwayService } from './initialize-pathway.service'; - -describe('PDSPAInitializePathwayService', () => { - let service: PDSPAInitializePathwayService; - let commandBus: CommandBus; - - beforeEach(async () => { - const module = await Test.createTestingModule({ - providers: [ - PDSPAInitializePathwayService, - { - provide: CommandBus, - useValue: { - execute: mock(() => Promise.resolve({})), - }, - }, - ], - }).compile(); - - service = module.get( - PDSPAInitializePathwayService - ); - commandBus = module.get(CommandBus); - }); - - describe('When I initialize a pathway', () => { - let pathway: PDSPBEPathwayEntity; - const PDSPAinitPathwayCommand = new PDSPAInitializePathwayCommand( - 'My pathway', - 'Pathway description', - 'biomedicine' - ); - const result = {} as PDSPBEPathwayEntity; - - beforeEach(async () => { - pathway = await service.init(PDSPAinitPathwayCommand); - }); - - test('should call commandBus.execute with the correct command', () => { - expect(commandBus.execute).toHaveBeenCalledWith( - PDSPAinitPathwayCommand - ); - }); - - test('should return the result from commandBus.execute', () => { - expect(pathway).toStrictEqual(result); - }); - }); -}); diff --git a/libs/pathway-design/server/pathway/application/src/lib/initialize/usecase/initialize-pathway.usecase.feature b/libs/pathway-design/server/pathway/application/src/lib/initialize/usecase/initialize-pathway.usecase.feature index 9ee0c246..8784df88 100644 --- a/libs/pathway-design/server/pathway/application/src/lib/initialize/usecase/initialize-pathway.usecase.feature +++ b/libs/pathway-design/server/pathway/application/src/lib/initialize/usecase/initialize-pathway.usecase.feature @@ -1,28 +1,36 @@ Feature: Initiate a pathway - Scenario: I want to initialize a pathway - When I want to initialize a pathway with these data - | title | description | researchField | - | My Pathway | A test pathway | biology | - Then I should receive the attributes of the pathway - | title | description | researchField | - | My Pathway | A test pathway | biology | + # Scenario: I want to initialize a pathway + # When I want to initialize a pathway with these data + # | title | description | researchField | + # | My Pathway | A test pathway | biology | + # Then I should receive the attributes of the pathway + # | title | description | researchField | + # | My Pathway | A test pathway | biology | - Scenario: I want to initialize a pathway with an empty title - When I want to initialize a pathway with these data - | title | description | researchField | - | | A test pathway | biology | - Then I should see an error message "Title is required" during initialization of the pathway + # Scenario: When I initiliaze a pathway, an event should be emitted + # When I want to initialize a pathway with these data + # | title | description | researchField | + # | My Pathway | A test pathway | biology | + # Then it should emitted an event "PathwayInitialized" with the attributes of the pathway + # | title | description | researchField | + # | My Pathway | A test pathway | biology | - Scenario: I want to initialize a pathway with an empty description - When I want to initialize a pathway with these data - | title | description | researchField | - | My Pathway | | biology | - Then I should see an error message "Description is required" during initialization of the pathway + # Scenario: I want to initialize a pathway with an empty title + # When I want to initialize a pathway with these data + # | title | description | researchField | + # | | A test pathway | biology | + # Then I should see an error message "Title is required" during initialization of the pathway + # Scenario: I want to initialize a pathway with an empty description + # When I want to initialize a pathway with these data + # | title | description | researchField | + # | My Pathway | | biology | + # Then I should see an error message "Description is required" during initialization of the pathway - Scenario: I want to initialize a pathway with an empty research field - When I want to initialize a pathway with these data - | title | description | researchField | - | My Pathway | A test pathway | | - Then I should see an error message "Research field is required" during initialization of the pathway + + # Scenario: I want to initialize a pathway with an empty research field + # When I want to initialize a pathway with these data + # | title | description | researchField | + # | My Pathway | A test pathway | | + # Then I should see an error message "Research field is required" during initialization of the pathway diff --git a/libs/pathway-design/server/pathway/application/src/lib/initialize/usecase/initialize-pathway.usecase.step.ts b/libs/pathway-design/server/pathway/application/src/lib/initialize/usecase/initialize-pathway.usecase.step.ts index b77d43a7..f6051789 100644 --- a/libs/pathway-design/server/pathway/application/src/lib/initialize/usecase/initialize-pathway.usecase.step.ts +++ b/libs/pathway-design/server/pathway/application/src/lib/initialize/usecase/initialize-pathway.usecase.step.ts @@ -1,14 +1,11 @@ -import { strict as assert } from 'node:assert'; - import type { PDSPBEPathwayEntity, - PDSPBFPathwayFactoryParams, PDSPBPInitializePathwayPersistencePort, PDSPBPToJsonPathwayPresenterPort, PDSPBPToJsonPathwayPresenterPortOutput, } from '@bewoak/pathway-design-server-pathway-business'; import type { DataTable } from '@cucumber/cucumber'; -import { binding, then, when } from 'cucumber-tsflow'; +import { binding, then } from 'cucumber-tsflow'; import { PDSPAIUInitializePathwayUsecase } from './initialize-pathway.usecase'; class InitializePathwayPersistence @@ -22,10 +19,10 @@ class InitializePathwayPersistence class ToJsonPathwayPresenter implements PDSPBPToJsonPathwayPresenterPort { present(pDSPBEPathwayEntity: PDSPBEPathwayEntity) { return { - description: pDSPBEPathwayEntity.description?.value ?? '', - id: pDSPBEPathwayEntity.id?.value ?? '', - researchField: pDSPBEPathwayEntity.researchField?.value ?? '', - title: pDSPBEPathwayEntity.title?.value ?? '', + description: pDSPBEPathwayEntity.description, + id: pDSPBEPathwayEntity.id, + researchField: pDSPBEPathwayEntity.researchField, + title: pDSPBEPathwayEntity.title, }; } } @@ -36,40 +33,47 @@ export default class ControllerSteps { private result: PDSPBPToJsonPathwayPresenterPortOutput | undefined; private error: Error | undefined; - @when('I want to initialize a pathway with these data') - public async whenIInitiateAPathway(dataTable: DataTable) { - try { - const firstRow = - dataTable.hashes()[0] as PDSPBFPathwayFactoryParams; + // @when('I want to initialize a pathway with these data') + // public async whenIInitiateAPathway(dataTable: DataTable) { + // try { + // const firstRow = + // dataTable.hashes()[0] as PDSPBFPathwayFactoryParams; - this.result = await this.pDSPBUInitPathwayUseCase.execute( - new InitializePathwayPersistence(), - new ToJsonPathwayPresenter(), - { - title: firstRow.title, - description: firstRow.description, - researchField: firstRow.researchField, - } - ); - } catch (error) { - this.error = error as Error; - } - } + // this.result = await this.pDSPBUInitPathwayUseCase.execute( + // new InitializePathwayPersistence(), + // new ToJsonPathwayPresenter(), + // { + // title: firstRow.title, + // description: firstRow.description, + // researchField: firstRow.researchField, + // } + // ); + // } catch (error) { + // this.error = error as Error; + // } + // } - @then('I should receive the attributes of the pathway') - public thenIShouldReceiveAttributesPathway(dataTable: DataTable) { - const firstRow = dataTable.hashes()[0] as PDSPBFPathwayFactoryParams; + // @then('I should receive the attributes of the pathway') + // public thenIShouldReceiveAttributesPathway(dataTable: DataTable) { + // const firstRow = dataTable.hashes()[0] as PDSPBFPathwayFactoryParams; - assert.strictEqual(this.result?.title, firstRow.title); - assert.strictEqual(this.result?.description, firstRow.description); - assert.strictEqual(this.result?.researchField, firstRow.researchField); - } + // assert.strictEqual(this.result?.title, firstRow.title); + // assert.strictEqual(this.result?.description, firstRow.description); + // assert.strictEqual(this.result?.researchField, firstRow.researchField); + // } + + // @then( + // 'I should see an error message {string} during initialization of the pathway' + // ) + // public thenIShouldSeeAnErrorMessage(errorMessage: string) { + // assert.notEqual(this.error, undefined); + // assert.strictEqual(this.error?.message, errorMessage); + // } @then( - 'I should see an error message {string} during initialization of the pathway' + 'it should emitted an event {string} with the attributes of the pathway' ) - public thenIShouldSeeAnErrorMessage(errorMessage: string) { - assert.notEqual(this.error, undefined); - assert.strictEqual(this.error?.message, errorMessage); + public thenItShouldEmittedAnEvent(eventName: string, dataTable: DataTable) { + // Apply of PDSPBEPathwayEntity and commit PDSPBEPathwayEntity should be applied. } } diff --git a/libs/pathway-design/server/pathway/business/src/index.ts b/libs/pathway-design/server/pathway/business/src/index.ts index b6d21489..be5132ae 100644 --- a/libs/pathway-design/server/pathway/business/src/index.ts +++ b/libs/pathway-design/server/pathway/business/src/index.ts @@ -1,6 +1,6 @@ export { PDSPBEPathwayEntity } from './lib/entities/pathway'; -export { pDSPBFPathwayFactory } from './lib/factories/pathway'; -export { type PDSPBFPathwayFactoryParams } from './lib/factories/pathway.types'; +export { pDSPBFPathwayFactory } from './lib/factories/pathway.factory'; +export { type PDSPBFPathwayFactoryParams } from './lib/factories/pathway.factory.types'; export { PDSPBP_INITIALIZE_PATHWAY_PERSISTENCE_PORT, type PDSPBPInitializePathwayPersistencePort, diff --git a/libs/pathway-design/server/pathway/business/src/lib/entities/pathway.feature b/libs/pathway-design/server/pathway/business/src/lib/entities/pathway.feature new file mode 100644 index 00000000..9b2c48c8 --- /dev/null +++ b/libs/pathway-design/server/pathway/business/src/lib/entities/pathway.feature @@ -0,0 +1,48 @@ +Feature: Manage Pathway Entity + + Scenario: I want to initialize a pathway with valid data + When I initialize a pathway with these data + | id | title | description | researchField | + | f7703737-186c-4c7c-8d46-925111c7c7c1 | My Pathway | A test pathway | biology | + Then I should retrieve the attributes of the pathway + | id | title | description | researchField | + | f7703737-186c-4c7c-8d46-925111c7c7c1 | My Pathway | A test pathway | biology | + + Scenario: I want to initialize a pathway with an empty title + When I initialize a pathway with these data + | id | title | description | researchField | + | f7703737-186c-4c7c-8d46-925111c7c7c1 | | A test pathway | biology | + Then I should see an error message "Title is required" + + Scenario: I want to initialize a pathway with an empty description + When I initialize a pathway with these data + | id | title | description | researchField | + | f7703737-186c-4c7c-8d46-925111c7c7c1 | My Pathway | | biology | + Then I should see an error message "Description is required" + + Scenario: I want to initialize a pathway with an empty research field + When I initialize a pathway with these data + | id | title | description | researchField | + | f7703737-186c-4c7c-8d46-925111c7c7c1 | My Pathway | A test pathway | | + Then I should see an error message "Research field is required" + + Scenario: I want to initialize a pathway with an invalid UUID + When I initialize a pathway with these data + | id | title | description | researchField | + | invalid-uuid | My Pathway | A test pathway | biology | + Then I should see an error message "Pathway id must be a valid uuid" + + Scenario: I want to change the title of an existing pathway + Given I have initialized a pathway with these data + | id | title | description | researchField | + | f7703737-186c-4c7c-8d46-925111c7c7c1 | My Pathway | A test pathway | biology | + When I change the title to "New Title" + Then I should retrieve the attributes of the pathway + | id | title | description | researchField | + | f7703737-186c-4c7c-8d46-925111c7c7c1 | New Title | A test pathway | biology | + + Scenario: I want to initialize a pathway with all empty fields + When I initialize a pathway with these data + | id | title | description | researchField | + | | | | | + Then I should see an error message "Pathway id must be a valid uuid" diff --git a/libs/pathway-design/server/pathway/business/src/lib/entities/pathway.step.ts b/libs/pathway-design/server/pathway/business/src/lib/entities/pathway.step.ts new file mode 100644 index 00000000..631b5d5e --- /dev/null +++ b/libs/pathway-design/server/pathway/business/src/lib/entities/pathway.step.ts @@ -0,0 +1,83 @@ +import type { DataTable } from '@cucumber/cucumber'; +import { binding, given, then, when } from 'cucumber-tsflow'; +import { strict as assert } from 'node:assert'; +import { DescriptionValueObject } from '../value-objects/description.value-object'; +import { PathwayIdValueObject } from '../value-objects/pathway-id.value-object'; +import { ResearchFieldValueObjects } from '../value-objects/research-field.value-object'; +import { PDSPBVOTitleValueObjects } from '../value-objects/title.value-object'; +import { PDSPBEPathwayEntity } from './pathway'; + +@binding() +export default class PathwaySteps { + private pathway: PDSPBEPathwayEntity | undefined; + private error: Error | undefined; + + @given('I have initialized a pathway with these data') + public givenIHaveInitializedAPathway(dataTable: DataTable) { + const data = dataTable.hashes()[0] as { + id: string; + title: string; + description: string; + researchField: string; + }; + + const id = new PathwayIdValueObject(data.id); + const title = new PDSPBVOTitleValueObjects(data.title); + const description = new DescriptionValueObject(data.description); + const researchField = new ResearchFieldValueObjects(data.researchField); + + this.pathway = new PDSPBEPathwayEntity(); + this.pathway.init({ id, title, description, researchField }); + } + + @when('I initialize a pathway with these data') + public async whenIInitializeAPathway(dataTable: DataTable) { + const data = dataTable.hashes()[0] as { + id: string; + title: string; + description: string; + researchField: string; + }; + + try { + const id = new PathwayIdValueObject(data.id); + const title = new PDSPBVOTitleValueObjects(data.title); + const description = new DescriptionValueObject(data.description); + const researchField = new ResearchFieldValueObjects( + data.researchField + ); + + this.pathway = new PDSPBEPathwayEntity(); + this.pathway.init({ id, title, description, researchField }); + } catch (error) { + this.error = error as Error; + } + } + + @when('I change the title to {string}') + public whenIChangeTheTitle(newTitle: string) { + const title = new PDSPBVOTitleValueObjects(newTitle); + this.pathway?.changeTitle(title); + } + + @then('I should retrieve the attributes of the pathway') + public thenIShouldRetrieveAttributesPathway(dataTable: DataTable) { + const data = dataTable.hashes()[0] as { + id: string; + title: string; + description: string; + researchField: string; + }; + + assert.strictEqual(this.pathway?.id, data.id); + assert.strictEqual(this.pathway?.title, data.title); + assert.strictEqual(this.pathway?.description, data.description); + assert.strictEqual(this.pathway?.researchField, data.researchField); + } + + @then('I should see an error message {string}') + public thenIShouldSeeAnErrorMessage(errorMessage: string) { + assert.notEqual(this.error, undefined); + assert.strictEqual(this.error?.message, errorMessage); + } +} diff --git a/libs/pathway-design/server/pathway/business/src/lib/entities/pathway.ts b/libs/pathway-design/server/pathway/business/src/lib/entities/pathway.ts index 60a2b0cb..4f5901a8 100644 --- a/libs/pathway-design/server/pathway/business/src/lib/entities/pathway.ts +++ b/libs/pathway-design/server/pathway/business/src/lib/entities/pathway.ts @@ -11,19 +11,19 @@ export class PDSPBEPathwayEntity { #title: PDSPBVOTitleValueObjects | undefined; get description() { - return this.#description; + return this.#description?.value ?? ''; } get id() { - return this.#id; + return this.#id?.value ?? ''; } get researchField() { - return this.#researchField; + return this.#researchField?.value ?? ''; } get title() { - return this.#title; + return this.#title?.value ?? ''; } init({ id, title, description, researchField }: InitializePathwayParams) { diff --git a/libs/pathway-design/server/pathway/business/src/lib/factories/pathway.factory.spec.ts b/libs/pathway-design/server/pathway/business/src/lib/factories/pathway.factory.spec.ts new file mode 100644 index 00000000..d0328ae7 --- /dev/null +++ b/libs/pathway-design/server/pathway/business/src/lib/factories/pathway.factory.spec.ts @@ -0,0 +1,105 @@ +import { describe, expect, it } from 'bun:test'; +import { PDSPBEPathwayEntity } from '../entities/pathway'; +import { PDSPBVOTitleValueObjects } from '../value-objects/title.value-object'; +import { pDSPBFPathwayFactory } from './pathway.factory'; +import type { PDSPBFPathwayFactoryParams } from './pathway.factory.types'; + +describe('pDSPBFPathwayFactory', () => { + it('should initialize a pathway with valid data', () => { + const params: PDSPBFPathwayFactoryParams = { + id: 'f7703737-186c-4c7c-8d46-925111c7c7c1', + title: 'My Pathway', + description: 'A test pathway', + researchField: 'biology', + }; + const pathway = pDSPBFPathwayFactory(params); + + expect(pathway).toBeInstanceOf(PDSPBEPathwayEntity); + expect(pathway.id).toBe(params.id); + expect(pathway.title).toBe(params.title); + expect(pathway.description).toBe(params.description); + expect(pathway.researchField).toBe(params.researchField); + }); + + it('should throw an error for an empty title', () => { + const params: PDSPBFPathwayFactoryParams = { + id: 'f7703737-186c-4c7c-8d46-925111c7c7c1', + title: '', + description: 'A test pathway', + researchField: 'biology', + }; + + expect(() => pDSPBFPathwayFactory(params)).toThrow('Title is required'); + }); + + it('should throw an error for an empty description', () => { + const params: PDSPBFPathwayFactoryParams = { + id: 'f7703737-186c-4c7c-8d46-925111c7c7c1', + title: 'My Pathway', + description: '', + researchField: 'biology', + }; + + expect(() => pDSPBFPathwayFactory(params)).toThrow( + 'Description is required' + ); + }); + + it('should throw an error for an empty research field', () => { + const params: PDSPBFPathwayFactoryParams = { + id: 'f7703737-186c-4c7c-8d46-925111c7c7c1', + title: 'My Pathway', + description: 'A test pathway', + researchField: '', + }; + + expect(() => pDSPBFPathwayFactory(params)).toThrow( + 'Research field is required' + ); + }); + + it('should throw an error for an invalid UUID', () => { + const params: PDSPBFPathwayFactoryParams = { + id: 'invalid-uuid', + title: 'My Pathway', + description: 'A test pathway', + researchField: 'biology', + }; + + expect(() => pDSPBFPathwayFactory(params)).toThrow( + 'Pathway id must be a valid uuid' + ); + }); + + it('should generate a valid UUID if none is provided', () => { + const params: PDSPBFPathwayFactoryParams = { + title: 'My Pathway', + description: 'A test pathway', + researchField: 'biology', + }; + const pathway = pDSPBFPathwayFactory(params); + + expect(pathway).toBeInstanceOf(PDSPBEPathwayEntity); + expect(pathway.id).toMatch( + /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i + ); + expect(pathway.title).toBe(params.title); + expect(pathway.description).toBe(params.description); + expect(pathway.researchField).toBe(params.researchField); + }); + + it('should change the title of an existing pathway', () => { + const params: PDSPBFPathwayFactoryParams = { + id: 'f7703737-186c-4c7c-8d46-925111c7c7c1', + title: 'My Pathway', + description: 'A test pathway', + researchField: 'biology', + }; + const pathway = pDSPBFPathwayFactory(params); + const newTitle = new PDSPBVOTitleValueObjects('New Title'); + + pathway.changeTitle(newTitle); + + expect(pathway.title).toBe('New Title'); + }); +}); diff --git a/libs/pathway-design/server/pathway/business/src/lib/factories/pathway.ts b/libs/pathway-design/server/pathway/business/src/lib/factories/pathway.factory.ts similarity index 93% rename from libs/pathway-design/server/pathway/business/src/lib/factories/pathway.ts rename to libs/pathway-design/server/pathway/business/src/lib/factories/pathway.factory.ts index b1a1b943..8940df6d 100644 --- a/libs/pathway-design/server/pathway/business/src/lib/factories/pathway.ts +++ b/libs/pathway-design/server/pathway/business/src/lib/factories/pathway.factory.ts @@ -4,7 +4,7 @@ import { DescriptionValueObject } from '../value-objects/description.value-objec import { PathwayIdValueObject } from '../value-objects/pathway-id.value-object'; import { ResearchFieldValueObjects } from '../value-objects/research-field.value-object'; import { PDSPBVOTitleValueObjects } from '../value-objects/title.value-object'; -import type { PDSPBFPathwayFactoryParams } from './pathway.types'; +import type { PDSPBFPathwayFactoryParams } from './pathway.factory.types'; export const pDSPBFPathwayFactory = ({ description: descriptionValue, diff --git a/libs/pathway-design/server/pathway/business/src/lib/factories/pathway.types.ts b/libs/pathway-design/server/pathway/business/src/lib/factories/pathway.factory.types.ts similarity index 100% rename from libs/pathway-design/server/pathway/business/src/lib/factories/pathway.types.ts rename to libs/pathway-design/server/pathway/business/src/lib/factories/pathway.factory.types.ts diff --git a/libs/pathway-design/server/pathway/infrastructure/src/lib/persistence/common/in-memory/mappers/in-memory-pathway.mapper.ts b/libs/pathway-design/server/pathway/infrastructure/src/lib/persistence/common/in-memory/mappers/in-memory-pathway.mapper.ts index 62424577..2f630391 100644 --- a/libs/pathway-design/server/pathway/infrastructure/src/lib/persistence/common/in-memory/mappers/in-memory-pathway.mapper.ts +++ b/libs/pathway-design/server/pathway/infrastructure/src/lib/persistence/common/in-memory/mappers/in-memory-pathway.mapper.ts @@ -8,10 +8,10 @@ export const mapPathwayEntityToInMemoryPersistence = ( pathway: PDSPBEPathwayEntity ): PathwayInMemoryEntity => { const pathwayInMemoryEntity = new PathwayInMemoryEntity( - pathway.id?.value ?? '', - pathway.description?.value ?? '', - pathway.researchField?.value ?? '', - pathway.title?.value ?? '' + pathway.id, + pathway.description, + pathway.researchField, + pathway.title ); return pathwayInMemoryEntity; diff --git a/libs/pathway-design/server/pathway/infrastructure/src/lib/persistence/initialize/in-memory/initialize-pathway-in-memory.persistence.spec.ts b/libs/pathway-design/server/pathway/infrastructure/src/lib/persistence/initialize/in-memory/initialize-pathway-in-memory.persistence.spec.ts index c8e5c235..77e0f724 100644 --- a/libs/pathway-design/server/pathway/infrastructure/src/lib/persistence/initialize/in-memory/initialize-pathway-in-memory.persistence.spec.ts +++ b/libs/pathway-design/server/pathway/infrastructure/src/lib/persistence/initialize/in-memory/initialize-pathway-in-memory.persistence.spec.ts @@ -1,10 +1,10 @@ -import { beforeEach, describe, expect, spyOn, test } from 'bun:test'; import { type PDSPBEPathwayEntity, pDSPBFPathwayFactory, } from '@bewoak/pathway-design-server-pathway-business'; import { NotFoundException } from '@nestjs/common'; import { Test } from '@nestjs/testing'; +import { beforeEach, describe, expect, spyOn, test } from 'bun:test'; import { PathwayInMemoryRepository } from '../../common/in-memory/repositories/in-memory-pathway.repository'; import { InitializePathwayInMemoryPersistence } from './initialize-pathway-in-memory.persistence'; @@ -59,16 +59,14 @@ describe('InitializePathwayInMemoryPersistence', () => { expect(pathwayInMemoryRepository.add).toHaveBeenCalledTimes(1); expect(pathwayInMemoryRepository.get).toHaveBeenCalledTimes(1); - expect(result.id).not.toBeUndefined(); + expect(result.id).not.toBeEmpty(); expect(result).not.toBe(pDSPBEPathwayEntity); - expect(result.title?.value).toStrictEqual( - pDSPBEPathwayEntity.title?.value as string - ); - expect(result.description?.value).toStrictEqual( - pDSPBEPathwayEntity.description?.value as string + expect(result.title).toStrictEqual(pDSPBEPathwayEntity.title); + expect(result.description).toStrictEqual( + pDSPBEPathwayEntity.description ); - expect(result.researchField?.value).toStrictEqual( - pDSPBEPathwayEntity.researchField?.value as string + expect(result.researchField).toStrictEqual( + pDSPBEPathwayEntity.researchField ); }); }); diff --git a/libs/pathway-design/server/pathway/presenters/src/lib/toJson/to-json-pathway.presenter.ts b/libs/pathway-design/server/pathway/presenters/src/lib/toJson/to-json-pathway.presenter.ts index 62225370..55672728 100644 --- a/libs/pathway-design/server/pathway/presenters/src/lib/toJson/to-json-pathway.presenter.ts +++ b/libs/pathway-design/server/pathway/presenters/src/lib/toJson/to-json-pathway.presenter.ts @@ -10,10 +10,10 @@ export class ToJsonPathwayPresenter { present(pDSPBEPathwayEntity: PDSPBEPathwayEntity) { return { - description: pDSPBEPathwayEntity.description?.value ?? '', - id: pDSPBEPathwayEntity.id?.value ?? '', - researchField: pDSPBEPathwayEntity.researchField?.value ?? '', - title: pDSPBEPathwayEntity.title?.value ?? '', + description: pDSPBEPathwayEntity.description, + id: pDSPBEPathwayEntity.id, + researchField: pDSPBEPathwayEntity.researchField, + title: pDSPBEPathwayEntity.title, }; } }