Skip to content

Commit

Permalink
Merge pull request #207 from IQSS/191-dynamic-root-alias
Browse files Browse the repository at this point in the history
Use  ':root', rather than alias 'root' for default root collection
  • Loading branch information
ofahimIQSS authored Oct 31, 2024
2 parents 38d68b7 + 9f7fae2 commit a40c600
Show file tree
Hide file tree
Showing 16 changed files with 71 additions and 49 deletions.
16 changes: 8 additions & 8 deletions docs/useCases.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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:

Expand All @@ -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.

Expand Down Expand Up @@ -454,15 +454,15 @@ _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.

### Datasets Write Use Cases

#### 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.

Expand Down Expand Up @@ -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.

Expand Down
2 changes: 1 addition & 1 deletion src/collections/domain/models/Collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ export interface CollectionInputLevel {
required: boolean
}

export const ROOT_COLLECTION_ALIAS = 'root'
export const ROOT_COLLECTION_ID = ':root'
8 changes: 4 additions & 4 deletions src/collections/domain/useCases/CreateCollection.ts
Original file line number Diff line number Diff line change
@@ -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<number> {
Expand All @@ -11,16 +11,16 @@ export class CreateCollection implements UseCase<number> {
}

/**
* 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<number>} - 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<number> {
return await this.collectionsRepository.createCollection(newCollection, parentCollectionId)
}
Expand Down
8 changes: 4 additions & 4 deletions src/collections/domain/useCases/GetCollection.ts
Original file line number Diff line number Diff line change
@@ -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<Collection> {
private collectionsRepository: ICollectionsRepository
Expand All @@ -12,11 +12,11 @@ export class GetCollection implements UseCase<Collection> {
/**
* 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<Collection>}
*/
async execute(collectionIdOrAlias: number | string = ROOT_COLLECTION_ALIAS): Promise<Collection> {
async execute(collectionIdOrAlias: number | string = ROOT_COLLECTION_ID): Promise<Collection> {
return await this.collectionsRepository.getCollection(collectionIdOrAlias)
}
}
8 changes: 4 additions & 4 deletions src/collections/domain/useCases/GetCollectionFacets.ts
Original file line number Diff line number Diff line change
@@ -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<CollectionFacet[]> {
Expand All @@ -13,12 +13,12 @@ export class GetCollectionFacets implements UseCase<CollectionFacet[]> {
/**
* 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<string[]>}
*/
async execute(
collectionIdOrAlias: number | string = ROOT_COLLECTION_ALIAS
collectionIdOrAlias: number | string = ROOT_COLLECTION_ID
): Promise<CollectionFacet[]> {
return await this.collectionsRepository.getCollectionFacets(collectionIdOrAlias)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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<CollectionUserPermissions> {
private collectionsRepository: ICollectionsRepository
Expand All @@ -12,11 +13,13 @@ export class GetCollectionUserPermissions implements UseCase<CollectionUserPermi
/**
* Returns an instance of CollectionUserPermissions that includes the permissions that the calling user has on a particular 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'
* @returns {Promise<CollectionUserPermissions>}
*/
async execute(collectionIdOrAlias: number | string): Promise<CollectionUserPermissions> {
async execute(
collectionIdOrAlias: number | string = ROOT_COLLECTION_ID
): Promise<CollectionUserPermissions> {
return await this.collectionsRepository.getCollectionUserPermissions(collectionIdOrAlias)
}
}
6 changes: 3 additions & 3 deletions src/collections/infra/repositories/CollectionsRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down Expand Up @@ -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<Collection> {
return this.doGet(`/${this.collectionsResourceName}/${collectionIdOrAlias}`, true, {
returnOwners: true
Expand All @@ -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<number> {
const dataverseContacts: NewCollectionContactRequestPayload[] = collectionDTO.contacts.map(
(contact) => ({
Expand Down
8 changes: 4 additions & 4 deletions src/datasets/domain/useCases/CreateDataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<CreatedDatasetIdentifiers> {
Expand All @@ -16,18 +16,18 @@ export class CreateDataset extends DatasetWriteUseCase<CreatedDatasetIdentifiers
}

/**
* Creates a new Dataset in a collection, given a DatasetDTO object and an optional collection identifier, which defaults to root.
* Creates a new Dataset in a collection, given a DatasetDTO object and an optional collection identifier, which defaults to :root.
*
* @param {DatasetDTO} [newDataset] - DatasetDTO object including the new dataset metadata field values for each metadata block.
* @param {string} [collectionId] - Specifies the collection identifier where the new dataset should be created (optional, defaults to root).
* @param {string} [collectionId] - Specifies the collection identifier where the new dataset should be created (optional, defaults to :root).
* @returns {Promise<CreatedDatasetIdentifiers>}
* @throws {ResourceValidationError} - If there are validation errors related to the provided information.
* @throws {ReadError} - If there are errors while reading data.
* @throws {WriteError} - If there are errors while writing data.
*/
async execute(
newDataset: DatasetDTO,
collectionId = ROOT_COLLECTION_ALIAS
collectionId = ROOT_COLLECTION_ID
): Promise<CreatedDatasetIdentifiers> {
const metadataBlocks = await this.getNewDatasetMetadataBlocks(newDataset)
this.getNewDatasetValidator().validate(newDataset, metadataBlocks)
Expand Down
Original file line number Diff line number Diff line change
@@ -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<MetadataBlock[]> {
Expand All @@ -13,13 +13,13 @@ export class GetCollectionMetadataBlocks implements UseCase<MetadataBlock[]> {
/**
* 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<MetadataBlock[]>}
*/
async execute(
collectionIdOrAlias: number | string = ROOT_COLLECTION_ALIAS,
collectionIdOrAlias: number | string = ROOT_COLLECTION_ID,
onlyDisplayedOnCreate = false
): Promise<MetadataBlock[]> {
return await this.metadataBlocksRepository.getCollectionMetadataBlocks(
Expand Down
3 changes: 2 additions & 1 deletion test/functional/collections/GetCollectionFacets.test.ts
Original file line number Diff line number Diff line change
@@ -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 () => {
Expand Down
19 changes: 18 additions & 1 deletion test/functional/collections/GetCollectionUserPermissions.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 () => {
Expand All @@ -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 {
Expand Down
4 changes: 2 additions & 2 deletions test/integration/collections/CollectionsRepository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
4 changes: 2 additions & 2 deletions test/integration/datasets/DatasetsRepository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Expand Down
Loading

0 comments on commit a40c600

Please sign in to comment.