From 9e7acead5acd76c793ef6d4e10ccb8d6a4d70ef6 Mon Sep 17 00:00:00 2001 From: Yury Saukou Date: Fri, 12 Jan 2024 16:00:55 +0400 Subject: [PATCH 1/3] UIORGS-418 Suppress banking information management for unauthorized user (#599) --- CHANGELOG.md | 1 + .../OrganizationIntegrationForm.test.js.snap | 69 +++++++++++-------- .../OrganizationAccountsForm.test.js.snap | 23 ++++--- .../OrganizationAgreementsForm.test.js.snap | 23 ++++--- .../OrganizationSummaryForm.test.js.snap | 27 ++++---- .../useBankingInformationManager.js | 13 +++- .../useOrganizationBankingInformation.js | 11 ++- .../__snapshots__/EditContact.test.js.snap | 27 ++++---- .../__snapshots__/EditInterface.test.js.snap | 54 ++++++++------- test/jest/__mock__/index.js | 1 + test/jest/__mock__/resizeObserver.mock.js | 5 ++ 11 files changed, 153 insertions(+), 101 deletions(-) create mode 100644 test/jest/__mock__/resizeObserver.mock.js diff --git a/CHANGELOG.md b/CHANGELOG.md index b0055b72..336fb330 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,7 @@ * Enable "Hourly" and "Monthly" EDI export scheduling frequency options. Refs UIORGS-415. * Create Privileged donor information accordion in organization record. Refs UIORGS-397. * Factor away from unsupported `color()` function. Refs UIORGS-416. +* Suppress banking information management for unauthorized user. Refs UIORGS-418. ## [5.0.0](https://github.com/folio-org/ui-organizations/tree/v5.0.0) (2023-10-12) [Full Changelog](https://github.com/folio-org/ui-organizations/compare/v4.0.0...v5.0.0) diff --git a/src/OrganizationIntegration/OrganizationIntegrationForm/__snapshots__/OrganizationIntegrationForm.test.js.snap b/src/OrganizationIntegration/OrganizationIntegrationForm/__snapshots__/OrganizationIntegrationForm.test.js.snap index 8342e0bb..64ea4cca 100644 --- a/src/OrganizationIntegration/OrganizationIntegrationForm/__snapshots__/OrganizationIntegrationForm.test.js.snap +++ b/src/OrganizationIntegration/OrganizationIntegrationForm/__snapshots__/OrganizationIntegrationForm.test.js.snap @@ -205,7 +205,7 @@ exports[`OrganizationIntegrationForm should render correct form structure 1`] = class="col-xs-3" >
-
+ class="inputGroup" + > + +
+
chunk(arr, 5).reduce((acc, chunked) => { }, Promise.resolve()); export const useBankingInformationManager = () => { + const stripes = useStripes(); const showCallout = useShowCallout(); const { enabled: isBankingInformationEnabled } = useBankingInformationSettings(); @@ -34,7 +36,15 @@ export const useBankingInformationManager = () => { bankingInformation, organization, }) => { - if (!(organization.isVendor && isBankingInformationEnabled)) return Promise.resolve(); + const isOperationRestricted = !( + organization.isVendor + && isBankingInformationEnabled + && stripes.hasPerm('organizations.banking-information.item.post') + && stripes.hasPerm('organizations.banking-information.item.put') + && stripes.hasPerm('organizations.banking-information.item.delete') + ); + + if (isOperationRestricted) return Promise.resolve(); const { created, @@ -60,6 +70,7 @@ export const useBankingInformationManager = () => { deleteBankingInformation, isBankingInformationEnabled, showCallout, + stripes, updateBankingInformation, ]); diff --git a/src/common/hooks/useOrganizationBankingInformation/useOrganizationBankingInformation.js b/src/common/hooks/useOrganizationBankingInformation/useOrganizationBankingInformation.js index 132f90c8..acacbf54 100644 --- a/src/common/hooks/useOrganizationBankingInformation/useOrganizationBankingInformation.js +++ b/src/common/hooks/useOrganizationBankingInformation/useOrganizationBankingInformation.js @@ -3,6 +3,7 @@ import { useQuery } from 'react-query'; import { useNamespace, useOkapiKy, + useStripes, } from '@folio/stripes/core'; import { LIMIT_MAX } from '@folio/stripes-acq-components'; @@ -11,12 +12,18 @@ import { BANKING_INFORMATION_API } from '../../constants'; const DEFAULT_DATA = []; export const useOrganizationBankingInformation = (organizationId, options = {}) => { + const stripes = useStripes(); const ky = useOkapiKy(); const [namespace] = useNamespace({ key: 'organization-banking-information' }); + const { enabled = true, ...rest } = options; const queryOptions = { - ...options, - enabled: options.enabled && Boolean(organizationId), + ...rest, + enabled: Boolean( + enabled + && Boolean(organizationId) + && stripes.hasPerm('organizations.banking-information.collection.get'), + ), }; const { diff --git a/src/contacts/EditContact/__snapshots__/EditContact.test.js.snap b/src/contacts/EditContact/__snapshots__/EditContact.test.js.snap index 57812565..825a34db 100644 --- a/src/contacts/EditContact/__snapshots__/EditContact.test.js.snap +++ b/src/contacts/EditContact/__snapshots__/EditContact.test.js.snap @@ -7923,7 +7923,7 @@ exports[`EditContact should render correct form structure 1`] = ` class="col-xs-6" >
-
+ class="inputGroup" + > + +
+
diff --git a/src/interfaces/EditInterface/__snapshots__/EditInterface.test.js.snap b/src/interfaces/EditInterface/__snapshots__/EditInterface.test.js.snap index ecc174f8..607332df 100644 --- a/src/interfaces/EditInterface/__snapshots__/EditInterface.test.js.snap +++ b/src/interfaces/EditInterface/__snapshots__/EditInterface.test.js.snap @@ -321,7 +321,7 @@ exports[`EditContact should render correct form structure 1`] = ` class="col-xs-12" >
-
+ class="inputGroup" + > + +
+
-
+ class="inputGroup" + > + +
+
diff --git a/test/jest/__mock__/index.js b/test/jest/__mock__/index.js index 2b2d24ef..2700c754 100644 --- a/test/jest/__mock__/index.js +++ b/test/jest/__mock__/index.js @@ -1 +1,2 @@ import './createRange.mock'; +import './resizeObserver.mock'; diff --git a/test/jest/__mock__/resizeObserver.mock.js b/test/jest/__mock__/resizeObserver.mock.js new file mode 100644 index 00000000..da66fa4f --- /dev/null +++ b/test/jest/__mock__/resizeObserver.mock.js @@ -0,0 +1,5 @@ +global.ResizeObserver = jest.fn().mockImplementation(() => ({ + observe: jest.fn(), + unobserve: jest.fn(), + disconnect: jest.fn(), +})); From 9fd81d1b94f6452b9268b0867164548f886bc86f Mon Sep 17 00:00:00 2001 From: Alisher Musurmonov Date: Tue, 16 Jan 2024 15:45:37 +0500 Subject: [PATCH 2/3] UIORGS-417: Add validation for `Day` field in `Monthly` scheduler for export method (#600) * UIORGS-417: Add validation for `Day` field in `Monthly` scheduler for export method * test: add test coverage for util functions * refactor validation code * test: improve test coverage --- CHANGELOG.md | 1 + .../SchedulingForm/SchedulingForm.js | 42 ++++++---------- .../SchedulingForm/constants.js | 12 +++++ .../SchedulingForm/utils.js | 33 +++++++++++++ .../SchedulingForm/utils.test.js | 49 +++++++++++++++++++ 5 files changed, 111 insertions(+), 26 deletions(-) create mode 100644 src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/constants.js create mode 100644 src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/utils.js create mode 100644 src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/utils.test.js diff --git a/CHANGELOG.md b/CHANGELOG.md index 336fb330..37df161d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,6 +13,7 @@ * Create Privileged donor information accordion in organization record. Refs UIORGS-397. * Factor away from unsupported `color()` function. Refs UIORGS-416. * Suppress banking information management for unauthorized user. Refs UIORGS-418. +* Add validation for `Day` field in `Monthly` scheduler for export method. Refs UIORGS-417. ## [5.0.0](https://github.com/folio-org/ui-organizations/tree/v5.0.0) (2023-10-12) [Full Changelog](https://github.com/folio-org/ui-organizations/compare/v4.0.0...v5.0.0) diff --git a/src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/SchedulingForm.js b/src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/SchedulingForm.js index 03de00ca..96dc814c 100644 --- a/src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/SchedulingForm.js +++ b/src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/SchedulingForm.js @@ -22,26 +22,16 @@ import { SCHEDULE_PERIODS, WEEKDAYS, } from '../../constants'; - -const ALLOWED_SCHEDULE_PERIODS = [ - SCHEDULE_PERIODS.none, - SCHEDULE_PERIODS.hours, - SCHEDULE_PERIODS.days, - SCHEDULE_PERIODS.weeks, - SCHEDULE_PERIODS.months, -]; - -const normalizeNumber = value => { - if (!value && value !== 0) return value; - - return Number(value); -}; - -const validatePeriod = (value) => { - return value !== SCHEDULE_PERIODS.none - ? undefined - : ; -}; +import { + ALLOWED_SCHEDULE_PERIODS, + MAX_DAYS_OF_MONTHLY_SCHEDULE, + MIN_REQUIRED_NUMBER, +} from './constants'; +import { + validateRequiredMinAndMaxNumber, + normalizeNumber, + validatePeriod, +} from './utils'; export const SchedulingForm = () => { const { formatMessage } = useIntl(); @@ -135,7 +125,7 @@ export const SchedulingForm = () => { label={} name="exportTypeSpecificParameters.vendorEdiOrdersExportConfig.ediSchedule.scheduleParameters.scheduleFrequency" type="number" - min={1} + min={MIN_REQUIRED_NUMBER} hasClearIcon={false} required validate={validateRequiredPositiveNumber} @@ -167,7 +157,7 @@ export const SchedulingForm = () => { label={} name="exportTypeSpecificParameters.vendorEdiOrdersExportConfig.ediSchedule.scheduleParameters.scheduleFrequency" type="number" - min={1} + min={MIN_REQUIRED_NUMBER} hasClearIcon={false} required validate={validateRequiredPositiveNumber} @@ -207,7 +197,7 @@ export const SchedulingForm = () => { label={} name="exportTypeSpecificParameters.vendorEdiOrdersExportConfig.ediSchedule.scheduleParameters.scheduleFrequency" type="number" - min={1} + min={MIN_REQUIRED_NUMBER} hasClearIcon={false} required validate={validateRequiredPositiveNumber} @@ -259,11 +249,11 @@ export const SchedulingForm = () => { label={} name="exportTypeSpecificParameters.vendorEdiOrdersExportConfig.ediSchedule.scheduleParameters.scheduleDay" type="number" - min={1} - max={31} + min={MIN_REQUIRED_NUMBER} + max={MAX_DAYS_OF_MONTHLY_SCHEDULE} hasClearIcon={false} required - validate={validateRequiredPositiveNumber} + validate={validateRequiredMinAndMaxNumber} parse={normalizeNumber} /> diff --git a/src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/constants.js b/src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/constants.js new file mode 100644 index 00000000..2c64c120 --- /dev/null +++ b/src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/constants.js @@ -0,0 +1,12 @@ +import { SCHEDULE_PERIODS } from '../../constants'; + +export const ALLOWED_SCHEDULE_PERIODS = [ + SCHEDULE_PERIODS.none, + SCHEDULE_PERIODS.hours, + SCHEDULE_PERIODS.days, + SCHEDULE_PERIODS.weeks, + SCHEDULE_PERIODS.months, +]; + +export const MIN_REQUIRED_NUMBER = 1; +export const MAX_DAYS_OF_MONTHLY_SCHEDULE = 31; diff --git a/src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/utils.js b/src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/utils.js new file mode 100644 index 00000000..eec77808 --- /dev/null +++ b/src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/utils.js @@ -0,0 +1,33 @@ +import { FormattedMessage } from 'react-intl'; + +import { + validateRequiredMinNumber, + validateRequiredMaxNumber, + validateRequiredNumber, +} from '@folio/stripes-acq-components'; + +import { SCHEDULE_PERIODS } from '../../constants'; +import { + MAX_DAYS_OF_MONTHLY_SCHEDULE, + MIN_REQUIRED_NUMBER, +} from './constants'; + +export const normalizeNumber = value => { + if (!value && value !== 0) return value; + + return Number(value); +}; + +export const validatePeriod = (value) => { + return value !== SCHEDULE_PERIODS.none + ? undefined + : ; +}; + +export const validateRequiredMinAndMaxNumber = (value) => { + return ( + validateRequiredNumber(value) + || validateRequiredMinNumber({ minNumber: MIN_REQUIRED_NUMBER, value }) + || validateRequiredMaxNumber({ maxNumber: MAX_DAYS_OF_MONTHLY_SCHEDULE, value }) + ); +}; diff --git a/src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/utils.test.js b/src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/utils.test.js new file mode 100644 index 00000000..08d907fe --- /dev/null +++ b/src/OrganizationIntegration/OrganizationIntegrationForm/SchedulingForm/utils.test.js @@ -0,0 +1,49 @@ +import { SCHEDULE_PERIODS } from '../../constants'; +import { + validateRequiredMinAndMaxNumber, + normalizeNumber, + validatePeriod, +} from './utils'; + +jest.mock('@folio/stripes-acq-components', () => ({ + ...jest.requireActual('@folio/stripes-acq-components'), + validateRequiredMinNumber: jest.fn(({ minNumber, value }) => (minNumber <= value ? undefined : 'min error')), + validateRequiredMaxNumber: jest.fn(({ maxNumber, value }) => (maxNumber >= value ? undefined : 'max error')), +})); + +describe('OrganizationIntegrationForm utils', () => { + describe('normalizeNumber', () => { + it('should return number', () => { + expect(normalizeNumber(0)).toBe(0); + }); + + it('should return number', () => { + expect(normalizeNumber('0')).toBe(0); + }); + + it('should return undefined', () => { + expect(normalizeNumber('')).toBe(''); + }); + }); + + describe('validatePeriod', () => { + it('should return undefined', () => { + expect(validatePeriod(SCHEDULE_PERIODS.monthly)).toBe(undefined); + }); + + it('should return error message', () => { + expect(validatePeriod(SCHEDULE_PERIODS.none)).toBeDefined(); + }); + }); + + describe('validateRequiredMinAndMaxNumber', () => { + it('should return undefined', () => { + expect(validateRequiredMinAndMaxNumber(0)).toBeTruthy(); + expect(validateRequiredMinAndMaxNumber('')).toBeTruthy(); + expect(validateRequiredMinAndMaxNumber(-1)).toBeTruthy(); + expect(validateRequiredMinAndMaxNumber(1)).toBe(undefined); + expect(validateRequiredMinAndMaxNumber(2)).toBe(undefined); + expect(validateRequiredMinAndMaxNumber(34)).toBeTruthy(); + }); + }); +}); From 95986e2ae52edffaeb4be4a65084181dab716361 Mon Sep 17 00:00:00 2001 From: Mikita Siadykh Date: Tue, 23 Jan 2024 11:34:33 +0400 Subject: [PATCH 3/3] UIORGS-417 update snapshots --- .../OrganizationIntegrationForm.test.js.snap | 6 ++--- .../OrganizationIntegrationView.test.js.snap | 6 ++--- .../OrganizationForm.test.js.snap | 24 +++++++++---------- .../__snapshots__/EditContact.test.js.snap | 8 +++---- .../__snapshots__/ViewContact.test.js.snap | 8 +++---- 5 files changed, 26 insertions(+), 26 deletions(-) diff --git a/src/OrganizationIntegration/OrganizationIntegrationForm/__snapshots__/OrganizationIntegrationForm.test.js.snap b/src/OrganizationIntegration/OrganizationIntegrationForm/__snapshots__/OrganizationIntegrationForm.test.js.snap index 64ea4cca..a0fe261f 100644 --- a/src/OrganizationIntegration/OrganizationIntegrationForm/__snapshots__/OrganizationIntegrationForm.test.js.snap +++ b/src/OrganizationIntegration/OrganizationIntegrationForm/__snapshots__/OrganizationIntegrationForm.test.js.snap @@ -147,7 +147,7 @@ exports[`OrganizationIntegrationForm should render correct form structure 1`] =