diff --git a/docs/useCases.md b/docs/useCases.md index 6d0e4602..bfe762bf 100644 --- a/docs/useCases.md +++ b/docs/useCases.md @@ -108,7 +108,7 @@ _See [use case](../src/collections/domain/useCases/GetCollection.ts)_ definition The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId). -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. +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. #### Get Collection Facets @@ -135,7 +135,7 @@ _See [use case](../src/collections/domain/useCases/GetCollectionFacets.ts)_ defi The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId). -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. +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. #### Get User Permissions on a Collection @@ -163,7 +163,7 @@ _See [use case](../src/collections/domain/useCases/GetCollectionUserPermissions. The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId). -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. +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. #### List All Collection Items @@ -203,7 +203,7 @@ This use case supports the following optional parameters depending on the search #### Create a Collection -Creates a new Collection, given a [CollectionDTO](../src/collections/domain/dtos/CollectionDTO.ts) object and an optional parent collection identifier, which defaults to `root`. +Creates a new Collection, given a [CollectionDTO](../src/collections/domain/dtos/CollectionDTO.ts) object and an optional parent collection identifier, which defaults to `:root`. ##### Example call: @@ -228,7 +228,7 @@ createCollection.execute(collectionDTO).then((createdCollectionId: number) => { _See [use case](../src/collections/domain/useCases/CreateCollection.ts) implementation_. -The above example creates the new collection in the `root` collection since no collection identifier is specified. If you want to create the collection in a different collection, you must add the collection identifier as a second parameter in the use case call. +The above example creates the new collection in the root collection since no collection identifier is specified. If you want to create the collection in a different collection, you must add the collection identifier as a second parameter in the use case call. The use case returns a number, which is the identifier of the created collection. @@ -454,7 +454,7 @@ _See [use case](../src/datasets/domain/useCases/GetAllDatasetPreviews.ts) implem Note that `limit` and `offset` are optional parameters for pagination. -Note that `collectionId` is an optional parameter to filter datasets by collection. If not set, the default value is `root`. +Note that `collectionId` is an optional parameter to filter datasets by collection. If not set, the default value is `:root`. The `DatasetPreviewSubset`returned instance contains a property called `totalDatasetCount` which is necessary for pagination. @@ -462,7 +462,7 @@ The `DatasetPreviewSubset`returned instance contains a property called `totalDat #### Create a Dataset -Creates a new Dataset in a collection, given a [DatasetDTO](../src/datasets/domain/dtos/DatasetDTO.ts) object and an optional collection identifier, which defaults to `root`. +Creates a new Dataset in a collection, given a [DatasetDTO](../src/datasets/domain/dtos/DatasetDTO.ts) object and an optional collection identifier, which defaults to `:root`. This use case validates the submitted fields of each metadata block and can return errors of type [ResourceValidationError](../src/core/domain/useCases/validators/errors/ResourceValidationError.ts), which include sufficient information to determine which field value is invalid and why. @@ -517,7 +517,7 @@ createDataset.execute(datasetDTO).then((newDatasetIds: CreatedDatasetIdentifiers _See [use case](../src/datasets/domain/useCases/CreateDataset.ts) implementation_. -The above example creates the new dataset in the `root` collection since no collection identifier is specified. If you want to create the dataset in a different collection, you must add the collection identifier as a second parameter in the use case call. +The above example creates the new dataset in the root collection since no collection identifier is specified. If you want to create the dataset in a different collection, you must add the collection identifier as a second parameter in the use case call. The use case returns a [CreatedDatasetIdentifiers](../src/datasets/domain/models/CreatedDatasetIdentifiers.ts) object, which includes the persistent and numeric identifiers of the created dataset. diff --git a/src/collections/domain/models/Collection.ts b/src/collections/domain/models/Collection.ts index 24dd60aa..1cc1f1e4 100644 --- a/src/collections/domain/models/Collection.ts +++ b/src/collections/domain/models/Collection.ts @@ -17,4 +17,4 @@ export interface CollectionInputLevel { required: boolean } -export const ROOT_COLLECTION_ALIAS = 'root' +export const ROOT_COLLECTION_ID = ':root' diff --git a/src/collections/domain/useCases/CreateCollection.ts b/src/collections/domain/useCases/CreateCollection.ts index cff0e78e..58a781c3 100644 --- a/src/collections/domain/useCases/CreateCollection.ts +++ b/src/collections/domain/useCases/CreateCollection.ts @@ -1,6 +1,6 @@ import { UseCase } from '../../../core/domain/useCases/UseCase' import { CollectionDTO } from '../dtos/CollectionDTO' -import { ROOT_COLLECTION_ALIAS } from '../models/Collection' +import { ROOT_COLLECTION_ID } from '../models/Collection' import { ICollectionsRepository } from '../repositories/ICollectionsRepository' export class CreateCollection implements UseCase { @@ -11,16 +11,16 @@ export class CreateCollection implements UseCase { } /** - * Creates a new collection, given a CollectionDTO object and an optional collection identifier, which defaults to root. + * Creates a new collection, given a CollectionDTO object and an optional collection identifier, which defaults to :root. * * @param {CollectionDTO} [newCollection] - CollectionDTO object including the new collection data. - * @param {string} [parentCollectionId] - Specifies the parent collection identifier (optional, defaults to root). + * @param {string} [parentCollectionId] - Specifies the parent collection identifier (optional, defaults to :root). * @returns {Promise} - The created collection identifier. * @throws {WriteError} - If there are errors while writing data. */ async execute( newCollection: CollectionDTO, - parentCollectionId: number | string = ROOT_COLLECTION_ALIAS + parentCollectionId: number | string = ROOT_COLLECTION_ID ): Promise { return await this.collectionsRepository.createCollection(newCollection, parentCollectionId) } diff --git a/src/collections/domain/useCases/GetCollection.ts b/src/collections/domain/useCases/GetCollection.ts index f17de63e..38f1d6d6 100644 --- a/src/collections/domain/useCases/GetCollection.ts +++ b/src/collections/domain/useCases/GetCollection.ts @@ -1,6 +1,6 @@ import { UseCase } from '../../../core/domain/useCases/UseCase' import { ICollectionsRepository } from '../repositories/ICollectionsRepository' -import { Collection, ROOT_COLLECTION_ALIAS } from '../models/Collection' +import { Collection, ROOT_COLLECTION_ID } from '../models/Collection' export class GetCollection implements UseCase { private collectionsRepository: ICollectionsRepository @@ -12,11 +12,11 @@ export class GetCollection implements UseCase { /** * Returns a Collection instance, given the search parameters to identify it. * - * @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) - * If this parameter is not set, the default value is: 'root' + * @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) + * If this parameter is not set, the default value is: ':root' * @returns {Promise} */ - async execute(collectionIdOrAlias: number | string = ROOT_COLLECTION_ALIAS): Promise { + async execute(collectionIdOrAlias: number | string = ROOT_COLLECTION_ID): Promise { return await this.collectionsRepository.getCollection(collectionIdOrAlias) } } diff --git a/src/collections/domain/useCases/GetCollectionFacets.ts b/src/collections/domain/useCases/GetCollectionFacets.ts index a1a8d849..3402dbf4 100644 --- a/src/collections/domain/useCases/GetCollectionFacets.ts +++ b/src/collections/domain/useCases/GetCollectionFacets.ts @@ -1,6 +1,6 @@ import { UseCase } from '../../../core/domain/useCases/UseCase' import { ICollectionsRepository } from '../repositories/ICollectionsRepository' -import { ROOT_COLLECTION_ALIAS } from '../models/Collection' +import { ROOT_COLLECTION_ID } from '../models/Collection' import { CollectionFacet } from '../models/CollectionFacet' export class GetCollectionFacets implements UseCase { @@ -13,12 +13,12 @@ export class GetCollectionFacets implements UseCase { /** * Returns a CollectionFacet array containing the facets of the requested collection, given the collection identifier or alias. * - * @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) - * If this parameter is not set, the default value is: 'root' + * @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) + * If this parameter is not set, the default value is: ':root' * @returns {Promise} */ async execute( - collectionIdOrAlias: number | string = ROOT_COLLECTION_ALIAS + collectionIdOrAlias: number | string = ROOT_COLLECTION_ID ): Promise { return await this.collectionsRepository.getCollectionFacets(collectionIdOrAlias) } diff --git a/src/collections/domain/useCases/GetCollectionUserPermissions.ts b/src/collections/domain/useCases/GetCollectionUserPermissions.ts index bf8cc7bd..58f83014 100644 --- a/src/collections/domain/useCases/GetCollectionUserPermissions.ts +++ b/src/collections/domain/useCases/GetCollectionUserPermissions.ts @@ -1,6 +1,7 @@ import { UseCase } from '../../../core/domain/useCases/UseCase' import { CollectionUserPermissions } from '../models/CollectionUserPermissions' import { ICollectionsRepository } from '../repositories/ICollectionsRepository' +import { ROOT_COLLECTION_ID } from '../models/Collection' export class GetCollectionUserPermissions implements UseCase { private collectionsRepository: ICollectionsRepository @@ -12,11 +13,13 @@ export class GetCollectionUserPermissions implements UseCase} */ - async execute(collectionIdOrAlias: number | string): Promise { + async execute( + collectionIdOrAlias: number | string = ROOT_COLLECTION_ID + ): Promise { return await this.collectionsRepository.getCollectionUserPermissions(collectionIdOrAlias) } } diff --git a/src/collections/infra/repositories/CollectionsRepository.ts b/src/collections/infra/repositories/CollectionsRepository.ts index 167a749e..46121723 100644 --- a/src/collections/infra/repositories/CollectionsRepository.ts +++ b/src/collections/infra/repositories/CollectionsRepository.ts @@ -5,7 +5,7 @@ import { transformCollectionItemsResponseToCollectionItemSubset, transformCollectionResponseToCollection } from './transformers/collectionTransformers' -import { Collection, ROOT_COLLECTION_ALIAS } from '../../domain/models/Collection' +import { Collection, ROOT_COLLECTION_ID } from '../../domain/models/Collection' import { CollectionDTO } from '../../domain/dtos/CollectionDTO' import { CollectionFacet } from '../../domain/models/CollectionFacet' import { CollectionUserPermissions } from '../../domain/models/CollectionUserPermissions' @@ -52,7 +52,7 @@ export class CollectionsRepository extends ApiRepository implements ICollections private readonly collectionsResourceName: string = 'dataverses' public async getCollection( - collectionIdOrAlias: number | string = ROOT_COLLECTION_ALIAS + collectionIdOrAlias: number | string = ROOT_COLLECTION_ID ): Promise { return this.doGet(`/${this.collectionsResourceName}/${collectionIdOrAlias}`, true, { returnOwners: true @@ -65,7 +65,7 @@ export class CollectionsRepository extends ApiRepository implements ICollections public async createCollection( collectionDTO: CollectionDTO, - parentCollectionId: number | string = ROOT_COLLECTION_ALIAS + parentCollectionId: number | string = ROOT_COLLECTION_ID ): Promise { const dataverseContacts: NewCollectionContactRequestPayload[] = collectionDTO.contacts.map( (contact) => ({ diff --git a/src/datasets/domain/useCases/CreateDataset.ts b/src/datasets/domain/useCases/CreateDataset.ts index 28e2b3f8..65bffae4 100644 --- a/src/datasets/domain/useCases/CreateDataset.ts +++ b/src/datasets/domain/useCases/CreateDataset.ts @@ -3,7 +3,7 @@ import { DatasetDTO } from '../dtos/DatasetDTO' import { ResourceValidator } from '../../../core/domain/useCases/validators/ResourceValidator' import { IMetadataBlocksRepository } from '../../../metadataBlocks/domain/repositories/IMetadataBlocksRepository' import { CreatedDatasetIdentifiers } from '../models/CreatedDatasetIdentifiers' -import { ROOT_COLLECTION_ALIAS } from '../../../collections/domain/models/Collection' +import { ROOT_COLLECTION_ID } from '../../../collections/domain/models/Collection' import { DatasetWriteUseCase } from './DatasetWriteUseCase' export class CreateDataset extends DatasetWriteUseCase { @@ -16,10 +16,10 @@ export class CreateDataset extends DatasetWriteUseCase} * @throws {ResourceValidationError} - If there are validation errors related to the provided information. * @throws {ReadError} - If there are errors while reading data. @@ -27,7 +27,7 @@ export class CreateDataset extends DatasetWriteUseCase { const metadataBlocks = await this.getNewDatasetMetadataBlocks(newDataset) this.getNewDatasetValidator().validate(newDataset, metadataBlocks) diff --git a/src/metadataBlocks/domain/useCases/GetCollectionMetadataBlocks.ts b/src/metadataBlocks/domain/useCases/GetCollectionMetadataBlocks.ts index 921a9343..c953c16a 100644 --- a/src/metadataBlocks/domain/useCases/GetCollectionMetadataBlocks.ts +++ b/src/metadataBlocks/domain/useCases/GetCollectionMetadataBlocks.ts @@ -1,6 +1,6 @@ import { UseCase } from '../../../core/domain/useCases/UseCase' import { MetadataBlock } from '../..' -import { ROOT_COLLECTION_ALIAS } from '../../../collections/domain/models/Collection' +import { ROOT_COLLECTION_ID } from '../../../collections/domain/models/Collection' import { IMetadataBlocksRepository } from '../repositories/IMetadataBlocksRepository' export class GetCollectionMetadataBlocks implements UseCase { @@ -13,13 +13,13 @@ export class GetCollectionMetadataBlocks implements UseCase { /** * Returns a MetadataBlock array containing the metadata blocks from the requested collection. * - * @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) - * If this parameter is not set, the default value is: 'root' + * @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) + * If this parameter is not set, the default value is: ':root' * @param {boolean} [onlyDisplayedOnCreate=false] - Indicates whether or not to return only the metadata blocks that are displayed on dataset creation. The default value is false. * @returns {Promise} */ async execute( - collectionIdOrAlias: number | string = ROOT_COLLECTION_ALIAS, + collectionIdOrAlias: number | string = ROOT_COLLECTION_ID, onlyDisplayedOnCreate = false ): Promise { return await this.metadataBlocksRepository.getCollectionMetadataBlocks( diff --git a/test/functional/collections/GetCollectionFacets.test.ts b/test/functional/collections/GetCollectionFacets.test.ts index 5054d16d..e2a88ffe 100644 --- a/test/functional/collections/GetCollectionFacets.test.ts +++ b/test/functional/collections/GetCollectionFacets.test.ts @@ -1,7 +1,8 @@ import { ApiConfig, CollectionFacet, ReadError, getCollectionFacets } from '../../../src' import { TestConstants } from '../../testHelpers/TestConstants' import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig' -import { ROOT_COLLECTION_ALIAS } from '../../../src/collections/domain/models/Collection' + +import { ROOT_COLLECTION_ALIAS } from '../../testHelpers/collections/collectionHelper' describe('execute', () => { beforeEach(async () => { diff --git a/test/functional/collections/GetCollectionUserPermissions.test.ts b/test/functional/collections/GetCollectionUserPermissions.test.ts index fd813979..fbac8b12 100644 --- a/test/functional/collections/GetCollectionUserPermissions.test.ts +++ b/test/functional/collections/GetCollectionUserPermissions.test.ts @@ -6,7 +6,8 @@ import { } from '../../../src' import { TestConstants } from '../../testHelpers/TestConstants' import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig' -import { ROOT_COLLECTION_ALIAS } from '../../../src/collections/domain/models/Collection' + +import { ROOT_COLLECTION_ALIAS } from '../../testHelpers/collections/collectionHelper' describe('execute', () => { beforeEach(async () => { @@ -17,6 +18,22 @@ describe('execute', () => { ) }) + test('should return user permissions for the default collection', async () => { + let actual: CollectionUserPermissions + try { + actual = await getCollectionUserPermissions.execute() + } catch (error) { + throw new Error('Permissions should be retrieved') + } finally { + expect(actual.canAddDataset).toBe(true) + expect(actual.canAddCollection).toBe(true) + expect(actual.canDeleteCollection).toBe(true) + expect(actual.canEditCollection).toBe(true) + expect(actual.canManageCollectionPermissions).toBe(true) + expect(actual.canPublishCollection).toBe(true) + expect(actual.canViewUnpublishedCollection).toBe(true) + } + }) test('should return user permissions when a valid collection alias is provided', async () => { let actual: CollectionUserPermissions try { diff --git a/test/integration/collections/CollectionsRepository.test.ts b/test/integration/collections/CollectionsRepository.test.ts index be293662..89d6d2ba 100644 --- a/test/integration/collections/CollectionsRepository.test.ts +++ b/test/integration/collections/CollectionsRepository.test.ts @@ -16,9 +16,9 @@ import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ import { createCollectionDTO, createCollectionViaApi, - deleteCollectionViaApi + deleteCollectionViaApi, + ROOT_COLLECTION_ALIAS } from '../../testHelpers/collections/collectionHelper' -import { ROOT_COLLECTION_ALIAS } from '../../../src/collections/domain/models/Collection' import { CollectionPayload } from '../../../src/collections/infra/repositories/transformers/CollectionPayload' import { uploadFileViaApi } from '../../testHelpers/files/filesHelper' import { deleteUnpublishedDatasetViaApi } from '../../testHelpers/datasets/datasetHelper' diff --git a/test/integration/datasets/DatasetsRepository.test.ts b/test/integration/datasets/DatasetsRepository.test.ts index 95df6123..db561395 100644 --- a/test/integration/datasets/DatasetsRepository.test.ts +++ b/test/integration/datasets/DatasetsRepository.test.ts @@ -26,10 +26,10 @@ import { DatasetContact, DatasetDescription } from '../../../src/datasets/domain/models/Dataset' -import { ROOT_COLLECTION_ALIAS } from '../../../src/collections/domain/models/Collection' import { createCollectionViaApi, - deleteCollectionViaApi + deleteCollectionViaApi, + ROOT_COLLECTION_ALIAS } from '../../testHelpers/collections/collectionHelper' describe('DatasetsRepository', () => { diff --git a/test/testHelpers/collections/collectionHelper.ts b/test/testHelpers/collections/collectionHelper.ts index b3521ed5..c2ecccf3 100644 --- a/test/testHelpers/collections/collectionHelper.ts +++ b/test/testHelpers/collections/collectionHelper.ts @@ -66,7 +66,7 @@ export async function createCollectionViaApi( ): Promise { try { if (parentCollectionAlias == undefined) { - parentCollectionAlias = 'root' + parentCollectionAlias = ':root' } return await axios @@ -186,3 +186,4 @@ export const createCollectionFacetRequestPayload = (): CollectionFacetPayload => displayName: 'testDisplayName' } } +export const ROOT_COLLECTION_ALIAS = 'root' diff --git a/test/unit/collections/CollectionsRepository.test.ts b/test/unit/collections/CollectionsRepository.test.ts index c1bdf958..dcdebc4b 100644 --- a/test/unit/collections/CollectionsRepository.test.ts +++ b/test/unit/collections/CollectionsRepository.test.ts @@ -13,7 +13,7 @@ import { } from '../../testHelpers/collections/collectionHelper' import { TestConstants } from '../../testHelpers/TestConstants' import { ReadError, WriteError } from '../../../src' -import { ROOT_COLLECTION_ALIAS } from '../../../src/collections/domain/models/Collection' +import { ROOT_COLLECTION_ID } from '../../../src/collections/domain/models/Collection' import { createCollectionUserPermissionsModel, createCollectionUserPermissionsPayload @@ -109,7 +109,7 @@ describe('CollectionsRepository', () => { describe('by default root id', () => { test('should return a Collection when no collection id, using ROOT instead is successful', async () => { jest.spyOn(axios, 'get').mockResolvedValue(testCollectionSuccessfulResponse) - const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/dataverses/${ROOT_COLLECTION_ALIAS}` + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/dataverses/${ROOT_COLLECTION_ID}` // API Key auth const actual = await sut.getCollection() @@ -120,7 +120,7 @@ describe('CollectionsRepository', () => { test('should return error on repository read error', async () => { jest.spyOn(axios, 'get').mockRejectedValue(TestConstants.TEST_ERROR_RESPONSE) - const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/dataverses/${ROOT_COLLECTION_ALIAS}` + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/dataverses/${ROOT_COLLECTION_ID}` let error = undefined as unknown as ReadError @@ -148,7 +148,7 @@ describe('CollectionsRepository', () => { const expectedNewCollectionRequestPayloadJson = JSON.stringify( createNewCollectionRequestPayload() ) - const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/dataverses/root` + const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/dataverses/:root` test('should call the API with a correct request payload', async () => { jest.spyOn(axios, 'post').mockResolvedValue(testCreateCollectionResponse) diff --git a/test/unit/datasets/CreateDataset.test.ts b/test/unit/datasets/CreateDataset.test.ts index 12ad59e3..92c73d78 100644 --- a/test/unit/datasets/CreateDataset.test.ts +++ b/test/unit/datasets/CreateDataset.test.ts @@ -9,7 +9,7 @@ import { import { ResourceValidationError } from '../../../src/core/domain/useCases/validators/errors/ResourceValidationError' import { WriteError, ReadError } from '../../../src' import { IMetadataBlocksRepository } from '../../../src/metadataBlocks/domain/repositories/IMetadataBlocksRepository' -import { ROOT_COLLECTION_ALIAS } from '../../../src/collections/domain/models/Collection' +import { ROOT_COLLECTION_ID } from '../../../src/collections/domain/models/Collection' describe('execute', () => { const testDataset = createDatasetDTO() @@ -51,7 +51,7 @@ describe('execute', () => { expect(datasetsRepositoryStub.createDataset).toHaveBeenCalledWith( testDataset, testMetadataBlocks, - ROOT_COLLECTION_ALIAS + ROOT_COLLECTION_ID ) }) @@ -111,7 +111,7 @@ describe('execute', () => { expect(datasetsRepositoryStub.createDataset).toHaveBeenCalledWith( testDataset, testMetadataBlocks, - ROOT_COLLECTION_ALIAS + ROOT_COLLECTION_ID ) })