Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add getCollection use case and tests #134

Merged
merged 19 commits into from
Mar 28, 2024
Merged
Show file tree
Hide file tree
Changes from 10 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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,5 @@ node_modules
coverage

# ignore npm lock
package-json.lock
package-json.lock
.npmrc
41 changes: 36 additions & 5 deletions docs/useCases.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ The different use cases currently available in the package are classified below,

## Table of Contents

- [Collections](#Collections)
- [Collections read use cases](#collections-read-use-cases)
- [Get a Collection](#get-a-collection)
- [Datasets](#Datasets)
- [Datasets read use cases](#datasets-read-use-cases)
- [Get a Dataset](#get-a-dataset)
Expand Down Expand Up @@ -42,6 +45,38 @@ The different use cases currently available in the package are classified below,
- [Get Maximum Embargo Duration In Months](#get-maximum-embargo-duration-in-months)
- [Get ZIP Download Limit](#get-zip-download-limit)

## Collections

### Collections Read Use Cases

#### Get a Collection

Returns a [Collection](../src/collections/domain/models/Collection.ts) instance, given the search parameters to identify it.

##### Example call:

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

/* ... */

const collectionId = 'collectionAlias'

getCollection.execute(collectionId).then((collection: Collection) => {
/* ... */
})

/* ... */
```

_See [use case](../src/collections/domain/useCases/GetCollection.ts)_ definition.

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

The optional `datasetVersionId` parameter can correspond to a numeric version identifier, as in the previous example, or a [DatasetNotNumberedVersion](../src/datasets/domain/models/DatasetNotNumberedVersion.ts) enum value. If not set, the default value is `DatasetNotNumberedVersion.LATEST`.

There is an optional third parameter called `includeDeaccessioned`, which indicates whether to consider deaccessioned versions or not in the dataset search. If not set, the default value is `false`.

MellyGray marked this conversation as resolved.
Show resolved Hide resolved
## Datasets

### Datasets Read Use Cases
Expand Down Expand Up @@ -69,11 +104,7 @@ getDataset.execute(datasetId, datasetVersionId).then((dataset: Dataset) => {

_See [use case](../src/datasets/domain/useCases/GetDataset.ts)_ definition.

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

The optional `datasetVersionId` parameter can correspond to a numeric version identifier, as in the previous example, or a [DatasetNotNumberedVersion](../src/datasets/domain/models/DatasetNotNumberedVersion.ts) enum value. If not set, the default value is `DatasetNotNumberedVersion.LATEST`.

There is an optional third parameter called `includeDeaccessioned`, which indicates whether to consider deaccessioned versions or not in the dataset search. If not set, the default value is `false`.
The `collectionId` parameter can be a string, for identifying by the collection alias, or a number, for numeric identifiers.
MellyGray marked this conversation as resolved.
Show resolved Hide resolved

#### Get Dataset By Private URL Token

Expand Down
7 changes: 7 additions & 0 deletions src/collections/domain/models/Collection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// NOTE: Props referenced from JsonPrinter.java
MellyGray marked this conversation as resolved.
Show resolved Hide resolved
export interface Collection {
id: number
name: string
alias: string
affiliation: string
}
MellyGray marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 4 additions & 0 deletions src/collections/domain/repositories/ICollectionsRepository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { Collection } from '../models/Collection'
export interface ICollectionsRepository {
getCollection(collectionId: number | string): Promise<Collection>
}
22 changes: 22 additions & 0 deletions src/collections/domain/useCases/GetCollection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { ICollectionsRepository } from '../repositories/ICollectionsRepository'
import { Collection } from '../models/Collection'

export class GetCollection implements UseCase<Collection> {
private collectionsRepository: ICollectionsRepository

constructor(collectionsRepository: ICollectionsRepository) {
this.collectionsRepository = collectionsRepository
}

/**
* Returns a Collection instance, given the search parameters to identify it.
*
* https://guides.dataverse.org/en/6.0/api/native-api.html#view-a-dataverse-collection
* @param {number | string} [collectionId] - The collection identifier ...
* @returns {Promise<Collection>}
*/
async execute(collectionId: number): Promise<Collection> {
MellyGray marked this conversation as resolved.
Show resolved Hide resolved
return await this.collectionsRepository.getCollection(collectionId)
}
MellyGray marked this conversation as resolved.
Show resolved Hide resolved
}
10 changes: 10 additions & 0 deletions src/collections/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { GetCollection } from './domain/useCases/GetCollection'

import { CollectionsRepository } from './infra/repositories/CollectionsRepository'

const collectionsRepository = new CollectionsRepository()

const getCollection = new GetCollection(collectionsRepository)

export { getCollection }
export { Collection } from './domain/models/Collection'
16 changes: 16 additions & 0 deletions src/collections/infra/repositories/CollectionsRepository.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { ApiRepository } from '../../../core/infra/repositories/ApiRepository'
import { ICollectionsRepository } from '../../domain/repositories/ICollectionsRepository'
import { transformCollectionIdResponseToPayload } from './transformers/collectionTransformers'
export class CollectionsRepository extends ApiRepository implements ICollectionsRepository {
private readonly collectionsResourceName: string = 'dataverses'

// NOTE: Used 'disable` for the type below per gPortas.
// eslint-disable-next-line @typescript-eslint/no-explicit-any
public async getCollection(collectionId: any): Promise<any> {
MellyGray marked this conversation as resolved.
Show resolved Hide resolved
return this.doGet(this.buildApiEndpoint(this.collectionsResourceName, collectionId), true)
MellyGray marked this conversation as resolved.
Show resolved Hide resolved
.then((response) => transformCollectionIdResponseToPayload(response))
.catch((error) => {
throw error
})
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export interface CollectionPayload {
id: number
alias: string
name: string
affiliation: string
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { Collection } from '../../../domain/models/Collection'
import { AxiosResponse } from 'axios'
import { CollectionPayload } from './CollectionPayload'

export const transformCollectionIdResponseToPayload = (response: AxiosResponse): Collection => {
MellyGray marked this conversation as resolved.
Show resolved Hide resolved
const collectionPayload = response.data.data
return transformPayloadToCollection(collectionPayload)
}

const transformPayloadToCollection = (collectionPayload: CollectionPayload): Collection => {
const collectionModel: Collection = {
id: collectionPayload.id,
alias: collectionPayload.alias,
name: collectionPayload.name,
affiliation: collectionPayload.affiliation
}
return collectionModel
}
2 changes: 1 addition & 1 deletion src/core/infra/repositories/ApiRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ export abstract class ApiRepository {
switch (ApiConfig.dataverseApiAuthMechanism) {
case DataverseApiAuthMechanism.SESSION_COOKIE:
/*
We set { withCredentials: true } to send the JSESSIONID cookie in the requests for API authentication.
We set { withCredentials: true } to send the JSESSIONID cookie in the requests for API authentication.
This is required, along with the session auth feature flag enabled in the backend, to be able to authenticate using the JSESSIONID cookie.
Auth mechanisms like this are configurable to set the one that fits the particular use case of js-dataverse. (For the SPA MVP, it is the session cookie API auth).
*/
Expand Down
14 changes: 7 additions & 7 deletions src/datasets/domain/repositories/IDatasetsRepository.ts
Original file line number Diff line number Diff line change
@@ -1,32 +1,32 @@
import { Dataset } from '../models/Dataset'
import { DatasetUserPermissions } from '../models/DatasetUserPermissions'
import { DatasetLock } from '../models/DatasetLock'
import { DatasetPreviewSubset } from '../models/DatasetPreviewSubset'
import { DatasetUserPermissions } from '../models/DatasetUserPermissions'
import { CreatedDatasetIdentifiers } from '../models/CreatedDatasetIdentifiers'
import { NewDatasetDTO } from '../dtos/NewDatasetDTO'
import { MetadataBlock } from '../../../metadataBlocks'
import { CreatedDatasetIdentifiers } from '../models/CreatedDatasetIdentifiers'

export interface IDatasetsRepository {
getDatasetSummaryFieldNames(): Promise<string[]>
getDataset(
datasetId: number | string,
datasetVersionId: string,
includeDeaccessioned: boolean
): Promise<Dataset>
getPrivateUrlDataset(token: string): Promise<Dataset>
getDatasetLocks(datasetId: number | string): Promise<DatasetLock[]>
getDatasetCitation(
datasetId: number,
datasetVersionId: string,
includeDeaccessioned: boolean
): Promise<string>
getPrivateUrlDatasetCitation(token: string): Promise<string>
getDatasetUserPermissions(datasetId: number | string): Promise<DatasetUserPermissions>
getDatasetLocks(datasetId: number | string): Promise<DatasetLock[]>
getPrivateUrlDataset(token: string): Promise<Dataset>
getAllDatasetPreviews(
limit?: number,
offset?: number,
collectionId?: string
): Promise<DatasetPreviewSubset>
getDatasetSummaryFieldNames(): Promise<string[]>
getPrivateUrlDatasetCitation(token: string): Promise<string>
getDatasetUserPermissions(datasetId: number | string): Promise<DatasetUserPermissions>
createDataset(
newDataset: NewDatasetDTO,
datasetMetadataBlocks: MetadataBlock[],
Expand Down
46 changes: 23 additions & 23 deletions src/datasets/index.ts
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
import { DatasetsRepository } from './infra/repositories/DatasetsRepository'
import { GetDatasetSummaryFieldNames } from './domain/useCases/GetDatasetSummaryFieldNames'
import { MetadataBlocksRepository } from '../metadataBlocks/infra/repositories/MetadataBlocksRepository'
import { GetDataset } from './domain/useCases/GetDataset'
import { GetPrivateUrlDataset } from './domain/useCases/GetPrivateUrlDataset'
import { GetDatasetCitation } from './domain/useCases/GetDatasetCitation'
import { GetPrivateUrlDatasetCitation } from './domain/useCases/GetPrivateUrlDatasetCitation'
import { GetDatasetUserPermissions } from './domain/useCases/GetDatasetUserPermissions'
import { CreateDataset } from './domain/useCases/CreateDataset'
import { GetDatasetLocks } from './domain/useCases/GetDatasetLocks'
import { GetDatasetCitation } from './domain/useCases/GetDatasetCitation'
import { GetPrivateUrlDataset } from './domain/useCases/GetPrivateUrlDataset'
import { GetAllDatasetPreviews } from './domain/useCases/GetAllDatasetPreviews'
import { NewDatasetResourceValidator } from './domain/useCases/validators/NewDatasetResourceValidator'
import { MetadataBlocksRepository } from '../metadataBlocks/infra/repositories/MetadataBlocksRepository'
import { CreateDataset } from './domain/useCases/CreateDataset'
import { MetadataFieldValidator } from './domain/useCases/validators/MetadataFieldValidator'
import { GetDatasetUserPermissions } from './domain/useCases/GetDatasetUserPermissions'
import { NewDatasetResourceValidator } from './domain/useCases/validators/NewDatasetResourceValidator'
import { GetDatasetSummaryFieldNames } from './domain/useCases/GetDatasetSummaryFieldNames'
import { GetPrivateUrlDatasetCitation } from './domain/useCases/GetPrivateUrlDatasetCitation'
import { SingleMetadataFieldValidator } from './domain/useCases/validators/SingleMetadataFieldValidator'
import { MultipleMetadataFieldValidator } from './domain/useCases/validators/MultipleMetadataFieldValidator'

const datasetsRepository = new DatasetsRepository()

const getDatasetSummaryFieldNames = new GetDatasetSummaryFieldNames(datasetsRepository)
const getDataset = new GetDataset(datasetsRepository)
const getPrivateUrlDataset = new GetPrivateUrlDataset(datasetsRepository)
const getDatasetCitation = new GetDatasetCitation(datasetsRepository)
const getPrivateUrlDatasetCitation = new GetPrivateUrlDatasetCitation(datasetsRepository)
const getDatasetUserPermissions = new GetDatasetUserPermissions(datasetsRepository)
const getDatasetLocks = new GetDatasetLocks(datasetsRepository)
const getDatasetCitation = new GetDatasetCitation(datasetsRepository)
const getPrivateUrlDataset = new GetPrivateUrlDataset(datasetsRepository)
const getAllDatasetPreviews = new GetAllDatasetPreviews(datasetsRepository)
const getDatasetUserPermissions = new GetDatasetUserPermissions(datasetsRepository)
const getDatasetSummaryFieldNames = new GetDatasetSummaryFieldNames(datasetsRepository)
const getPrivateUrlDatasetCitation = new GetPrivateUrlDatasetCitation(datasetsRepository)
const singleMetadataFieldValidator = new SingleMetadataFieldValidator()
const metadataFieldValidator = new MetadataFieldValidator(
new SingleMetadataFieldValidator(),
Expand All @@ -36,37 +36,37 @@ const createDataset = new CreateDataset(
)

export {
getDatasetSummaryFieldNames,
getDataset,
getPrivateUrlDataset,
getDatasetCitation,
getPrivateUrlDatasetCitation,
getDatasetUserPermissions,
getDatasetLocks,
getDatasetCitation,
getPrivateUrlDataset,
getAllDatasetPreviews,
getDatasetUserPermissions,
getDatasetSummaryFieldNames,
getPrivateUrlDatasetCitation,
createDataset
}
export { DatasetNotNumberedVersion } from './domain/models/DatasetNotNumberedVersion'
export { DatasetUserPermissions } from './domain/models/DatasetUserPermissions'
export { DatasetLock, DatasetLockType } from './domain/models/DatasetLock'
export {
Dataset,
DatasetLicense,
DatasetVersionInfo,
DatasetVersionState,
DatasetLicense,
DatasetMetadataBlocks,
DatasetMetadataBlock,
DatasetMetadataBlocks,
DatasetMetadataFields,
DatasetMetadataFieldValue,
DatasetMetadataSubField
DatasetMetadataSubField,
DatasetMetadataFieldValue
} from './domain/models/Dataset'
export { DatasetPreview } from './domain/models/DatasetPreview'
export { DatasetPreviewSubset } from './domain/models/DatasetPreviewSubset'
export {
NewDatasetDTO as NewDataset,
NewDatasetMetadataBlockValuesDTO as NewDatasetMetadataBlockValues,
NewDatasetMetadataFieldsDTO as NewDatasetMetadataFields,
NewDatasetMetadataFieldValueDTO as NewDatasetMetadataFieldValue,
NewDatasetMetadataBlockValuesDTO as NewDatasetMetadataBlockValues,
NewDatasetMetadataChildFieldValueDTO as NewDatasetMetadataChildFieldValue
} from './domain/dtos/NewDatasetDTO'
export { CreatedDatasetIdentifiers } from './domain/models/CreatedDatasetIdentifiers'
12 changes: 6 additions & 6 deletions src/datasets/infra/repositories/DatasetsRepository.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { ApiRepository } from '../../../core/infra/repositories/ApiRepository'
import { IDatasetsRepository } from '../../domain/repositories/IDatasetsRepository'
import { Dataset } from '../../domain/models/Dataset'
import { transformVersionResponseToDataset } from './transformers/datasetTransformers'
import { DatasetUserPermissions } from '../../domain/models/DatasetUserPermissions'
import { transformDatasetUserPermissionsResponseToDatasetUserPermissions } from './transformers/datasetUserPermissionsTransformers'
import { DatasetLock } from '../../domain/models/DatasetLock'
import { transformDatasetLocksResponseToDatasetLocks } from './transformers/datasetLocksTransformers'
import { transformDatasetPreviewsResponseToDatasetPreviewSubset } from './transformers/datasetPreviewsTransformers'
import { DatasetUserPermissions } from '../../domain/models/DatasetUserPermissions'
import { CreatedDatasetIdentifiers } from '../../domain/models/CreatedDatasetIdentifiers'
import { DatasetPreviewSubset } from '../../domain/models/DatasetPreviewSubset'
import { NewDatasetDTO } from '../../domain/dtos/NewDatasetDTO'
import { MetadataBlock } from '../../../metadataBlocks'
import { transformVersionResponseToDataset } from './transformers/datasetTransformers'
import { transformNewDatasetModelToRequestPayload } from './transformers/newDatasetTransformers'
import { CreatedDatasetIdentifiers } from '../../domain/models/CreatedDatasetIdentifiers'
import { transformDatasetLocksResponseToDatasetLocks } from './transformers/datasetLocksTransformers'
import { transformDatasetPreviewsResponseToDatasetPreviewSubset } from './transformers/datasetPreviewsTransformers'
import { transformDatasetUserPermissionsResponseToDatasetUserPermissions } from './transformers/datasetUserPermissionsTransformers'

export interface GetAllDatasetPreviewsQueryParams {
per_page?: number
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
import {
Dataset,
DatasetLicense,
DatasetVersionState,
DatasetMetadataBlocks,
DatasetMetadataFields,
DatasetMetadataSubField,
DatasetMetadataFieldValue,
DatasetLicense,
DatasetMetadataBlocks,
ANONYMIZED_FIELD_VALUE
} from '../../../domain/models/Dataset'
import { AxiosResponse } from 'axios'
import {
DatasetPayload,
LicensePayload,
MetadataBlocksPayload,
MetadataSubfieldValuePayload,
MetadataFieldPayload,
MetadataFieldValuePayload
MetadataBlocksPayload,
MetadataFieldValuePayload,
MetadataSubfieldValuePayload
} from './DatasetPayload'
import { transformPayloadToOwnerNode } from '../../../../core/infra/repositories/transformers/dvObjectOwnerNodeTransformer'
import TurndownService from 'turndown'
Expand All @@ -30,8 +30,8 @@ export const transformVersionResponseToDataset = (response: AxiosResponse): Data
export const transformVersionPayloadToDataset = (versionPayload: DatasetPayload): Dataset => {
const datasetModel: Dataset = {
id: versionPayload.datasetId,
persistentId: versionPayload.datasetPersistentId,
versionId: versionPayload.id,
persistentId: versionPayload.datasetPersistentId,
versionInfo: {
majorNumber: versionPayload.versionNumber,
minorNumber: versionPayload.versionMinorNumber,
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,6 @@ export * from './info'
export * from './users'
export * from './auth'
export * from './datasets'
export * from './collections'
export * from './metadataBlocks'
export * from './files'
Loading
Loading