Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions docs/useCases.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,15 @@ The different use cases currently available in the package are classified below,
- [Get Differences between Two Dataset Versions](#get-differences-between-two-dataset-versions)
- [List All Datasets](#list-all-datasets)
- [Get Dataset Versions Summaries](#get-dataset-versions-summaries)
- [Get Dataset Linked Collections](#get-dataset-linked-collections)
- [Datasets write use cases](#datasets-write-use-cases)
- [Create a Dataset](#create-a-dataset)
- [Update a Dataset](#update-a-dataset)
- [Publish a Dataset](#publish-a-dataset)
- [Deaccession a Dataset](#deaccession-a-dataset)
- [Delete a Draft Dataset](#delete-a-draft-dataset)
- [Link a Dataset](#link-a-dataset)
- [Unlink a Dataset](#unlink-a-dataset)
- [Files](#Files)
- [Files read use cases](#files-read-use-cases)
- [Get a File](#get-a-file)
Expand Down Expand Up @@ -735,6 +738,30 @@ _See [use case](../src/datasets/domain/useCases/GetDatasetVersionsSummaries.ts)

The `datasetId` parameter can be a string, for persistent identifiers, or a number, for numeric identifiers.

#### Get Dataset Linked Collections

Returns an array of [DatasetLinkedCollection](../src/datasets/domain/models/DatasetLinkedCollection.ts) that contains the collections linked to a dataset.

##### Example call:

```typescript
import { getDatasetLinkedCollections } from '@iqss/dataverse-client-javascript'

/* ... */

const datasetId = 'doi:10.77777/FK2/AAAAAA'

getDatasetLinkedCollections
.execute(datasetId)
.then((datasetLinkedCollections: DatasetLinkedCollection[]) => {
/* ... */
})

/* ... */
```

_See [use case](../src/datasets/domain/useCases/GetDatasetLinkedCollections.ts) implementation_.

### Datasets Write Use Cases

#### Create a Dataset
Expand Down Expand Up @@ -944,6 +971,48 @@ The `datasetId` parameter is a number for numeric identifiers or string for pers

If you try to delete a dataset without draft version, you will get a not found error.

#### Link a Dataset

Creates a link between a Dataset and a Collection.

##### Example call:

```typescript
import { linkDataset } from '@iqss/dataverse-client-javascript'

/* ... */

const datasetId = 1
const collectionAlias = 'collection-alias'

linkDataset.execute(datasetId, collectionAlias)

/* ... */
```

_See [use case](../src/datasets/domain/useCases/LinkDataset.ts) implementation_.

#### Unlink a Dataset

Removes a link between a Dataset and a Collection.

##### Example call:

```typescript
import { unlinkDataset } from '@iqss/dataverse-client-javascript'

/* ... */

const datasetId = 1
const collectionAlias = 'collection-alias'

unlinkDataset.execute(datasetId, collectionAlias)

/* ... */
```

_See [use case](../src/datasets/domain/useCases/UnlinkDataset.ts) implementation_.

#### Get Download Count of a Dataset

Total number of downloads requested for a dataset, given a dataset numeric identifier,
Expand Down
5 changes: 5 additions & 0 deletions src/datasets/domain/models/DatasetLinkedCollection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface DatasetLinkedCollection {
id: number
alias: string
displayName: string
}
4 changes: 4 additions & 0 deletions src/datasets/domain/repositories/IDatasetsRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { MetadataBlock } from '../../../metadataBlocks'
import { DatasetVersionDiff } from '../models/DatasetVersionDiff'
import { DatasetDownloadCount } from '../models/DatasetDownloadCount'
import { DatasetVersionSummaryInfo } from '../models/DatasetVersionSummaryInfo'
import { DatasetLinkedCollection } from '../models/DatasetLinkedCollection'

export interface IDatasetsRepository {
getDataset(
Expand Down Expand Up @@ -61,4 +62,7 @@ export interface IDatasetsRepository {
): Promise<DatasetDownloadCount>
getDatasetVersionsSummaries(datasetId: number | string): Promise<DatasetVersionSummaryInfo[]>
deleteDatasetDraft(datasetId: number | string): Promise<void>
linkDataset(datasetId: number, collectionAlias: string): Promise<void>
unlinkDataset(datasetId: number, collectionAlias: string): Promise<void>
getDatasetLinkedCollections(datasetId: number | string): Promise<DatasetLinkedCollection[]>
}
21 changes: 21 additions & 0 deletions src/datasets/domain/useCases/GetDatasetLinkedCollections.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { DatasetLinkedCollection } from '../models/DatasetLinkedCollection'
import { IDatasetsRepository } from '../repositories/IDatasetsRepository'

export class GetDatasetLinkedCollections implements UseCase<DatasetLinkedCollection[]> {
private datasetsRepository: IDatasetsRepository

constructor(datasetsRepository: IDatasetsRepository) {
this.datasetsRepository = datasetsRepository
}

/**
* Returns a list of collections linked to a dataset.
*
* @param {number | string} [datasetId] - The dataset identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
* @returns {Promise<DatasetLinkedCollection[]>}
*/
async execute(datasetId: number | string): Promise<DatasetLinkedCollection[]> {
return await this.datasetsRepository.getDatasetLinkedCollections(datasetId)
}
}
21 changes: 21 additions & 0 deletions src/datasets/domain/useCases/LinkDataset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { IDatasetsRepository } from '../repositories/IDatasetsRepository'

export class LinkDataset implements UseCase<void> {
private datasetsRepository: IDatasetsRepository

constructor(datasetsRepository: IDatasetsRepository) {
this.datasetsRepository = datasetsRepository
}

/**
* Creates a link between a Dataset and a Collection.
*
* @param {number} [datasetId] - The dataset id.
* @param {string} [collectionAlias] - The collection alias.
* @returns {Promise<void>} - This method does not return anything upon successful completion.
*/
async execute(datasetId: number, collectionAlias: string): Promise<void> {
return await this.datasetsRepository.linkDataset(datasetId, collectionAlias)
}
}
21 changes: 21 additions & 0 deletions src/datasets/domain/useCases/UnlinkDataset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { IDatasetsRepository } from '../repositories/IDatasetsRepository'

export class UnlinkDataset implements UseCase<void> {
private datasetsRepository: IDatasetsRepository

constructor(datasetsRepository: IDatasetsRepository) {
this.datasetsRepository = datasetsRepository
}

/**
* Removes a link between a Dataset and a Collection.
*
* @param {number} [datasetId] - The dataset id.
* @param {string} [collectionAlias] - The collection alias.
* @returns {Promise<void>} - This method does not return anything upon successful completion.
*/
async execute(datasetId: number, collectionAlias: string): Promise<void> {
return await this.datasetsRepository.unlinkDataset(datasetId, collectionAlias)
}
}
12 changes: 11 additions & 1 deletion src/datasets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import { DeaccessionDataset } from './domain/useCases/DeaccessionDataset'
import { GetDatasetDownloadCount } from './domain/useCases/GetDatasetDownloadCount'
import { GetDatasetVersionsSummaries } from './domain/useCases/GetDatasetVersionsSummaries'
import { DeleteDatasetDraft } from './domain/useCases/DeleteDatasetDraft'
import { LinkDataset } from './domain/useCases/LinkDataset'
import { UnlinkDataset } from './domain/useCases/UnlinkDataset'
import { GetDatasetLinkedCollections } from './domain/useCases/GetDatasetLinkedCollections'

const datasetsRepository = new DatasetsRepository()

Expand Down Expand Up @@ -54,6 +57,9 @@ const deaccessionDataset = new DeaccessionDataset(datasetsRepository)
const getDatasetDownloadCount = new GetDatasetDownloadCount(datasetsRepository)
const getDatasetVersionsSummaries = new GetDatasetVersionsSummaries(datasetsRepository)
const deleteDatasetDraft = new DeleteDatasetDraft(datasetsRepository)
const linkDataset = new LinkDataset(datasetsRepository)
const unlinkDataset = new UnlinkDataset(datasetsRepository)
const getDatasetLinkedCollections = new GetDatasetLinkedCollections(datasetsRepository)

export {
getDataset,
Expand All @@ -71,7 +77,10 @@ export {
deaccessionDataset,
getDatasetDownloadCount,
getDatasetVersionsSummaries,
deleteDatasetDraft
deleteDatasetDraft,
linkDataset,
unlinkDataset,
getDatasetLinkedCollections
}
export { DatasetNotNumberedVersion } from './domain/models/DatasetNotNumberedVersion'
export { DatasetUserPermissions } from './domain/models/DatasetUserPermissions'
Expand Down Expand Up @@ -105,3 +114,4 @@ export {
DatasetVersionSummaryInfo,
DatasetVersionSummaryStringValues
} from './domain/models/DatasetVersionSummaryInfo'
export { DatasetLinkedCollection } from './domain/models/DatasetLinkedCollection'
30 changes: 30 additions & 0 deletions src/datasets/infra/repositories/DatasetsRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import { DatasetVersionDiff } from '../../domain/models/DatasetVersionDiff'
import { transformDatasetVersionDiffResponseToDatasetVersionDiff } from './transformers/datasetVersionDiffTransformers'
import { DatasetDownloadCount } from '../../domain/models/DatasetDownloadCount'
import { DatasetVersionSummaryInfo } from '../../domain/models/DatasetVersionSummaryInfo'
import { DatasetLinkedCollection } from '../../domain/models/DatasetLinkedCollection'
import { transformDatasetLinkedCollectionsResponseToDatasetLinkedCollection } from './transformers/datasetLinkedCollectionsTransformers'

export interface GetAllDatasetPreviewsQueryParams {
per_page?: number
Expand Down Expand Up @@ -287,4 +289,32 @@ export class DatasetsRepository extends ApiRepository implements IDatasetsReposi
throw error
})
}

public async linkDataset(datasetId: number, collectionAlias: string): Promise<void> {
return this.doPut(`/${this.datasetsResourceName}/${datasetId}/link/${collectionAlias}`, {})
.then(() => undefined)
.catch((error) => {
throw error
})
}

public async unlinkDataset(datasetId: number, collectionAlias: string): Promise<void> {
return this.doDelete(`/${this.datasetsResourceName}/${datasetId}/deleteLink/${collectionAlias}`)
.then(() => undefined)
.catch((error) => {
throw error
})
}

public async getDatasetLinkedCollections(
datasetId: number | string
): Promise<DatasetLinkedCollection[]> {
return this.doGet(this.buildApiEndpoint(this.datasetsResourceName, 'links', datasetId), true)
.then((response) =>
transformDatasetLinkedCollectionsResponseToDatasetLinkedCollection(response.data.data)
)
.catch((error) => {
throw error
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export interface DatasetLinkedCollectionsPayload {
id: number
identifier: string
'linked-dataverses': {
id: number
alias: string
displayName: string
}[]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { DatasetLinkedCollection } from '../../../domain/models/DatasetLinkedCollection'
import { DatasetLinkedCollectionsPayload } from './DatasetLinkedCollectionsPayload'

export const transformDatasetLinkedCollectionsResponseToDatasetLinkedCollection = (
payload: DatasetLinkedCollectionsPayload
): DatasetLinkedCollection[] => {
return payload['linked-dataverses'].map((linkedDataverse) => ({
id: linkedDataverse.id,
alias: linkedDataverse.alias,
displayName: linkedDataverse.displayName
}))
}
62 changes: 62 additions & 0 deletions test/functional/datasets/GetDatasetLinkedCollections.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import {
ApiConfig,
createDataset,
getDatasetLinkedCollections,
linkDataset,
ReadError
} from '../../../src'
import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'
import {
createCollectionViaApi,
deleteCollectionViaApi
} from '../../testHelpers/collections/collectionHelper'
import { deleteUnpublishedDatasetViaApi } from '../../testHelpers/datasets/datasetHelper'
import { TestConstants } from '../../testHelpers/TestConstants'

describe('execute', () => {
const testCollectionAlias = 'getDatasetLinkedCollectionsFunctionalTestCollection'
beforeEach(async () => {
ApiConfig.init(
TestConstants.TEST_API_URL,
DataverseApiAuthMechanism.API_KEY,
process.env.TEST_API_KEY
)
})

it('should return empty array when no collections are linked', async () => {
const createdDatasetIdentifiers = await createDataset.execute(
TestConstants.TEST_NEW_DATASET_DTO
)
const linkedCollections = await getDatasetLinkedCollections.execute(
createdDatasetIdentifiers.numericId
)
expect(linkedCollections.length).toBe(0)
await deleteUnpublishedDatasetViaApi(createdDatasetIdentifiers.numericId)
})

it('should return linked collections for a dataset', async () => {
const createdDatasetIdentifiers = await createDataset.execute(
TestConstants.TEST_NEW_DATASET_DTO
)
await createCollectionViaApi(testCollectionAlias)

await linkDataset.execute(createdDatasetIdentifiers.numericId, testCollectionAlias)

const linkedCollections = await getDatasetLinkedCollections.execute(
createdDatasetIdentifiers.numericId
)
expect(linkedCollections.length).toBe(1)
expect(linkedCollections[0].alias).toBe(testCollectionAlias)

await deleteUnpublishedDatasetViaApi(createdDatasetIdentifiers.numericId)
await deleteCollectionViaApi(testCollectionAlias)
})

it('should return error when dataset does not exist', async () => {
const nonExistentDatasetId = 99999

await expect(getDatasetLinkedCollections.execute(nonExistentDatasetId)).rejects.toBeInstanceOf(
ReadError
)
})
})
Loading