From ab761a7290691189c85bde8a891af7e4b1f36745 Mon Sep 17 00:00:00 2001 From: Vera Clemens Date: Wed, 10 Dec 2025 16:57:11 +0100 Subject: [PATCH 1/4] feat: add use case for getting list of collections a user can create datasets in --- .../repositories/ICollectionsRepository.ts | 1 + .../useCases/GetCollectionsForCreating.ts | 21 +++++++++++++++ src/collections/index.ts | 5 +++- .../repositories/CollectionsRepository.ts | 26 +++++++++++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) create mode 100644 src/collections/domain/useCases/GetCollectionsForCreating.ts diff --git a/src/collections/domain/repositories/ICollectionsRepository.ts b/src/collections/domain/repositories/ICollectionsRepository.ts index bc8960c8..a7076293 100644 --- a/src/collections/domain/repositories/ICollectionsRepository.ts +++ b/src/collections/domain/repositories/ICollectionsRepository.ts @@ -68,4 +68,5 @@ export interface ICollectionsRepository { searchTerm: string, alreadyLinked: boolean ): Promise + getCollectionsForCreating(userIdentifier?: string): Promise } diff --git a/src/collections/domain/useCases/GetCollectionsForCreating.ts b/src/collections/domain/useCases/GetCollectionsForCreating.ts new file mode 100644 index 00000000..d0310320 --- /dev/null +++ b/src/collections/domain/useCases/GetCollectionsForCreating.ts @@ -0,0 +1,21 @@ +import { UseCase } from '../../../core/domain/useCases/UseCase' +import { ICollectionsRepository } from '../repositories/ICollectionsRepository' +import { CollectionSummary } from '../models/CollectionSummary' + +export class GetCollectionsForCreating implements UseCase { + private collectionsRepository: ICollectionsRepository + + constructor(collectionsRepository: ICollectionsRepository) { + this.collectionsRepository = collectionsRepository + } + + /** + * Returns an array of CollectionSummary (id, alias, displayName) of the collections an authenticated user can create a Dataset in. + * @param userIdentifier - May be used by a superuser to get the collections for a specific user. + */ + async execute( + userIdentifier?: string + ): Promise { + return await this.collectionsRepository.getCollectionsForCreating(userIdentifier) + } +} diff --git a/src/collections/index.ts b/src/collections/index.ts index 59e2e50b..54519357 100644 --- a/src/collections/index.ts +++ b/src/collections/index.ts @@ -16,6 +16,7 @@ import { LinkCollection } from './domain/useCases/LinkCollection' import { UnlinkCollection } from './domain/useCases/UnlinkCollection' import { GetCollectionLinks } from './domain/useCases/GetCollectionLinks' import { GetCollectionsForLinking } from './domain/useCases/GetCollectionsForLinking' +import { GetCollectionsForCreating } from './domain/useCases/GetCollectionsForCreating' const collectionsRepository = new CollectionsRepository() @@ -36,6 +37,7 @@ const linkCollection = new LinkCollection(collectionsRepository) const unlinkCollection = new UnlinkCollection(collectionsRepository) const getCollectionLinks = new GetCollectionLinks(collectionsRepository) const getCollectionsForLinking = new GetCollectionsForLinking(collectionsRepository) +const getCollectionsForCreating = new GetCollectionsForCreating(collectionsRepository) export { getCollection, @@ -54,7 +56,8 @@ export { linkCollection, unlinkCollection, getCollectionLinks, - getCollectionsForLinking + getCollectionsForLinking, + getCollectionsForCreating } export { Collection, CollectionInputLevel } from './domain/models/Collection' export { CollectionFacet } from './domain/models/CollectionFacet' diff --git a/src/collections/infra/repositories/CollectionsRepository.ts b/src/collections/infra/repositories/CollectionsRepository.ts index e0e459b0..6e902831 100644 --- a/src/collections/infra/repositories/CollectionsRepository.ts +++ b/src/collections/infra/repositories/CollectionsRepository.ts @@ -528,4 +528,30 @@ export class CollectionsRepository extends ApiRepository implements ICollections throw error }) } + + public async getCollectionsForCreating(userIdentifier?: string): Promise { + const queryParams = new URLSearchParams() + + if (userIdentifier) { + queryParams.set(GetMyDataCollectionItemsQueryParams.USER_IDENTIFIER, userIdentifier) + } + + return this.doGet("/mydata/retrieve/collectionList", true, queryParams) + .then((response) => { + const payload = response.data.data as { + id: number + alias: string + name: string + }[] + + return payload.map((item) => ({ + id: item.id, + alias: item.alias, + displayName: item.name + })) + }) + .catch((error) => { + throw error + }) + } } From 1814b77b1de719173ca3b088bf9da2ce91c6f804 Mon Sep 17 00:00:00 2001 From: Vera Clemens Date: Wed, 10 Dec 2025 17:11:49 +0100 Subject: [PATCH 2/4] fix: add use case for getting list of collections a user can create datasets in --- src/collections/infra/repositories/CollectionsRepository.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/collections/infra/repositories/CollectionsRepository.ts b/src/collections/infra/repositories/CollectionsRepository.ts index 6e902831..ec5383cd 100644 --- a/src/collections/infra/repositories/CollectionsRepository.ts +++ b/src/collections/infra/repositories/CollectionsRepository.ts @@ -538,7 +538,7 @@ export class CollectionsRepository extends ApiRepository implements ICollections return this.doGet("/mydata/retrieve/collectionList", true, queryParams) .then((response) => { - const payload = response.data.data as { + const payload = response.data.data.items as { id: number alias: string name: string From 3725bb7cb83616d549ee8076ea7082ccb5f64329 Mon Sep 17 00:00:00 2001 From: Vera Clemens Date: Tue, 27 Jan 2026 10:07:43 +0100 Subject: [PATCH 3/4] test: test use case for getting list of collections a user can create datasets in --- .../GetCollectionsForCreating.test.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 test/unit/collections/GetCollectionsForCreating.test.ts diff --git a/test/unit/collections/GetCollectionsForCreating.test.ts b/test/unit/collections/GetCollectionsForCreating.test.ts new file mode 100644 index 00000000..d4042b3b --- /dev/null +++ b/test/unit/collections/GetCollectionsForCreating.test.ts @@ -0,0 +1,28 @@ +import { ICollectionsRepository } from '../../../src/collections/domain/repositories/ICollectionsRepository' +import { GetCollectionsForCreating } from '../../../src/collections/domain/useCases/GetCollectionsForCreating' +import { CollectionSummary, ReadError } from '../../../src' + +const sample: CollectionSummary[] = [ + { id: 1, alias: 'col1', displayName: 'Collection 1' }, + { id: 2, alias: 'col2', displayName: 'Collection 2' } +] + +describe('GetCollectionsForCreating', () => { + test('should return collections for creating on success', async () => { + const repo: ICollectionsRepository = {} as ICollectionsRepository + repo.getCollectionsForCreating = jest.fn().mockResolvedValue(sample) + + const uc = new GetCollectionsForCreating(repo) + await expect(uc.execute('testUser')).resolves.toEqual(sample) + expect(repo.getCollectionsForCreating).toHaveBeenCalledWith('@testUser') + }) + + test('should return error result on repository error', async () => { + const repo: ICollectionsRepository = {} as ICollectionsRepository + repo.getCollectionsForCreating = jest.fn().mockRejectedValue(new ReadError('x')) + + const uc = new GetCollectionsForCreating(repo) + await expect(uc.execute('testUser')).rejects.toThrow(ReadError) + expect(repo.getCollectionsForCreating).toHaveBeenCalledWith('@testUser') + }) +}) From b575086d5f807834777635963b72dad721dd1a2c Mon Sep 17 00:00:00 2001 From: Vera Clemens Date: Tue, 27 Jan 2026 10:21:54 +0100 Subject: [PATCH 4/4] docs: add docs for getting list of collections a user can create datasets in --- docs/useCases.md | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/docs/useCases.md b/docs/useCases.md index f77a40e1..21ba1424 100644 --- a/docs/useCases.md +++ b/docs/useCases.md @@ -17,6 +17,7 @@ The different use cases currently available in the package are classified below, - [List My Data Collection Items](#list-my-data-collection-items) - [Get Collection Featured Items](#get-collection-featured-items) - [Get Collections for Linking](#get-collections-for-linking) + - [Get Collections for Creating](#get-collections-for-creating) - [Collections write use cases](#collections-write-use-cases) - [Create a Collection](#create-a-collection) - [Update a Collection](#update-a-collection) @@ -409,6 +410,46 @@ Notes: - When the first argument is `'collection'`, the second argument can be a numeric collection id or a collection alias. - When the first argument is `'dataset'`, the second argument must be the dataset persistent identifier string (e.g., `doi:...`). +#### Get Collections for Creating + +Returns an array of [CollectionSummary](../src/collections/domain/models/CollectionSummary.ts) (id, alias, displayName) representing the Dataverse collections which an authenticated user may create a new dataset in. + +##### Example calls: + +```typescript +import { getCollectionsForCreating } from '@iqss/dataverse-client-javascript' + +/* ... */ + +// Case 1: For the user who is currently authenticated +getCollectionsForCreating + .execute() + .then((collections) => { + // collections: CollectionSummary[] + /* ... */ + }) + .catch((error: Error) => { + /* ... */ + }) + +/* ... */ + +// Case 2: For a given user (by username) +const username = 'anotherUser' + +getCollectionsForCreating + .execute(username) + .then((collections) => { + // collections: CollectionSummary[] + /* ... */ + }) + .catch((error: Error) => { + /* ... */ + }) +``` + +_See [use case](../src/collections/domain/useCases/GetCollectionsForCreating.ts) implementation_. + ### Collections Write Use Cases #### Create a Collection