Skip to content

Commit a937365

Browse files
authored
Merge pull request #389 from IQSS/updateTermsOfAccess
Edit Terms: Use Case Update Terms of Access
2 parents 205715c + ec2282b commit a937365

File tree

12 files changed

+334
-4
lines changed

12 files changed

+334
-4
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel
1212
- New Use Case: [Get Collections For Linking Use Case](./docs/useCases.md#get-collections-for-linking).
1313
- New Use Case: [Create a Dataset Template](./docs/useCases.md#create-a-dataset-template) under Collections.
1414

15+
- New Use Case: [Update Terms of Access](./docs/useCases.md#update-terms-of-access).
16+
1517
### Changed
1618

1719
- Add pagination query parameters to Dataset Version Summeries and File Version Summaries use cases

docs/useCases.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,6 +1152,38 @@ The `versionUpdateType` parameter can be a [VersionUpdateType](../src/datasets/d
11521152
- `VersionUpdateType.MAJOR`
11531153
- `VersionUpdateType.UPDATE_CURRENT`
11541154

1155+
#### Update Terms of Access
1156+
1157+
Updates the Terms of Access for restricted files on a dataset.
1158+
1159+
##### Example call:
1160+
1161+
```typescript
1162+
import { updateTermsOfAccess } from '@iqss/dataverse-client-javascript'
1163+
1164+
/* ... */
1165+
1166+
const datasetId = 3
1167+
1168+
await updateTermsOfAccess.execute(datasetId, {
1169+
fileAccessRequest: true,
1170+
termsOfAccessForRestrictedFiles: 'Your terms of access for restricted files',
1171+
dataAccessPlace: 'Your data access place',
1172+
originalArchive: 'Your original archive',
1173+
availabilityStatus: 'Your availability status',
1174+
contactForAccess: 'Your contact for access',
1175+
sizeOfCollection: 'Your size of collection',
1176+
studyCompletion: 'Your study completion'
1177+
})
1178+
```
1179+
1180+
_See [use case](../src/datasets/domain/useCases/UpdateTermsOfAccess.ts) implementation_.
1181+
1182+
Notes:
1183+
1184+
- If the dataset is already published, this action creates a DRAFT version containing the new terms.
1185+
- Unspecified fields are treated as omissions: sending only `fileAccessRequest` will update that field and leave all other terms absent (undefined). In practice, the new values you send fully replace the previous set of terms — so if you omit a field, you are effectively clearing it unless you include its original value in the new input.
1186+
11551187
#### Deaccession a Dataset
11561188

11571189
Deaccession a Dataset, given its identifier, version, and deaccessionDatasetDTO to perform.

src/datasets/domain/models/Dataset.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ export interface CustomTerms {
5151
conditions?: string
5252
disclaimer?: string
5353
}
54+
5455
export interface TermsOfAccess {
5556
fileAccessRequest: boolean
5657
termsOfAccessForRestrictedFiles?: string

src/datasets/domain/repositories/IDatasetsRepository.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { CitationFormat } from '../models/CitationFormat'
1414
import { FormattedCitation } from '../models/FormattedCitation'
1515
import { DatasetTemplate } from '../models/DatasetTemplate'
1616
import { DatasetType } from '../models/DatasetType'
17+
import { TermsOfAccess } from '../models/Dataset'
1718
import { DatasetLicenseUpdateRequest } from '../dtos/DatasetLicenseUpdateRequest'
1819
import { DatasetTypeDTO } from '../dtos/DatasetTypeDTO'
1920

@@ -96,6 +97,7 @@ export interface IDatasetsRepository {
9697
licenses: string[]
9798
): Promise<void>
9899
deleteDatasetType(datasetTypeId: number): Promise<void>
100+
updateTermsOfAccess(datasetId: number | string, termsOfAccess: TermsOfAccess): Promise<void>
99101
updateDatasetLicense(
100102
datasetId: number | string,
101103
payload: DatasetLicenseUpdateRequest

src/datasets/domain/useCases/SetAvailableLicensesForDatasetType.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ export class SetAvailableLicensesForDatasetType implements UseCase<void> {
1010

1111
/**
1212
* Sets the available licenses for a given dataset type. This limits the license options when creating a dataset of this type.
13+
*
14+
* @param {number | string} [datasetTypeId] - The dataset type identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
15+
* @param {string[]} licenses - The licenses to set for the dataset type.
16+
* @returns {Promise<void>} - This method does not return anything upon successful completion.
1317
*/
1418
async execute(datasetTypeId: number | string, licenses: string[]): Promise<void> {
1519
return await this.datasetsRepository.setAvailableLicensesForDatasetType(datasetTypeId, licenses)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { IDatasetsRepository } from '../repositories/IDatasetsRepository'
3+
import { TermsOfAccess } from '../models/Dataset'
4+
5+
export class UpdateTermsOfAccess implements UseCase<void> {
6+
private datasetsRepository: IDatasetsRepository
7+
8+
constructor(datasetsRepository: IDatasetsRepository) {
9+
this.datasetsRepository = datasetsRepository
10+
}
11+
12+
/**
13+
* Sets the terms of access for a given dataset.
14+
*
15+
* @param {number | string} [datasetId] - The dataset identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
16+
* @param {TermsOfAccess} termsOfAccess - The terms of access to set for the dataset.
17+
* @returns {Promise<void>} - This method does not return anything upon successful completion.
18+
*/
19+
async execute(datasetId: number | string, termsOfAccess: TermsOfAccess): Promise<void> {
20+
return await this.datasetsRepository.updateTermsOfAccess(datasetId, termsOfAccess)
21+
}
22+
}

src/datasets/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { SetAvailableLicensesForDatasetType } from './domain/useCases/SetAvailab
3232
import { DeleteDatasetType } from './domain/useCases/DeleteDatasetType'
3333
import { GetDatasetCitationInOtherFormats } from './domain/useCases/GetDatasetCitationInOtherFormats'
3434
import { GetDatasetTemplates } from './domain/useCases/GetDatasetTemplates'
35+
import { UpdateTermsOfAccess } from './domain/useCases/UpdateTermsOfAccess'
3536
import { UpdateDatasetLicense } from './domain/useCases/UpdateDatasetLicense'
3637

3738
const datasetsRepository = new DatasetsRepository()
@@ -81,6 +82,7 @@ const setAvailableLicensesForDatasetType = new SetAvailableLicensesForDatasetTyp
8182
const deleteDatasetType = new DeleteDatasetType(datasetsRepository)
8283
const getDatasetCitationInOtherFormats = new GetDatasetCitationInOtherFormats(datasetsRepository)
8384
const getDatasetTemplates = new GetDatasetTemplates(datasetsRepository)
85+
const updateTermsOfAccess = new UpdateTermsOfAccess(datasetsRepository)
8486
const updateDatasetLicense = new UpdateDatasetLicense(datasetsRepository)
8587

8688
export {
@@ -106,6 +108,7 @@ export {
106108
getDatasetAvailableCategories,
107109
getDatasetCitationInOtherFormats,
108110
getDatasetTemplates,
111+
updateTermsOfAccess,
109112
getDatasetAvailableDatasetTypes,
110113
getDatasetAvailableDatasetType,
111114
addDatasetType,

src/datasets/infra/repositories/DatasetsRepository.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ import { DatasetTemplate } from '../../domain/models/DatasetTemplate'
2929
import { DatasetTemplatePayload } from './transformers/DatasetTemplatePayload'
3030
import { transformDatasetTemplatePayloadToDatasetTemplate } from './transformers/datasetTemplateTransformers'
3131
import { DatasetType } from '../../domain/models/DatasetType'
32+
import { TermsOfAccess } from '../../domain/models/Dataset'
33+
import { transformTermsOfAccessToUpdatePayload } from './transformers/termsOfAccessTransformers'
3234
import { DatasetLicenseUpdateRequest } from '../../domain/dtos/DatasetLicenseUpdateRequest'
3335
import { DatasetTypeDTO } from '../../domain/dtos/DatasetTypeDTO'
3436

@@ -486,6 +488,20 @@ export class DatasetsRepository extends ApiRepository implements IDatasetsReposi
486488
})
487489
}
488490

491+
public async updateTermsOfAccess(
492+
datasetId: number | string,
493+
termsOfAccess: TermsOfAccess
494+
): Promise<void> {
495+
return this.doPut(
496+
this.buildApiEndpoint(this.datasetsResourceName, 'access', datasetId),
497+
transformTermsOfAccessToUpdatePayload(termsOfAccess)
498+
)
499+
.then(() => undefined)
500+
.catch((error) => {
501+
throw error
502+
})
503+
}
504+
489505
public async updateDatasetLicense(
490506
datasetId: number | string,
491507
payload: DatasetLicenseUpdateRequest
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { TermsOfAccess } from '../../../domain/models/Dataset'
2+
3+
export const transformTermsOfAccessToUpdatePayload = (
4+
terms: TermsOfAccess & { termsOfAccess?: string }
5+
) => {
6+
const {
7+
fileAccessRequest,
8+
dataAccessPlace,
9+
originalArchive,
10+
availabilityStatus,
11+
contactForAccess,
12+
sizeOfCollection,
13+
studyCompletion
14+
} = terms
15+
16+
const termsOfAccessForRestrictedFiles =
17+
terms.termsOfAccess ?? terms.termsOfAccessForRestrictedFiles
18+
19+
return {
20+
customTermsOfAccess: {
21+
fileAccessRequest,
22+
termsOfAccess: termsOfAccessForRestrictedFiles,
23+
dataAccessPlace,
24+
originalArchive,
25+
availabilityStatus,
26+
contactForAccess,
27+
sizeOfCollection,
28+
studyCompletion
29+
}
30+
}
31+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { TestConstants } from '../../testHelpers/TestConstants'
2+
import {
3+
ApiConfig,
4+
DataverseApiAuthMechanism
5+
} from '../../../src/core/infra/repositories/ApiConfig'
6+
import {
7+
createDataset,
8+
DatasetNotNumberedVersion,
9+
getDataset,
10+
updateTermsOfAccess
11+
} from '../../../src/datasets'
12+
import { WriteError } from '../../../src'
13+
14+
describe('UpdateTermsOfAccess (functional)', () => {
15+
beforeAll(() => {
16+
ApiConfig.init(
17+
TestConstants.TEST_API_URL,
18+
DataverseApiAuthMechanism.API_KEY,
19+
process.env.TEST_API_KEY
20+
)
21+
})
22+
23+
test('should update terms of access with provided fields', async () => {
24+
const ids = await createDataset.execute(TestConstants.TEST_NEW_DATASET_DTO)
25+
26+
await updateTermsOfAccess.execute(ids.numericId, {
27+
fileAccessRequest: true,
28+
termsOfAccessForRestrictedFiles: 'Your terms',
29+
dataAccessPlace: 'Place'
30+
})
31+
32+
const dataset = await getDataset.execute(
33+
ids.numericId,
34+
DatasetNotNumberedVersion.LATEST,
35+
false,
36+
false
37+
)
38+
39+
expect(dataset.termsOfUse.termsOfAccess.fileAccessRequest).toBe(true)
40+
expect(dataset.termsOfUse.termsOfAccess.termsOfAccessForRestrictedFiles).toBe('Your terms')
41+
expect(dataset.termsOfUse.termsOfAccess.dataAccessPlace).toBe('Place')
42+
})
43+
44+
test('should throw when dataset does not exist', async () => {
45+
await expect(
46+
updateTermsOfAccess.execute(999999, {
47+
fileAccessRequest: false
48+
})
49+
).rejects.toBeInstanceOf(WriteError)
50+
})
51+
})

0 commit comments

Comments
 (0)