From fd282696dc8ac4c83007497b5bfdfaee134e728b Mon Sep 17 00:00:00 2001 From: Mathieu Collette Date: Thu, 17 Oct 2024 12:05:45 +0200 Subject: [PATCH] refactor: extract business rules --- .../business/pathway/rules/src/index.ts | 5 +- .../src/lib/description/description.rules.ts | 19 +++++++ .../src/lib/description/description.spec.ts | 52 +++++++++++++++++++ .../src/lib/pathway-id/pathway-id.rules.ts | 10 ++++ .../src/lib/pathway-id/pathway-id.spec.ts | 22 ++++++++ .../research-field/research-field.rules.ts | 19 +++++++ .../lib/research-field/research-field.spec.ts | 52 +++++++++++++++++++ .../rules/src/lib/title/title.rules.ts | 19 ++++--- .../pathway/rules/src/lib/title/title.spec.ts | 38 +++++++++----- .../business/pathway/rules/src/lib/types.ts | 7 +-- .../src/lib/factories/pathway.factory.spec.ts | 44 ---------------- .../change-name/change-title-pathway.feature | 4 +- .../change-name/change-title-pathway.step.ts | 7 +-- .../initialize/initialize-pathway.feature | 51 ++---------------- .../initialize/initialize-pathway.step.ts | 7 +-- .../description.value-object.spec.ts | 5 +- .../value-objects/description.value-object.ts | 9 ++-- .../pathway-id.value-object.spec.ts | 5 +- .../value-objects/pathway-id.value-object.ts | 11 ++-- .../research-field.value-object.spec.ts | 5 +- .../research-field.value-object.ts | 5 +- .../value-objects/title.value-object.spec.ts | 5 +- .../lib/value-objects/title.value-object.ts | 6 +-- 23 files changed, 259 insertions(+), 148 deletions(-) create mode 100644 libs/pathway-design/common/business/pathway/rules/src/lib/description/description.rules.ts create mode 100644 libs/pathway-design/common/business/pathway/rules/src/lib/description/description.spec.ts create mode 100644 libs/pathway-design/common/business/pathway/rules/src/lib/pathway-id/pathway-id.rules.ts create mode 100644 libs/pathway-design/common/business/pathway/rules/src/lib/pathway-id/pathway-id.spec.ts create mode 100644 libs/pathway-design/common/business/pathway/rules/src/lib/research-field/research-field.rules.ts create mode 100644 libs/pathway-design/common/business/pathway/rules/src/lib/research-field/research-field.spec.ts diff --git a/libs/pathway-design/common/business/pathway/rules/src/index.ts b/libs/pathway-design/common/business/pathway/rules/src/index.ts index fbdd5d04..3996f116 100644 --- a/libs/pathway-design/common/business/pathway/rules/src/index.ts +++ b/libs/pathway-design/common/business/pathway/rules/src/index.ts @@ -1 +1,4 @@ -export { PDCBPR_titleRules } from './lib/title/title.rules'; +export { pDCBPRDescriptionRules } from './lib/description/description.rules'; +export { pDCBPRPathwayIdRules } from './lib/pathway-id/pathway-id.rules'; +export { pDCBPRResearchFieldRules } from './lib/research-field/research-field.rules'; +export { pDCBPRTitleRules } from './lib/title/title.rules'; diff --git a/libs/pathway-design/common/business/pathway/rules/src/lib/description/description.rules.ts b/libs/pathway-design/common/business/pathway/rules/src/lib/description/description.rules.ts new file mode 100644 index 00000000..8a8ab19d --- /dev/null +++ b/libs/pathway-design/common/business/pathway/rules/src/lib/description/description.rules.ts @@ -0,0 +1,19 @@ +import type { Rules } from '../types'; + +export const pDCBPRDescriptionRules: Rules = { + isValid: function (value) { + return ( + value !== undefined && + value !== null && + value.trim().length !== 0 && + value.trim().length >= this.minLength && + value.trim().length <= this.maxLength + ); + }, + isRequired: true, + maxLength: 100, + minLength: 1, + textError: function () { + return `The description is required and it must be between ${this.minLength} and ${this.maxLength} characters long.`; + }, +}; diff --git a/libs/pathway-design/common/business/pathway/rules/src/lib/description/description.spec.ts b/libs/pathway-design/common/business/pathway/rules/src/lib/description/description.spec.ts new file mode 100644 index 00000000..e91a70b0 --- /dev/null +++ b/libs/pathway-design/common/business/pathway/rules/src/lib/description/description.spec.ts @@ -0,0 +1,52 @@ +import { describe, expect, test } from 'bun:test'; +import { pDCBPRDescriptionRules } from './description.rules'; + +describe('Description business rules', () => { + test('should return true for a valid description', () => { + const validDescription = 'A valid description'; + expect(pDCBPRDescriptionRules.isValid(validDescription)).toBe(true); + }); + + test('should return false for a null value', () => { + expect(pDCBPRDescriptionRules.isValid(null)).toBe(false); + }); + + test('should return false for an undefined value', () => { + expect(pDCBPRDescriptionRules.isValid(undefined)).toBe(false); + }); + + test('should return false for an empty description', () => { + const emptyDescription = ''; + expect(pDCBPRDescriptionRules.isValid(emptyDescription)).toBe(false); + }); + + test('should return false for a description longer than the maxLength', () => { + const longDescription = 'A'.repeat(pDCBPRDescriptionRules.maxLength + 1); + expect(pDCBPRDescriptionRules.isValid(longDescription)).toBe(false); + }); + + test('should return true for a description exactly at maxLength', () => { + const maxLengthDescription = 'A'.repeat(pDCBPRDescriptionRules.maxLength); + expect(pDCBPRDescriptionRules.isValid(maxLengthDescription)).toBe(true); + }); + + test('should return false for a description shorter than minLength', () => { + const shortDescription = 'A'.repeat(pDCBPRDescriptionRules.minLength - 1); + expect(pDCBPRDescriptionRules.isValid(shortDescription)).toBe(false); + }); + + test('should return true for a description exactly at minLength', () => { + const minLengthDescription = 'A'.repeat(pDCBPRDescriptionRules.minLength); + expect(pDCBPRDescriptionRules.isValid(minLengthDescription)).toBe(true); + }); + + test('should return false for a description with only spaces', () => { + const spacesDescription = ' '; + expect(pDCBPRDescriptionRules.isValid(spacesDescription)).toBe(false); + }); + + test('should return correct error message textError', () => { + const expectedErrorMessage = `The description is required and it must be between ${pDCBPRDescriptionRules.minLength} and ${pDCBPRDescriptionRules.maxLength} characters long.`; + expect(pDCBPRDescriptionRules.textError()).toBe(expectedErrorMessage); + }); +}); diff --git a/libs/pathway-design/common/business/pathway/rules/src/lib/pathway-id/pathway-id.rules.ts b/libs/pathway-design/common/business/pathway/rules/src/lib/pathway-id/pathway-id.rules.ts new file mode 100644 index 00000000..3784e9ec --- /dev/null +++ b/libs/pathway-design/common/business/pathway/rules/src/lib/pathway-id/pathway-id.rules.ts @@ -0,0 +1,10 @@ +import type { Rules } from '../types'; + +export const pDCBPRPathwayIdRules: Omit, 'minLength' | 'maxLength'> = { + isValid: (value) => { + const uuidV4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; + return value !== null && value !== undefined && uuidV4Regex.test(value); + }, + isRequired: true, + textError: () => 'The pathway id is required and it must be a uuid v4', +}; diff --git a/libs/pathway-design/common/business/pathway/rules/src/lib/pathway-id/pathway-id.spec.ts b/libs/pathway-design/common/business/pathway/rules/src/lib/pathway-id/pathway-id.spec.ts new file mode 100644 index 00000000..ecb53268 --- /dev/null +++ b/libs/pathway-design/common/business/pathway/rules/src/lib/pathway-id/pathway-id.spec.ts @@ -0,0 +1,22 @@ +import { describe, expect, test } from 'bun:test'; +import { pDCBPRPathwayIdRules } from './pathway-id.rules'; + +describe('Pathway id business rules', () => { + test('should return true for a valid uuid v4 pathway id', () => { + const validPathwayId = 'e24054b9-92ca-4a22-be67-cf14cc94e6f8'; + expect(pDCBPRPathwayIdRules.isValid(validPathwayId)).toBe(true); + }); + + test('should return false for a non uuid v4 value', () => { + expect(pDCBPRPathwayIdRules.isValid(null)).toBe(false); + expect(pDCBPRPathwayIdRules.isValid(undefined)).toBe(false); + expect(pDCBPRPathwayIdRules.isValid('')).toBe(false); + expect(pDCBPRPathwayIdRules.isValid('12345')).toBe(false); + expect(pDCBPRPathwayIdRules.isValid('e24054b9-92ca-7a22-be67-cf14cc94e6f8')).toBe(false); + }); + + test('should return correct error message textError', () => { + const expectedErrorMessage = 'The pathway id is required and it must be a uuid v4'; + expect(pDCBPRPathwayIdRules.textError()).toBe(expectedErrorMessage); + }); +}); diff --git a/libs/pathway-design/common/business/pathway/rules/src/lib/research-field/research-field.rules.ts b/libs/pathway-design/common/business/pathway/rules/src/lib/research-field/research-field.rules.ts new file mode 100644 index 00000000..73e6fa9d --- /dev/null +++ b/libs/pathway-design/common/business/pathway/rules/src/lib/research-field/research-field.rules.ts @@ -0,0 +1,19 @@ +import type { Rules } from '../types'; + +export const pDCBPRResearchFieldRules: Rules = { + isValid: function (value) { + return ( + value !== undefined && + value !== null && + value.trim().length !== 0 && + value.trim().length >= this.minLength && + value.trim().length <= this.maxLength + ); + }, + isRequired: true, + maxLength: 100, + minLength: 1, + textError: function () { + return `The research field is required and it must be between ${this.minLength} and ${this.maxLength} characters long.`; + }, +}; diff --git a/libs/pathway-design/common/business/pathway/rules/src/lib/research-field/research-field.spec.ts b/libs/pathway-design/common/business/pathway/rules/src/lib/research-field/research-field.spec.ts new file mode 100644 index 00000000..6e0d67af --- /dev/null +++ b/libs/pathway-design/common/business/pathway/rules/src/lib/research-field/research-field.spec.ts @@ -0,0 +1,52 @@ +import { describe, expect, test } from 'bun:test'; +import { pDCBPRResearchFieldRules } from './research-field.rules'; + +describe('Research field business rules', () => { + test('should return true for a valid research field', () => { + const validResearchField = 'A valid research field'; + expect(pDCBPRResearchFieldRules.isValid(validResearchField)).toBe(true); + }); + + test('should return false for a null value', () => { + expect(pDCBPRResearchFieldRules.isValid(null)).toBe(false); + }); + + test('should return false for an undefined value', () => { + expect(pDCBPRResearchFieldRules.isValid(undefined)).toBe(false); + }); + + test('should return false for an empty research field', () => { + const emptyResearchField = ''; + expect(pDCBPRResearchFieldRules.isValid(emptyResearchField)).toBe(false); + }); + + test('should return false for a research field longer than the maxLength', () => { + const longResearchField = 'A'.repeat(pDCBPRResearchFieldRules.maxLength + 1); + expect(pDCBPRResearchFieldRules.isValid(longResearchField)).toBe(false); + }); + + test('should return true for a research field exactly at maxLength', () => { + const maxLengthResearchField = 'A'.repeat(pDCBPRResearchFieldRules.maxLength); + expect(pDCBPRResearchFieldRules.isValid(maxLengthResearchField)).toBe(true); + }); + + test('should return false for a research field shorter than minLength', () => { + const shortResearchField = 'A'.repeat(pDCBPRResearchFieldRules.minLength - 1); + expect(pDCBPRResearchFieldRules.isValid(shortResearchField)).toBe(false); + }); + + test('should return true for a research field exactly at minLength', () => { + const minLengthResearchField = 'A'.repeat(pDCBPRResearchFieldRules.minLength); + expect(pDCBPRResearchFieldRules.isValid(minLengthResearchField)).toBe(true); + }); + + test('should return false for a research field with only spaces', () => { + const spacesResearchField = ' '; + expect(pDCBPRResearchFieldRules.isValid(spacesResearchField)).toBe(false); + }); + + test('should return correct error message textError', () => { + const expectedErrorMessage = `The research field is required and it must be between ${pDCBPRResearchFieldRules.minLength} and ${pDCBPRResearchFieldRules.maxLength} characters long.`; + expect(pDCBPRResearchFieldRules.textError()).toBe(expectedErrorMessage); + }); +}); diff --git a/libs/pathway-design/common/business/pathway/rules/src/lib/title/title.rules.ts b/libs/pathway-design/common/business/pathway/rules/src/lib/title/title.rules.ts index 2370ceef..5651a431 100644 --- a/libs/pathway-design/common/business/pathway/rules/src/lib/title/title.rules.ts +++ b/libs/pathway-design/common/business/pathway/rules/src/lib/title/title.rules.ts @@ -1,12 +1,19 @@ import type { Rules } from '../types'; -export const PDCBPR_titleRules: Rules = { - textError: function () { - return `Renseigner un nom entre 1 et ${this.maxLength} caractères.`; - }, - isValid: function (value: string | null | undefined) { - return value !== undefined && value !== null && value.trim().length !== 0 && value.trim().length <= this.maxLength; +export const pDCBPRTitleRules: Rules = { + isValid: function (value) { + return ( + value !== undefined && + value !== null && + value.trim().length !== 0 && + value.trim().length >= this.minLength && + value.trim().length <= this.maxLength + ); }, isRequired: true, maxLength: 100, + minLength: 1, + textError: function () { + return `The title is required and it must be between ${this.minLength} and ${this.maxLength} characters long.`; + }, }; diff --git a/libs/pathway-design/common/business/pathway/rules/src/lib/title/title.spec.ts b/libs/pathway-design/common/business/pathway/rules/src/lib/title/title.spec.ts index 0db3c85c..34bef7b7 100644 --- a/libs/pathway-design/common/business/pathway/rules/src/lib/title/title.spec.ts +++ b/libs/pathway-design/common/business/pathway/rules/src/lib/title/title.spec.ts @@ -1,38 +1,52 @@ import { describe, expect, test } from 'bun:test'; -import { PDCBPR_titleRules } from './title.rules'; +import { pDCBPRTitleRules } from './title.rules'; -describe('PDCBPR_titleRules', () => { +describe('Title business rules', () => { test('should return true for a valid title', () => { const validTitle = 'A valid title'; - expect(PDCBPR_titleRules.isValid(validTitle)).toBe(true); + expect(pDCBPRTitleRules.isValid(validTitle)).toBe(true); }); test('should return false for a null value', () => { - expect(PDCBPR_titleRules.isValid(null)).toBe(false); + expect(pDCBPRTitleRules.isValid(null)).toBe(false); + }); + + test('should return false for an undefined value', () => { + expect(pDCBPRTitleRules.isValid(undefined)).toBe(false); }); test('should return false for an empty title', () => { const emptyTitle = ''; - expect(PDCBPR_titleRules.isValid(emptyTitle)).toBe(false); + expect(pDCBPRTitleRules.isValid(emptyTitle)).toBe(false); }); test('should return false for a title longer than the maxLength', () => { - const longTitle = 'A'.repeat(PDCBPR_titleRules.maxLength + 1); - expect(PDCBPR_titleRules.isValid(longTitle)).toBe(false); + const longTitle = 'A'.repeat(pDCBPRTitleRules.maxLength + 1); + expect(pDCBPRTitleRules.isValid(longTitle)).toBe(false); }); test('should return true for a title exactly at maxLength', () => { - const maxLengthTitle = 'A'.repeat(PDCBPR_titleRules.maxLength); - expect(PDCBPR_titleRules.isValid(maxLengthTitle)).toBe(true); + const maxLengthTitle = 'A'.repeat(pDCBPRTitleRules.maxLength); + expect(pDCBPRTitleRules.isValid(maxLengthTitle)).toBe(true); + }); + + test('should return false for a title shorter than minLength', () => { + const shortTitle = 'A'.repeat(pDCBPRTitleRules.minLength - 1); + expect(pDCBPRTitleRules.isValid(shortTitle)).toBe(false); + }); + + test('should return true for a title exactly at minLength', () => { + const minLengthTitle = 'A'.repeat(pDCBPRTitleRules.minLength); + expect(pDCBPRTitleRules.isValid(minLengthTitle)).toBe(true); }); test('should return false for a title with only spaces', () => { const spacesTitle = ' '; - expect(PDCBPR_titleRules.isValid(spacesTitle)).toBe(false); + expect(pDCBPRTitleRules.isValid(spacesTitle)).toBe(false); }); test('should return correct error message textError', () => { - const expectedErrorMessage = `Renseigner un nom entre 1 et ${PDCBPR_titleRules.maxLength} caractères.`; - expect(PDCBPR_titleRules.textError()).toBe(expectedErrorMessage); + const expectedErrorMessage = `The title is required and it must be between ${pDCBPRTitleRules.minLength} and ${pDCBPRTitleRules.maxLength} characters long.`; + expect(pDCBPRTitleRules.textError()).toBe(expectedErrorMessage); }); }); diff --git a/libs/pathway-design/common/business/pathway/rules/src/lib/types.ts b/libs/pathway-design/common/business/pathway/rules/src/lib/types.ts index 5fe8a853..80d53201 100644 --- a/libs/pathway-design/common/business/pathway/rules/src/lib/types.ts +++ b/libs/pathway-design/common/business/pathway/rules/src/lib/types.ts @@ -1,6 +1,7 @@ -export interface Rules { - textError: () => string; - isValid: (value: string | null) => boolean; +export interface Rules { + isValid: (value: T) => boolean; readonly isRequired: boolean; readonly maxLength: number; + readonly minLength: number; + textError: () => string; } 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 index 050edb8d..799d2da2 100644 --- 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 @@ -20,50 +20,6 @@ describe('pDSPBFPathwayFactory', () => { expect(pathway.researchField).toBe(params.researchField); }); - it('should throw an error for an empty title', () => { - const params: PathwayFactoryParams = { - 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: PathwayFactoryParams = { - 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: PathwayFactoryParams = { - 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: PathwayFactoryParams = { - 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: PathwayFactoryParams = { title: 'My Pathway', diff --git a/libs/pathway-design/server/pathway/business/src/lib/specs/change-name/change-title-pathway.feature b/libs/pathway-design/server/pathway/business/src/lib/specs/change-name/change-title-pathway.feature index a63810ed..b4875590 100644 --- a/libs/pathway-design/server/pathway/business/src/lib/specs/change-name/change-title-pathway.feature +++ b/libs/pathway-design/server/pathway/business/src/lib/specs/change-name/change-title-pathway.feature @@ -8,9 +8,9 @@ Feature: Business - Change the title of a pathway Then It should apply an event indicating that the title of the pathway has been changed Then I should see the title of the pathway in business changed to "My New Pathway" - Scenario: I want to change the title of a pathway with an empty title + Scenario: I want to change the title of a pathway with an invalid title Given I have a pathway in business with these data | title | description | researchField | | My Pathway | A test pathway | biology | When I change the title of the pathway in business to "" - Then I should see an error message from business "Title is required" during the title change + Then I should see an error message from business during the title change diff --git a/libs/pathway-design/server/pathway/business/src/lib/specs/change-name/change-title-pathway.step.ts b/libs/pathway-design/server/pathway/business/src/lib/specs/change-name/change-title-pathway.step.ts index 89fe4e47..ee552162 100644 --- a/libs/pathway-design/server/pathway/business/src/lib/specs/change-name/change-title-pathway.step.ts +++ b/libs/pathway-design/server/pathway/business/src/lib/specs/change-name/change-title-pathway.step.ts @@ -68,9 +68,10 @@ export default class ControllerSteps { assert.strictEqual(this.pDSPBEPathwayEntity.title, title); } - @then('I should see an error message from business {string} during the title change') - public thenIShouldSeeAnErrorMessageDuringTitleChange(errorMessage: string) { + @then('I should see an error message from business during the title change') + public thenIShouldSeeAnErrorMessageDuringTitleChange() { assert.notEqual(this.error, undefined); - assert.strictEqual(this.error?.message, errorMessage); + assert.notEqual(this.error?.message, undefined); + assert.notEqual(this.error?.message, ''); } } diff --git a/libs/pathway-design/server/pathway/business/src/lib/specs/initialize/initialize-pathway.feature b/libs/pathway-design/server/pathway/business/src/lib/specs/initialize/initialize-pathway.feature index d6caa0e5..cafae371 100644 --- a/libs/pathway-design/server/pathway/business/src/lib/specs/initialize/initialize-pathway.feature +++ b/libs/pathway-design/server/pathway/business/src/lib/specs/initialize/initialize-pathway.feature @@ -9,56 +9,13 @@ Feature: Business - Initialize a pathway | id | title | description | researchField | | f7703737-186c-4c7c-8d46-925111c7c7c1 | My Pathway | A test pathway | biology | - Scenario: I want to initialize a pathway in business with an empty title - When I initialize a pathway in business with these data - | id | title | description | researchField | - | f7703737-186c-4c7c-8d46-925111c7c7c1 | | A test pathway | biology | - Then I should see an error message from business "Title is required" during the initialization - - Scenario: I want to initialize a pathway in business with an empty description - When I initialize a pathway in business with these data - | id | title | description | researchField | - | f7703737-186c-4c7c-8d46-925111c7c7c1 | My Pathway | | biology | - Then I should see an error message from business "Description is required" during the initialization - - Scenario: I want to initialize a pathway in business with an empty research field - When I initialize a pathway in business with these data - | id | title | description | researchField | - | f7703737-186c-4c7c-8d46-925111c7c7c1 | My Pathway | A test pathway | | - Then I should see an error message from business "Research field is required" during the initialization - - Scenario: I want to initialize a pathway in business with an invalid UUID - When I initialize a pathway in business with these data - | id | title | description | researchField | - | invalid-uuid | My Pathway | A test pathway | biology | - Then I should see an error message from business "Pathway id must be a valid uuid" during the initialization - - Scenario: I want to initialize a pathway in business with all empty fields + Scenario: I want to initialize a pathway in business with invalid data When I initialize a pathway in business with these data | id | title | description | researchField | | | | | | - Then I should see an error message from business "Pathway id must be a valid uuid" during the initialization + Then I should see an error message from business during the initialization - Scenario: I want to initialize a pathway in business with missing id + Scenario: I want to initialize a pathway in business with missing fields When I initialize a pathway in business with these data | title | description | researchField | - | My Pathway | A test pathway | biology | - Then I should see an error message from business "Pathway id must be a valid uuid" during the initialization - - Scenario: I want to initialize a pathway in business with missing title - When I initialize a pathway in business with these data - | id | description | researchField | - | f7703737-186c-4c7c-8d46-925111c7c7c1 | A test pathway | biology | - Then I should see an error message from business "Title is required" during the initialization - - Scenario: I want to initialize a pathway in business with missing description - When I initialize a pathway in business with these data - | id | title | researchField | - | f7703737-186c-4c7c-8d46-925111c7c7c1 | My Pathway | biology | - Then I should see an error message from business "Description is required" during the initialization - - Scenario: I want to initialize a pathway in business with missing research field - When I initialize a pathway in business with these data - | id | title | description | - | f7703737-186c-4c7c-8d46-925111c7c7c1 | My Pathway | A test pathway | - Then I should see an error message from business "Research field is required" during the initialization + Then I should see an error message from business during the initialization diff --git a/libs/pathway-design/server/pathway/business/src/lib/specs/initialize/initialize-pathway.step.ts b/libs/pathway-design/server/pathway/business/src/lib/specs/initialize/initialize-pathway.step.ts index 973c24fd..fc2eca48 100644 --- a/libs/pathway-design/server/pathway/business/src/lib/specs/initialize/initialize-pathway.step.ts +++ b/libs/pathway-design/server/pathway/business/src/lib/specs/initialize/initialize-pathway.step.ts @@ -100,9 +100,10 @@ export default class PathwaySteps { assert.deepStrictEqual(callArgs, expectedEvent); } - @then('I should see an error message from business {string} during the initialization') - public thenIShouldSeeAnErrorMessageDuringInitialization(errorMessage: string) { + @then('I should see an error message from business during the initialization') + public thenIShouldSeeAnErrorMessageDuringInitialization() { assert.notEqual(this.error, undefined); - assert.strictEqual(this.error?.message, errorMessage); + assert.notEqual(this.error?.message, undefined); + assert.notEqual(this.error?.message, ''); } } diff --git a/libs/pathway-design/server/pathway/business/src/lib/value-objects/description.value-object.spec.ts b/libs/pathway-design/server/pathway/business/src/lib/value-objects/description.value-object.spec.ts index 55859aba..2e402781 100644 --- a/libs/pathway-design/server/pathway/business/src/lib/value-objects/description.value-object.spec.ts +++ b/libs/pathway-design/server/pathway/business/src/lib/value-objects/description.value-object.spec.ts @@ -1,4 +1,5 @@ import { beforeAll, describe, expect, test } from 'bun:test'; +import { pDCBPRDescriptionRules } from '@bewoak/pathway-design-common-business-pathway-rules'; import { DescriptionValueObject } from './description.value-object'; describe('DescriptionValueObject', () => { @@ -15,8 +16,8 @@ describe('DescriptionValueObject', () => { expect(description.value).toBe('Test description'); }); - test('should throw an error if the description is empty', () => { - expect(() => new DescriptionValueObject('')).toThrowError('Description is required'); + test('should throw an error if the description is invalid', () => { + expect(() => new DescriptionValueObject('')).toThrowError(pDCBPRDescriptionRules.textError()); }); test('should return true when comparing two equal descriptions', () => { diff --git a/libs/pathway-design/server/pathway/business/src/lib/value-objects/description.value-object.ts b/libs/pathway-design/server/pathway/business/src/lib/value-objects/description.value-object.ts index efecf497..8d5d7718 100644 --- a/libs/pathway-design/server/pathway/business/src/lib/value-objects/description.value-object.ts +++ b/libs/pathway-design/server/pathway/business/src/lib/value-objects/description.value-object.ts @@ -1,9 +1,10 @@ import { CTSEBadRequestException } from '@bewoak/common-tools-server-http-exceptions'; +import { pDCBPRDescriptionRules } from '@bewoak/pathway-design-common-business-pathway-rules'; export class DescriptionValueObject { constructor(private readonly description: string) { - if (this.isEmpty(description)) { - throw new CTSEBadRequestException('Description is required'); + if (pDCBPRDescriptionRules.isValid(description) === false) { + throw new CTSEBadRequestException(pDCBPRDescriptionRules.textError()); } } get value() { @@ -17,8 +18,4 @@ export class DescriptionValueObject { toString() { return this.description; } - - private isEmpty(name: string | undefined) { - return name === undefined || name.length === 0; - } } diff --git a/libs/pathway-design/server/pathway/business/src/lib/value-objects/pathway-id.value-object.spec.ts b/libs/pathway-design/server/pathway/business/src/lib/value-objects/pathway-id.value-object.spec.ts index 7069afac..c4df193c 100644 --- a/libs/pathway-design/server/pathway/business/src/lib/value-objects/pathway-id.value-object.spec.ts +++ b/libs/pathway-design/server/pathway/business/src/lib/value-objects/pathway-id.value-object.spec.ts @@ -1,4 +1,5 @@ import { beforeAll, describe, expect, test } from 'bun:test'; +import { pDCBPRPathwayIdRules } from '@bewoak/pathway-design-common-business-pathway-rules'; import { PathwayIdValueObject } from './pathway-id.value-object'; describe('PathwayIdValueObject', () => { @@ -16,8 +17,8 @@ describe('PathwayIdValueObject', () => { expect(pathwayIdValueObject1.value).toBe('e24054b9-92ca-4a22-be67-cf14cc94e6f8'); }); - test('should throw an error if the id is not a uuid', () => { - expect(() => new PathwayIdValueObject('12345')).toThrowError('Pathway id must be a valid uuid'); + test('should throw an error if the pathway id is invalid', () => { + expect(() => new PathwayIdValueObject('12345')).toThrowError(pDCBPRPathwayIdRules.textError()); }); test('should return true when comparing two equal pathway id', () => { diff --git a/libs/pathway-design/server/pathway/business/src/lib/value-objects/pathway-id.value-object.ts b/libs/pathway-design/server/pathway/business/src/lib/value-objects/pathway-id.value-object.ts index fb1ee0c4..b1cad2e5 100644 --- a/libs/pathway-design/server/pathway/business/src/lib/value-objects/pathway-id.value-object.ts +++ b/libs/pathway-design/server/pathway/business/src/lib/value-objects/pathway-id.value-object.ts @@ -1,9 +1,10 @@ import { CTSEBadRequestException } from '@bewoak/common-tools-server-http-exceptions'; +import { pDCBPRPathwayIdRules } from '@bewoak/pathway-design-common-business-pathway-rules'; export class PathwayIdValueObject { constructor(private readonly id: string) { - if (!this.isUuid(id)) { - throw new CTSEBadRequestException('Pathway id must be a valid uuid'); + if (pDCBPRPathwayIdRules.isValid(id) === false) { + throw new CTSEBadRequestException(pDCBPRPathwayIdRules.textError()); } } get value() { @@ -17,10 +18,4 @@ export class PathwayIdValueObject { toString() { return this.id.toString(); } - - private isUuid(id: string) { - const uuidV4Regex = /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i; - - return uuidV4Regex.test(id); - } } diff --git a/libs/pathway-design/server/pathway/business/src/lib/value-objects/research-field.value-object.spec.ts b/libs/pathway-design/server/pathway/business/src/lib/value-objects/research-field.value-object.spec.ts index e7a35829..e1679595 100644 --- a/libs/pathway-design/server/pathway/business/src/lib/value-objects/research-field.value-object.spec.ts +++ b/libs/pathway-design/server/pathway/business/src/lib/value-objects/research-field.value-object.spec.ts @@ -1,4 +1,5 @@ import { beforeAll, describe, expect, test } from 'bun:test'; +import { pDCBPRResearchFieldRules } from '@bewoak/pathway-design-common-business-pathway-rules'; import { ResearchFieldValueObjects } from './research-field.value-object'; describe('ResearchFieldValueObjects', () => { @@ -15,8 +16,8 @@ describe('ResearchFieldValueObjects', () => { expect(researchField.value).toBe('Test researchField'); }); - test('should throw an error if the researchField is empty', () => { - expect(() => new ResearchFieldValueObjects('')).toThrowError('Research field is required'); + test('should throw an error if the researchField is invalid', () => { + expect(() => new ResearchFieldValueObjects('')).toThrowError(pDCBPRResearchFieldRules.textError()); }); test('should return true when comparing two equal researchFields', () => { diff --git a/libs/pathway-design/server/pathway/business/src/lib/value-objects/research-field.value-object.ts b/libs/pathway-design/server/pathway/business/src/lib/value-objects/research-field.value-object.ts index ccccd251..56d6855c 100644 --- a/libs/pathway-design/server/pathway/business/src/lib/value-objects/research-field.value-object.ts +++ b/libs/pathway-design/server/pathway/business/src/lib/value-objects/research-field.value-object.ts @@ -1,9 +1,10 @@ import { CTSEBadRequestException } from '@bewoak/common-tools-server-http-exceptions'; +import { pDCBPRResearchFieldRules } from '@bewoak/pathway-design-common-business-pathway-rules'; export class ResearchFieldValueObjects { constructor(private readonly researchField: string) { - if (this.isEmpty(researchField)) { - throw new CTSEBadRequestException('Research field is required'); + if (pDCBPRResearchFieldRules.isValid(researchField) === false) { + throw new CTSEBadRequestException(pDCBPRResearchFieldRules.textError()); } } get value() { diff --git a/libs/pathway-design/server/pathway/business/src/lib/value-objects/title.value-object.spec.ts b/libs/pathway-design/server/pathway/business/src/lib/value-objects/title.value-object.spec.ts index 05a7c360..8fc788ec 100644 --- a/libs/pathway-design/server/pathway/business/src/lib/value-objects/title.value-object.spec.ts +++ b/libs/pathway-design/server/pathway/business/src/lib/value-objects/title.value-object.spec.ts @@ -1,4 +1,5 @@ import { beforeAll, describe, expect, test } from 'bun:test'; +import { pDCBPRTitleRules } from '@bewoak/pathway-design-common-business-pathway-rules'; import { PDSPBVOTitleValueObjects } from './title.value-object'; describe('PDSPBVOTitleValueObjects', () => { @@ -15,8 +16,8 @@ describe('PDSPBVOTitleValueObjects', () => { expect(title.value).toBe('Test Title'); }); - test('should throw an error if the title is empty', () => { - expect(() => new PDSPBVOTitleValueObjects('')).toThrowError('Title is required'); + test('should throw an error if the title is not valid', () => { + expect(() => new PDSPBVOTitleValueObjects('')).toThrowError(pDCBPRTitleRules.textError()); }); test('should return true when comparing two equal titles', () => { diff --git a/libs/pathway-design/server/pathway/business/src/lib/value-objects/title.value-object.ts b/libs/pathway-design/server/pathway/business/src/lib/value-objects/title.value-object.ts index 2f891ef1..6e99427e 100644 --- a/libs/pathway-design/server/pathway/business/src/lib/value-objects/title.value-object.ts +++ b/libs/pathway-design/server/pathway/business/src/lib/value-objects/title.value-object.ts @@ -1,10 +1,10 @@ import { CTSEBadRequestException } from '@bewoak/common-tools-server-http-exceptions'; -import { PDCBPR_titleRules } from '@bewoak/pathway-design-common-business-pathway-rules'; +import { pDCBPRTitleRules } from '@bewoak/pathway-design-common-business-pathway-rules'; export class PDSPBVOTitleValueObjects { constructor(private readonly title: string) { - if (PDCBPR_titleRules.isValid(title) === false) { - throw new CTSEBadRequestException('Title is required'); + if (pDCBPRTitleRules.isValid(title) === false) { + throw new CTSEBadRequestException(pDCBPRTitleRules.textError()); } }