Skip to content
Merged
Show file tree
Hide file tree
Changes from 7 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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel
- New Use Case: [Create a Template](./docs/useCases.md#create-a-template) under Templates.
- New Use Case: [Get a Template](./docs/useCases.md#get-a-template) under Templates.
- New Use Case: [Delete a Template](./docs/useCases.md#delete-a-template) under Templates.
- Templates: Added `setTemplateAsDefault` use case and repository method to support Dataverse endpoint `POST /dataverses/{id}/template/default/{templateId}`.
- Templates: Added `unsetTemplateAsDefault` use case and repository method to support Dataverse endpoint `DELETE /dataverses/{id}/template/default`.
- New Use Case: [Update Terms of Access](./docs/useCases.md#update-terms-of-access).
- Guestbooks: Added use cases and repository support for guestbook creation, listing, and enabling/disabling.
- Guestbooks: Added dataset-level guestbook assignment and removal support via `assignDatasetGuestbook` (`PUT /api/datasets/{identifier}/guestbook`) and `removeDatasetGuestbook` (`DELETE /api/datasets/{identifier}/guestbook`).
Expand Down
39 changes: 39 additions & 0 deletions docs/useCases.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ The different use cases currently available in the package are classified below,
- [Templates write use cases](#templates-write-use-cases)
- [Create a Template](#create-a-template)
- [Delete a Template](#delete-a-template)
- [Set Template As Default](#set-template-as-default)
- [Unset Template As Default](#unset-template-as-default)
- [Datasets](#Datasets)
- [Datasets read use cases](#datasets-read-use-cases)
- [Get a Dataset](#get-a-dataset)
Expand Down Expand Up @@ -685,6 +687,43 @@ await deleteTemplate.execute(templateId)

_See [use case](../src/templates/domain/useCases/DeleteTemplate.ts)_ definition.

#### Set Template As Default

Sets the default template for a given Dataverse collection.

You must have edit permissions on the collection in order to use this endpoint.

##### Example call:

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

const collectionIdOrAlias = ':root'
const templateId = 12345

await setTemplateAsDefault.execute(templateId, collectionIdOrAlias)
```

_See [use case](../src/templates/domain/useCases/SetTemplateAsDefault.ts)_ definition.

#### Unset Template As Default

Removes the default template from a given Dataverse collection.

You must have edit permissions on the collection in order to use this endpoint.

##### Example call:

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

const collectionIdOrAlias = ':root'

await unsetTemplateAsDefault.execute(collectionIdOrAlias)
```

_See [use case](../src/templates/domain/useCases/UnsetTemplateAsDefault.ts)_ definition.

## Datasets

### Datasets Read Use Cases
Expand Down
2 changes: 2 additions & 0 deletions src/templates/domain/repositories/ITemplatesRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,6 @@ export interface ITemplatesRepository {
getTemplate(templateId: number): Promise<Template>
getTemplatesByCollectionId(collectionIdOrAlias: number | string): Promise<Template[]>
deleteTemplate(templateId: number): Promise<void>
setTemplateAsDefault(collectionIdOrAlias: number | string, templateId: number): Promise<void>
unsetTemplateAsDefault(collectionIdOrAlias: number | string): Promise<void>
}
25 changes: 25 additions & 0 deletions src/templates/domain/useCases/SetTemplateAsDefault.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { ROOT_COLLECTION_ID } from '../../../collections/domain/models/Collection'
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { ITemplatesRepository } from '../repositories/ITemplatesRepository'

export class SetTemplateAsDefault implements UseCase<void> {
private templatesRepository: ITemplatesRepository

constructor(templatesRepository: ITemplatesRepository) {
this.templatesRepository = templatesRepository
}

/**
* Sets the default template for the specified collection.
*
* @param {number} templateId - Template id to set as default.
* @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'.
*/
async execute(
templateId: number,
collectionIdOrAlias: number | string = ROOT_COLLECTION_ID
): Promise<void> {
return await this.templatesRepository.setTemplateAsDefault(collectionIdOrAlias, templateId)
}
}
21 changes: 21 additions & 0 deletions src/templates/domain/useCases/UnsetTemplateAsDefault.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { ROOT_COLLECTION_ID } from '../../../collections/domain/models/Collection'
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { ITemplatesRepository } from '../repositories/ITemplatesRepository'

export class UnsetTemplateAsDefault implements UseCase<void> {
private templatesRepository: ITemplatesRepository

constructor(templatesRepository: ITemplatesRepository) {
this.templatesRepository = templatesRepository
}

/**
* Removes the default template for the specified 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'.
*/
async execute(collectionIdOrAlias: number | string = ROOT_COLLECTION_ID): Promise<void> {
return await this.templatesRepository.unsetTemplateAsDefault(collectionIdOrAlias)
}
}
13 changes: 12 additions & 1 deletion src/templates/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,26 @@ import { CreateTemplate } from './domain/useCases/CreateTemplate'
import { DeleteTemplate } from './domain/useCases/DeleteTemplate'
import { GetTemplatesByCollectionId } from './domain/useCases/GetTemplatesByCollectionId'
import { GetTemplate } from './domain/useCases/GetTemplate'
import { SetTemplateAsDefault } from './domain/useCases/SetTemplateAsDefault'
import { UnsetTemplateAsDefault } from './domain/useCases/UnsetTemplateAsDefault'

const templatesRepository = new TemplatesRepository()

const createTemplate = new CreateTemplate(templatesRepository)
const deleteTemplate = new DeleteTemplate(templatesRepository)
const getTemplatesByCollectionId = new GetTemplatesByCollectionId(templatesRepository)
const getTemplate = new GetTemplate(templatesRepository)
const setTemplateAsDefault = new SetTemplateAsDefault(templatesRepository)
const unsetTemplateAsDefault = new UnsetTemplateAsDefault(templatesRepository)

export { createTemplate, deleteTemplate, getTemplatesByCollectionId, getTemplate }
export {
createTemplate,
deleteTemplate,
getTemplatesByCollectionId,
getTemplate,
setTemplateAsDefault,
unsetTemplateAsDefault
}
export {
CreateTemplateDTO,
TemplateFieldDTO,
Expand Down
22 changes: 22 additions & 0 deletions src/templates/infra/repositories/TemplatesRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,26 @@ export class TemplatesRepository extends ApiRepository implements ITemplatesRepo
throw error
})
}

public async setTemplateAsDefault(
collectionIdOrAlias: number | string,
templateId: number
): Promise<void> {
return this.doPost(
`/${this.collectionsResourceName}/${collectionIdOrAlias}/template/default/${templateId}`,
{}
)
.then(() => undefined)
.catch((error) => {
throw error
})
}

public async unsetTemplateAsDefault(collectionIdOrAlias: number | string): Promise<void> {
return this.doDelete(`/${this.collectionsResourceName}/${collectionIdOrAlias}/template/default`)
.then(() => undefined)
.catch((error) => {
throw error
})
}
}
75 changes: 75 additions & 0 deletions test/functional/templates/SetTemplateAsDefault.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import { ApiConfig } from '../../../src'
import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'
import { TestConstants } from '../../testHelpers/TestConstants'
import {
createTemplate,
getTemplatesByCollectionId,
setTemplateAsDefault
} from '../../../src/templates'
import { CreateTemplateDTO } from '../../../src/templates/domain/dtos/CreateTemplateDTO'
import { MetadataFieldTypeClass } from '../../../src/metadataBlocks/domain/models/MetadataBlock'
import { deleteDatasetTemplateViaApi } from '../../testHelpers/datasets/datasetTemplatesHelper'

describe('SetTemplateAsDefault.execute', () => {
const collectionIdOrAlias = ':root'

beforeEach(async () => {
ApiConfig.init(
TestConstants.TEST_API_URL,
DataverseApiAuthMechanism.API_KEY,
process.env.TEST_API_KEY
)
})

test('should set the default template for a collection', async () => {
const templateName = `TestDefaultTemplate-${Date.now()}`
const templateDto: CreateTemplateDTO = {
name: templateName,
isDefault: false,
fields: [
{
typeName: 'author',
typeClass: MetadataFieldTypeClass.Compound,
multiple: true,
value: [
{
authorName: {
typeName: 'authorName',
typeClass: MetadataFieldTypeClass.Primitive,
value: 'Belicheck, Bill'
},
authorAffiliation: {
typeName: 'authorIdentifierScheme',
typeClass: MetadataFieldTypeClass.Primitive,
value: 'ORCID'
}
}
]
}
],
instructions: [
{
instructionField: 'author',
instructionText: 'The author data'
}
]
}

await createTemplate.execute(templateDto, collectionIdOrAlias)
const templatesAfterCreate = await getTemplatesByCollectionId.execute(collectionIdOrAlias)
const createdTemplate = templatesAfterCreate.find((template) => template.name === templateName)

if (!createdTemplate) {
throw new Error('Created template was not found in collection templates.')
}

await setTemplateAsDefault.execute(createdTemplate.id, collectionIdOrAlias)

const templatesAfterSet = await getTemplatesByCollectionId.execute(collectionIdOrAlias)
const updatedTemplate = templatesAfterSet.find((template) => template.id === createdTemplate.id)

expect(updatedTemplate?.isDefault).toBe(true)

await deleteDatasetTemplateViaApi(createdTemplate.id)
})
})
77 changes: 77 additions & 0 deletions test/functional/templates/UnsetTemplateAsDefault.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import { ApiConfig } from '../../../src'
import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'
import { TestConstants } from '../../testHelpers/TestConstants'
import {
createTemplate,
getTemplatesByCollectionId,
setTemplateAsDefault,
unsetTemplateAsDefault
} from '../../../src/templates'
import { CreateTemplateDTO } from '../../../src/templates/domain/dtos/CreateTemplateDTO'
import { MetadataFieldTypeClass } from '../../../src/metadataBlocks/domain/models/MetadataBlock'
import { deleteDatasetTemplateViaApi } from '../../testHelpers/datasets/datasetTemplatesHelper'

describe('UnsetTemplateAsDefault.execute', () => {
const collectionIdOrAlias = ':root'

beforeEach(async () => {
ApiConfig.init(
TestConstants.TEST_API_URL,
DataverseApiAuthMechanism.API_KEY,
process.env.TEST_API_KEY
)
})

test('should remove the default template from a collection', async () => {
const templateName = `TestUnsetTemplateAsDefault-${Date.now()}`
const templateDto: CreateTemplateDTO = {
name: templateName,
isDefault: false,
fields: [
{
typeName: 'author',
typeClass: MetadataFieldTypeClass.Compound,
multiple: true,
value: [
{
authorName: {
typeName: 'authorName',
typeClass: MetadataFieldTypeClass.Primitive,
value: 'Belicheck, Bill'
},
authorAffiliation: {
typeName: 'authorIdentifierScheme',
typeClass: MetadataFieldTypeClass.Primitive,
value: 'ORCID'
}
}
]
}
],
instructions: [
{
instructionField: 'author',
instructionText: 'The author data'
}
]
}

await createTemplate.execute(templateDto, collectionIdOrAlias)
const templatesAfterCreate = await getTemplatesByCollectionId.execute(collectionIdOrAlias)
const createdTemplate = templatesAfterCreate.find((template) => template.name === templateName)

if (!createdTemplate) {
throw new Error('Created template was not found in collection templates.')
}

await setTemplateAsDefault.execute(createdTemplate.id, collectionIdOrAlias)
await unsetTemplateAsDefault.execute(collectionIdOrAlias)

const templatesAfterRemove = await getTemplatesByCollectionId.execute(collectionIdOrAlias)
const hasDefaultTemplate = templatesAfterRemove.some((template) => template.isDefault)

expect(hasDefaultTemplate).toBe(false)

await deleteDatasetTemplateViaApi(createdTemplate.id)
})
})
Loading
Loading