Skip to content

Commit d6aeece

Browse files
committed
Added: GetCollectionUserPermissions use case
1 parent ceba6f3 commit d6aeece

File tree

14 files changed

+305
-3
lines changed

14 files changed

+305
-3
lines changed

docs/useCases.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ The different use cases currently available in the package are classified below,
1212
- [Collections read use cases](#collections-read-use-cases)
1313
- [Get a Collection](#get-a-collection)
1414
- [Get Collection Facets](#get-collection-facets)
15+
- [Get User Permissions on a Collection](#get-user-permissions-on-a-collection)
1516
- [Collections write use cases](#collections-write-use-cases)
1617
- [Create a Collection](#create-a-collection)
1718
- [Datasets](#Datasets)
@@ -128,6 +129,34 @@ The `collectionIdOrAlias` is a generic collection identifier, which can be eithe
128129

129130
If no collection identifier is specified, the default collection identifier; `root` will be used. If you want to search for a different collection, you must add the collection identifier as a parameter in the use case call.
130131

132+
#### Get User Permissions on a Collection
133+
134+
Returns an instance of [CollectionUserPermissions](../src/collections/domain/models/CollectionUserPermissions.ts) that includes the permissions that the calling user has on a particular Collection.
135+
136+
##### Example call:
137+
138+
```typescript
139+
import { getCollectionUserPermissions } from '@iqss/dataverse-client-javascript'
140+
141+
/* ... */
142+
143+
const collectionIdOrAlias = 12345
144+
145+
getCollectionUserPermissions
146+
.execute(collectionIdOrAlias)
147+
.then((permissions: CollectionUserPermissions) => {
148+
/* ... */
149+
})
150+
151+
/* ... */
152+
```
153+
154+
_See [use case](../src/collections/domain/useCases/GetCollectionUserPermissions.ts) implementation_.
155+
156+
The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId).
157+
158+
If no collection identifier is specified, the default collection identifier; `root` will be used. If you want to search for a different collection, you must add the collection identifier as a parameter in the use case call.
159+
131160
### Collections Write Use Cases
132161

133162
#### Create a Collection
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export interface CollectionUserPermissions {
2+
canAddCollection: boolean
3+
canAddDataset: boolean
4+
canViewUnpublishedCollection: boolean
5+
canEditCollection: boolean
6+
canManageCollectionPermissions: boolean
7+
canPublishCollection: boolean
8+
canDeleteCollection: boolean
9+
}

src/collections/domain/repositories/ICollectionsRepository.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { CollectionDTO } from '../dtos/CollectionDTO'
22
import { Collection } from '../models/Collection'
3+
import { CollectionUserPermissions } from '../models/CollectionUserPermissions'
34

45
export interface ICollectionsRepository {
56
getCollection(collectionIdOrAlias: number | string): Promise<Collection>
@@ -8,4 +9,7 @@ export interface ICollectionsRepository {
89
parentCollectionId: number | string
910
): Promise<number>
1011
getCollectionFacets(collectionIdOrAlias: number | string): Promise<string[]>
12+
getCollectionUserPermissions(
13+
collectionIdOrAlias: number | string
14+
): Promise<CollectionUserPermissions>
1115
}
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 { CollectionUserPermissions } from '../models/CollectionUserPermissions'
3+
import { ICollectionsRepository } from '../repositories/ICollectionsRepository'
4+
5+
export class GetCollectionUserPermissions implements UseCase<CollectionUserPermissions> {
6+
private collectionsRepository: ICollectionsRepository
7+
8+
constructor(collectionsRepository: ICollectionsRepository) {
9+
this.collectionsRepository = collectionsRepository
10+
}
11+
12+
/**
13+
* Returns an instance of CollectionUserPermissions that includes the permissions that the calling user has on a particular Collection.
14+
*
15+
* @param {number | string} [collectionIdOrAlias = 'root'] - A generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId)
16+
* If this parameter is not set, the default value is: 'root'
17+
* @returns {Promise<CollectionUserPermissions>}
18+
*/
19+
async execute(collectionIdOrAlias: number | string): Promise<CollectionUserPermissions> {
20+
return await this.collectionsRepository.getCollectionUserPermissions(collectionIdOrAlias)
21+
}
22+
}

src/collections/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { CreateCollection } from './domain/useCases/CreateCollection'
22
import { GetCollection } from './domain/useCases/GetCollection'
33
import { GetCollectionFacets } from './domain/useCases/GetCollectionFacets'
4+
import { GetCollectionUserPermissions } from './domain/useCases/GetCollectionUserPermissions'
45

56
import { CollectionsRepository } from './infra/repositories/CollectionsRepository'
67

@@ -9,7 +10,9 @@ const collectionsRepository = new CollectionsRepository()
910
const getCollection = new GetCollection(collectionsRepository)
1011
const createCollection = new CreateCollection(collectionsRepository)
1112
const getCollectionFacets = new GetCollectionFacets(collectionsRepository)
13+
const getCollectionUserPermissions = new GetCollectionUserPermissions(collectionsRepository)
1214

13-
export { getCollection, createCollection, getCollectionFacets }
15+
export { getCollection, createCollection, getCollectionFacets, getCollectionUserPermissions }
1416
export { Collection, CollectionInputLevel } from './domain/models/Collection'
17+
export { CollectionUserPermissions } from './domain/models/CollectionUserPermissions'
1518
export { CollectionDTO, CollectionInputLevelDTO } from './domain/dtos/CollectionDTO'

src/collections/infra/repositories/CollectionsRepository.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { ICollectionsRepository } from '../../domain/repositories/ICollectionsRe
33
import { transformCollectionResponseToCollection } from './transformers/collectionTransformers'
44
import { Collection, ROOT_COLLECTION_ALIAS } from '../../domain/models/Collection'
55
import { CollectionDTO } from '../../domain/dtos/CollectionDTO'
6+
import { CollectionUserPermissions } from '../../domain/models/CollectionUserPermissions'
7+
import { transformCollectionUserPermissionsResponseToCollectionUserPermissions } from './transformers/collectionUserPermissionsTransformers'
68

79
export interface NewCollectionRequestPayload {
810
alias: string
@@ -86,4 +88,19 @@ export class CollectionsRepository extends ApiRepository implements ICollections
8688
throw error
8789
})
8890
}
91+
92+
public async getCollectionUserPermissions(
93+
collectionIdOrAlias: number | string
94+
): Promise<CollectionUserPermissions> {
95+
return this.doGet(
96+
`/${this.collectionsResourceName}/${collectionIdOrAlias}/userPermissions`,
97+
true
98+
)
99+
.then((response) =>
100+
transformCollectionUserPermissionsResponseToCollectionUserPermissions(response)
101+
)
102+
.catch((error) => {
103+
throw error
104+
})
105+
}
89106
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
export interface CollectionUserPermissionsPayload {
2+
canAddDataverse: boolean
3+
canAddDataset: boolean
4+
canViewUnpublishedDataverse: boolean
5+
canEditDataverse: boolean
6+
canManageDataversePermissions: boolean
7+
canPublishDataverse: boolean
8+
canDeleteDataverse: boolean
9+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { AxiosResponse } from 'axios'
2+
import { CollectionUserPermissions } from '../../../domain/models/CollectionUserPermissions'
3+
4+
export const transformCollectionUserPermissionsResponseToCollectionUserPermissions = (
5+
response: AxiosResponse
6+
): CollectionUserPermissions => {
7+
const collectionUserPermissionsPayload = response.data.data
8+
return {
9+
canAddCollection: collectionUserPermissionsPayload.canAddDataverse,
10+
canAddDataset: collectionUserPermissionsPayload.canAddDataset,
11+
canViewUnpublishedCollection: collectionUserPermissionsPayload.canViewUnpublishedDataverse,
12+
canEditCollection: collectionUserPermissionsPayload.canEditDataverse,
13+
canManageCollectionPermissions: collectionUserPermissionsPayload.canManageDataversePermissions,
14+
canPublishCollection: collectionUserPermissionsPayload.canPublishDataverse,
15+
canDeleteCollection: collectionUserPermissionsPayload.canDeleteDataverse
16+
}
17+
}

test/environment/.env

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
POSTGRES_VERSION=13
22
DATAVERSE_DB_USER=dataverse
33
SOLR_VERSION=9.3.0
4-
DATAVERSE_IMAGE_REGISTRY=docker.io
5-
DATAVERSE_IMAGE_TAG=unstable
4+
DATAVERSE_IMAGE_REGISTRY=ghcr.io
5+
DATAVERSE_IMAGE_TAG=10749-dataverse-user-permissions-api
66
DATAVERSE_BOOTSTRAP_TIMEOUT=5m
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
import {
2+
ApiConfig,
3+
CollectionUserPermissions,
4+
ReadError,
5+
getCollectionUserPermissions
6+
} from '../../../src'
7+
import { TestConstants } from '../../testHelpers/TestConstants'
8+
import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'
9+
import { ROOT_COLLECTION_ALIAS } from '../../../src/collections/domain/models/Collection'
10+
11+
describe('execute', () => {
12+
beforeEach(async () => {
13+
ApiConfig.init(
14+
TestConstants.TEST_API_URL,
15+
DataverseApiAuthMechanism.API_KEY,
16+
process.env.TEST_API_KEY
17+
)
18+
})
19+
20+
test('should return user permissions when a valid collection alias is provided', async () => {
21+
let actual: CollectionUserPermissions
22+
try {
23+
actual = await getCollectionUserPermissions.execute(ROOT_COLLECTION_ALIAS)
24+
} catch (error) {
25+
throw new Error('Permissions should be retrieved')
26+
} finally {
27+
expect(actual.canAddDataset).toBe(true)
28+
expect(actual.canAddCollection).toBe(true)
29+
expect(actual.canDeleteCollection).toBe(true)
30+
expect(actual.canEditCollection).toBe(true)
31+
expect(actual.canManageCollectionPermissions).toBe(true)
32+
expect(actual.canPublishCollection).toBe(true)
33+
expect(actual.canViewUnpublishedCollection).toBe(true)
34+
}
35+
})
36+
37+
test('should throw an error when collection does not exist', async () => {
38+
expect.assertions(2)
39+
let readError: ReadError
40+
try {
41+
await getCollectionUserPermissions.execute(TestConstants.TEST_DUMMY_COLLECTION_ID)
42+
throw new Error('Use case should throw an error')
43+
} catch (error) {
44+
readError = error
45+
} finally {
46+
expect(readError).toBeInstanceOf(ReadError)
47+
expect(readError.message).toEqual(
48+
`There was an error when reading the resource. Reason was: [404] Can't find dataverse with identifier='${TestConstants.TEST_DUMMY_COLLECTION_ID}'`
49+
)
50+
}
51+
})
52+
})

0 commit comments

Comments
 (0)