From c38b3f280ad696c34f3d7981df80714456fae1be Mon Sep 17 00:00:00 2001 From: karilint Date: Tue, 17 Mar 2026 18:01:33 +0200 Subject: [PATCH] Extract reference validation helpers for unit test isolation --- backend/src/routes/reference.ts | 3 +- backend/src/services/reference.ts | 52 +++---------------- backend/src/services/referenceValidation.ts | 48 +++++++++++++++++ .../unit-tests/reference/validation.test.ts | 2 +- 4 files changed, 56 insertions(+), 49 deletions(-) create mode 100644 backend/src/services/referenceValidation.ts diff --git a/backend/src/routes/reference.ts b/backend/src/routes/reference.ts index d4e1293b..27369234 100644 --- a/backend/src/routes/reference.ts +++ b/backend/src/routes/reference.ts @@ -7,11 +7,10 @@ import { getReferenceJournals, getReferenceLocalities, getReferenceSpecies, - buildReferenceDisplayLabelMap, - validateEntireReference, getAuthorsOfReference, getJournalById, } from '../services/reference' +import { buildReferenceDisplayLabelMap, validateEntireReference } from '../services/referenceValidation' import { requireOneOf } from '../middlewares/authorizer' import { Role, EditMetaData, ReferenceDetailsType, EditDataType } from '../../../frontend/src/shared/types' import { deleteReference, writeReference } from '../services/write/reference' diff --git a/backend/src/services/reference.ts b/backend/src/services/reference.ts index ed0250cc..051e5660 100644 --- a/backend/src/services/reference.ts +++ b/backend/src/services/reference.ts @@ -1,17 +1,10 @@ import { nowDb } from '../utils/db' -import { EditDataType, ReferenceDetailsType } from '../../../frontend/src/shared/types' -import { ValidationObject } from '../../../frontend/src/shared/validators/validator' -import { - ReferenceDisplayLabelMap, - ReferenceFieldDisplayNames, - validateReference, -} from '../../../frontend/src/shared/validators/reference' -import { type ref_ref } from '../../prisma/generated/now_test_client' import { TabListQueryOptions } from './tabularQuery' - -type ReferenceTypeFieldName = { field_name: string | null; ref_field_name: string | null } - -export type ReferenceTypeWithFieldNames = { ref_type_id: number; ref_field_name: ReferenceTypeFieldName[] } +import { + buildReferenceDisplayLabelMap, + type ReferenceTypeWithFieldNames, + validateEntireReference, +} from './referenceValidation' export const getAllReferences = async () => { const result = await nowDb.ref_ref.findMany({ @@ -118,28 +111,6 @@ export const getReferenceTypes = async (): Promise { - const labelMap: ReferenceDisplayLabelMap = {} - - referenceTypes.forEach(referenceType => { - const labelsForType = referenceType.ref_field_name.reduce((typeLabels, field) => { - if (field.field_name && field.ref_field_name) { - typeLabels[field.field_name as keyof ReferenceFieldDisplayNames] = field.ref_field_name - } - - return typeLabels - }, {}) - - if (Object.keys(labelsForType).length > 0) { - labelMap[referenceType.ref_type_id] = labelsForType - } - }) - - return labelMap -} - export const getReferenceAuthors = async () => { const uniqueReferenceAuthors = await nowDb.ref_authors.groupBy({ by: ['author_surname', 'author_initials'], @@ -185,15 +156,4 @@ export const getReferenceJournals = async () => { return referenceJournalTypes } -export const validateEntireReference = ( - editedFields: EditDataType, - options?: { displayLabelMap?: ReferenceDisplayLabelMap } -) => { - const keys = Object.keys(editedFields as Record) as (keyof EditDataType)[] - const errors: ValidationObject[] = [] - for (const key of keys) { - const error = validateReference(editedFields as EditDataType, key, options) - if (error.error) errors.push(error) - } - return errors -} +export { buildReferenceDisplayLabelMap, validateEntireReference } diff --git a/backend/src/services/referenceValidation.ts b/backend/src/services/referenceValidation.ts new file mode 100644 index 00000000..afd71c31 --- /dev/null +++ b/backend/src/services/referenceValidation.ts @@ -0,0 +1,48 @@ +import { EditDataType, ReferenceDetailsType } from '../../../frontend/src/shared/types' +import { ValidationObject } from '../../../frontend/src/shared/validators/validator' +import { + ReferenceDisplayLabelMap, + ReferenceFieldDisplayNames, + validateReference, +} from '../../../frontend/src/shared/validators/reference' + +type ReferenceTypeFieldName = { field_name: string | null; ref_field_name: string | null } + +export type ReferenceTypeWithFieldNames = { ref_type_id: number; ref_field_name: ReferenceTypeFieldName[] } + +export const buildReferenceDisplayLabelMap = ( + referenceTypes: ReferenceTypeWithFieldNames[] +): ReferenceDisplayLabelMap => { + const labelMap: ReferenceDisplayLabelMap = {} + + referenceTypes.forEach(referenceType => { + const labelsForType = referenceType.ref_field_name.reduce((typeLabels, field) => { + if (field.field_name && field.ref_field_name) { + typeLabels[field.field_name as keyof ReferenceFieldDisplayNames] = field.ref_field_name + } + + return typeLabels + }, {}) + + if (Object.keys(labelsForType).length > 0) { + labelMap[referenceType.ref_type_id] = labelsForType + } + }) + + return labelMap +} + +export const validateEntireReference = ( + editedFields: EditDataType, + options?: { displayLabelMap?: ReferenceDisplayLabelMap } +) => { + const keys = Object.keys(editedFields as Record) as (keyof EditDataType)[] + const errors: ValidationObject[] = [] + + for (const key of keys) { + const error = validateReference(editedFields, key, options) + if (error.error) errors.push(error) + } + + return errors +} diff --git a/backend/src/unit-tests/reference/validation.test.ts b/backend/src/unit-tests/reference/validation.test.ts index a656b7bb..6bc2d4b7 100644 --- a/backend/src/unit-tests/reference/validation.test.ts +++ b/backend/src/unit-tests/reference/validation.test.ts @@ -4,7 +4,7 @@ import { buildReferenceDisplayLabelMap, validateEntireReference, type ReferenceTypeWithFieldNames, -} from '../../services/reference' +} from '../../services/referenceValidation' import { EditDataType, ReferenceDetailsType } from '../../../../frontend/src/shared/types' const electronicCitationReferenceType: ReferenceTypeWithFieldNames = {