diff --git a/src/packages/components/advanced-search/home.tsx b/src/packages/components/advanced-search/home.tsx index a3f942794..c4d68616d 100644 --- a/src/packages/components/advanced-search/home.tsx +++ b/src/packages/components/advanced-search/home.tsx @@ -5,9 +5,9 @@ import { NumberResults } from '../number-results'; type AdvancedSearchListTypes = { title: string; - data: any; - initializeState?: any; - redirect?: any; + data: unknown[]; + initializeState?: unknown; + redirect?: JSX.Element; }; export const AdvancedSearchList = ({ title, diff --git a/src/packages/model/Dataset.ts b/src/packages/model/Dataset.ts index a3999eb17..6792115aa 100644 --- a/src/packages/model/Dataset.ts +++ b/src/packages/model/Dataset.ts @@ -37,7 +37,7 @@ export type Dataset = { export type CatalogRecord = { created: string; updated: string; - contributor: string; + contributor: string | string[]; creator: string; catalogRecord: CatalogRecord; validationState: ValidationState; diff --git a/src/packages/modules-datasets/datasets/view/menu.spec.jsx b/src/packages/modules-datasets/datasets/view/menu.spec.jsx index 44ee3b1c8..dd3ebffff 100644 --- a/src/packages/modules-datasets/datasets/view/menu.spec.jsx +++ b/src/packages/modules-datasets/datasets/view/menu.spec.jsx @@ -53,7 +53,7 @@ describe('Dataset View Menu', () => { it('an Gestionnaire_jeu_donnees_RMESGNCS can goBack, publish and update a dataset if the stamp is correct and validationState is unpublished', () => { const dataset = { validationState: 'Published', - catalogRecord: { contributor: 'INSEE' }, + catalogRecord: { contributor: ['INSEE'] }, }; render( @@ -70,7 +70,7 @@ describe('Dataset View Menu', () => { it('an Gestionnaire_jeu_donnees_RMESGNCS can only goBack if the stamp not is correct', () => { const dataset = { validationState: 'Published', - catalogRecord: { contributor: 'XXXXXX' }, + catalogRecord: { contributor: ['XXXXXX'] }, }; render( diff --git a/src/packages/modules-datasets/datasets/view/menu.tsx b/src/packages/modules-datasets/datasets/view/menu.tsx index d887d9dda..870c094a1 100644 --- a/src/packages/modules-datasets/datasets/view/menu.tsx +++ b/src/packages/modules-datasets/datasets/view/menu.tsx @@ -1,4 +1,4 @@ -import { ADMIN, DATASET_CONTRIBUTOR } from '../../../auth/roles'; +import { ADMIN } from '../../../auth/roles'; import { ValidationButton } from '../../../components'; import { ActionToolbar } from '../../../components/action-toolbar'; import { @@ -10,6 +10,7 @@ import { Dataset } from '../../../model/Dataset'; import { UNPUBLISHED } from '../../../model/ValidationState'; import { usePermission } from '../../../redux/hooks/usePermission'; import { useGoBack } from '../../../utils/hooks/useGoBack'; +import { checkIfContributorContainsUserStamp } from '../../utils/check-stamp-with-contributor'; type ViewMenuTypes = { dataset: Dataset; @@ -25,9 +26,11 @@ export const ViewMenu = ({ const permission = usePermission(); - const hasDatasetRightsBasedOnStamp = - permission?.stamp === dataset?.catalogRecord?.contributor && - permission?.roles?.includes(DATASET_CONTRIBUTOR); + const hasDatasetRightsBasedOnStamp = checkIfContributorContainsUserStamp( + dataset, + permission, + ); + const isAdmin = permission?.roles?.includes(ADMIN); return ( diff --git a/src/packages/modules-datasets/distributions/view/menu.spec.tsx b/src/packages/modules-datasets/distributions/view/menu.spec.tsx index 03fd03b66..5c42fbdf1 100644 --- a/src/packages/modules-datasets/distributions/view/menu.spec.tsx +++ b/src/packages/modules-datasets/distributions/view/menu.spec.tsx @@ -50,8 +50,8 @@ describe('Distribution View Menu', () => { it('an Gestionnaire_jeu_donnees_RMESGNCS can goBack, publish, delete and update a distribution if the stamp is correct and validationState is unpublished', () => { const dataset = { validationState: UNPUBLISHED, - catalogRecord: { contributor: 'INSEE' }, - } as Dataset; + catalogRecord: { contributor: ['INSEE'] }, + } as unknown as Dataset; const distribution = {} as Distribution; render( @@ -74,7 +74,7 @@ describe('Distribution View Menu', () => { it('an Gestionnaire_jeu_donnees_RMESGNCS can goBack, publish and update a distribution if the stamp is correct and validationState is published', () => { const dataset = { validationState: 'Published', - catalogRecord: { contributor: 'INSEE' }, + catalogRecord: { contributor: ['INSEE'] }, } as unknown as Dataset; const distribution = {} as Distribution; @@ -98,7 +98,7 @@ describe('Distribution View Menu', () => { it('an Gestionnaire_jeu_donnees_RMESGNCS can only goBack if the stamp not is correct', () => { const dataset = { validationState: 'Published', - catalogRecord: { contributor: 'XXXXXX' }, + catalogRecord: { contributor: ['XXXXXX'] }, } as unknown as Dataset; const distribution = {} as Distribution; diff --git a/src/packages/modules-datasets/distributions/view/menu.tsx b/src/packages/modules-datasets/distributions/view/menu.tsx index f65a1cd72..55e824221 100644 --- a/src/packages/modules-datasets/distributions/view/menu.tsx +++ b/src/packages/modules-datasets/distributions/view/menu.tsx @@ -1,4 +1,4 @@ -import { ADMIN, DATASET_CONTRIBUTOR } from '../../../auth/roles'; +import { ADMIN } from '../../../auth/roles'; import { ValidationButton } from '../../../components'; import { ActionToolbar } from '../../../components/action-toolbar'; import { @@ -10,6 +10,7 @@ import { Dataset, Distribution } from '../../../model/Dataset'; import { UNPUBLISHED } from '../../../model/ValidationState'; import { usePermission } from '../../../redux/hooks/usePermission'; import { useGoBack } from '../../../utils/hooks/useGoBack'; +import { checkIfContributorContainsUserStamp } from '../../utils/check-stamp-with-contributor'; type ViewMenuTypes = { distribution: Distribution; @@ -28,9 +29,11 @@ export const ViewMenu = ({ const permission = usePermission(); - const hasDatasetRightsBasedOnStamp = - permission?.stamp === dataset?.catalogRecord?.contributor && - permission?.roles?.includes(DATASET_CONTRIBUTOR); + const hasDatasetRightsBasedOnStamp = checkIfContributorContainsUserStamp( + dataset, + permission, + ); + const isAdmin = permission?.roles?.includes(ADMIN); return ( diff --git a/src/packages/modules-datasets/utils/check-stamp-with-contributor.spec.ts b/src/packages/modules-datasets/utils/check-stamp-with-contributor.spec.ts new file mode 100644 index 000000000..a518933b1 --- /dev/null +++ b/src/packages/modules-datasets/utils/check-stamp-with-contributor.spec.ts @@ -0,0 +1,76 @@ +import { describe, it, expect } from 'vitest'; +import { checkIfContributorContainsUserStamp } from './check-stamp-with-contributor'; +import { DATASET_CONTRIBUTOR } from '../../auth/roles'; +import { Dataset } from '../../model/Dataset'; +import { Permission } from '../../redux/selectors'; + +describe('checkIfContributorContainsUserStamp', () => { + it('should return true if the user stamp is in contributors and the role is correct', () => { + const dataset: Dataset = { + catalogRecord: { + contributor: ['userStamp1', 'userStamp2'], + }, + } as Dataset; + const permission: Permission = { + stamp: 'userStamp1', + roles: [DATASET_CONTRIBUTOR], + } as Permission; + + expect(checkIfContributorContainsUserStamp(dataset, permission)).toBe(true); + }); + + it('should return false if the user stamp is not in contributors', () => { + const dataset: Dataset = { + catalogRecord: { + contributor: ['userStamp2', 'userStamp3'], + }, + } as Dataset; + const permission: Permission = { + stamp: 'userStamp1', + roles: [DATASET_CONTRIBUTOR], + } as Permission; + + expect(checkIfContributorContainsUserStamp(dataset, permission)).toBe( + false, + ); + }); + + it('should return false if the user role does not include DATASET_CONTRIBUTOR', () => { + const dataset: Dataset = { + catalogRecord: { + contributor: ['userStamp1', 'userStamp2'], + }, + } as Dataset; + const permission: Permission = { + stamp: 'userStamp1', + roles: ['ANOTHER_ROLE'], + } as Permission; + + expect(checkIfContributorContainsUserStamp(dataset, permission)).toBe( + false, + ); + }); + + it('should correctly handle a single non-array contributor', () => { + const dataset: Dataset = { + catalogRecord: { + contributor: 'userStamp1', + }, + } as Dataset; + const permission: Permission = { + stamp: 'userStamp1', + roles: [DATASET_CONTRIBUTOR], + } as Permission; + + expect(checkIfContributorContainsUserStamp(dataset, permission)).toBe(true); + }); + + it('should return false if the dataset or permission is undefined', () => { + expect( + checkIfContributorContainsUserStamp( + undefined as unknown as Dataset, + undefined as unknown as Permission, + ), + ).toBe(false); + }); +}); diff --git a/src/packages/modules-datasets/utils/check-stamp-with-contributor.ts b/src/packages/modules-datasets/utils/check-stamp-with-contributor.ts new file mode 100644 index 000000000..010fd45f3 --- /dev/null +++ b/src/packages/modules-datasets/utils/check-stamp-with-contributor.ts @@ -0,0 +1,17 @@ +import { DATASET_CONTRIBUTOR } from '../../auth/roles'; +import { Dataset } from '../../model/Dataset'; +import { Permission } from '../../redux/selectors'; + +export const checkIfContributorContainsUserStamp = ( + dataset: Dataset, + permission: Permission, +) => { + const contributors = Array.isArray(dataset?.catalogRecord?.contributor) + ? dataset?.catalogRecord?.contributor + : [dataset?.catalogRecord?.contributor]; + + return !!( + contributors.find((c) => c === permission?.stamp) && + permission?.roles?.includes(DATASET_CONTRIBUTOR) + ); +}; diff --git a/src/packages/redux/selectors.ts b/src/packages/redux/selectors.ts index 658bc5ff7..a26760d7b 100644 --- a/src/packages/redux/selectors.ts +++ b/src/packages/redux/selectors.ts @@ -1,5 +1,10 @@ import { ReduxModel } from './model'; +export type Permission = { + authType: string; + roles: string[]; + stamp: string; +} export const getPermission = (state: ReduxModel) => { const { type: authType,