Skip to content

Commit 3219a71

Browse files
authored
Merge pull request #344 from IQSS/336-file-use-cases-get-available-dataset-file-categories
File: Use Case Get Available Dataset File Categories
2 parents 158f842 + ace8b9d commit 3219a71

File tree

9 files changed

+139
-2
lines changed

9 files changed

+139
-2
lines changed

docs/useCases.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ The different use cases currently available in the package are classified below,
3737
- [List All Datasets](#list-all-datasets)
3838
- [Get Dataset Versions Summaries](#get-dataset-versions-summaries)
3939
- [Get Dataset Linked Collections](#get-dataset-linked-collections)
40+
- [Get Dataset Available Categories](#get-dataset-available-categories)
4041
- [Datasets write use cases](#datasets-write-use-cases)
4142
- [Create a Dataset](#create-a-dataset)
4243
- [Update a Dataset](#update-a-dataset)
@@ -64,6 +65,8 @@ The different use cases currently available in the package are classified below,
6465
- [Replace a File](#replace-a-file)
6566
- [Restrict or Unrestrict a File](#restrict-or-unrestrict-a-file)
6667
- [Update File Metadata](#update-file-metadata)
68+
- [Update File Categories](#update-file-categories)
69+
- [Update File Tabular Tags](#update-file-tabular-tags)
6770
- [Metadata Blocks](#metadata-blocks)
6871
- [Metadata Blocks read use cases](#metadata-blocks-read-use-cases)
6972
- [Get All Facetable Metadata Fields](#get-all-facetable-metadata-fields)
@@ -1080,6 +1083,28 @@ The `includeMDC` parameter is optional.
10801083
- If MDC isn't enabled, the download count will return a total count, without `MDCStartDate`.
10811084
- If MDC is enabled but the `includeMDC` is false, the count will be limited to the time before `MDCStartDate`
10821085

1086+
#### Get Dataset Available Categories
1087+
1088+
Returns a list of available file categories that may be applied to the files of a given dataset.
1089+
1090+
###### Example call:
1091+
1092+
```typescript
1093+
import { getDatasetAvailableCategories } from '@iqss/dataverse-client-javascript'
1094+
1095+
/* ... */
1096+
1097+
const datasetId = 1
1098+
1099+
getDatasetAvailableCategories.execute(datasetId).then((categories: String[]) => {
1100+
/* ... */
1101+
})
1102+
```
1103+
1104+
_See [use case](../src/datasets/domain/useCases/GetDatasetAvailableCategories.ts) implementation_.
1105+
1106+
The `datasetId` parameter is a number for numeric identifiers or string for persistent identifiers.
1107+
10831108
## Files
10841109

10851110
### Files read use cases

src/datasets/domain/repositories/IDatasetsRepository.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ export interface IDatasetsRepository {
6767
linkDataset(datasetId: number, collectionAlias: string): Promise<void>
6868
unlinkDataset(datasetId: number, collectionAlias: string): Promise<void>
6969
getDatasetLinkedCollections(datasetId: number | string): Promise<DatasetLinkedCollection[]>
70+
getDatasetAvailableCategories(datasetId: number | string): Promise<string[]>
7071
getDatasetCitationInOtherFormats(
7172
datasetId: number | string,
7273
datasetVersionId: string,
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { UseCase } from '../../../core/domain/useCases/UseCase'
2+
import { IDatasetsRepository } from '../repositories/IDatasetsRepository'
3+
4+
export class GetDatasetAvailableCategories implements UseCase<string[]> {
5+
private readonly datasetsRepository: IDatasetsRepository
6+
7+
constructor(datasetsRepository: IDatasetsRepository) {
8+
this.datasetsRepository = datasetsRepository
9+
}
10+
11+
/**
12+
* Retrieves the available file categories for a dataset.
13+
*
14+
* @param {number | string} [datasetId] - Persistent dataset identifier
15+
* @returns {Promise<string[]>} - List of available file categories
16+
*/
17+
async execute(datasetId: number | string): Promise<string[]> {
18+
return this.datasetsRepository.getDatasetAvailableCategories(datasetId)
19+
}
20+
}

src/datasets/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { DeleteDatasetDraft } from './domain/useCases/DeleteDatasetDraft'
2323
import { LinkDataset } from './domain/useCases/LinkDataset'
2424
import { UnlinkDataset } from './domain/useCases/UnlinkDataset'
2525
import { GetDatasetLinkedCollections } from './domain/useCases/GetDatasetLinkedCollections'
26+
import { GetDatasetAvailableCategories } from './domain/useCases/GetDatasetAvailableCategories'
2627
import { GetDatasetCitationInOtherFormats } from './domain/useCases/GetDatasetCitationInOtherFormats'
2728

2829
const datasetsRepository = new DatasetsRepository()
@@ -61,6 +62,7 @@ const deleteDatasetDraft = new DeleteDatasetDraft(datasetsRepository)
6162
const linkDataset = new LinkDataset(datasetsRepository)
6263
const unlinkDataset = new UnlinkDataset(datasetsRepository)
6364
const getDatasetLinkedCollections = new GetDatasetLinkedCollections(datasetsRepository)
65+
const getDatasetAvailableCategories = new GetDatasetAvailableCategories(datasetsRepository)
6466
const getDatasetCitationInOtherFormats = new GetDatasetCitationInOtherFormats(datasetsRepository)
6567

6668
export {
@@ -83,6 +85,7 @@ export {
8385
linkDataset,
8486
unlinkDataset,
8587
getDatasetLinkedCollections,
88+
getDatasetAvailableCategories,
8689
getDatasetCitationInOtherFormats
8790
}
8891
export { DatasetNotNumberedVersion } from './domain/models/DatasetNotNumberedVersion'

src/datasets/infra/repositories/DatasetsRepository.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -346,4 +346,15 @@ export class DatasetsRepository extends ApiRepository implements IDatasetsReposi
346346
throw error
347347
})
348348
}
349+
350+
public async getDatasetAvailableCategories(datasetId: number | string): Promise<string[]> {
351+
return this.doGet(
352+
this.buildApiEndpoint(this.datasetsResourceName, 'availableFileCategories', datasetId),
353+
true
354+
)
355+
.then((response) => response.data.data as string[])
356+
.catch((error) => {
357+
throw error
358+
})
359+
}
349360
}

src/files/domain/useCases/UpdateFileCategories.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export class UpdateFileCategories implements UseCase<void> {
1010

1111
/**
1212
* Updates the categories for a particular File.
13-
* More detailed information about updating a file's categories behavior can be found in https://guides.dataverse.org/en/latest/api/native-api.html#updating-file-metadata
13+
* More detailed information about updating a file's categories behavior can be found in https://guides.dataverse.org/en/latest/api/native-api.html#updating-file-metadata-categories
1414
*
1515
* @param {number | string} [fileId] - The file identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
1616
* @param {string[]} [categories] - The categories to be added to the file.

src/files/domain/useCases/UpdateFileTabularTags.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export class UpdateFileTabularTags implements UseCase<void> {
1010

1111
/**
1212
* Updates the tabular tabular Tags for a particular File.
13-
* More detailed information about updating a file's tabularTags behavior can be found in https://guides.dataverse.org/en/latest/api/native-api.html#updating-file-metadata
13+
* More detailed information about updating a file's tabularTags behavior can be found in https://guides.dataverse.org/en/latest/api/native-api.html#updating-file-tabular-tags
1414
*
1515
* @param {number | string} [fileId] - The file identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
1616
* @param {string[]} [tabularTags] - The tabular tags to be added to the file.
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import { ApiConfig, createDataset, getDatasetAvailableCategories, ReadError } from '../../../src'
2+
import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'
3+
import { deleteUnpublishedDatasetViaApi } from '../../testHelpers/datasets/datasetHelper'
4+
import { CreatedDatasetIdentifiers } from '../../../src/datasets/domain/models/CreatedDatasetIdentifiers'
5+
import { TestConstants } from '../../testHelpers/TestConstants'
6+
7+
describe('execute', () => {
8+
let createdDatasetIdentifiers: CreatedDatasetIdentifiers
9+
beforeEach(async () => {
10+
ApiConfig.init(
11+
TestConstants.TEST_API_URL,
12+
DataverseApiAuthMechanism.API_KEY,
13+
process.env.TEST_API_KEY
14+
)
15+
createdDatasetIdentifiers = await createDataset.execute(TestConstants.TEST_NEW_DATASET_DTO)
16+
})
17+
18+
afterEach(async () => {
19+
deleteUnpublishedDatasetViaApi(createdDatasetIdentifiers.numericId)
20+
})
21+
22+
it('should return categories array when a dataset has files categories', async () => {
23+
const defaultCategories = ['Code', 'Data', 'Documentation']
24+
const categoriesList = await getDatasetAvailableCategories.execute(
25+
createdDatasetIdentifiers.numericId
26+
)
27+
expect(categoriesList.sort()).toEqual(defaultCategories.sort())
28+
})
29+
30+
it('should return error when dataset does not exist', async () => {
31+
const nonExistentDatasetId = 99999
32+
33+
await expect(
34+
getDatasetAvailableCategories.execute(nonExistentDatasetId)
35+
).rejects.toBeInstanceOf(ReadError)
36+
})
37+
})

test/integration/datasets/DatasetsRepository.test.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1609,4 +1609,44 @@ describe('DatasetsRepository', () => {
16091609
await expect(sut.getDatasetLinkedCollections(nonExistentTestDatasetId)).rejects.toThrow()
16101610
})
16111611
})
1612+
1613+
describe('getDatasetAvailableCategories', () => {
1614+
let testDatasetIds: CreatedDatasetIdentifiers
1615+
1616+
beforeAll(async () => {
1617+
testDatasetIds = await createDataset.execute(TestConstants.TEST_NEW_DATASET_DTO)
1618+
})
1619+
1620+
afterAll(async () => {
1621+
await deletePublishedDatasetViaApi(testDatasetIds.persistentId)
1622+
})
1623+
1624+
test('should get available categories', async () => {
1625+
const fileMetadata = {
1626+
description: 'test description',
1627+
directoryLabel: 'directoryLabel',
1628+
categories: ['category1', 'category2', 'Documentation', 'Data', 'Code']
1629+
}
1630+
1631+
await uploadFileViaApi(testDatasetIds.numericId, testTextFile1Name, fileMetadata)
1632+
1633+
const actual = await sut.getDatasetAvailableCategories(testDatasetIds.numericId)
1634+
expect(actual.sort()).toEqual(fileMetadata.categories.sort())
1635+
})
1636+
1637+
test('should get available categorie if dataset id is persistent id', async () => {
1638+
const fileMetadata = {
1639+
description: 'test description',
1640+
directoryLabel: 'directoryLabel',
1641+
categories: ['category1', 'category2', 'Documentation', 'Data', 'Code']
1642+
}
1643+
1644+
const actual = await sut.getDatasetAvailableCategories(testDatasetIds.persistentId)
1645+
expect(actual.sort()).toEqual(fileMetadata.categories.sort())
1646+
})
1647+
1648+
test('should return error when dataset does not exist', async () => {
1649+
await expect(sut.getDatasetAvailableCategories(nonExistentTestDatasetId)).rejects.toThrow()
1650+
})
1651+
})
16121652
})

0 commit comments

Comments
 (0)