From 086c09519a0eba70aeeb8172d9e1e9a638dd61eb Mon Sep 17 00:00:00 2001 From: Denys Bohdan Date: Thu, 3 Oct 2024 16:51:26 +0200 Subject: [PATCH] UIQM-709 Duplicate LCCN checking query > Do not return instance/bib record that is set for deletion --- CHANGELOG.md | 1 + src/hooks/useValidation/rules.js | 1 + src/hooks/useValidation/useValidation.test.js | 115 ++++++++++++++++++ src/hooks/useValidation/validators.js | 19 +-- 4 files changed, 127 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 13b498b7..8b497fe0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ * [UIQM-706](https://issues.folio.org/browse/UIQM-706) *BREAKING* Upgrade `marc-records-editor` to `6.0`. * [UIQM-698](https://issues.folio.org/browse/UIQM-698) Validate 006/007 field lengths. * [UIQM-704](https://issues.folio.org/browse/UIQM-704) Linked fields - combine split fields before sending for validation. +* [UIQM-709](https://issues.folio.org/browse/UIQM-709) Duplicate LCCN checking query > Do not return instance/bib record that is set for deletion. ## [8.0.1] (https://github.com/folio-org/ui-quick-marc/tree/v8.0.1) (2024-04-18) diff --git a/src/hooks/useValidation/rules.js b/src/hooks/useValidation/rules.js index 5e0b495b..365cf929 100644 --- a/src/hooks/useValidation/rules.js +++ b/src/hooks/useValidation/rules.js @@ -112,6 +112,7 @@ const BASE_BIB_VALIDATORS = [ { tag: '010', validator: RULES.DUPLICATE_LCCN, + ignore: ({ duplicateLccnCheckingEnabled }) => !duplicateLccnCheckingEnabled, message: () => ({ id: 'ui-quick-marc.record.error.010.lccnDuplicated' }), }, ]; diff --git a/src/hooks/useValidation/useValidation.test.js b/src/hooks/useValidation/useValidation.test.js index 93fa3ec7..d2ab9f4a 100644 --- a/src/hooks/useValidation/useValidation.test.js +++ b/src/hooks/useValidation/useValidation.test.js @@ -354,6 +354,7 @@ describe('useValidation', () => { marcType: MARC_TYPES.HOLDINGS, action: QUICK_MARC_ACTIONS.EDIT, locations, + }; testCommonValidationRules({ marcContext }); @@ -365,6 +366,7 @@ describe('useValidation', () => { marcType: MARC_TYPES.HOLDINGS, action: QUICK_MARC_ACTIONS.CREATE, locations, + }; testCommonValidationRules({ marcContext }); @@ -409,6 +411,7 @@ describe('useValidation', () => { linkableBibFields, linkingRules, fixedFieldSpec: fixedFieldSpecBib, + }; const record = { @@ -651,6 +654,60 @@ describe('useValidation', () => { })); }); }); + + describe('when instance is staff suppressed', () => { + it('should not validate LCCN duplication', async () => { + useOkapiKy.mockReturnValueOnce({ + get: jest.fn().mockReturnValue({ + json: jest.fn().mockResolvedValue({ instances: [{}] }), + }), + }); + const { result } = renderHook(() => useValidation({ + ...marcContext, + instance: { + staffSuppress: true, + }, + }), { + wrapper: getWrapper(), + }); + + await result.current.validate(record.records); + + expect(quickMarcContext.setValidationErrors).not.toHaveBeenCalledWith(expect.objectContaining({ + 4: [{ + id: 'ui-quick-marc.record.error.010.lccnDuplicated', + severity: 'error', + }], + })); + }); + }); + + describe('when instance is discovery suppressed', () => { + it('should not validate LCCN duplication', async () => { + useOkapiKy.mockReturnValueOnce({ + get: jest.fn().mockReturnValue({ + json: jest.fn().mockResolvedValue({ instances: [{}] }), + }), + }); + const { result } = renderHook(() => useValidation({ + ...marcContext, + instance: { + discoverySuppress: true, + }, + }), { + wrapper: getWrapper(), + }); + + await result.current.validate(record.records); + + expect(quickMarcContext.setValidationErrors).not.toHaveBeenCalledWith(expect.objectContaining({ + 4: [{ + id: 'ui-quick-marc.record.error.010.lccnDuplicated', + severity: 'error', + }], + })); + }); + }); }); describe('when validating Holdings record', () => { @@ -889,6 +946,7 @@ describe('useValidation', () => { marcType: MARC_TYPES.HOLDINGS, action: QUICK_MARC_ACTIONS.EDIT, locations, + }; testBaseHoldingsValidation({ marcContext }); @@ -900,6 +958,7 @@ describe('useValidation', () => { marcType: MARC_TYPES.HOLDINGS, action: QUICK_MARC_ACTIONS.CREATE, locations, + }; testBaseHoldingsValidation({ marcContext }); @@ -944,6 +1003,7 @@ describe('useValidation', () => { linkableBibFields, linkingRules, fixedFieldSpec: fixedFieldSpecAuth, + }; const record = { @@ -1039,6 +1099,60 @@ describe('useValidation', () => { }]); }); }); + + describe('when instance is staff suppressed', () => { + it('should not validate LCCN duplication', async () => { + useOkapiKy.mockReturnValueOnce({ + get: jest.fn().mockReturnValue({ + json: jest.fn().mockResolvedValue({ instances: [{}] }), + }), + }); + const { result } = renderHook(() => useValidation({ + ...marcContext, + instance: { + staffSuppress: true, + }, + }), { + wrapper: getWrapper(), + }); + + await result.current.validate(record.records); + + expect(quickMarcContext.setValidationErrors).not.toHaveBeenCalledWith(expect.objectContaining({ + 4: [{ + id: 'ui-quick-marc.record.error.010.lccnDuplicated', + severity: 'error', + }], + })); + }); + }); + + describe('when instance is discovery suppressed', () => { + it('should not validate LCCN duplication', async () => { + useOkapiKy.mockReturnValueOnce({ + get: jest.fn().mockReturnValue({ + json: jest.fn().mockResolvedValue({ instances: [{}] }), + }), + }); + const { result } = renderHook(() => useValidation({ + ...marcContext, + instance: { + discoverySuppress: true, + }, + }), { + wrapper: getWrapper(), + }); + + await result.current.validate(record.records); + + expect(quickMarcContext.setValidationErrors).not.toHaveBeenCalledWith(expect.objectContaining({ + 4: [{ + id: 'ui-quick-marc.record.error.010.lccnDuplicated', + severity: 'error', + }], + })); + }); + }); }); describe('when action is CREATE', () => { @@ -1076,6 +1190,7 @@ describe('useValidation', () => { linkableBibFields, linkingRules, fixedFieldSpec: fixedFieldSpecAuth, + }; const record = { diff --git a/src/hooks/useValidation/validators.js b/src/hooks/useValidation/validators.js index a1dfb5d2..6d7fbe3d 100644 --- a/src/hooks/useValidation/validators.js +++ b/src/hooks/useValidation/validators.js @@ -442,18 +442,19 @@ export const validateFixedFieldLength = ({ marcRecords, fixedFieldSpec, marcType return undefined; }; -export const validateLccnDuplication = async ({ - ky, - marcRecords, - duplicateLccnCheckingEnabled, - instanceId, - action, - marcType, -}, rule) => { - if (!duplicateLccnCheckingEnabled) { +export const validateLccnDuplication = async (context, rule) => { + if (rule.ignore?.(context)) { return undefined; } + const { + ky, + marcRecords, + instanceId, + action, + marcType, + } = context; + const fields = marcRecords.filter(record => record.tag.match(rule.tag)); const validateField = async (field) => {