Skip to content

Commit 28495e8

Browse files
committed
feat: update restrict extension
1 parent 79e2be1 commit 28495e8

File tree

8 files changed

+94
-27
lines changed

8 files changed

+94
-27
lines changed

docs/useCases.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1376,7 +1376,7 @@ The use case returns a number, which is the identifier of the new file.
13761376

13771377
#### Restrict or Unrestrict a File
13781378

1379-
Restrict or unrestrict an existing file.
1379+
Restrict or unrestrict an existing file, given a [RestrictFileDTO](../src/users/domain/dtos/RestrictFileDTO.ts)
13801380

13811381
##### Example call:
13821382

@@ -1386,15 +1386,23 @@ import { restrictFile } from '@iqss/dataverse-client-javascript'
13861386
/* ... */
13871387

13881388
const fileId = 12345
1389+
const restrictFileDTO = {
1390+
restrict: true,
1391+
enableAccessRequest: boolean,
1392+
termsOfAccess: string
1393+
}
13891394

1390-
restrictFile.execute(fileId, true)
1395+
restrictFile.execute(fileId, restrictFileDTO)
13911396

13921397
/* ... */
13931398
```
13941399

13951400
_See [use case](../src/files/domain/useCases/RestrictFile.ts) implementation_.
13961401

13971402
The `fileId` parameter can be a string, for persistent identifiers, or a number, for numeric identifiers.
1403+
If restrict is false then enableAccessRequest and termsOfAccess are ignored
1404+
If restrict is true and enableAccessRequest is false then termsOfAccess is required.
1405+
The enableAccessRequest and termsOfAccess are applied to the Draft version of the Dataset and affect all of the restricted files in said Draft version.
13981406

13991407
## Metadata Blocks
14001408

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export interface RestrictFileDTO {
2+
restrict: boolean
3+
enableAccessRequest?: boolean
4+
termsOfAccess?: string
5+
}

src/files/domain/repositories/IFilesRepository.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { Dataset } from '../../../datasets'
99
import { FileUploadDestination } from '../models/FileUploadDestination'
1010
import { UploadedFileDTO } from '../dtos/UploadedFileDTO'
1111
import { UpdateFileMetadataDTO } from '../dtos/UpdateFileMetadataDTO'
12+
import { RestrictFileDTO } from '../dtos/RestrictFileDTO'
1213

1314
export interface IFilesRepository {
1415
getDatasetFiles(
@@ -65,7 +66,8 @@ export interface IFilesRepository {
6566

6667
replaceFile(fileId: number | string, uploadedFileDTO: UploadedFileDTO): Promise<number>
6768

68-
restrictFile(fileId: number | string, restrict: boolean): Promise<undefined>
69+
restrictFile(fileId: number | string, restrictFileDTO: RestrictFileDTO): Promise<string>
70+
6971
updateFileMetadata(
7072
fileId: number | string,
7173
updateFileMetadataDTO: UpdateFileMetadataDTO
Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
11
import { IFilesRepository } from '../repositories/IFilesRepository'
22
import { UseCase } from '../../../core/domain/useCases/UseCase'
3-
4-
export class RestrictFile implements UseCase<void> {
3+
import { RestrictFileDTO } from '../dtos/RestrictFileDTO'
4+
// https://github.com/IQSS/dataverse/pull/11349/files
5+
export class RestrictFile implements UseCase<string> {
56
constructor(private readonly filesRepository: IFilesRepository) {}
67

78
/**
89
* Restrict or unrestrict an existing file.
910
* More detailed information about the file restriction behavior can be found in https://guides.dataverse.org/en/latest/api/native-api.html#restrict-files
1011
*
1112
* @param {number | string} [fileId] - The File identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
12-
* @param {boolean} [restrict] - A boolean value that indicates whether the file should be restricted or unrestricted.
13+
* @param {RestrictFileDTO} [restrictFileDTO] - The DTO containing the file restriction information.
1314
* @returns {Promise<void>} -This method does not return anything upon successful completion.
1415
*/
15-
async execute(fileId: number | string, restrict: boolean): Promise<void> {
16-
return await this.filesRepository.restrictFile(fileId, restrict)
16+
17+
async execute(fileId: number | string, restrictFileDTO: RestrictFileDTO): Promise<string> {
18+
return await this.filesRepository.restrictFile(fileId, restrictFileDTO)
1719
}
1820
}

src/files/infra/repositories/FilesRepository.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import { transformUploadDestinationsResponseToUploadDestination } from './transf
2121
import { UploadedFileDTO } from '../../domain/dtos/UploadedFileDTO'
2222
import { UpdateFileMetadataDTO } from '../../domain/dtos/UpdateFileMetadataDTO'
2323
import { ApiConstants } from '../../../core/infra/repositories/ApiConstants'
24+
import { RestrictFileDTO } from '../../domain/dtos/RestrictFileDTO'
2425

2526
export interface GetFilesQueryParams {
2627
includeDeaccessioned: boolean
@@ -346,9 +347,18 @@ export class FilesRepository extends ApiRepository implements IFilesRepository {
346347
})
347348
}
348349

349-
public async restrictFile(fileId: number | string, restrict: boolean): Promise<undefined> {
350-
return this.doPut(this.buildApiEndpoint(this.filesResourceName, 'restrict', fileId), restrict)
351-
.then(() => undefined)
350+
public async restrictFile(
351+
fileId: number | string,
352+
restrictFileDTO: RestrictFileDTO
353+
): Promise<string> {
354+
return this.doPut(
355+
this.buildApiEndpoint(this.filesResourceName, 'restrict', fileId),
356+
restrictFileDTO
357+
)
358+
.then((response) => {
359+
console.log('test', response.data.data.message)
360+
return response.data.data.message
361+
})
352362
.catch((error) => {
353363
throw error
354364
})

test/functional/files/RestrictFile.test.ts

Lines changed: 34 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -58,32 +58,36 @@ describe('execute', () => {
5858
try {
5959
const datasetFiles = await getDatasetFiles.execute(testDatasetIds.numericId)
6060

61-
await restrictFile.execute(datasetFiles.files[0].id, true)
61+
await restrictFile.execute(datasetFiles.files[0].id, { restrict: true })
6262
} catch (error) {
63-
throw new Error('File should be deleted')
63+
throw new Error('File should be restricted')
6464
} finally {
6565
const datasetFilesAfterRestriction = await getDatasetFiles.execute(testDatasetIds.numericId)
66-
6766
expect(datasetFilesAfterRestriction.files[0].restricted).toEqual(true)
68-
6967
// Unrestrict the file for the next test
70-
await restrictFile.execute(datasetFilesAfterRestriction.files[0].id, false)
68+
await restrictFile.execute(datasetFilesAfterRestriction.files[0].id, { restrict: false })
7169
}
7270
})
7371

7472
test('should succesfully unrestrict a file', async () => {
7573
try {
7674
const datasetFiles = await getDatasetFiles.execute(testDatasetIds.numericId)
77-
78-
await restrictFile.execute(datasetFiles.files[0].id, true)
79-
80-
await restrictFile.execute(datasetFiles.files[0].id, false)
75+
await restrictFile.execute(datasetFiles.files[0].id, { restrict: true })
8176
} catch (error) {
82-
throw new Error('File should be deleted')
77+
throw new Error('File should be restricted')
8378
} finally {
8479
const datasetFilesAfterRestriction = await getDatasetFiles.execute(testDatasetIds.numericId)
80+
expect(datasetFilesAfterRestriction.files[0].restricted).toEqual(true)
81+
}
8582

86-
expect(datasetFilesAfterRestriction.files[0].restricted).toEqual(false)
83+
try {
84+
const datasetFilesAfterRestriction = await getDatasetFiles.execute(testDatasetIds.numericId)
85+
await restrictFile.execute(datasetFilesAfterRestriction.files[0].id, { restrict: false })
86+
} catch (error) {
87+
throw new Error('File should be unrestricted')
88+
} finally {
89+
const datasetFilesAfterUnrestriction = await getDatasetFiles.execute(testDatasetIds.numericId)
90+
expect(datasetFilesAfterUnrestriction.files[0].restricted).toEqual(false)
8791
}
8892
})
8993

@@ -93,7 +97,7 @@ describe('execute', () => {
9397
const nonExistentFileId = 5
9498

9599
try {
96-
await restrictFile.execute(nonExistentFileId, true)
100+
await restrictFile.execute(nonExistentFileId, { restrict: true })
97101
throw new Error('Use case should throw an error')
98102
} catch (error) {
99103
writeError = error as WriteError
@@ -105,4 +109,22 @@ describe('execute', () => {
105109
)
106110
}
107111
})
112+
113+
test('should throw an error when the terms of use is empty while enableAccess is false', async () => {
114+
let caughtError: unknown
115+
try {
116+
const datasetFiles = await getDatasetFiles.execute(testDatasetIds.numericId)
117+
await restrictFile.execute(datasetFiles.files[0].id, {
118+
restrict: true,
119+
enableAccessRequest: false
120+
})
121+
} catch (error) {
122+
caughtError = error
123+
}
124+
125+
expect(caughtError).toBeInstanceOf(WriteError)
126+
expect((caughtError as WriteError).message).toEqual(
127+
'There was an error when writing the resource. Reason was: [409] Terms of Use and Access are invalid. You must enable request access or add terms of access in datasets with restricted files.'
128+
)
129+
})
108130
})

test/integration/files/FilesRepository.test.ts

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ import {
4141
deleteCollectionViaApi,
4242
setStorageDriverViaApi
4343
} from '../../testHelpers/collections/collectionHelper'
44+
import { RestrictFileDTO } from '../../../src/files/domain/dtos/RestrictFileDTO'
4445

4546
describe('FilesRepository', () => {
4647
const sut: FilesRepository = new FilesRepository()
@@ -766,13 +767,23 @@ describe('FilesRepository', () => {
766767
describe('restrictFile', () => {
767768
let restrictFileDatasetIds: CreatedDatasetIdentifiers
768769
const testTextFile1Name = 'test-file-1.txt'
770+
const restrictFileDTO: RestrictFileDTO = {
771+
restrict: true,
772+
enableAccessRequest: true,
773+
termsOfAccess: 'This file is restricted for testing purposes'
774+
}
775+
776+
const unrestrictFileDTO: RestrictFileDTO = {
777+
restrict: false,
778+
termsOfAccess: 'This file is restricted for testing purposes'
779+
}
769780

770781
const setFileToRestricted = async (fileId: number) => {
771-
await sut.restrictFile(fileId, true)
782+
await sut.restrictFile(fileId, restrictFileDTO)
772783
}
773784

774785
const setFileToUnrestricted = async (fileId: number) => {
775-
await sut.restrictFile(fileId, false)
786+
await sut.restrictFile(fileId, unrestrictFileDTO)
776787
}
777788

778789
beforeEach(async () => {

test/unit/files/RestrictFile.test.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,22 @@
11
import { WriteError } from '../../../src'
2+
import { RestrictFileDTO } from '../../../src/files/domain/dtos/RestrictFileDTO'
23
import { IFilesRepository } from '../../../src/files/domain/repositories/IFilesRepository'
34
import { RestrictFile } from '../../../src/files/domain/useCases/RestrictFile'
45

56
describe('execute', () => {
7+
const restrictFileDTO: RestrictFileDTO = {
8+
restrict: true,
9+
enableAccessRequest: true,
10+
termsOfAccess: 'This file is restricted for testing purposes'
11+
}
12+
613
test('should return undefined when repository call is successful', async () => {
714
const filesRepositoryStub: IFilesRepository = {} as IFilesRepository
815
filesRepositoryStub.restrictFile = jest.fn().mockResolvedValue(undefined)
916

1017
const sut = new RestrictFile(filesRepositoryStub)
1118

12-
const actual = await sut.execute(1, true)
19+
const actual = await sut.execute(1, restrictFileDTO)
1320

1421
expect(actual).toEqual(undefined)
1522
})
@@ -20,6 +27,6 @@ describe('execute', () => {
2027

2128
const sut = new RestrictFile(filesRepositoryStub)
2229

23-
await expect(sut.execute(1, true)).rejects.toThrow(WriteError)
30+
await expect(sut.execute(1, restrictFileDTO)).rejects.toThrow(WriteError)
2431
})
2532
})

0 commit comments

Comments
 (0)