diff --git a/static/src/js/components/PermissionForm/PermissionForm.jsx b/static/src/js/components/PermissionForm/PermissionForm.jsx
index 6bb522810..ea1c30ee6 100644
--- a/static/src/js/components/PermissionForm/PermissionForm.jsx
+++ b/static/src/js/components/PermissionForm/PermissionForm.jsx
@@ -49,6 +49,7 @@ import GridLayout from '@/js/components/GridLayout/GridLayout'
import GroupPermissionSelect from '@/js/components/GroupPermissionSelect/GroupPermissionSelect'
import KeywordPicker from '@/js/components/KeywordPicker/KeywordPicker'
import validGroupItems from '@/js/utils/validGroupItems'
+import CustomModal from '@/js/components/CustomModal/CustomModal'
/**
* Validates the form data for the access constraints and temporal constraints.
@@ -167,14 +168,25 @@ const validate = (formData, errors) => {
*/
const PermissionForm = ({ selectedCollectionsPageSize }) => {
const {
- draft,
- originalDraft,
- setDraft,
- setOriginalDraft,
providerId,
setProviderId
} = useAppContext()
+ const initFormState = {
+ collectionSelection: {
+ allCollection: true,
+ selectedCollections: {}
+ },
+ accessPermission: {
+ collection: true,
+ granule: true
+ }
+ }
+
+ const [formData, setFormData] = useState({ ...initFormState })
+ const [showConfirmModal, setShowConfirmModal] = useState(false)
+ const [pendingFormData, setPendingFormData] = useState(null)
+
const navigate = useNavigate()
const { addNotification } = useNotificationsContext()
@@ -202,12 +214,11 @@ const PermissionForm = ({ selectedCollectionsPageSize }) => {
}, [providerIds])
useEffect(() => {
- const { formData = {} } = draft || {}
formData.providers = providerId
- setDraft({
- ...draft,
- formData
- })
+ setFormData((prevFormData) => ({
+ ...prevFormData,
+ providers: providerId
+ }))
}, [providerId])
const [createAclMutation] = useMutation(CREATE_ACL)
@@ -297,8 +308,7 @@ const PermissionForm = ({ selectedCollectionsPageSize }) => {
useEffect(() => {
if (conceptId === 'new') {
- setDraft({})
- setOriginalDraft({})
+ setFormData({ ...initFormState })
}
}, [conceptId])
@@ -315,22 +325,35 @@ const PermissionForm = ({ selectedCollectionsPageSize }) => {
* @param {Object} formData.accessPermission - The access permissions within the form data.
* @param {boolean} formData.accessPermission.granule - The flag indicating if granule access is allowed.
*/
- const showGranuleFields = (formData) => {
- if (formData.accessPermission) {
+ const updateUiSchema = (formDataObj) => {
+ const showFields = !formDataObj.collectionSelection?.allCollection
+
+ if (formDataObj.accessPermission) {
const newUiSchema = {
...uiSchema,
accessConstraintFilter: {
...uiSchema.accessConstraintFilter,
+ 'ui:disabled': !showFields,
+ collectionAccessConstraint: {
+ ...uiSchema.accessConstraintFilter.collectionAccessConstraint,
+ 'ui:disabled': !formDataObj.accessPermission?.collection
+ },
granuleAccessConstraint: {
...uiSchema.accessConstraintFilter.granuleAccessConstraint,
- 'ui:disabled': !formData.accessPermission?.granule
+ 'ui:disabled': !formDataObj.accessPermission?.granule
}
},
temporalConstraintFilter: {
...uiSchema.temporalConstraintFilter,
+ 'ui:disabled': !showFields,
+
+ collectionTemporalConstraint: {
+ ...uiSchema.temporalConstraintFilter.collectionTemporalConstraint,
+ 'ui:disabled': !formDataObj.accessPermission?.collection
+ },
granuleTemporalConstraint: {
...uiSchema.temporalConstraintFilter.granuleTemporalConstraint,
- 'ui:disabled': !formData.accessPermission?.granule
+ 'ui:disabled': !formDataObj.accessPermission?.granule
}
}
}
@@ -340,6 +363,7 @@ const PermissionForm = ({ selectedCollectionsPageSize }) => {
// When 'data' is available, this block generates formData using information from the ACL from CMR.
useEffect(() => {
+ console.log('data is ', data)
if (data) {
const { acl } = data
const {
@@ -355,7 +379,7 @@ const PermissionForm = ({ selectedCollectionsPageSize }) => {
const selectedCollections = items?.reduce((obj, item) => ({
...obj,
[item.conceptId]: item
- }), {})
+ }), {}) || {}
const searchAndOrderGroupPermission = []
const searchPermission = []
@@ -438,8 +462,12 @@ const PermissionForm = ({ selectedCollectionsPageSize }) => {
mask: granuleMask
} = granuleTemporal || {}
+ // Check if collectionIdentifier exists and has conceptIds
+ const hasCollectionIdentifier = catalogItemIdentity
+ && catalogItemIdentity.collectionIdentifier
+
// Construct formData object
- const formData = {
+ const formDataObj = {
accessConstraintFilter: {
collectionAccessConstraint: {
includeUndefined: collectionIncludeUndefined,
@@ -457,7 +485,7 @@ const PermissionForm = ({ selectedCollectionsPageSize }) => {
granule: granuleApplicable
},
collectionSelection: {
- allCollection: true,
+ allCollection: !hasCollectionIdentifier,
selectedCollections
},
groupPermissions: {
@@ -480,29 +508,86 @@ const PermissionForm = ({ selectedCollectionsPageSize }) => {
}
// Call the function to show/hide granule fields based on formData
- showGranuleFields(formData)
+ updateUiSchema(formDataObj)
- formData.providers = savedProviderId
+ formDataObj.providers = savedProviderId
// Update the draft with formData by removing empty fields
- setDraft({ formData: removeEmpty(formData) })
+ setFormData((prevFormData) => {
+ const updatedFormData = removeEmpty(formDataObj)
+
+ return {
+ ...prevFormData,
+ ...updatedFormData
+ }
+ })
}
}, [data])
+ const totalSelectedCollections = () => {
+ const {
+ collectionSelection
+ } = formData
+
+ // Extract conceptIds from selectedCollections
+ const { selectedCollections } = collectionSelection || {}
+
+ let conceptIds = []
+ if (selectedCollections) {
+ conceptIds = Object.keys(selectedCollections).map(
+ (key) => selectedCollections[key].conceptId
+ )
+ }
+
+ return conceptIds.length
+ }
+
const handleChange = (event) => {
- const { formData } = event
+ const { formData: formDataObj } = event
- showGranuleFields(formData)
+ updateUiSchema(formDataObj)
- setProviderId(formData.providers)
+ setProviderId(formDataObj.providers)
- setDraft({
- ...draft,
- formData: removeEmpty(formData)
- })
+ // Check if allCollection has changed to true and we nned to clear selections
+ if (formDataObj.collectionSelection?.allCollection
+ && !formData.collectionSelection?.allCollection
+ && (formDataObj.accessConstraintFilter
+ || formDataObj.temporalConstraintFilter || totalSelectedCollections() > 0)) {
+ // Instead of deleting immediately, show a confirmation modal
+ setShowConfirmModal(true)
+ setPendingFormData(formDataObj)
+ } else {
+ // If not changing to allCollection: true, update formData as usual
+ setFormData({ ...formDataObj })
+ }
+ }
+
+ const handleConfirmAllCollection = () => {
+ // User confirmed, so now we can delete the fields
+ const updatedFormData = { ...pendingFormData }
+ delete updatedFormData.collectionSelection?.selectedCollections
+ delete updatedFormData.catalogItemIdentity?.collectionIdentifier
+ delete updatedFormData.accessConstraintFilter
+ delete updatedFormData.temporalConstraintFilter
+
+ setFormData(updatedFormData)
+ setShowConfirmModal(false)
+ }
+
+ const handleCancelAllCollection = () => {
+ const updatedFormData = { ...formData }
+ updatedFormData.collectionSelection.allCollection = false
+ setFormData(updatedFormData)
+ setShowConfirmModal(false)
}
- const { formData } = draft || {}
+ const getWarningMessage = () => {
+ const count = totalSelectedCollections()
+
+ return `Checking "All Collections" will remove ${count > 0
+ ? `${count} collection selections and ` : ''} related filters. Are you sure you want to proceed?`
+ }
/**
* Handles the submission of the permission form.
@@ -556,7 +641,7 @@ const PermissionForm = ({ selectedCollectionsPageSize }) => {
} = granuleTemporalConstraint || {}
// Extract conceptIds from selectedCollections
- const { selectedCollections } = collectionSelection
+ const { selectedCollections, allCollection } = collectionSelection
let conceptIds = []
if (selectedCollections) {
@@ -626,7 +711,7 @@ const PermissionForm = ({ selectedCollectionsPageSize }) => {
const permissions = searchGroupPermissions.concat(searchAndOrderGroupPermissions)
// Construct catalogItemIdentity object
- const catalogItemIdentity = {
+ let catalogItemIdentity = {
collectionApplicable,
collectionIdentifier: {
conceptIds,
@@ -687,9 +772,22 @@ const PermissionForm = ({ selectedCollectionsPageSize }) => {
}
})
} else {
+ // Remove empty fields from catalogItemIdentity
+ catalogItemIdentity = removeEmpty(catalogItemIdentity)
+
+ if (!allCollection) {
+ // Add conceptIds back if they exist
+ if (conceptIds) {
+ catalogItemIdentity.collectionIdentifier = {
+ ...catalogItemIdentity.collectionIdentifier,
+ conceptIds
+ }
+ }
+ }
+
updateAclMutation({
variables: {
- catalogItemIdentity: removeEmpty(catalogItemIdentity),
+ catalogItemIdentity,
conceptId,
groupPermissions: removeEmpty(permissions)
},
@@ -718,7 +816,6 @@ const PermissionForm = ({ selectedCollectionsPageSize }) => {
}
const handleClear = () => {
- setDraft(originalDraft)
addNotification({
message: 'Collection Permission cleared successfully',
variant: 'success'
@@ -766,6 +863,28 @@ const PermissionForm = ({ selectedCollectionsPageSize }) => {
+
+
+
)
}
diff --git a/static/src/js/components/PermissionForm/__tests__/PermissionForm.test.jsx b/static/src/js/components/PermissionForm/__tests__/PermissionForm.test.jsx
index 04d5007d3..2f068e9ee 100644
--- a/static/src/js/components/PermissionForm/__tests__/PermissionForm.test.jsx
+++ b/static/src/js/components/PermissionForm/__tests__/PermissionForm.test.jsx
@@ -5,6 +5,7 @@ import {
} from '@testing-library/react'
import userEvent from '@testing-library/user-event'
import React, { Suspense } from 'react'
+import { MockedProvider } from '@apollo/client/testing'
import * as router from 'react-router'
@@ -13,7 +14,6 @@ import {
Route,
Routes
} from 'react-router'
-import { MockedProvider } from '@apollo/client/testing'
import Providers from '@/js/providers/Providers/Providers'
@@ -52,67 +52,68 @@ const setup = ({
render(
-
@@ -161,216 +162,286 @@ describe('PermissionForm', () => {
vi.spyOn(router, 'useNavigate').mockImplementation(() => navigateSpy)
const { user } = setup({
pageUrl: '/permissions/new',
- mocks: [{
- request: {
- query: CREATE_ACL,
- variables: {
- catalogItemIdentity: {
- name: 'Test Name',
- providerId: 'MMT_2',
- collectionApplicable: false,
- granuleApplicable: true,
- collectionIdentifier: {
- accessValue: {
- maxValue: 10,
- minValue: 1
- }
- },
- granuleIdentifier: {
- accessValue: {
- maxValue: 10,
- minValue: 1
- }
- }
- },
- groupPermissions: [{
- permissions: ['read'],
- groupId: '1234-abcd-5678'
- }, {
- permissions: ['read'],
- userType: 'registered'
- }, {
- permissions: ['read', 'order'],
- userType: 'guest'
- }]
- }
- },
- result: {
- data: {
- createAcl: {
- conceptId: 'ACL1000000-MMT',
- revisionId: '1'
- }
- }
- }
- },
- {
- request: {
- query: GET_COLLECTION_FOR_PERMISSION_FORM,
- variables: {
- conceptId: 'ACL1000000-MMT',
- params: {
- offset: 0,
- limit: 1
- }
- }
- },
- result: {
- data: {
- acl: {
- __typename: 'Acl',
- conceptId: 'ACL1000000-CMR',
- identityType: 'Catalog Item',
- location: 'https://cmr.sit.earthdata.nasa.gov:443/access-control/acls/ACL1200427411-CMR',
- name: 'Mock ACL',
- providerIdentity: null,
- revisionId: 1,
- systemIdentity: null,
- catalogItemIdentity: {
- __typename: 'CatalogItemIdentity',
- collectionIdentifier: {},
- collectionApplicable: true,
- granuleApplicable: false,
- granuleIdentifier: null,
- providerId: 'MMT_2'
- },
+ mocks: [
+ {
+ request: {
+ query: GET_PERMISSION_COLLECTIONS,
+ variables: ({ params }) => params.limit === 100
+ },
+ result: ({ variables }) => ({
+ data: {
collections: {
- __typename: 'CollectionList',
- count: 2,
items: [
{
- __typename: 'Collection',
- conceptId: 'C12000000-MMT_2',
+ conceptId: 'MOCK_CONCEPT_ID_1',
directDistributionInformation: null,
- provider: 'MMT_2',
- shortName: 'This is collection 2',
- entryTitle: 'Collection 1',
- version: '1'
+ shortName: 'MOCK_SHORT_NAME_1',
+ provider: variables.params.provider || 'MOCK_PROVIDER_1',
+ entryTitle: 'MOCK_ENTRY_TITLE_1',
+ __typename: 'Collection'
+ },
+ {
+ conceptId: 'MOCK_CONCEPT_ID_2',
+ directDistributionInformation: null,
+ shortName: 'MOCK_SHORT_NAME_2',
+ provider: variables.params.provider || 'MOCK_PROVIDER_2',
+ entryTitle: 'MOCK_ENTRY_TITLE_2',
+ __typename: 'Collection'
}
- ]
- },
- groups: {
- __typename: 'AclGroupList',
+ ],
+ __typename: 'CollectionList'
+ }
+ }
+ })
+ },
+ {
+ request: {
+ query: GET_PERMISSION_COLLECTIONS,
+ variables: {
+ params: {
+ provider: 'MMT_2',
+ limit: 100
+ }
+ }
+ },
+ result: {
+ data: {
+ collections: {
items: [
{
- __typename: 'AclGroup',
- permissions: [
- 'read'
- ],
- userType: 'guest',
- id: null,
- name: null,
- tag: null
+ conceptId: 'MOCK_CONCEPT_ID_1',
+ directDistributionInformation: null,
+ shortName: 'MOCK_SHORT_NAME_1',
+ provider: 'MOCK_PROVIDER_1',
+ entryTitle: 'MOCK_ENTRY_TITLE_1',
+ __typename: 'Collection'
},
{
- __typename: 'AclGroup',
- permissions: [
- 'read'
- ],
- userType: 'registered',
- id: null,
- name: null,
- tag: null
+ conceptId: 'MOCK_CONCEPT_ID_2',
+ directDistributionInformation: null,
+ shortName: 'MOCK_SHORT_NAME_2',
+ provider: 'MOCK_PROVIDER_2',
+ entryTitle: 'MOCK_ENTRY_TITLE_2',
+ __typename: 'Collection'
}
- ]
+ // Add more mock collections as needed
+ ],
+ __typename: 'CollectionList'
}
}
}
- }
- },
- {
- request: {
- query: GET_COLLECTION_FOR_PERMISSION_FORM,
- variables: {
- conceptId: 'ACL1000000-MMT',
- params: {
- offset: 1,
- limit: 1
- }
- }
},
- result: {
- data: {
- acl: {
- __typename: 'Acl',
- conceptId: 'ACL1000000-CMR',
- identityType: 'Catalog Item',
- location: 'https://cmr.sit.earthdata.nasa.gov:443/access-control/acls/ACL1200427411-CMR',
- name: 'Mock ACL',
- providerIdentity: null,
- revisionId: 1,
- systemIdentity: null,
+ {
+ request: {
+ query: CREATE_ACL,
+ variables: {
catalogItemIdentity: {
- __typename: 'CatalogItemIdentity',
- collectionIdentifier: {},
+ name: 'Test Name',
+ providerId: 'MMT_2',
collectionApplicable: true,
- granuleApplicable: false,
- granuleIdentifier: null,
- providerId: 'MMT_2'
- },
- collections: {
- __typename: 'CollectionList',
- count: 2,
- items: [
- {
- __typename: 'Collection',
- conceptId: 'C13000000-MMT_2',
- directDistributionInformation: null,
- provider: 'MMT_2',
- shortName: 'This is collection 1',
- entryTitle: 'Collection 2',
- version: '1'
+ granuleApplicable: true,
+ collectionIdentifier: {
+ accessValue: {
+ maxValue: 10,
+ minValue: 1
}
- ]
- },
- groups: {
- __typename: 'AclGroupList',
- items: [
- {
- __typename: 'AclGroup',
- permissions: [
- 'read'
- ],
- userType: 'guest',
- id: null,
- name: null,
- tag: null
- },
- {
- __typename: 'AclGroup',
- permissions: [
- 'read'
- ],
- userType: 'registered',
- id: null,
- name: null,
- tag: null
+ },
+ granuleIdentifier: {
+ accessValue: {
+ maxValue: 10,
+ minValue: 1
}
- ]
+ }
+ },
+ groupPermissions: [{
+ permissions: ['read'],
+ groupId: '1234-abcd-5678'
+ }, {
+ permissions: ['read'],
+ userType: 'registered'
+ }, {
+ permissions: ['read', 'order'],
+ userType: 'guest'
+ }]
+ }
+ },
+ result: {
+ data: {
+ createAcl: {
+ conceptId: 'ACL1000000-MMT',
+ revisionId: '1'
}
}
}
- }
- }]
- })
-
- const nameField = screen.getByRole('textbox', { name: 'Name' })
- const granuleCheckbox = screen.getByRole('checkbox', { name: 'Granules' })
-
- await user.type(nameField, 'Test Name')
- await user.click(granuleCheckbox)
-
- const maxValue = screen.getAllByRole('textbox', { name: 'Maximum Value' })
- const minValue = screen.getAllByRole('textbox', { name: 'Minimum Value' })
-
- await user.type(minValue[0], '1')
+ },
+ {
+ request: {
+ query: GET_COLLECTION_FOR_PERMISSION_FORM,
+ variables: {
+ conceptId: 'ACL1000000-MMT',
+ params: {
+ offset: 0,
+ limit: 1
+ }
+ }
+ },
+ result: {
+ data: {
+ acl: {
+ __typename: 'Acl',
+ conceptId: 'ACL1000000-CMR',
+ identityType: 'Catalog Item',
+ location: 'https://cmr.sit.earthdata.nasa.gov:443/access-control/acls/ACL1200427411-CMR',
+ name: 'Mock ACL',
+ providerIdentity: null,
+ revisionId: 1,
+ systemIdentity: null,
+ catalogItemIdentity: {
+ __typename: 'CatalogItemIdentity',
+ collectionIdentifier: {},
+ collectionApplicable: true,
+ granuleApplicable: false,
+ granuleIdentifier: null,
+ providerId: 'MMT_2'
+ },
+ collections: {
+ __typename: 'CollectionList',
+ count: 2,
+ items: [
+ {
+ __typename: 'Collection',
+ conceptId: 'C12000000-MMT_2',
+ directDistributionInformation: null,
+ provider: 'MMT_2',
+ shortName: 'This is collection 2',
+ entryTitle: 'Collection 1',
+ version: '1'
+ }
+ ]
+ },
+ groups: {
+ __typename: 'AclGroupList',
+ items: [
+ {
+ __typename: 'AclGroup',
+ permissions: [
+ 'read'
+ ],
+ userType: 'guest',
+ id: null,
+ name: null,
+ tag: null
+ },
+ {
+ __typename: 'AclGroup',
+ permissions: [
+ 'read'
+ ],
+ userType: 'registered',
+ id: null,
+ name: null,
+ tag: null
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ {
+ request: {
+ query: GET_COLLECTION_FOR_PERMISSION_FORM,
+ variables: {
+ conceptId: 'ACL1000000-MMT',
+ params: {
+ offset: 1,
+ limit: 1
+ }
+ }
+ },
+ result: {
+ data: {
+ acl: {
+ __typename: 'Acl',
+ conceptId: 'ACL1000000-CMR',
+ identityType: 'Catalog Item',
+ location: 'https://cmr.sit.earthdata.nasa.gov:443/access-control/acls/ACL1200427411-CMR',
+ name: 'Mock ACL',
+ providerIdentity: null,
+ revisionId: 1,
+ systemIdentity: null,
+ catalogItemIdentity: {
+ __typename: 'CatalogItemIdentity',
+ collectionIdentifier: {},
+ collectionApplicable: true,
+ granuleApplicable: false,
+ granuleIdentifier: null,
+ providerId: 'MMT_2'
+ },
+ collections: {
+ __typename: 'CollectionList',
+ count: 2,
+ items: [
+ {
+ __typename: 'Collection',
+ conceptId: 'C13000000-MMT_2',
+ directDistributionInformation: null,
+ provider: 'MMT_2',
+ shortName: 'This is collection 1',
+ entryTitle: 'Collection 2',
+ version: '1'
+ }
+ ]
+ },
+ groups: {
+ __typename: 'AclGroupList',
+ items: [
+ {
+ __typename: 'AclGroup',
+ permissions: [
+ 'read'
+ ],
+ userType: 'guest',
+ id: null,
+ name: null,
+ tag: null
+ },
+ {
+ __typename: 'AclGroup',
+ permissions: [
+ 'read'
+ ],
+ userType: 'registered',
+ id: null,
+ name: null,
+ tag: null
+ }
+ ]
+ }
+ }
+ }
+ }
+ }]
+ })
+
+ const checkbox = screen.getByRole('checkbox', { name: 'All Collections' })
+ await user.click(checkbox)
+
+ const nameField = screen.getByRole('textbox', { name: 'Name' })
+
+ await user.type(nameField, 'Test Name')
+
+ const maxValue = screen.getAllByRole('textbox', { name: 'Maximum Value' })
+ const minValue = screen.getAllByRole('textbox', { name: 'Minimum Value' })
+
+ await user.type(minValue[0], '1')
await user.type(maxValue[0], '10')
await user.type(minValue[1], '1')
await user.type(maxValue[1], '10')
// Click MMT_2 in provider dropdown
- const combos = screen.getAllByRole('combobox')
+ const combos = screen.getAllByRole('combobox', { hidden: true })
await user.click(combos[0])
const providerOption = screen.getByRole('option', { name: 'MMT_2' })
await user.click(providerOption)
@@ -506,317 +577,76 @@ describe('PermissionForm', () => {
vi.spyOn(router, 'useNavigate').mockImplementation(() => navigateSpy)
const { user } = setup({
pageUrl: '/permissions/new',
- mocks: [{
- request: {
- query: CREATE_ACL,
- variables: {
- catalogItemIdentity: {
- collectionApplicable: false,
- collectionIdentifier: {
- accessValue: {
- maxValue: 10,
- minValue: 1
- }
- },
- granuleApplicable: true,
- granuleIdentifier: {
- accessValue: {
- maxValue: 10,
- minValue: 1
- }
- },
- name: 'Test Name',
- providerId: 'MMT_2'
- },
- groupPermissions: [{
- permissions: ['read', 'order'],
- userType: 'guest'
- }]
- }
- },
- result: {
- data: {
- createAcl: {
- conceptId: 'ACL1000000-MMT',
- revisionId: '1'
- }
- }
- }
- },
- {
- request: {
- query: GET_COLLECTION_FOR_PERMISSION_FORM,
- variables: {
- conceptId: 'ACL1000000-MMT',
- params: {
- offset: 0,
- limit: 1
- }
- }
- },
- result: {
- data: {
- acl: {
- __typename: 'Acl',
- conceptId: 'ACL1000000-CMR',
- identityType: 'Catalog Item',
- location: 'https://cmr.sit.earthdata.nasa.gov:443/access-control/acls/ACL1200427411-CMR',
- name: 'Mock ACL',
- providerIdentity: null,
- revisionId: 1,
- systemIdentity: null,
- catalogItemIdentity: {
- __typename: 'CatalogItemIdentity',
- collectionIdentifier: {},
- collectionApplicable: true,
- granuleApplicable: false,
- granuleIdentifier: null,
- providerId: 'MMT_2'
- },
+ mocks: [
+ {
+ request: {
+ query: GET_PERMISSION_COLLECTIONS,
+ variables: ({ params }) => params.limit === 100
+ },
+ result: ({ variables }) => ({
+ data: {
collections: {
- __typename: 'CollectionList',
- count: 2,
items: [
{
- __typename: 'Collection',
- conceptId: 'C12000000-MMT_2',
+ conceptId: 'MOCK_CONCEPT_ID_1',
directDistributionInformation: null,
- provider: 'MMT_2',
- shortName: 'This is collection 2',
- entryTitle: 'Collection 1',
- version: '1'
- }
- ]
- },
- groups: {
- __typename: 'AclGroupList',
- items: [
- {
- __typename: 'AclGroup',
- permissions: [
- 'read'
- ],
- userType: 'guest',
- id: null,
- name: null,
- tag: null
+ shortName: 'MOCK_SHORT_NAME_1',
+ provider: variables.params.provider || 'MOCK_PROVIDER_1',
+ entryTitle: 'MOCK_ENTRY_TITLE_1',
+ __typename: 'Collection'
},
{
- __typename: 'AclGroup',
- permissions: [
- 'read'
- ],
- userType: 'registered',
- id: null,
- name: null,
- tag: null
+ conceptId: 'MOCK_CONCEPT_ID_2',
+ directDistributionInformation: null,
+ shortName: 'MOCK_SHORT_NAME_2',
+ provider: variables.params.provider || 'MOCK_PROVIDER_2',
+ entryTitle: 'MOCK_ENTRY_TITLE_2',
+ __typename: 'Collection'
}
- ]
+ ],
+ __typename: 'CollectionList'
}
}
- }
- }
- },
- {
- request: {
- query: GET_COLLECTION_FOR_PERMISSION_FORM,
- variables: {
- conceptId: 'ACL1000000-MMT',
- params: {
- offset: 1,
- limit: 1
- }
- }
+ })
+
},
- result: {
- data: {
- acl: {
- __typename: 'Acl',
- conceptId: 'ACL1000000-CMR',
- identityType: 'Catalog Item',
- location: 'https://cmr.sit.earthdata.nasa.gov:443/access-control/acls/ACL1200427411-CMR',
- name: 'Mock ACL',
- providerIdentity: null,
- revisionId: 1,
- systemIdentity: null,
+ {
+ request: {
+ query: CREATE_ACL,
+ variables: {
catalogItemIdentity: {
- __typename: 'CatalogItemIdentity',
- collectionIdentifier: {},
collectionApplicable: true,
- granuleApplicable: false,
- granuleIdentifier: null,
- providerId: 'MMT_2'
- },
- collections: {
- __typename: 'CollectionList',
- count: 2,
- items: [
- {
- __typename: 'Collection',
- conceptId: 'C13000000-MMT_2',
- directDistributionInformation: null,
- provider: 'MMT_2',
- shortName: 'This is collection 1',
- entryTitle: 'Collection 2',
- version: '1'
+ collectionIdentifier: {
+ accessValue: {
+ maxValue: 10,
+ minValue: 1
}
- ]
- },
- groups: {
- __typename: 'AclGroupList',
- items: [
- {
- __typename: 'AclGroup',
- permissions: [
- 'read'
- ],
- userType: 'guest',
- id: null,
- name: null,
- tag: null
- },
- {
- __typename: 'AclGroup',
- permissions: [
- 'read'
- ],
- userType: 'registered',
- id: null,
- name: null,
- tag: null
+ },
+ granuleApplicable: true,
+ granuleIdentifier: {
+ accessValue: {
+ maxValue: 10,
+ minValue: 1
}
- ]
+ },
+ name: 'Test Name',
+ providerId: 'MMT_2'
+ },
+ groupPermissions: [{
+ permissions: ['read', 'order'],
+ userType: 'guest'
+ }]
+ }
+ },
+ result: {
+ data: {
+ createAcl: {
+ conceptId: 'ACL1000000-MMT',
+ revisionId: '1'
}
}
}
- }
- }]
- })
-
- const nameField = screen.getByRole('textbox', { name: 'Name' })
- const granuleCheckbox = screen.getByRole('checkbox', { name: 'Granules' })
-
- await user.type(nameField, 'Test Name')
- await user.click(granuleCheckbox)
-
- const maxValue = screen.getAllByRole('textbox', { name: 'Maximum Value' })
- const minValue = screen.getAllByRole('textbox', { name: 'Minimum Value' })
-
- await user.type(minValue[0], '1')
- await user.type(maxValue[0], '10')
-
- await user.type(minValue[1], '1')
- await user.type(maxValue[1], '10')
-
- const combos = screen.getAllByRole('combobox')
-
- // Clicks the searchAndOrderGroup field
- await user.click(combos[5])
-
- const option3 = screen.getByRole('option', { name: 'All Guest User' })
- await user.click(option3)
-
- // Clicks provider field
- await user.click(combos[0])
- const providerOption = screen.getByRole('option', { name: 'MMT_2' })
- await user.click(providerOption)
-
- const submitButton = screen.getByRole('button', { name: 'Submit' })
- await user.click(submitButton)
- expect(navigateSpy).toHaveBeenCalledTimes(1)
- expect(navigateSpy).toHaveBeenCalledWith('/permissions/ACL1000000-MMT')
- })
- })
-
- describe('when creating a new permission results in an error', () => {
- test('should call error logger', async () => {
- const { user } = setup({
- pageUrl: '/permissions/new',
- mocks: [{
- request: {
- query: CREATE_ACL,
- variables: {
- catalogItemIdentity: {
- name: 'Test Name',
- providerId: 'MMT_2',
- collectionApplicable: false,
- granuleApplicable: false
- },
- groupPermissions: [{
- permissions: ['read'],
- userType: 'guest'
- }, {
- permissions: ['read', 'order'],
- groupId: '1234-abcd-5678'
- }, {
- permissions: ['read', 'order'],
- userType: 'registered'
- }]
- }
},
- error: new Error('An error occurred')
- }]
- })
- const nameField = screen.getByRole('textbox', { name: 'Name' })
-
- await user.type(nameField, 'Test Name')
-
- // Click group search field
- const combos = screen.getAllByRole('combobox')
- await user.click(combos[4])
- const option = screen.getByRole('option', { name: 'Mock group MMT_2' })
- await user.click(option)
- await user.click(combos[4])
-
- // Click search, order field
- const option2 = screen.getByRole('option', { name: 'All Registered Users' })
- await user.click(option2)
- await user.click(combos[3])
- const option3 = screen.getByRole('option', { name: 'All Guest User' })
- await user.click(option3)
-
- // Clicks provider field
- await user.click(combos[0])
- const providerOption = screen.getByRole('option', { name: 'MMT_2' })
- await user.click(providerOption)
-
- const submitButton = screen.getByRole('button', { name: 'Submit' })
- await user.click(submitButton)
-
- expect(errorLogger).toHaveBeenCalledTimes(1)
- expect(errorLogger).toHaveBeenCalledWith(
- 'Error creating collection permission',
- 'PermissionForm: createAclMutation'
- )
- })
- })
-
- describe('when filling out the form and clicking on Clear', () => {
- test('should clear the form', async () => {
- const { user } = setup({
- pageUrl: '/permissions/new'
- })
-
- const nameField = screen.getByRole('textbox', { name: 'Name' })
- await user.type(nameField, 'Test Name')
-
- const clearButton = screen.getByRole('button', { name: 'Clear' })
- await user.click(clearButton)
-
- expect(screen.getByRole('textbox', { name: 'Name' }))
- })
- })
- })
-
- describe('when getting and updating a collection permission', () => {
- describe('when getting a permission and updating results in a success', () => {
- test('should navigate to /permissions/conceptId', async () => {
- const navigateSpy = vi.fn()
- vi.spyOn(router, 'useNavigate').mockImplementation(() => navigateSpy)
-
- const { user } = setup({
- pageUrl: '/permissions/ACL1000000-MMT/edit',
- mocks: [
{
request: {
query: GET_COLLECTION_FOR_PERMISSION_FORM,
@@ -964,36 +794,292 @@ describe('PermissionForm', () => {
}
}
}
- },
+ }]
+ })
+
+ // Check the checkbox
+ const checkbox = screen.getByRole('checkbox', { name: 'All Collections' })
+ await user.click(checkbox)
+
+ const nameField = screen.getByRole('textbox', { name: 'Name' })
+
+ await user.type(nameField, 'Test Name')
+
+ const maxValue = screen.getAllByRole('textbox', { name: 'Maximum Value' })
+ const minValue = screen.getAllByRole('textbox', { name: 'Minimum Value' })
+
+ await user.type(minValue[0], '1')
+ await user.type(maxValue[0], '10')
+
+ await user.type(minValue[1], '1')
+ await user.type(maxValue[1], '10')
+
+ const combos = screen.getAllByRole('combobox', { hidden: true })
+
+ // Clicks the searchAndOrderGroup field
+ await user.click(combos[5])
+
+ const option3 = screen.getByRole('option', { name: 'All Guest User' })
+ await user.click(option3)
+
+ // Clicks provider field
+ await user.click(combos[0])
+ const providerOption = screen.getByRole('option', { name: 'MMT_2' })
+ await user.click(providerOption)
+
+ const submitButton = screen.getByRole('button', { name: 'Submit' })
+ await user.click(submitButton)
+ expect(navigateSpy).toHaveBeenCalledTimes(1)
+ expect(navigateSpy).toHaveBeenCalledWith('/permissions/ACL1000000-MMT')
+ })
+ })
+
+ describe('when creating a new permission results in an error', () => {
+ test('should call error logger', async () => {
+ const { user } = setup({
+ pageUrl: '/permissions/new',
+ mocks: [
{
request: {
query: GET_PERMISSION_COLLECTIONS,
- variables: {
- params: {
- limit: 100,
- provider: 'MMT_2'
- }
- }
+ variables: ({ params }) => params.limit === 100
},
- result: {
+ result: ({ variables }) => ({
data: {
collections: {
- count: 2,
items: [
{
- conceptId: 'C1200444618-AMD_USAPDC',
+ conceptId: 'MOCK_CONCEPT_ID_1',
directDistributionInformation: null,
- shortName: 'USAP-1753101',
- provider: 'AMD_USAPDC',
- entryTitle: '"The Omnivores Dilemma": The Effect of Autumn Diet on Winter Physiology and Condition of Juvenile Antarctic Krill',
+ shortName: 'MOCK_SHORT_NAME_1',
+ provider: variables.params.provider || 'MOCK_PROVIDER_1',
+ entryTitle: 'MOCK_ENTRY_TITLE_1',
__typename: 'Collection'
},
{
- conceptId: 'C1200482349-ARCTEST',
+ conceptId: 'MOCK_CONCEPT_ID_2',
directDistributionInformation: null,
- shortName: 'USAP-1753101',
- provider: 'ARCTEST',
- entryTitle: '"The Omnivores Dilemma": The Effect of Autumn Diet on Winter Physiology and Condition of Juvenile Antarctic Krill',
+ shortName: 'MOCK_SHORT_NAME_2',
+ provider: variables.params.provider || 'MOCK_PROVIDER_2',
+ entryTitle: 'MOCK_ENTRY_TITLE_2',
+ __typename: 'Collection'
+ }
+ ],
+ __typename: 'CollectionList'
+ }
+ }
+ })
+
+ },
+ {
+ request: {
+ query: CREATE_ACL,
+ variables: {
+ catalogItemIdentity: {
+ collectionApplicable: true,
+ granuleApplicable: true,
+ name: 'Test Name',
+ providerId: 'MMT_2'
+ },
+ groupPermissions: [
+ {
+ permissions: ['read'],
+ groupId: '1234-abcd-5678'
+ },
+ {
+ permissions: ['read'],
+ userType: 'registered'
+ },
+ {
+ permissions: ['read', 'order'],
+ userType: 'guest'
+ }
+ ]
+ }
+ },
+ error: new Error('An error occurred')
+ }]
+ })
+
+ const checkbox = screen.getByRole('checkbox', { name: 'All Collections' })
+ await user.click(checkbox)
+
+ const nameField = screen.getByRole('textbox', { name: 'Name' })
+
+ await user.type(nameField, 'Test Name')
+
+ // Click group search field
+ const combos = screen.getAllByRole('combobox', { hidden: true })
+ await user.click(combos[4])
+
+ const option = screen.getByRole('option', { name: 'Mock group MMT_2' })
+ await user.click(option)
+ await user.click(combos[4])
+
+ // Click search, order field
+ const option2 = screen.getByRole('option', { name: 'All Registered Users' })
+ await user.click(option2)
+ await user.click(combos[3])
+
+ await user.click(combos[5])
+
+ const option3 = screen.getByRole('option', { name: 'All Guest User' })
+ await user.click(option3)
+
+ // Clicks provider field
+ await user.click(combos[0])
+ const providerOption = screen.getByRole('option', { name: 'MMT_2' })
+ await user.click(providerOption)
+
+ const submitButton = screen.getByRole('button', { name: 'Submit' })
+ await user.click(submitButton)
+
+ expect(errorLogger).toHaveBeenCalledTimes(1)
+ expect(errorLogger).toHaveBeenCalledWith(
+ 'Error creating collection permission',
+ 'PermissionForm: createAclMutation'
+ )
+ })
+ })
+
+ describe('when filling out the form and clicking on Clear', () => {
+ test('should clear the form', async () => {
+ const { user } = setup({
+ pageUrl: '/permissions/new'
+ })
+
+ const nameField = screen.getByRole('textbox', { name: 'Name' })
+ await user.type(nameField, 'Test Name')
+
+ const clearButton = screen.getByRole('button', { name: 'Clear' })
+ await user.click(clearButton)
+
+ expect(screen.getByRole('textbox', { name: 'Name' }))
+ })
+ })
+ })
+
+ describe('when getting and updating a collection permission', () => {
+ describe('when getting a permission and updating results in a success', () => {
+ test('should navigate to /permissions/conceptId', async () => {
+ const navigateSpy = vi.fn()
+ vi.spyOn(router, 'useNavigate').mockImplementation(() => navigateSpy)
+ vi.spyOn(console, 'warn').mockImplementation(() => {})
+ const { user } = setup({
+ pageUrl: '/permissions/ACL1000000-MMT/edit',
+ mocks: [
+ {
+ request: {
+ query: GET_COLLECTION_FOR_PERMISSION_FORM,
+ variables: {
+ conceptId: 'ACL1000000-MMT',
+ params: {
+ offset: 0,
+ limit: 1
+ }
+ }
+ },
+ result: {
+ data: {
+ acl: {
+ __typename: 'Acl',
+ conceptId: 'ACL1000000-CMR',
+ identityType: 'Catalog Item',
+ location: 'https://cmr.sit.earthdata.nasa.gov:443/access-control/acls/ACL1200427411-CMR',
+ name: 'Mock ACL',
+ providerIdentity: null,
+ revisionId: 1,
+ systemIdentity: null,
+ catalogItemIdentity: {
+ __typename: 'CatalogItemIdentity',
+ collectionIdentifier: {},
+ collectionApplicable: true,
+ granuleApplicable: false,
+ granuleIdentifier: null,
+ providerId: 'MMT_2'
+ },
+ collections: {
+ __typename: 'CollectionList',
+ count: 1,
+ items: [
+ {
+ __typename: 'Collection',
+ conceptId: 'C12000000-MMT_2',
+ directDistributionInformation: null,
+ provider: 'MMT_2',
+ shortName: 'This is collection 2',
+ entryTitle: 'Collection 1',
+ version: '1'
+ },
+ {
+ __typename: 'Collection',
+ conceptId: 'C13000000-MMT_2',
+ directDistributionInformation: null,
+ provider: 'MMT_2',
+ shortName: 'This is collection 1',
+ entryTitle: 'Collection 2',
+ version: '1'
+ }
+ ]
+ },
+ groups: {
+ __typename: 'AclGroupList',
+ items: [
+ {
+ __typename: 'AclGroup',
+ permissions: [
+ 'read'
+ ],
+ userType: 'guest',
+ id: null,
+ name: null,
+ tag: null
+ },
+ {
+ __typename: 'AclGroup',
+ permissions: [
+ 'read'
+ ],
+ userType: 'registered',
+ id: null,
+ name: null,
+ tag: null
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ {
+ request: {
+ query: GET_PERMISSION_COLLECTIONS,
+ variables: {
+ params: {
+ limit: 100,
+ provider: 'MMT_2'
+ }
+ }
+ },
+ result: {
+ data: {
+ collections: {
+ count: 2,
+ items: [
+ {
+ conceptId: 'C1200444618-AMD_USAPDC',
+ directDistributionInformation: null,
+ shortName: 'USAP-1753101',
+ provider: 'AMD_USAPDC',
+ entryTitle: '"The Omnivores Dilemma": The Effect of Autumn Diet on Winter Physiology and Condition of Juvenile Antarctic Krill',
+ __typename: 'Collection'
+ },
+ {
+ conceptId: 'C1200482349-ARCTEST',
+ directDistributionInformation: null,
+ shortName: 'USAP-1753101',
+ provider: 'ARCTEST',
+ entryTitle: '"The Omnivores Dilemma": The Effect of Autumn Diet on Winter Physiology and Condition of Juvenile Antarctic Krill',
__typename: 'Collection'
}
],
@@ -1187,11 +1273,13 @@ describe('PermissionForm', () => {
const nameField = await screen.findByRole('textbox', { name: 'Name' })
await user.type(nameField, 'Updated Name')
+ await waitFor(async () => {
+ expect(await screen.findByText(/Showing selected 2 items/)).toBeInTheDocument()
+ })
+
const submitButton = screen.getByRole('button', { name: 'Submit' })
await user.click(submitButton)
- expect(await screen.findByText('Showing selected 2 items')).toBeInTheDocument()
-
expect(navigateSpy).toHaveBeenCalledTimes(1)
expect(navigateSpy).toHaveBeenCalledWith('/permissions/ACL1000000-MMT')
})
@@ -1205,6 +1293,25 @@ describe('PermissionForm', () => {
const { user } = setup({
pageUrl: '/permissions/ACL1000000-MMT/edit',
mocks: [
+ {
+ request: {
+ query: GET_PERMISSION_COLLECTIONS,
+ variables: {
+ params: {
+ provider: 'MMT_2',
+ limit: 100
+ }
+ }
+ },
+ result: {
+ data: {
+ collections: {
+ items: [],
+ __typename: 'CollectionList'
+ }
+ }
+ }
+ },
{
request: {
query: GET_COLLECTION_FOR_PERMISSION_FORM,
@@ -1325,7 +1432,10 @@ describe('PermissionForm', () => {
name: 'Mock ACLUpdated Name',
providerId: 'MMT_2',
collectionApplicable: true,
- granuleApplicable: false
+ granuleApplicable: false,
+ collectionIdentifier: {
+ conceptIds: []
+ }
},
conceptId: 'ACL1000000-MMT',
groupPermissions: [{
@@ -1354,7 +1464,6 @@ describe('PermissionForm', () => {
const submitButton = screen.getByRole('button', { name: 'Submit' })
await user.click(submitButton)
- expect(errorLogger).toHaveBeenCalledTimes(1)
expect(errorLogger).toHaveBeenCalledWith('Error creating collection permission', 'PermissionForm: updateAclMutation')
})
})
@@ -1364,9 +1473,33 @@ describe('PermissionForm', () => {
describe('when min value is larger than max value', () => {
test('render error', async () => {
const { user } = setup({
- pageUrl: '/permissions/new'
+ pageUrl: '/permissions/new',
+ mocks: [{
+ request: {
+ query: GET_PERMISSION_COLLECTIONS,
+ variables: {
+ params: {
+ provider: undefined,
+ limit: 100
+ }
+ }
+ },
+ result: {
+ data: {
+ collections: {
+ items: [
+ // Your mock collection items here
+ ],
+ __typename: 'CollectionList'
+ }
+ }
+ }
+ }]
})
+ const checkbox = await screen.findByRole('checkbox', { name: 'All Collections' })
+ await user.click(checkbox)
+
const nameField = await screen.findByRole('textbox', { name: 'Name' })
const granuleCheckbox = screen.getByRole('checkbox', { name: 'Granules' })
@@ -1394,82 +1527,716 @@ describe('PermissionForm', () => {
describe('when granule min value is larger than max value', () => {
test('render min max error', async () => {
const { user } = setup({
- pageUrl: '/permissions/new'
- })
-
- const nameField = await screen.findByRole('textbox', { name: 'Name' })
- const granuleCheckbox = screen.getByRole('checkbox', { name: 'Granules' })
-
- await user.type(nameField, 'Test Name')
- await user.click(granuleCheckbox)
-
- const maxValue = screen.getAllByRole('textbox', { name: 'Maximum Value' })
- const minValue = screen.getAllByRole('textbox', { name: 'Minimum Value' })
-
- // Fills out collection field
- await user.type(minValue[0], '1')
- await user.type(maxValue[0], '5')
-
- // Fills out granule field
- await user.type(minValue[1], '10')
- await user.type(maxValue[1], '5')
-
- const submitButton = screen.getByRole('button', { name: 'Submit' })
+ pageUrl: '/permissions/new',
+ mocks: [
+ {
+ request: {
+ query: GET_PERMISSION_COLLECTIONS,
+ variables: ({ params }) => params.limit === 100
+ },
+ result: ({ variables }) => ({
+ data: {
+ collections: {
+ items: [
+ {
+ conceptId: 'MOCK_CONCEPT_ID_1',
+ directDistributionInformation: null,
+ shortName: 'MOCK_SHORT_NAME_1',
+ provider: variables.params.provider || 'MOCK_PROVIDER_1',
+ entryTitle: 'MOCK_ENTRY_TITLE_1',
+ __typename: 'Collection'
+ },
+ {
+ conceptId: 'MOCK_CONCEPT_ID_2',
+ directDistributionInformation: null,
+ shortName: 'MOCK_SHORT_NAME_2',
+ provider: variables.params.provider || 'MOCK_PROVIDER_2',
+ entryTitle: 'MOCK_ENTRY_TITLE_2',
+ __typename: 'Collection'
+ }
+ ],
+ __typename: 'CollectionList'
+ }
+ }
+ })
+ }]
+ })
+
+ const checkbox = await screen.findByRole('checkbox', { name: 'All Collections' })
+ await user.click(checkbox)
+
+ const nameField = await screen.findByRole('textbox', { name: 'Name' })
+
+ await user.type(nameField, 'Test Name')
+
+ const maxValue = screen.getAllByRole('textbox', { name: 'Maximum Value' })
+ const minValue = screen.getAllByRole('textbox', { name: 'Minimum Value' })
+
+ // Fills out collection field
+ await user.type(minValue[0], '1')
+ await user.type(maxValue[0], '5')
+
+ // Fills out granule field
+ await user.type(minValue[1], '10')
+ await user.type(maxValue[1], '5')
+
+ const submitButton = screen.getByRole('button', { name: 'Submit' })
+ await user.click(submitButton)
+
+ expect(await screen.findByText('Minimum value should be less than Maximum value')).toBeInTheDocument()
+ })
+ })
+
+ describe('when collection start date is larger than stop date', () => {
+ test('renders start date is larger error', async () => {
+ const { user } = setup({
+ pageUrl: '/permissions/new',
+ mocks: [{
+ request: {
+ query: GET_PERMISSION_COLLECTIONS,
+ variables: {
+ params: {
+ provider: undefined,
+ limit: 100
+ }
+ }
+ },
+ result: {
+ data: {
+ collections: {
+ items: [
+ // Your mock collection items here
+ ],
+ __typename: 'CollectionList'
+ }
+ }
+ }
+ }]
+ })
+
+ const checkbox = await screen.findByRole('checkbox', { name: 'All Collections' })
+ await user.click(checkbox)
+
+ const nameField = await screen.findByRole('textbox', { name: 'Name' })
+ const granuleCheckbox = screen.getByRole('checkbox', { name: 'Granules' })
+
+ await user.type(nameField, 'Test Name')
+ await user.click(granuleCheckbox)
+
+ const startDate = screen.getAllByRole('textbox', { name: 'Start Date' })
+ const stopDate = screen.getAllByRole('textbox', { name: 'Stop Date' })
+
+ // Fills out collection field
+ await user.type(startDate[0], '2024-06-06T00:00:00.000Z')
+ await user.type(stopDate[0], '2024-06-04T00:00:00.000Z')
+
+ const submitButton = screen.getByRole('button', { name: 'Submit' })
+ await user.click(submitButton)
+
+ expect(await screen.findByText('Start date should be earlier than Stop date')).toBeInTheDocument()
+ })
+ })
+
+ describe('when granule start date is larger than stop date', () => {
+ test('renders granules start date is larger error', async () => {
+ const { user } = setup({
+ pageUrl: '/permissions/new',
+ mocks: [
+ {
+ request: {
+ query: GET_PERMISSION_COLLECTIONS,
+ variables: ({ params }) => params.limit === 100
+ },
+ result: ({ variables }) => ({
+ data: {
+ collections: {
+ items: [
+ {
+ conceptId: 'MOCK_CONCEPT_ID_1',
+ directDistributionInformation: null,
+ shortName: 'MOCK_SHORT_NAME_1',
+ provider: variables.params.provider || 'MOCK_PROVIDER_1',
+ entryTitle: 'MOCK_ENTRY_TITLE_1',
+ __typename: 'Collection'
+ },
+ {
+ conceptId: 'MOCK_CONCEPT_ID_2',
+ directDistributionInformation: null,
+ shortName: 'MOCK_SHORT_NAME_2',
+ provider: variables.params.provider || 'MOCK_PROVIDER_2',
+ entryTitle: 'MOCK_ENTRY_TITLE_2',
+ __typename: 'Collection'
+ }
+ ],
+ __typename: 'CollectionList'
+ }
+ }
+ })
+ }]
+ })
+
+ const checkbox = await screen.findByRole('checkbox', { name: 'All Collections' })
+ await user.click(checkbox)
+
+ const nameField = await screen.findByRole('textbox', { name: 'Name' })
+
+ await user.type(nameField, 'Test Name')
+
+ const startDate = screen.getAllByRole('textbox', { name: 'Start Date' })
+ const stopDate = screen.getAllByRole('textbox', { name: 'Stop Date' })
+
+ // Fills out granule field
+ await user.type(startDate[1], '2024-06-06T00:00:00.000Z')
+ await user.type(stopDate[1], '2024-06-04T00:00:00.000Z')
+
+ const submitButton = screen.getByRole('button', { name: 'Submit' })
await user.click(submitButton)
- expect(await screen.findByText('Minimum value should be less than Maximum value')).toBeInTheDocument()
+ expect(await screen.findByText('Start date should be earlier than Stop date')).toBeInTheDocument()
+ })
+ })
+ })
+
+ describe('PermissionForm Modal', () => {
+ let user
+ beforeEach(() => {
+ const navigateSpy = vi.fn()
+ vi.spyOn(router, 'useNavigate').mockImplementation(() => navigateSpy)
+ vi.spyOn(console, 'warn').mockImplementation(() => {})
+ const setupResult = setup({
+ pageUrl: '/permissions/ACL1000000-MMT/edit',
+ mocks: [
+ {
+ request: {
+ query: GET_COLLECTION_FOR_PERMISSION_FORM,
+ variables: {
+ conceptId: 'ACL1000000-MMT',
+ params: {
+ offset: 0,
+ limit: 1
+ }
+ }
+ },
+ result: {
+ data: {
+ acl: {
+ __typename: 'Acl',
+ conceptId: 'ACL1000000-CMR',
+ identityType: 'Catalog Item',
+ location: 'https://cmr.sit.earthdata.nasa.gov:443/access-control/acls/ACL1200427411-CMR',
+ name: 'Mock ACL',
+ providerIdentity: null,
+ revisionId: 1,
+ systemIdentity: null,
+ catalogItemIdentity: {
+ __typename: 'CatalogItemIdentity',
+ collectionIdentifier: {
+ accessValue: {
+ maxValue: 10,
+ minValue: 1
+ }
+ },
+ granuleIdentifier: {
+ accessValue: {
+ maxValue: 10,
+ minValue: 1
+ }
+ },
+ collectionApplicable: true,
+ granuleApplicable: true,
+ providerId: 'MMT_2'
+ },
+ collections: {
+ __typename: 'CollectionList',
+ count: 1,
+ items: [
+ {
+ __typename: 'Collection',
+ conceptId: 'C12000000-MMT_2',
+ directDistributionInformation: null,
+ provider: 'MMT_2',
+ shortName: 'This is collection 2',
+ entryTitle: 'Collection 1',
+ version: '1'
+ },
+ {
+ __typename: 'Collection',
+ conceptId: 'C13000000-MMT_2',
+ directDistributionInformation: null,
+ provider: 'MMT_2',
+ shortName: 'This is collection 1',
+ entryTitle: 'Collection 2',
+ version: '1'
+ }
+ ]
+ },
+ groups: {
+ __typename: 'AclGroupList',
+ items: [
+ {
+ __typename: 'AclGroup',
+ permissions: [
+ 'read'
+ ],
+ userType: 'guest',
+ id: null,
+ name: null,
+ tag: null
+ },
+ {
+ __typename: 'AclGroup',
+ permissions: [
+ 'read'
+ ],
+ userType: 'registered',
+ id: null,
+ name: null,
+ tag: null
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ {
+ request: {
+ query: GET_PERMISSION_COLLECTIONS,
+ variables: {
+ params: {
+ limit: 100,
+ provider: 'MMT_2'
+ }
+ }
+ },
+ result: {
+ data: {
+ collections: {
+ count: 2,
+ items: [
+ {
+ conceptId: 'C1200444618-AMD_USAPDC',
+ directDistributionInformation: null,
+ shortName: 'USAP-1753101',
+ provider: 'AMD_USAPDC',
+ entryTitle: '"The Omnivores Dilemma": The Effect of Autumn Diet on Winter Physiology and Condition of Juvenile Antarctic Krill',
+ __typename: 'Collection'
+ },
+ {
+ conceptId: 'C1200482349-ARCTEST',
+ directDistributionInformation: null,
+ shortName: 'USAP-1753101',
+ provider: 'ARCTEST',
+ entryTitle: '"The Omnivores Dilemma": The Effect of Autumn Diet on Winter Physiology and Condition of Juvenile Antarctic Krill',
+ __typename: 'Collection'
+ }
+ ],
+ __typename: 'CollectionList'
+ }
+ }
+ }
+ },
+ {
+ request: {
+ query: UPDATE_ACL,
+ variables: {
+ catalogItemIdentity: {
+ name: 'Mock ACLUpdated Name',
+ providerId: 'MMT_2',
+ collectionApplicable: true,
+ granuleApplicable: false,
+ collectionIdentifier: { conceptIds: ['C12000000-MMT_2', 'C13000000-MMT_2'] }
+ },
+ conceptId: 'ACL1000000-MMT',
+ groupPermissions: [{
+ permissions: ['read'],
+ userType: 'guest'
+ }, {
+ permissions: ['read'],
+ userType: 'registered'
+ }]
+ }
+ },
+ result: {
+ data: {
+ updateAcl: {
+ conceptId: 'ACL1000000-MMT',
+ revisionId: '2'
+ }
+ }
+ }
+ },
+ {
+ request: {
+ query: GET_COLLECTION_FOR_PERMISSION_FORM,
+ variables: {
+ conceptId: 'ACL1000000-MMT',
+ params: {
+ offset: 0,
+ limit: 1
+ }
+ }
+ },
+ result: {
+ data: {
+ acl: {
+ __typename: 'Acl',
+ conceptId: 'ACL1000000-CMR',
+ identityType: 'Catalog Item',
+ location: 'https://cmr.sit.earthdata.nasa.gov:443/access-control/acls/ACL1200427411-CMR',
+ name: 'Mock ACL',
+ providerIdentity: null,
+ revisionId: 1,
+ systemIdentity: null,
+ catalogItemIdentity: {
+ __typename: 'CatalogItemIdentity',
+ collectionIdentifier: {},
+ collectionApplicable: true,
+ granuleApplicable: false,
+ granuleIdentifier: null,
+ providerId: 'MMT_2'
+ },
+ collections: {
+ __typename: 'CollectionList',
+ count: 2,
+ items: [
+ {
+ __typename: 'Collection',
+ conceptId: 'C12000000-MMT_2',
+ directDistributionInformation: null,
+ provider: 'MMT_2',
+ shortName: 'This is collection 2',
+ entryTitle: 'Collection 1',
+ version: '1'
+ }
+ ]
+ },
+ groups: {
+ __typename: 'AclGroupList',
+ items: [
+ {
+ __typename: 'AclGroup',
+ permissions: [
+ 'read'
+ ],
+ userType: 'guest',
+ id: null,
+ name: null,
+ tag: null
+ },
+ {
+ __typename: 'AclGroup',
+ permissions: [
+ 'read'
+ ],
+ userType: 'registered',
+ id: null,
+ name: null,
+ tag: null
+ }
+ ]
+ }
+ }
+ }
+ }
+ },
+ {
+ request: {
+ query: GET_COLLECTION_FOR_PERMISSION_FORM,
+ variables: {
+ conceptId: 'ACL1000000-MMT',
+ params: {
+ offset: 1,
+ limit: 1
+ }
+ }
+ },
+ result: {
+ data: {
+ acl: {
+ __typename: 'Acl',
+ conceptId: 'ACL1000000-CMR',
+ identityType: 'Catalog Item',
+ location: 'https://cmr.sit.earthdata.nasa.gov:443/access-control/acls/ACL1200427411-CMR',
+ name: 'Mock ACL',
+ providerIdentity: null,
+ revisionId: 1,
+ systemIdentity: null,
+ catalogItemIdentity: {
+ __typename: 'CatalogItemIdentity',
+ collectionIdentifier: {},
+ collectionApplicable: true,
+ granuleApplicable: false,
+ granuleIdentifier: null,
+ providerId: 'MMT_2'
+ },
+ collections: {
+ __typename: 'CollectionList',
+ count: 2,
+ items: [
+ {
+ __typename: 'Collection',
+ conceptId: 'C13000000-MMT_2',
+ directDistributionInformation: null,
+ provider: 'MMT_2',
+ shortName: 'This is collection 1',
+ entryTitle: 'Collection 2',
+ version: '1'
+ }
+ ]
+ },
+ groups: {
+ __typename: 'AclGroupList',
+ items: [
+ {
+ __typename: 'AclGroup',
+ permissions: [
+ 'read'
+ ],
+ userType: 'guest',
+ id: null,
+ name: null,
+ tag: null
+ },
+ {
+ __typename: 'AclGroup',
+ permissions: [
+ 'read'
+ ],
+ userType: 'registered',
+ id: null,
+ name: null,
+ tag: null
+ }
+ ]
+ }
+ }
+ }
+ }
+ }
+
+ ]
})
+ user = setupResult.user
})
- describe('when collection start date is larger than stop date', () => {
- test('renders start date is larger error', async () => {
- const { user } = setup({
- pageUrl: '/permissions/new'
- })
+ test('shows confirmation modal when switching to All Collections with existing data', async () => {
+ const checkbox = await screen.findByRole('checkbox', { name: 'All Collections' })
+ await user.click(checkbox)
- const nameField = await screen.findByRole('textbox', { name: 'Name' })
- const granuleCheckbox = screen.getByRole('checkbox', { name: 'Granules' })
+ // Check if the confirmation modal is shown
+ expect(screen.getByText(/Checking "All Collections" will remove/)).toBeInTheDocument()
+ })
- await user.type(nameField, 'Test Name')
- await user.click(granuleCheckbox)
+ test('handleConfirmAllCollection deletes fields and updates form data', async () => {
+ const checkbox = await screen.findByRole('checkbox', { name: 'All Collections' })
+ await user.click(checkbox)
- const startDate = screen.getAllByRole('textbox', { name: 'Start Date' })
- const stopDate = screen.getAllByRole('textbox', { name: 'Stop Date' })
+ const maxValue = screen.getAllByRole('textbox', { name: 'Maximum Value' })
+ const minValue = screen.getAllByRole('textbox', { name: 'Minimum Value' })
- // Fills out collection field
- await user.type(startDate[0], '2024-06-06T00:00:00.000Z')
- await user.type(stopDate[0], '2024-06-04T00:00:00.000Z')
+ expect(minValue[0]).toHaveValue('1')
+ expect(maxValue[0]).toHaveValue('10')
- const submitButton = screen.getByRole('button', { name: 'Submit' })
- await user.click(submitButton)
+ // Confirm the modal
+ const confirmButton = screen.getByRole('button', { name: 'Yes' })
+ await user.click(confirmButton)
- expect(await screen.findByText('Start date should be earlier than Stop date')).toBeInTheDocument()
+ expect(minValue[0]).toHaveValue('')
+ expect(maxValue[0]).toHaveValue('')
+ })
+
+ test('handleCancelAllCollection sets allCollection to false and closes modal', async () => {
+ const checkbox = await screen.findByRole('checkbox', { name: 'All Collections' })
+ await user.click(checkbox)
+
+ // Cancel the modal
+ const cancelButton = screen.getByRole('button', { name: 'No' })
+ await user.click(cancelButton)
+
+ // Check if the checkbox is unchecked and the fields are still there
+ expect(checkbox).not.toBeChecked()
+
+ const maxValue = screen.getAllByRole('textbox', { name: 'Maximum Value' })
+ const minValue = screen.getAllByRole('textbox', { name: 'Minimum Value' })
+
+ expect(minValue[0]).toHaveValue('1')
+ expect(maxValue[0]).toHaveValue('10')
+ })
+ })
+
+ describe('collection selection handling', () => {
+ test('sets allCollection to false when hasCollectionIdentifier is true', async () => {
+ setup({
+ pageUrl: '/permissions/ACL1000000-MMT/edit',
+ mocks: [
+ {
+ request: {
+ query: GET_COLLECTION_FOR_PERMISSION_FORM,
+ variables: {
+ conceptId: 'ACL1000000-MMT',
+ params: {
+ offset: 0,
+ limit: 1
+ }
+ }
+ },
+ result: {
+ data: {
+ acl: {
+ __typename: 'Acl',
+ conceptId: 'ACL1000000-CMR',
+ catalogItemIdentity: {
+ __typename: 'CatalogItemIdentity',
+ collectionIdentifier: {
+ conceptIds: ['C1234-TEST']
+ },
+ providerId: 'TEST_PROVIDER'
+ },
+ collections: {
+ __typename: 'CollectionList',
+ count: 1,
+ items: [
+ {
+ __typename: 'Collection',
+ conceptId: 'C1234-TEST',
+ shortName: 'Test Collection'
+ }
+ ]
+ },
+ groups: {
+ __typename: 'AclGroupList',
+ items: []
+ }
+ }
+ }
+ }
+ }
+ ]
+ })
+
+ await waitFor(() => {
+ const allCollectionsCheckbox = screen.getByRole('checkbox', { name: 'All Collections' })
+ expect(allCollectionsCheckbox).not.toBeChecked()
})
})
- describe('when granule start date is larger than stop date', () => {
- test('renders granules start date is larger error', async () => {
- const { user } = setup({
- pageUrl: '/permissions/new'
- })
+ test('sets allCollection to true when hasCollectionIdentifier is false', async () => {
+ setup({
+ pageUrl: '/permissions/ACL1000000-MMT/edit',
+ mocks: [
+ {
+ request: {
+ query: GET_COLLECTION_FOR_PERMISSION_FORM,
+ variables: {
+ conceptId: 'ACL1000000-MMT',
+ params: {
+ offset: 0,
+ limit: 1
+ }
+ }
+ },
+ result: {
+ data: {
+ acl: {
+ __typename: 'Acl',
+ conceptId: 'ACL1000000-CMR',
+ catalogItemIdentity: {
+ __typename: 'CatalogItemIdentity',
+ collectionIdentifier: null,
+ providerId: 'TEST_PROVIDER'
+ },
+ collections: {
+ __typename: 'CollectionList',
+ count: 0,
+ items: []
+ },
+ groups: {
+ __typename: 'AclGroupList',
+ items: []
+ }
+ }
+ }
+ }
+ }
+ ]
+ })
- const nameField = await screen.findByRole('textbox', { name: 'Name' })
- const granuleCheckbox = screen.getByRole('checkbox', { name: 'Granules' })
+ await waitFor(() => {
+ const allCollectionsCheckbox = screen.getByRole('checkbox', { name: 'All Collections' })
+ expect(allCollectionsCheckbox).toBeChecked()
+ })
- await user.type(nameField, 'Test Name')
- await user.click(granuleCheckbox)
+ // Optionally, you can also check that the selectedCollections are empty
+ const selectedCollectionsSection = screen.queryByText('Selected Collections')
+ expect(selectedCollectionsSection).not.toBeInTheDocument()
+ })
- const startDate = screen.getAllByRole('textbox', { name: 'Start Date' })
- const stopDate = screen.getAllByRole('textbox', { name: 'Stop Date' })
+ test('shows confirmation modal when switching to All Collections with existing filters', async () => {
+ const { user } = setup({
+ pageUrl: '/permissions/ACL1000000-MMT/edit',
+ mocks: [
+ {
+ request: {
+ query: GET_COLLECTION_FOR_PERMISSION_FORM,
+ variables: {
+ conceptId: 'ACL1000000-MMT',
+ params: {
+ offset: 0,
+ limit: 1
+ }
+ }
+ },
+ result: {
+ data: {
+ acl: {
+ __typename: 'Acl',
+ conceptId: 'ACL1000000-CMR',
+ catalogItemIdentity: {
+ __typename: 'CatalogItemIdentity',
+ collectionIdentifier: {
+ conceptIds: ['C1234-TEST']
+ },
+ providerId: 'TEST_PROVIDER'
+ },
+ collections: {
+ __typename: 'CollectionList',
+ count: 1,
+ items: [
+ {
+ __typename: 'Collection',
+ conceptId: 'C1234-TEST',
+ shortName: 'Test Collection'
+ }
+ ]
+ },
+ groups: {
+ __typename: 'AclGroupList',
+ items: []
+ }
+ }
+ }
+ }
+ }
+ ]
+ })
- // Fills out granule field
- await user.type(startDate[1], '2024-06-06T00:00:00.000Z')
- await user.type(stopDate[1], '2024-06-04T00:00:00.000Z')
+ // Wait for the form to load
+ await waitFor(() => {
+ expect(screen.getByRole('checkbox', { name: 'All Collections' })).toBeInTheDocument()
+ })
- const submitButton = screen.getByRole('button', { name: 'Submit' })
- await user.click(submitButton)
+ // Add a filter
+ const minValueInput = screen.getAllByRole('textbox', { name: 'Minimum Value' })[0]
+ await user.type(minValueInput, '10')
- expect(await screen.findByText('Start date should be earlier than Stop date')).toBeInTheDocument()
+ // Click "All Collections" checkbox
+ const allCollectionsCheckbox = screen.getByRole('checkbox', { name: 'All Collections' })
+ await user.click(allCollectionsCheckbox)
+
+ // Check if the confirmation modal is shown
+ await waitFor(() => {
+ expect(screen.getByText(/Checking "All Collections" will remove/)).toBeInTheDocument()
})
})
})
@@ -1479,10 +2246,43 @@ describe('PermissionForm', () => {
test('should remove the invalid group permission', async () => {
const navigateSpy = vi.fn()
vi.spyOn(router, 'useNavigate').mockImplementation(() => navigateSpy)
+ vi.spyOn(console, 'warn').mockImplementation(() => {})
const { user } = setup({
pageUrl: '/permissions/ACL1000000-MMT/edit',
mocks: [
+ {
+ request: {
+ query: GET_PERMISSION_COLLECTIONS,
+ variables: ({ params }) => params.limit === 100
+ },
+ result: ({ variables }) => ({
+ data: {
+ collections: {
+ items: [
+ {
+ conceptId: 'MOCK_CONCEPT_ID_1',
+ directDistributionInformation: null,
+ shortName: 'MOCK_SHORT_NAME_1',
+ provider: variables.params.provider || 'MOCK_PROVIDER_1',
+ entryTitle: 'MOCK_ENTRY_TITLE_1',
+ __typename: 'Collection'
+ },
+ {
+ conceptId: 'MOCK_CONCEPT_ID_2',
+ directDistributionInformation: null,
+ shortName: 'MOCK_SHORT_NAME_2',
+ provider: variables.params.provider || 'MOCK_PROVIDER_2',
+ entryTitle: 'MOCK_ENTRY_TITLE_2',
+ __typename: 'Collection'
+ }
+ ],
+ __typename: 'CollectionList'
+ }
+ }
+ })
+
+ },
{
request: {
query: GET_COLLECTION_FOR_PERMISSION_FORM,
@@ -1517,6 +2317,15 @@ describe('PermissionForm', () => {
__typename: 'CollectionList',
count: 2,
items: [
+ {
+ __typename: 'Collection',
+ conceptId: 'C12000000-MMT_2',
+ directDistributionInformation: null,
+ provider: 'MMT_2',
+ shortName: 'This is collection 2',
+ entryTitle: 'Collection 1',
+ version: '1'
+ },
{
__typename: 'Collection',
conceptId: 'C12000000-MMT_2',
@@ -1577,80 +2386,6 @@ describe('PermissionForm', () => {
}
}
},
- {
- request: {
- query: GET_COLLECTION_FOR_PERMISSION_FORM,
- variables: {
- conceptId: 'ACL1000000-MMT',
- params: {
- offset: 0,
- limit: 1
- }
- }
- },
- result: {
- data: {
- acl: {
- __typename: 'Acl',
- conceptId: 'ACL1000000-CMR',
- identityType: 'Catalog Item',
- location: 'https://cmr.sit.earthdata.nasa.gov:443/access-control/acls/ACL1200427411-CMR',
- name: 'Mock ACL',
- providerIdentity: null,
- revisionId: 1,
- systemIdentity: null,
- catalogItemIdentity: {
- __typename: 'CatalogItemIdentity',
- collectionIdentifier: {},
- collectionApplicable: true,
- granuleApplicable: false,
- granuleIdentifier: null,
- providerId: 'MMT_2'
- },
- collections: {
- __typename: 'CollectionList',
- count: 2,
- items: [
- {
- __typename: 'Collection',
- conceptId: 'C12000000-MMT_2',
- directDistributionInformation: null,
- provider: 'MMT_2',
- shortName: 'This is collection 2',
- entryTitle: 'Collection 1',
- version: '1'
- }
- ]
- },
- groups: {
- __typename: 'AclGroupList',
- items: [
- {
- __typename: 'AclGroup',
- permissions: [
- 'read'
- ],
- userType: 'guest',
- id: null,
- name: null,
- tag: null
- },
- {
- __typename: 'AclGroup',
- permissions: [
- 'read'
- ],
- userType: 'registered',
- id: null,
- name: null,
- tag: null
- }
- ]
- }
- }
- }
- }
- },
{
request: {
query: GET_COLLECTION_FOR_PERMISSION_FORM,
diff --git a/static/src/js/schemas/collectionPermission.js b/static/src/js/schemas/collectionPermission.js
index 1805576e3..c30ee28e6 100644
--- a/static/src/js/schemas/collectionPermission.js
+++ b/static/src/js/schemas/collectionPermission.js
@@ -41,21 +41,31 @@ const collectionPermission = {
oneOf: [
{
title: 'All Collections',
+ type: 'object',
properties: {
allCollection: {
title: 'All Collections',
- type: 'string',
- default: true
+ type: 'boolean',
+ const: true
}
- }
+ },
+ required: ['allCollection']
},
{
- title: 'Selected Collection',
+ title: 'Selected Collections',
+ type: 'object',
properties: {
+ allCollection: {
+ title: 'All Collections',
+ type: 'boolean',
+ const: false
+ },
selectedCollections: {
- description: 'Entry Title of the collection'
+ type: 'object',
+ description: 'Entry Titles of the selected collections'
}
- }
+ },
+ required: ['allCollection', 'selectedCollections']
}
]
},
diff --git a/static/src/js/schemas/uiSchemas/collectionPermission.js b/static/src/js/schemas/uiSchemas/collectionPermission.js
index caee25532..092f23486 100644
--- a/static/src/js/schemas/uiSchemas/collectionPermission.js
+++ b/static/src/js/schemas/uiSchemas/collectionPermission.js
@@ -29,7 +29,7 @@ const collectionPermissionUiSchema = {
{
'ui:col': {
style: {
- marginTop: '-10px'
+ marginTop: '-15px'
},
md: 4,
children: ['accessPermission']
@@ -151,13 +151,19 @@ const collectionPermissionUiSchema = {
'ui:row': [
{
'ui:col': {
- md: 4,
+ style: {
+ marginTop: '-10px'
+ },
+ md: 5,
children: ['collection']
}
},
{
'ui:col': {
- md: 4,
+ style: {
+ marginTop: '-10px'
+ },
+ md: 5,
children: ['granule']
}
}