diff --git a/docs/useCases.md b/docs/useCases.md index 2c5e9b5a..ff537daa 100644 --- a/docs/useCases.md +++ b/docs/useCases.md @@ -40,6 +40,7 @@ The different use cases currently available in the package are classified below, - [Get Dataset Available Categories](#get-dataset-available-categories) - [Get Dataset Templates](#get-dataset-templates) - [Get Dataset Available Dataset Types](#get-dataset-available-dataset-types) + - [Get Dataset Available Dataset Type](#get-dataset-available-dataset-type) - [Datasets write use cases](#datasets-write-use-cases) - [Create a Dataset](#create-a-dataset) - [Update a Dataset](#update-a-dataset) @@ -48,6 +49,10 @@ The different use cases currently available in the package are classified below, - [Delete a Draft Dataset](#delete-a-draft-dataset) - [Link a Dataset](#link-a-dataset) - [Unlink a Dataset](#unlink-a-dataset) + - [Add a Dataset Type](#add-a-dataset-type) + - [Link Dataset Type with Metadata Blocks](#link-dataset-type-with-metadata-blocks) + - [Set Available Licenses For Dataset Type](#set-available-licenses-for-dataset-type) + - [Delete a Dataset Type](#delete-a-dataset-type) - [Files](#Files) - [Files read use cases](#files-read-use-cases) - [Get a File](#get-a-file) @@ -833,6 +838,24 @@ getDatasetAvailableDatasetTypes.execute().then((datasetTypes: DatasetType[]) => _See [use case](../src/datasets/domain/useCases/GetDatasetAvailableDatasetTypes.ts) implementation_. +#### Get Dataset Available Dataset Type + +Returns an available dataset types that can be used at dataset creation. + +###### Example call: + +```typescript +import { getDatasetAvailableDatasetType } from '@iqss/dataverse-client-javascript' + +/* ... */ + +getDatasetAvailableDatasetType.execute().then((datasetType: DatasetType) => { + /* ... */ +}) +``` + +_See [use case](../src/datasets/domain/useCases/GetDatasetAvailableDatasetType.ts) implementation_. + ### Datasets Write Use Cases #### Create a Dataset @@ -1156,6 +1179,78 @@ getDatasetTemplates.execute(collectionIdOrAlias).then((datasetTemplates: Dataset _See [use case](../src/datasets/domain/useCases/GetDatasetTemplates.ts)_ definition. +#### Add a Dataset Type + +Adds a dataset types that can be used at dataset creation. + +###### Example call: + +```typescript +import { addDatasetType } from '@iqss/dataverse-client-javascript' + +/* ... */ + +addDatasetType.execute(datasetType).then((datasetType: DatasetType) => { + /* ... */ +}) +``` + +_See [use case](../src/datasets/domain/useCases/AddDatasetType.ts) implementation_. + +#### Link Dataset Type with Metadata Blocks + +Link a dataset type with metadata blocks. + +###### Example call: + +```typescript +import { linkDatasetTypeWithMetadataBlocks } from '@iqss/dataverse-client-javascript' + +/* ... */ + +linkDatasetTypeWithMetadataBlocks.execute(datasetTypeId, ['geospatial']).then(() => { + /* ... */ +}) +``` + +_See [use case](../src/datasets/domain/useCases/LinkDatasetTypeWithMetadataBlocks.ts) implementation_. + +#### Set Available Licenses For Dataset Type + +Set available licenses for dataset type. + +###### Example call: + +```typescript +import { setAvailableLicensesForDatasetType } from '@iqss/dataverse-client-javascript' + +/* ... */ + +setAvailableLicensesForDatasetType.execute(datasetTypeId, ['CC BY 4.0']).then(() => { + /* ... */ +}) +``` + +_See [use case](../src/datasets/domain/useCases/SetAvailableLicensesForDatasetType.ts) implementation_. + +#### Delete a Dataset Type + +Delete a dataset type. + +###### Example call: + +```typescript +import { deleteDatasetType } from '@iqss/dataverse-client-javascript' + +/* ... */ + +deleteDatasetType.execute(datasetTypeId).then(() => { + /* ... */ +}) +``` + +_See [use case](../src/datasets/domain/useCases/DeleteDatasetType.ts) implementation_. + ## Files ### Files read use cases diff --git a/src/datasets/domain/models/DatasetType.ts b/src/datasets/domain/models/DatasetType.ts index 5475cdaf..56a5ed43 100644 --- a/src/datasets/domain/models/DatasetType.ts +++ b/src/datasets/domain/models/DatasetType.ts @@ -1,5 +1,5 @@ export interface DatasetType { - id: number + id?: number name: string linkedMetadataBlocks?: string[] availableLicenses?: string[] diff --git a/src/datasets/domain/repositories/IDatasetsRepository.ts b/src/datasets/domain/repositories/IDatasetsRepository.ts index fb8b26d5..3fe1c7ab 100644 --- a/src/datasets/domain/repositories/IDatasetsRepository.ts +++ b/src/datasets/domain/repositories/IDatasetsRepository.ts @@ -78,4 +78,15 @@ export interface IDatasetsRepository { ): Promise getDatasetTemplates(collectionIdOrAlias: number | string): Promise getDatasetAvailableDatasetTypes(): Promise + getDatasetAvailableDatasetType(datasetTypeId: number | string): Promise + addDatasetType(datasetType: DatasetType): Promise + linkDatasetTypeWithMetadataBlocks( + datasetTypeId: number | string, + metadataBlocks: string[] + ): Promise + setAvailableLicensesForDatasetType( + datasetTypeId: number | string, + licenses: string[] + ): Promise + deleteDatasetType(datasetTypeId: number): Promise } diff --git a/src/datasets/domain/useCases/AddDatasetType.ts b/src/datasets/domain/useCases/AddDatasetType.ts new file mode 100644 index 00000000..7e2e11c9 --- /dev/null +++ b/src/datasets/domain/useCases/AddDatasetType.ts @@ -0,0 +1,18 @@ +import { UseCase } from '../../../core/domain/useCases/UseCase' +import { DatasetType } from '../models/DatasetType' +import { IDatasetsRepository } from '../repositories/IDatasetsRepository' + +export class AddDatasetType implements UseCase { + private datasetsRepository: IDatasetsRepository + + constructor(datasetsRepository: IDatasetsRepository) { + this.datasetsRepository = datasetsRepository + } + + /** + * Add a dataset type that can be selected when creating a dataset. + */ + async execute(datasetType: DatasetType): Promise { + return await this.datasetsRepository.addDatasetType(datasetType) + } +} diff --git a/src/datasets/domain/useCases/DeleteDatasetType.ts b/src/datasets/domain/useCases/DeleteDatasetType.ts new file mode 100644 index 00000000..b3c841aa --- /dev/null +++ b/src/datasets/domain/useCases/DeleteDatasetType.ts @@ -0,0 +1,17 @@ +import { UseCase } from '../../../core/domain/useCases/UseCase' +import { IDatasetsRepository } from '../repositories/IDatasetsRepository' + +export class DeleteDatasetType implements UseCase { + private datasetsRepository: IDatasetsRepository + + constructor(datasetsRepository: IDatasetsRepository) { + this.datasetsRepository = datasetsRepository + } + + /** + * Deletes a dataset type. + */ + async execute(datasetTypeId: number): Promise { + return await this.datasetsRepository.deleteDatasetType(datasetTypeId) + } +} diff --git a/src/datasets/domain/useCases/GetDatasetAvailableDatasetType.ts b/src/datasets/domain/useCases/GetDatasetAvailableDatasetType.ts new file mode 100644 index 00000000..b870216c --- /dev/null +++ b/src/datasets/domain/useCases/GetDatasetAvailableDatasetType.ts @@ -0,0 +1,18 @@ +import { UseCase } from '../../../core/domain/useCases/UseCase' +import { DatasetType } from '../models/DatasetType' +import { IDatasetsRepository } from '../repositories/IDatasetsRepository' + +export class GetDatasetAvailableDatasetType implements UseCase { + private datasetsRepository: IDatasetsRepository + + constructor(datasetsRepository: IDatasetsRepository) { + this.datasetsRepository = datasetsRepository + } + + /** + * Returns a single available dataset type that can be selected when creating a dataset. + */ + async execute(datasetTypeId: number | string): Promise { + return await this.datasetsRepository.getDatasetAvailableDatasetType(datasetTypeId) + } +} diff --git a/src/datasets/domain/useCases/LinkDatasetTypeWithMetadataBlocks.ts b/src/datasets/domain/useCases/LinkDatasetTypeWithMetadataBlocks.ts new file mode 100644 index 00000000..f9a6b447 --- /dev/null +++ b/src/datasets/domain/useCases/LinkDatasetTypeWithMetadataBlocks.ts @@ -0,0 +1,20 @@ +import { UseCase } from '../../../core/domain/useCases/UseCase' +import { IDatasetsRepository } from '../repositories/IDatasetsRepository' + +export class LinkDatasetTypeWithMetadataBlocks implements UseCase { + private datasetsRepository: IDatasetsRepository + + constructor(datasetsRepository: IDatasetsRepository) { + this.datasetsRepository = datasetsRepository + } + + /** + * Links a dataset type with one or more metadata blocks. These metadata blocks will be shown when creating a dataset of this type. + */ + async execute(datasetTypeId: number | string, metadataBlocks: string[]): Promise { + return await this.datasetsRepository.linkDatasetTypeWithMetadataBlocks( + datasetTypeId, + metadataBlocks + ) + } +} diff --git a/src/datasets/domain/useCases/SetAvailableLicensesForDatasetType.ts b/src/datasets/domain/useCases/SetAvailableLicensesForDatasetType.ts new file mode 100644 index 00000000..e4df9ab2 --- /dev/null +++ b/src/datasets/domain/useCases/SetAvailableLicensesForDatasetType.ts @@ -0,0 +1,17 @@ +import { UseCase } from '../../../core/domain/useCases/UseCase' +import { IDatasetsRepository } from '../repositories/IDatasetsRepository' + +export class SetAvailableLicensesForDatasetType implements UseCase { + private datasetsRepository: IDatasetsRepository + + constructor(datasetsRepository: IDatasetsRepository) { + this.datasetsRepository = datasetsRepository + } + + /** + * Sets the available licenses for a given dataset type. This limits the license options when creating a dataset of this type. + */ + async execute(datasetTypeId: number | string, licenses: string[]): Promise { + return await this.datasetsRepository.setAvailableLicensesForDatasetType(datasetTypeId, licenses) + } +} diff --git a/src/datasets/index.ts b/src/datasets/index.ts index e6de1b8c..6b93a7cd 100644 --- a/src/datasets/index.ts +++ b/src/datasets/index.ts @@ -25,6 +25,11 @@ import { UnlinkDataset } from './domain/useCases/UnlinkDataset' import { GetDatasetLinkedCollections } from './domain/useCases/GetDatasetLinkedCollections' import { GetDatasetAvailableCategories } from './domain/useCases/GetDatasetAvailableCategories' import { GetDatasetAvailableDatasetTypes } from './domain/useCases/GetDatasetAvailableDatasetTypes' +import { GetDatasetAvailableDatasetType } from './domain/useCases/GetDatasetAvailableDatasetType' +import { AddDatasetType } from './domain/useCases/AddDatasetType' +import { LinkDatasetTypeWithMetadataBlocks } from './domain/useCases/LinkDatasetTypeWithMetadataBlocks' +import { SetAvailableLicensesForDatasetType } from './domain/useCases/SetAvailableLicensesForDatasetType' +import { DeleteDatasetType } from './domain/useCases/DeleteDatasetType' import { GetDatasetCitationInOtherFormats } from './domain/useCases/GetDatasetCitationInOtherFormats' import { GetDatasetTemplates } from './domain/useCases/GetDatasetTemplates' @@ -66,6 +71,13 @@ const unlinkDataset = new UnlinkDataset(datasetsRepository) const getDatasetLinkedCollections = new GetDatasetLinkedCollections(datasetsRepository) const getDatasetAvailableCategories = new GetDatasetAvailableCategories(datasetsRepository) const getDatasetAvailableDatasetTypes = new GetDatasetAvailableDatasetTypes(datasetsRepository) +const getDatasetAvailableDatasetType = new GetDatasetAvailableDatasetType(datasetsRepository) +const addDatasetType = new AddDatasetType(datasetsRepository) +const linkDatasetTypeWithMetadataBlocks = new LinkDatasetTypeWithMetadataBlocks(datasetsRepository) +const setAvailableLicensesForDatasetType = new SetAvailableLicensesForDatasetType( + datasetsRepository +) +const deleteDatasetType = new DeleteDatasetType(datasetsRepository) const getDatasetCitationInOtherFormats = new GetDatasetCitationInOtherFormats(datasetsRepository) const getDatasetTemplates = new GetDatasetTemplates(datasetsRepository) @@ -92,7 +104,12 @@ export { getDatasetAvailableCategories, getDatasetCitationInOtherFormats, getDatasetTemplates, - getDatasetAvailableDatasetTypes + getDatasetAvailableDatasetTypes, + getDatasetAvailableDatasetType, + addDatasetType, + linkDatasetTypeWithMetadataBlocks, + setAvailableLicensesForDatasetType, + deleteDatasetType } export { DatasetNotNumberedVersion } from './domain/models/DatasetNotNumberedVersion' export { DatasetUserPermissions } from './domain/models/DatasetUserPermissions' diff --git a/src/datasets/infra/repositories/DatasetsRepository.ts b/src/datasets/infra/repositories/DatasetsRepository.ts index 594744b4..99b380df 100644 --- a/src/datasets/infra/repositories/DatasetsRepository.ts +++ b/src/datasets/infra/repositories/DatasetsRepository.ts @@ -382,4 +382,70 @@ export class DatasetsRepository extends ApiRepository implements IDatasetsReposi throw error }) } + + public async getDatasetAvailableDatasetType( + datasetTypeId: number | string + ): Promise { + const endpoint = this.buildApiEndpoint( + this.datasetsResourceName, + 'datasetTypes/' + datasetTypeId + ) + return this.doGet(endpoint) + .then((response) => response.data.data) + .catch((error) => { + throw error + }) + } + + public async addDatasetType(datasetType: DatasetType): Promise { + return this.doPost( + this.buildApiEndpoint(this.datasetsResourceName, 'datasetTypes'), + datasetType + ) + .then((response) => response.data.data) + .catch((error) => { + throw error + }) + } + + public async linkDatasetTypeWithMetadataBlocks( + datasetTypeId: number | string, + metadataBlocks: string[] + ): Promise { + return this.doPut( + this.buildApiEndpoint(this.datasetsResourceName, 'datasetTypes/' + datasetTypeId), + metadataBlocks + ) + .then((response) => response.data.data) + .catch((error) => { + throw error + }) + } + + public async setAvailableLicensesForDatasetType( + datasetTypeId: number | string, + licenses: string[] + ): Promise { + return this.doPut( + this.buildApiEndpoint( + this.datasetsResourceName, + 'datasetTypes/' + datasetTypeId + '/licenses' + ), + licenses + ) + .then((response) => response.data.data) + .catch((error) => { + throw error + }) + } + + public async deleteDatasetType(datasetTypeId: number): Promise { + return this.doDelete( + this.buildApiEndpoint(this.datasetsResourceName, 'datasetTypes/' + datasetTypeId) + ) + .then((response) => response.data.data) + .catch((error) => { + throw error + }) + } } diff --git a/test/functional/datasets/AddDatasetType.test.ts b/test/functional/datasets/AddDatasetType.test.ts new file mode 100644 index 00000000..409c18b9 --- /dev/null +++ b/test/functional/datasets/AddDatasetType.test.ts @@ -0,0 +1,28 @@ +import { ApiConfig, DatasetType, addDatasetType, deleteDatasetType } from '../../../src' +import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig' +import { TestConstants } from '../../testHelpers/TestConstants' + +describe('AddDatasetType', () => { + describe('execute', () => { + beforeAll(async () => { + ApiConfig.init( + TestConstants.TEST_API_URL, + DataverseApiAuthMechanism.API_KEY, + process.env.TEST_API_KEY + ) + }) + + test('should allow for adding and deleting a dataset type', async () => { + const randomName = `datasetType-${crypto.randomUUID().slice(0, 6)}` + const actual: DatasetType = await addDatasetType.execute({ + name: randomName, + linkedMetadataBlocks: [], + availableLicenses: [] + }) + expect(actual.name).toEqual(randomName) + + const deleted: void = await deleteDatasetType.execute(actual.id as number) + expect(deleted).toEqual({ message: 'deleted' }) + }) + }) +}) diff --git a/test/functional/datasets/DeleteDatasetType.test.ts b/test/functional/datasets/DeleteDatasetType.test.ts new file mode 100644 index 00000000..8f447822 --- /dev/null +++ b/test/functional/datasets/DeleteDatasetType.test.ts @@ -0,0 +1,28 @@ +import { ApiConfig, DatasetType, addDatasetType, deleteDatasetType } from '../../../src' +import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig' +import { TestConstants } from '../../testHelpers/TestConstants' + +describe('DeleteDatasetType', () => { + describe('execute', () => { + beforeAll(async () => { + ApiConfig.init( + TestConstants.TEST_API_URL, + DataverseApiAuthMechanism.API_KEY, + process.env.TEST_API_KEY + ) + }) + + test('should allow for adding and deleting a dataset type', async () => { + const randomName = `datasetType-${crypto.randomUUID().slice(0, 6)}` + const actual: DatasetType = await addDatasetType.execute({ + name: randomName, + linkedMetadataBlocks: [], + availableLicenses: [] + }) + expect(actual.name).toEqual(randomName) + + const deleted: void = await deleteDatasetType.execute(actual.id as number) + expect(deleted).toEqual({ message: 'deleted' }) + }) + }) +}) diff --git a/test/functional/datasets/GetDatasetAvailableDatasetType.test.ts b/test/functional/datasets/GetDatasetAvailableDatasetType.test.ts new file mode 100644 index 00000000..3d80f35a --- /dev/null +++ b/test/functional/datasets/GetDatasetAvailableDatasetType.test.ts @@ -0,0 +1,30 @@ +import { ApiConfig, DatasetType, getDatasetAvailableDatasetType } from '../../../src' +import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig' +import { TestConstants } from '../../testHelpers/TestConstants' + +describe('getDatasetAvailableDatasetType', () => { + describe('execute', () => { + beforeAll(async () => { + ApiConfig.init( + TestConstants.TEST_API_URL, + DataverseApiAuthMechanism.API_KEY, + process.env.TEST_API_KEY + ) + }) + + test('should return the default available dataset type', async () => { + const defaultDatasetType = 'dataset' + const actualDatasetType: DatasetType = await getDatasetAvailableDatasetType.execute( + defaultDatasetType + ) + const expectedDatasetType = { + id: 1, + name: 'dataset', + linkedMetadataBlocks: [], + availableLicenses: [] + } + + expect(actualDatasetType).toEqual(expectedDatasetType) + }) + }) +}) diff --git a/test/functional/datasets/LinkDatasetTypeWithMetadataBlocks.test.ts b/test/functional/datasets/LinkDatasetTypeWithMetadataBlocks.test.ts new file mode 100644 index 00000000..c6f4c3f8 --- /dev/null +++ b/test/functional/datasets/LinkDatasetTypeWithMetadataBlocks.test.ts @@ -0,0 +1,44 @@ +import { + ApiConfig, + DatasetType, + addDatasetType, + deleteDatasetType, + linkDatasetTypeWithMetadataBlocks +} from '../../../src' +import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig' +import { TestConstants } from '../../testHelpers/TestConstants' + +describe('LinkDatasetTypeWithMetadataBlocks', () => { + describe('execute', () => { + beforeAll(async () => { + ApiConfig.init( + TestConstants.TEST_API_URL, + DataverseApiAuthMechanism.API_KEY, + process.env.TEST_API_KEY + ) + }) + + test('should allow for linking a dataset type to metadata blocks', async () => { + const randomName = `datasetType-${crypto.randomUUID().slice(0, 6)}` + const actual: DatasetType = await addDatasetType.execute({ + name: randomName, + linkedMetadataBlocks: [], + availableLicenses: [] + }) + expect(actual.name).toEqual(randomName) + + const linked: void = await linkDatasetTypeWithMetadataBlocks.execute(actual.id as number, [ + 'geospatial' + ]) + expect(linked).toEqual({ + linkedMetadataBlocks: { + before: [], + after: ['geospatial'] + } + }) + + const deleted: void = await deleteDatasetType.execute(actual.id as number) + expect(deleted).toEqual({ message: 'deleted' }) + }) + }) +}) diff --git a/test/functional/datasets/SetAvailableLicensesForDatasetType.test.ts b/test/functional/datasets/SetAvailableLicensesForDatasetType.test.ts new file mode 100644 index 00000000..0c4d6876 --- /dev/null +++ b/test/functional/datasets/SetAvailableLicensesForDatasetType.test.ts @@ -0,0 +1,44 @@ +import { + ApiConfig, + DatasetType, + addDatasetType, + deleteDatasetType, + setAvailableLicensesForDatasetType +} from '../../../src' +import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig' +import { TestConstants } from '../../testHelpers/TestConstants' + +describe('SetAvailableLicensesForDatasetType', () => { + describe('execute', () => { + beforeAll(async () => { + ApiConfig.init( + TestConstants.TEST_API_URL, + DataverseApiAuthMechanism.API_KEY, + process.env.TEST_API_KEY + ) + }) + + test('should allow for setting available licenses for a dataset type', async () => { + const randomName = `datasetType-${crypto.randomUUID().slice(0, 6)}` + const actual: DatasetType = await addDatasetType.execute({ + name: randomName, + linkedMetadataBlocks: [], + availableLicenses: [] + }) + expect(actual.name).toEqual(randomName) + + const linked: void = await setAvailableLicensesForDatasetType.execute(actual.id as number, [ + 'CC BY 4.0' + ]) + expect(linked).toEqual({ + availableLicenses: { + before: [], + after: ['CC BY 4.0'] + } + }) + + const deleted: void = await deleteDatasetType.execute(actual.id as number) + expect(deleted).toEqual({ message: 'deleted' }) + }) + }) +}) diff --git a/test/integration/datasets/DatasetsRepository.test.ts b/test/integration/datasets/DatasetsRepository.test.ts index bb44f3d2..5374b5f8 100644 --- a/test/integration/datasets/DatasetsRepository.test.ts +++ b/test/integration/datasets/DatasetsRepository.test.ts @@ -22,7 +22,12 @@ import { DatasetDeaccessionDTO, publishDataset, DatasetType, - getDatasetAvailableDatasetTypes + getDatasetAvailableDatasetTypes, + getDatasetAvailableDatasetType, + addDatasetType, + deleteDatasetType, + linkDatasetTypeWithMetadataBlocks, + setAvailableLicensesForDatasetType } from '../../../src/datasets' import { ApiConfig, WriteError } from '../../../src' import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig' @@ -1706,4 +1711,93 @@ describe('DatasetsRepository', () => { expect(actualDatasetTypes).toEqual(expectedDatasetTypes) }) }) + + describe('getDatasetAvailableDatasetType', () => { + test('should return available the default dataset type', async () => { + const defaultDatasetType = 'dataset' + const actualDatasetType: DatasetType = await getDatasetAvailableDatasetType.execute( + defaultDatasetType + ) + const expectedDatasetType = { + id: 1, + name: 'dataset', + linkedMetadataBlocks: [], + availableLicenses: [] + } + + expect(actualDatasetType).toEqual(expectedDatasetType) + }) + }) + + describe('addDatasetType', () => { + test('should add a dataset type', async () => { + const randomName = `datasetType-${crypto.randomUUID().slice(0, 6)}` + const actual: DatasetType = await addDatasetType.execute({ + name: randomName, + linkedMetadataBlocks: [], + availableLicenses: [] + }) + + expect(actual.name).toEqual(randomName) + }) + }) + + describe('deleteDatasetType', () => { + test('should delete a dataset type (after adding it)', async () => { + const randomName = `datasetType-${crypto.randomUUID().slice(0, 6)}` + const actual: DatasetType = await addDatasetType.execute({ + name: randomName, + linkedMetadataBlocks: [], + availableLicenses: [] + }) + expect(actual.name).toEqual(randomName) + + const deleted: void = await deleteDatasetType.execute(actual.id as number) + expect(deleted).toEqual({ message: 'deleted' }) + }) + }) + + describe('linkDatasetTypeWithMetadataBlocks', () => { + test('should allow for linking a dataset type to metadata blocks', async () => { + const randomName = `datasetType-${crypto.randomUUID().slice(0, 6)}` + const actual: DatasetType = await addDatasetType.execute({ + name: randomName, + linkedMetadataBlocks: [], + availableLicenses: [] + }) + expect(actual.name).toEqual(randomName) + + const linked: void = await linkDatasetTypeWithMetadataBlocks.execute(actual.id as number, [ + 'geospatial' + ]) + expect(linked).toEqual({ + linkedMetadataBlocks: { + before: [], + after: ['geospatial'] + } + }) + }) + }) + + describe('setAvailableLicensesForDatasetType', () => { + test('should allow for setting available licenses for a dataset type', async () => { + const randomName = `datasetType-${crypto.randomUUID().slice(0, 6)}` + const actual: DatasetType = await addDatasetType.execute({ + name: randomName, + linkedMetadataBlocks: [], + availableLicenses: [] + }) + expect(actual.name).toEqual(randomName) + + const linked: void = await setAvailableLicensesForDatasetType.execute(actual.id as number, [ + 'CC BY 4.0' + ]) + expect(linked).toEqual({ + availableLicenses: { + before: [], + after: ['CC BY 4.0'] + } + }) + }) + }) }) diff --git a/test/unit/datasets/DeleteDatasetType.test.ts b/test/unit/datasets/DeleteDatasetType.test.ts new file mode 100644 index 00000000..b8104a7a --- /dev/null +++ b/test/unit/datasets/DeleteDatasetType.test.ts @@ -0,0 +1,23 @@ +import { DeleteDatasetType } from '../../../src/datasets/domain/useCases/DeleteDatasetType' +import { IDatasetsRepository } from '../../../src/datasets/domain/repositories/IDatasetsRepository' +import { WriteError } from '../../../src' + +describe('execute', () => { + test('should return undefined on delete success', async () => { + const datasetsRepositoryStub: IDatasetsRepository = {} as IDatasetsRepository + datasetsRepositoryStub.deleteDatasetType = jest.fn().mockResolvedValue(undefined) + const sut = new DeleteDatasetType(datasetsRepositoryStub) + + const actual = await sut.execute(1) + expect(actual).toEqual(undefined) + }) + + test('should return error result on delete error', async () => { + const datasetsRepositoryStub: IDatasetsRepository = {} as IDatasetsRepository + datasetsRepositoryStub.deleteDatasetType = jest.fn().mockRejectedValue(new WriteError()) + const sut = new DeleteDatasetType(datasetsRepositoryStub) + + const nonExistentDatasetTypeId = 111 + await expect(sut.execute(nonExistentDatasetTypeId)).rejects.toThrow(WriteError) + }) +}) diff --git a/test/unit/datasets/GetDatasetAvailableDatasetType.test.ts b/test/unit/datasets/GetDatasetAvailableDatasetType.test.ts new file mode 100644 index 00000000..d6b4d958 --- /dev/null +++ b/test/unit/datasets/GetDatasetAvailableDatasetType.test.ts @@ -0,0 +1,54 @@ +import { GetDatasetAvailableDatasetType } from '../../../src/datasets/domain/useCases/GetDatasetAvailableDatasetType' +import { IDatasetsRepository } from '../../../src/datasets/domain/repositories/IDatasetsRepository' +import { DatasetType } from '../../../src/datasets/domain/models/DatasetType' +import { ReadError } from '../../../src' + +describe('GetDatasetAvailableDatasetType', () => { + const datasetTypesRepositoryStub: IDatasetsRepository = {} as IDatasetsRepository + + const datasetTypeId = 1 + const datasetTypeName = 'dataset' + const expectedDatasetType: DatasetType = { + id: datasetTypeId, + name: datasetTypeName, + linkedMetadataBlocks: [], + availableLicenses: [] + } + + it('should get a dataset type by database id', async () => { + datasetTypesRepositoryStub.getDatasetAvailableDatasetType = jest + .fn() + .mockResolvedValue(expectedDatasetType) + const sut = new GetDatasetAvailableDatasetType(datasetTypesRepositoryStub) + + const actual = await sut.execute(datasetTypeId) + + expect(actual).toEqual(expectedDatasetType) + expect(datasetTypesRepositoryStub.getDatasetAvailableDatasetType).toHaveBeenCalledTimes(1) + }) + + it('should get a dataset type by name', async () => { + datasetTypesRepositoryStub.getDatasetAvailableDatasetType = jest + .fn() + .mockResolvedValue(expectedDatasetType) + const sut = new GetDatasetAvailableDatasetType(datasetTypesRepositoryStub) + + const actual = await sut.execute(datasetTypeName) + + expect(actual).toEqual(expectedDatasetType) + expect(datasetTypesRepositoryStub.getDatasetAvailableDatasetType).toHaveBeenCalledTimes(1) + }) + + test('should return error result on repository error', async () => { + const datasetsRepositoryStub: IDatasetsRepository = {} as IDatasetsRepository + const datasetTypeId = 1 + const expectedError = new ReadError('Failed to fetch dataset type') + datasetsRepositoryStub.getDatasetAvailableDatasetType = jest + .fn() + .mockRejectedValue(expectedError) + const sut = new GetDatasetAvailableDatasetType(datasetsRepositoryStub) + + await expect(sut.execute(datasetTypeId)).rejects.toThrow(ReadError) + expect(datasetsRepositoryStub.getDatasetAvailableDatasetType).toHaveBeenCalledTimes(1) + }) +}) diff --git a/test/unit/datasets/LinkDatasetTypeWithMetadataBlocks.test.ts b/test/unit/datasets/LinkDatasetTypeWithMetadataBlocks.test.ts new file mode 100644 index 00000000..c284e0c1 --- /dev/null +++ b/test/unit/datasets/LinkDatasetTypeWithMetadataBlocks.test.ts @@ -0,0 +1,27 @@ +import { LinkDatasetTypeWithMetadataBlocks } from '../../../src/datasets/domain/useCases/LinkDatasetTypeWithMetadataBlocks' +import { IDatasetsRepository } from '../../../src/datasets/domain/repositories/IDatasetsRepository' +import { WriteError } from '../../../src' + +describe('execute', () => { + test('should return undefined on link dataset type with metadata block success', async () => { + const datasetsRepositoryStub: IDatasetsRepository = {} as IDatasetsRepository + datasetsRepositoryStub.linkDatasetTypeWithMetadataBlocks = jest + .fn() + .mockResolvedValue(undefined) + const sut = new LinkDatasetTypeWithMetadataBlocks(datasetsRepositoryStub) + + const actual = await sut.execute(1, ['geospatial']) + expect(actual).toEqual(undefined) + }) + + test('should return error result on link dataset type with metadata block error', async () => { + const datasetsRepositoryStub: IDatasetsRepository = {} as IDatasetsRepository + datasetsRepositoryStub.linkDatasetTypeWithMetadataBlocks = jest + .fn() + .mockRejectedValue(new WriteError()) + const sut = new LinkDatasetTypeWithMetadataBlocks(datasetsRepositoryStub) + + const nonExistentDatasetTypeId = 111 + await expect(sut.execute(nonExistentDatasetTypeId, ['geospatial'])).rejects.toThrow(WriteError) + }) +}) diff --git a/test/unit/datasets/SetAvailableLicensesForDatasetType.test.ts b/test/unit/datasets/SetAvailableLicensesForDatasetType.test.ts new file mode 100644 index 00000000..965ebcef --- /dev/null +++ b/test/unit/datasets/SetAvailableLicensesForDatasetType.test.ts @@ -0,0 +1,27 @@ +import { SetAvailableLicensesForDatasetType } from '../../../src/datasets/domain/useCases/SetAvailableLicensesForDatasetType' +import { IDatasetsRepository } from '../../../src/datasets/domain/repositories/IDatasetsRepository' +import { WriteError } from '../../../src' + +describe('execute', () => { + test('should return undefined on set available licenses for dataset type success', async () => { + const datasetsRepositoryStub: IDatasetsRepository = {} as IDatasetsRepository + datasetsRepositoryStub.setAvailableLicensesForDatasetType = jest + .fn() + .mockResolvedValue(undefined) + const sut = new SetAvailableLicensesForDatasetType(datasetsRepositoryStub) + + const actual = await sut.execute(1, ['geospatial']) + expect(actual).toEqual(undefined) + }) + + test('should return error result on set available licenses for dataset type error', async () => { + const datasetsRepositoryStub: IDatasetsRepository = {} as IDatasetsRepository + datasetsRepositoryStub.setAvailableLicensesForDatasetType = jest + .fn() + .mockRejectedValue(new WriteError()) + const sut = new SetAvailableLicensesForDatasetType(datasetsRepositoryStub) + + const nonExistentDatasetTypeId = 111 + await expect(sut.execute(nonExistentDatasetTypeId, ['geospatial'])).rejects.toThrow(WriteError) + }) +})