diff --git a/src/datasets/domain/models/Dataset.ts b/src/datasets/domain/models/Dataset.ts index 819b3dd8..fc6163a2 100644 --- a/src/datasets/domain/models/Dataset.ts +++ b/src/datasets/domain/models/Dataset.ts @@ -36,9 +36,19 @@ export interface DatasetLicense { iconUri?: string } -export interface TermsOfUse { +export interface CustomTerms { + termsOfUse: string + confidentialityDeclaration?: string + specialPermissions?: string + restrictions?: string + citationRequirements?: string + depositorRequirements?: string + conditions?: string + disclaimer?: string +} +export interface TermsOfAccess { fileAccessRequest: boolean - termsOfAccess?: string + termsOfAccessForRestrictedFiles?: string dataAccessPlace?: string originalArchive?: string availabilityStatus?: string @@ -55,6 +65,10 @@ export interface TermsOfUse { disclaimer?: string } +export interface TermsOfUse { + termsOfAccess: TermsOfAccess + customTerms?: CustomTerms +} export type DatasetMetadataBlocks = [CitationMetadataBlock, ...DatasetMetadataBlock[]] export interface DatasetMetadataBlock { diff --git a/src/datasets/index.ts b/src/datasets/index.ts index 2eaaed5d..40533d37 100644 --- a/src/datasets/index.ts +++ b/src/datasets/index.ts @@ -73,7 +73,8 @@ export { DatasetMetadataBlocks, DatasetMetadataFields, DatasetMetadataSubField, - DatasetMetadataFieldValue + DatasetMetadataFieldValue, + TermsOfUse } from './domain/models/Dataset' export { DatasetPreview } from './domain/models/DatasetPreview' export { DatasetVersionDiff } from './domain/models/DatasetVersionDiff' diff --git a/src/datasets/infra/repositories/transformers/datasetTransformers.ts b/src/datasets/infra/repositories/transformers/datasetTransformers.ts index 22c06b35..b9e19378 100644 --- a/src/datasets/infra/repositories/transformers/datasetTransformers.ts +++ b/src/datasets/infra/repositories/transformers/datasetTransformers.ts @@ -235,15 +235,35 @@ export const transformVersionPayloadToDataset = ( releaseTime: new Date(versionPayload.releaseTime) }, termsOfUse: { - fileAccessRequest: versionPayload.fileAccessRequest, - termsOfAccess: transformPayloadText(keepRawFields, versionPayload.termsOfAccess), - dataAccessPlace: transformPayloadText(keepRawFields, versionPayload.dataAccessPlace), - originalArchive: transformPayloadText(keepRawFields, versionPayload.originalArchive), - availabilityStatus: transformPayloadText(keepRawFields, versionPayload.availabilityStatus), - contactForAccess: transformPayloadText(keepRawFields, versionPayload.contactForAccess), - sizeOfCollection: transformPayloadText(keepRawFields, versionPayload.sizeOfCollection), - studyCompletion: transformPayloadText(keepRawFields, versionPayload.studyCompletion), - termsOfUse: transformPayloadText(keepRawFields, versionPayload.termsOfUse), + termsOfAccess: { + fileAccessRequest: versionPayload.fileAccessRequest, + termsOfAccessForRestrictedFiles: transformPayloadText( + keepRawFields, + versionPayload.termsOfAccess + ), + dataAccessPlace: transformPayloadText(keepRawFields, versionPayload.dataAccessPlace), + originalArchive: transformPayloadText(keepRawFields, versionPayload.originalArchive), + availabilityStatus: transformPayloadText(keepRawFields, versionPayload.availabilityStatus), + contactForAccess: transformPayloadText(keepRawFields, versionPayload.contactForAccess), + sizeOfCollection: transformPayloadText(keepRawFields, versionPayload.sizeOfCollection), + studyCompletion: transformPayloadText(keepRawFields, versionPayload.studyCompletion) + } + }, + metadataBlocks: transformPayloadToDatasetMetadataBlocks( + versionPayload.metadataBlocks, + keepRawFields + ), + ...(versionPayload.isPartOf && { + isPartOf: transformPayloadToOwnerNode(versionPayload.isPartOf) + }) + } + if ('license' in versionPayload) { + datasetModel.license = transformPayloadToDatasetLicense( + versionPayload.license as LicensePayload + ) + } else { + datasetModel.termsOfUse.customTerms = { + termsOfUse: transformPayloadText(keepRawFields, versionPayload.termsOfUse) as string, confidentialityDeclaration: transformPayloadText( keepRawFields, versionPayload.confidentialityDeclaration @@ -260,19 +280,7 @@ export const transformVersionPayloadToDataset = ( ), conditions: transformPayloadText(keepRawFields, versionPayload.conditions), disclaimer: transformPayloadText(keepRawFields, versionPayload.disclaimer) - }, - metadataBlocks: transformPayloadToDatasetMetadataBlocks( - versionPayload.metadataBlocks, - keepRawFields - ), - ...(versionPayload.isPartOf && { - isPartOf: transformPayloadToOwnerNode(versionPayload.isPartOf) - }) - } - if ('license' in versionPayload) { - datasetModel.license = transformPayloadToDatasetLicense( - versionPayload.license as LicensePayload - ) + } } if ('alternativePersistentId' in versionPayload) { datasetModel.alternativePersistentId = versionPayload.alternativePersistentId @@ -286,7 +294,13 @@ export const transformVersionPayloadToDataset = ( return datasetModel } -const transformPayloadToDatasetLicense = (licensePayload: LicensePayload): DatasetLicense => { +const transformPayloadToDatasetLicense = ( + licensePayload: LicensePayload +): DatasetLicense | undefined => { + if (!licensePayload) { + return undefined + } + const datasetLicense: DatasetLicense = { name: licensePayload.name, uri: licensePayload.uri @@ -295,6 +309,7 @@ const transformPayloadToDatasetLicense = (licensePayload: LicensePayload): Datas if ('iconUri' in licensePayload) { datasetLicense.iconUri = licensePayload.iconUri } + return datasetLicense } diff --git a/test/functional/datasets/GetDataset.test.ts b/test/functional/datasets/GetDataset.test.ts index 5ff15bc1..771e432d 100644 --- a/test/functional/datasets/GetDataset.test.ts +++ b/test/functional/datasets/GetDataset.test.ts @@ -76,7 +76,23 @@ describe('execute', () => { await expect(getDataset.execute(nonExistentTestDatasetId)).rejects.toThrow(expectedError) }) - + test('should not return custom terms if license is set', async () => { + const versionPayload = createDatasetVersionPayload() + versionPayload.license = { + name: 'CC0', + uri: 'https://creativecommons.org/publicdomain/zero/1.0/', + iconUri: 'https://creativecommons.org/publicdomain/zero/1.0/' + } + const dataset = transformVersionPayloadToDataset(versionPayload, false) + expect(dataset.termsOfUse.termsOfAccess.termsOfAccessForRestrictedFiles).toBe('Terms of access') + expect(dataset.termsOfUse.customTerms).toBe(undefined) + }) + test('should return custom terms if license is undefined', async () => { + const versionPayload = createDatasetVersionPayload() + const dataset = transformVersionPayloadToDataset(versionPayload, false) + expect(dataset.termsOfUse.termsOfAccess.termsOfAccessForRestrictedFiles).toBe('Terms of access') + expect(dataset.termsOfUse.customTerms?.termsOfUse).toBe('Terms of use') + }) test('should return metadata fields in markdown format when keepRawFields is false', async () => { const createdDatasetIdentifiers = await createDataset.execute(testNewDataset) @@ -98,13 +114,15 @@ describe('execute', () => { const versionPayload = createDatasetVersionPayload() versionPayload.termsOfAccess = 'Hello world' const dataset = transformVersionPayloadToDataset(versionPayload, false) - expect(dataset.termsOfUse.termsOfAccess).toBe('Hello **world**') + expect(dataset.termsOfUse.termsOfAccess.termsOfAccessForRestrictedFiles).toBe('Hello **world**') }) test('should return terms of use fields in html format when keepRawFields is true', async () => { const versionPayload = createDatasetVersionPayload() const dataset = transformVersionPayloadToDataset(versionPayload, true) - expect(dataset.termsOfUse.termsOfAccess).toBe(versionPayload.termsOfAccess) + expect(dataset.termsOfUse.termsOfAccess.termsOfAccessForRestrictedFiles).toBe( + versionPayload.termsOfAccess + ) }) test('should not return metadata fields in markdown format when keepRawFields is true', async () => { diff --git a/test/testHelpers/datasets/datasetHelper.ts b/test/testHelpers/datasets/datasetHelper.ts index 50e4e1d1..66a24da8 100644 --- a/test/testHelpers/datasets/datasetHelper.ts +++ b/test/testHelpers/datasets/datasetHelper.ts @@ -53,22 +53,16 @@ export const createDatasetModel = ( releaseTime: new Date(DATASET_RELEASE_TIME_STR) }, termsOfUse: { - fileAccessRequest: true, - termsOfAccess: 'Terms of access', - dataAccessPlace: 'Data access place', - originalArchive: 'Original archive', - availabilityStatus: 'Availability status', - contactForAccess: 'Contact for access', - sizeOfCollection: 'Size of collection', - studyCompletion: 'Study completion', - termsOfUse: 'Terms of use', - confidentialityDeclaration: 'Confidentiality declaration', - specialPermissions: 'Special permissions', - restrictions: 'Restrictions', - citationRequirements: 'Citation requirements', - depositorRequirements: 'Depositor requirements', - conditions: 'Conditions', - disclaimer: 'Disclaimer' + termsOfAccess: { + fileAccessRequest: true, + termsOfAccessForRestrictedFiles: 'Terms of access', + dataAccessPlace: 'Data access place', + originalArchive: 'Original archive', + availabilityStatus: 'Availability status', + contactForAccess: 'Contact for access', + sizeOfCollection: 'Size of collection', + studyCompletion: 'Study completion' + } }, publicationDate: DATASET_PUBLICATION_DATE_STR, metadataBlocks: [ @@ -105,6 +99,17 @@ export const createDatasetModel = ( } if (license !== undefined) { datasetModel.license = license + } else { + datasetModel.termsOfUse.customTerms = { + termsOfUse: 'Terms of use', + confidentialityDeclaration: 'Confidentiality declaration', + specialPermissions: 'Special permissions', + restrictions: 'Restrictions', + citationRequirements: 'Citation requirements', + depositorRequirements: 'Depositor requirements', + conditions: 'Conditions', + disclaimer: 'Disclaimer' + } } if (addOptionalParameters) { datasetModel.alternativePersistentId = 'doi:10.5072/FK2/HC6KTB' @@ -137,14 +142,6 @@ export const createDatasetVersionPayload = ( contactForAccess: 'Contact for access', sizeOfCollection: 'Size of collection', studyCompletion: 'Study completion', - termsOfUse: 'Terms of use', - confidentialityDeclaration: 'Confidentiality declaration', - specialPermissions: 'Special permissions', - restrictions: 'Restrictions', - citationRequirements: 'Citation requirements', - depositorRequirements: 'Depositor requirements', - conditions: 'Conditions', - disclaimer: 'Disclaimer', metadataBlocks: { citation: { name: 'citation', @@ -240,6 +237,15 @@ export const createDatasetVersionPayload = ( } if (license !== undefined) { datasetPayload.license = license + } else { + datasetPayload.termsOfUse = 'Terms of use' + datasetPayload.confidentialityDeclaration = 'Confidentiality declaration' + datasetPayload.specialPermissions = 'Special permissions' + datasetPayload.restrictions = 'Restrictions' + datasetPayload.citationRequirements = 'Citation requirements' + datasetPayload.depositorRequirements = 'Depositor requirements' + datasetPayload.conditions = 'Conditions' + datasetPayload.disclaimer = 'Disclaimer' } if (addOptionalProperties) { datasetPayload.alternativePersistentId = 'doi:10.5072/FK2/HC6KTB' diff --git a/test/unit/datasets/DatasetsRepository.test.ts b/test/unit/datasets/DatasetsRepository.test.ts index 55671c8b..50d5b3cd 100644 --- a/test/unit/datasets/DatasetsRepository.test.ts +++ b/test/unit/datasets/DatasetsRepository.test.ts @@ -221,6 +221,64 @@ describe('DatasetsRepository', () => { ) expect(actual).toStrictEqual(createDatasetModel(undefined, true)) }) + test('should return Dataset with customTerms when license is undefined', async () => { + jest.spyOn(axios, 'get').mockResolvedValue(testDatasetVersionSuccessfulResponse) + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/${testVersionId}` + + // API Key auth + let actual = await sut.getDataset( + testDatasetModel.id, + testVersionId, + testIncludeDeaccessioned, + false + ) + + expect(axios.get).toHaveBeenCalledWith(expectedApiEndpoint, expectedRequestConfigApiKey) + expect(actual).toStrictEqual(testDatasetModel) + + // Session cookie auth + ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE) + actual = await sut.getDataset( + testDatasetModel.id, + testVersionId, + testIncludeDeaccessioned, + false + ) + expect(axios.get).toHaveBeenCalledWith( + expectedApiEndpoint, + expectedRequestConfigSessionCookie + ) + expect(actual).toStrictEqual(testDatasetModel) + }) + test('should return Dataset without customTerms when license is defined', async () => { + jest.spyOn(axios, 'get').mockResolvedValue(testDatasetVersionSuccessfulResponse) + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/${testVersionId}` + + // API Key auth + let actual = await sut.getDataset( + testDatasetModel.id, + testVersionId, + testIncludeDeaccessioned, + false + ) + + expect(axios.get).toHaveBeenCalledWith(expectedApiEndpoint, expectedRequestConfigApiKey) + expect(actual).toStrictEqual(testDatasetModel) + + // Session cookie auth + ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE) + actual = await sut.getDataset( + testDatasetModel.id, + testVersionId, + testIncludeDeaccessioned, + false + ) + expect(axios.get).toHaveBeenCalledWith( + expectedApiEndpoint, + expectedRequestConfigSessionCookie + ) + expect(actual).toStrictEqual(testDatasetModel) + }) test('should return error on repository read error', async () => { jest.spyOn(axios, 'get').mockRejectedValue(TestConstants.TEST_ERROR_RESPONSE)