Skip to content

Commit d497b2b

Browse files
committed
Merge branch 'develop' into 437-access-repository-omit-credentials
2 parents 5be90ea + 9562e61 commit d497b2b

File tree

13 files changed

+475
-2
lines changed

13 files changed

+475
-2
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel
1515
- New Use Case: [Create a Template](./docs/useCases.md#create-a-template) under Templates.
1616
- New Use Case: [Get a Template](./docs/useCases.md#get-a-template) under Templates.
1717
- New Use Case: [Delete a Template](./docs/useCases.md#delete-a-template) under Templates.
18+
- Templates: Added `setTemplateAsDefault` use case and repository method to support Dataverse endpoint `POST /dataverses/{id}/template/default/{templateId}`.
19+
- Templates: Added `unsetTemplateAsDefault` use case and repository method to support Dataverse endpoint `DELETE /dataverses/{id}/template/default`.
1820
- New Use Case: [Update Terms of Access](./docs/useCases.md#update-terms-of-access).
1921
- Guestbooks: Added use cases and repository support for guestbook creation, listing, and enabling/disabling.
2022
- Guestbooks: Added dataset-level guestbook assignment and removal support via `assignDatasetGuestbook` (`PUT /api/datasets/{identifier}/guestbook`) and `removeDatasetGuestbook` (`DELETE /api/datasets/{identifier}/guestbook`).

docs/useCases.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ The different use cases currently available in the package are classified below,
3232
- [Templates write use cases](#templates-write-use-cases)
3333
- [Create a Template](#create-a-template)
3434
- [Delete a Template](#delete-a-template)
35+
- [Set Template As Default](#set-template-as-default)
36+
- [Unset Template As Default](#unset-template-as-default)
3537
- [Datasets](#Datasets)
3638
- [Datasets read use cases](#datasets-read-use-cases)
3739
- [Get a Dataset](#get-a-dataset)
@@ -685,6 +687,43 @@ await deleteTemplate.execute(templateId)
685687

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

690+
#### Set Template As Default
691+
692+
Sets the default template for a given Dataverse collection.
693+
694+
You must have edit permissions on the collection in order to use this endpoint.
695+
696+
##### Example call:
697+
698+
```typescript
699+
import { setTemplateAsDefault } from '@iqss/dataverse-client-javascript'
700+
701+
const collectionIdOrAlias = ':root'
702+
const templateId = 12345
703+
704+
await setTemplateAsDefault.execute(templateId, collectionIdOrAlias)
705+
```
706+
707+
_See [use case](../src/templates/domain/useCases/SetTemplateAsDefault.ts)_ definition.
708+
709+
#### Unset Template As Default
710+
711+
Removes the default template from a given Dataverse collection.
712+
713+
You must have edit permissions on the collection in order to use this endpoint.
714+
715+
##### Example call:
716+
717+
```typescript
718+
import { unsetTemplateAsDefault } from '@iqss/dataverse-client-javascript'
719+
720+
const collectionIdOrAlias = ':root'
721+
722+
await unsetTemplateAsDefault.execute(collectionIdOrAlias)
723+
```
724+
725+
_See [use case](../src/templates/domain/useCases/UnsetTemplateAsDefault.ts)_ definition.
726+
688727
## Datasets
689728

690729
### Datasets Read Use Cases

src/templates/domain/repositories/ITemplatesRepository.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,6 @@ export interface ITemplatesRepository {
66
getTemplate(templateId: number): Promise<Template>
77
getTemplatesByCollectionId(collectionIdOrAlias: number | string): Promise<Template[]>
88
deleteTemplate(templateId: number): Promise<void>
9+
setTemplateAsDefault(collectionIdOrAlias: number | string, templateId: number): Promise<void>
10+
unsetTemplateAsDefault(collectionIdOrAlias: number | string): Promise<void>
911
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import { ROOT_COLLECTION_ID } from '../../../collections/domain/models/Collection'
2+
import { UseCase } from '../../../core/domain/useCases/UseCase'
3+
import { ITemplatesRepository } from '../repositories/ITemplatesRepository'
4+
5+
export class SetTemplateAsDefault implements UseCase<void> {
6+
private templatesRepository: ITemplatesRepository
7+
8+
constructor(templatesRepository: ITemplatesRepository) {
9+
this.templatesRepository = templatesRepository
10+
}
11+
12+
/**
13+
* Sets the default template for the specified collection.
14+
*
15+
* @param {number} templateId - Template id to set as default.
16+
* @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)
17+
* If this parameter is not set, the default value is: ':root'.
18+
*/
19+
async execute(
20+
templateId: number,
21+
collectionIdOrAlias: number | string = ROOT_COLLECTION_ID
22+
): Promise<void> {
23+
return await this.templatesRepository.setTemplateAsDefault(collectionIdOrAlias, templateId)
24+
}
25+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { ROOT_COLLECTION_ID } from '../../../collections/domain/models/Collection'
2+
import { UseCase } from '../../../core/domain/useCases/UseCase'
3+
import { ITemplatesRepository } from '../repositories/ITemplatesRepository'
4+
5+
export class UnsetTemplateAsDefault implements UseCase<void> {
6+
private templatesRepository: ITemplatesRepository
7+
8+
constructor(templatesRepository: ITemplatesRepository) {
9+
this.templatesRepository = templatesRepository
10+
}
11+
12+
/**
13+
* Removes the default template for the specified collection.
14+
*
15+
* @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)
16+
* If this parameter is not set, the default value is: ':root'.
17+
*/
18+
async execute(collectionIdOrAlias: number | string = ROOT_COLLECTION_ID): Promise<void> {
19+
return await this.templatesRepository.unsetTemplateAsDefault(collectionIdOrAlias)
20+
}
21+
}

src/templates/index.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,26 @@ import { CreateTemplate } from './domain/useCases/CreateTemplate'
33
import { DeleteTemplate } from './domain/useCases/DeleteTemplate'
44
import { GetTemplatesByCollectionId } from './domain/useCases/GetTemplatesByCollectionId'
55
import { GetTemplate } from './domain/useCases/GetTemplate'
6+
import { SetTemplateAsDefault } from './domain/useCases/SetTemplateAsDefault'
7+
import { UnsetTemplateAsDefault } from './domain/useCases/UnsetTemplateAsDefault'
68

79
const templatesRepository = new TemplatesRepository()
810

911
const createTemplate = new CreateTemplate(templatesRepository)
1012
const deleteTemplate = new DeleteTemplate(templatesRepository)
1113
const getTemplatesByCollectionId = new GetTemplatesByCollectionId(templatesRepository)
1214
const getTemplate = new GetTemplate(templatesRepository)
15+
const setTemplateAsDefault = new SetTemplateAsDefault(templatesRepository)
16+
const unsetTemplateAsDefault = new UnsetTemplateAsDefault(templatesRepository)
1317

14-
export { createTemplate, deleteTemplate, getTemplatesByCollectionId, getTemplate }
18+
export {
19+
createTemplate,
20+
deleteTemplate,
21+
getTemplatesByCollectionId,
22+
getTemplate,
23+
setTemplateAsDefault,
24+
unsetTemplateAsDefault
25+
}
1526
export {
1627
CreateTemplateDTO,
1728
TemplateFieldDTO,

src/templates/infra/repositories/TemplatesRepository.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,4 +55,26 @@ export class TemplatesRepository extends ApiRepository implements ITemplatesRepo
5555
throw error
5656
})
5757
}
58+
59+
public async setTemplateAsDefault(
60+
collectionIdOrAlias: number | string,
61+
templateId: number
62+
): Promise<void> {
63+
return this.doPost(
64+
`/${this.collectionsResourceName}/${collectionIdOrAlias}/template/default/${templateId}`,
65+
{}
66+
)
67+
.then(() => undefined)
68+
.catch((error) => {
69+
throw error
70+
})
71+
}
72+
73+
public async unsetTemplateAsDefault(collectionIdOrAlias: number | string): Promise<void> {
74+
return this.doDelete(`/${this.collectionsResourceName}/${collectionIdOrAlias}/template/default`)
75+
.then(() => undefined)
76+
.catch((error) => {
77+
throw error
78+
})
79+
}
5880
}

test/functional/notifications/DeleteNotification.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ describe('execute', () => {
2525
})
2626

2727
test('should throw an error when the notification id does not exist', async () => {
28-
await expect(deleteNotification.execute(123)).rejects.toThrow(WriteError)
28+
await expect(deleteNotification.execute(9999)).rejects.toThrow(WriteError)
2929
})
3030
})
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import { ApiConfig } from '../../../src'
2+
import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'
3+
import { TestConstants } from '../../testHelpers/TestConstants'
4+
import {
5+
createTemplate,
6+
getTemplatesByCollectionId,
7+
setTemplateAsDefault
8+
} from '../../../src/templates'
9+
import { CreateTemplateDTO } from '../../../src/templates/domain/dtos/CreateTemplateDTO'
10+
import { MetadataFieldTypeClass } from '../../../src/metadataBlocks/domain/models/MetadataBlock'
11+
import { deleteDatasetTemplateViaApi } from '../../testHelpers/datasets/datasetTemplatesHelper'
12+
13+
describe('SetTemplateAsDefault.execute', () => {
14+
const collectionIdOrAlias = ':root'
15+
16+
beforeEach(async () => {
17+
ApiConfig.init(
18+
TestConstants.TEST_API_URL,
19+
DataverseApiAuthMechanism.API_KEY,
20+
process.env.TEST_API_KEY
21+
)
22+
})
23+
24+
test('should set the default template for a collection', async () => {
25+
const templateName = `TestDefaultTemplate-${Date.now()}`
26+
const templateDto: CreateTemplateDTO = {
27+
name: templateName,
28+
isDefault: false,
29+
fields: [
30+
{
31+
typeName: 'author',
32+
typeClass: MetadataFieldTypeClass.Compound,
33+
multiple: true,
34+
value: [
35+
{
36+
authorName: {
37+
typeName: 'authorName',
38+
typeClass: MetadataFieldTypeClass.Primitive,
39+
value: 'Belicheck, Bill'
40+
},
41+
authorAffiliation: {
42+
typeName: 'authorIdentifierScheme',
43+
typeClass: MetadataFieldTypeClass.Primitive,
44+
value: 'ORCID'
45+
}
46+
}
47+
]
48+
}
49+
],
50+
instructions: [
51+
{
52+
instructionField: 'author',
53+
instructionText: 'The author data'
54+
}
55+
]
56+
}
57+
58+
await createTemplate.execute(templateDto, collectionIdOrAlias)
59+
const templatesAfterCreate = await getTemplatesByCollectionId.execute(collectionIdOrAlias)
60+
const createdTemplate = templatesAfterCreate.find((template) => template.name === templateName)
61+
62+
if (!createdTemplate) {
63+
throw new Error('Created template was not found in collection templates.')
64+
}
65+
66+
await setTemplateAsDefault.execute(createdTemplate.id, collectionIdOrAlias)
67+
68+
const templatesAfterSet = await getTemplatesByCollectionId.execute(collectionIdOrAlias)
69+
const updatedTemplate = templatesAfterSet.find((template) => template.id === createdTemplate.id)
70+
71+
expect(updatedTemplate?.isDefault).toBe(true)
72+
73+
await deleteDatasetTemplateViaApi(createdTemplate.id)
74+
})
75+
})
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
import { ApiConfig } from '../../../src'
2+
import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'
3+
import { TestConstants } from '../../testHelpers/TestConstants'
4+
import {
5+
createTemplate,
6+
getTemplatesByCollectionId,
7+
setTemplateAsDefault,
8+
unsetTemplateAsDefault
9+
} from '../../../src/templates'
10+
import { CreateTemplateDTO } from '../../../src/templates/domain/dtos/CreateTemplateDTO'
11+
import { MetadataFieldTypeClass } from '../../../src/metadataBlocks/domain/models/MetadataBlock'
12+
import { deleteDatasetTemplateViaApi } from '../../testHelpers/datasets/datasetTemplatesHelper'
13+
14+
describe('UnsetTemplateAsDefault.execute', () => {
15+
const collectionIdOrAlias = ':root'
16+
17+
beforeEach(async () => {
18+
ApiConfig.init(
19+
TestConstants.TEST_API_URL,
20+
DataverseApiAuthMechanism.API_KEY,
21+
process.env.TEST_API_KEY
22+
)
23+
})
24+
25+
test('should remove the default template from a collection', async () => {
26+
const templateName = `TestUnsetTemplateAsDefault-${Date.now()}`
27+
const templateDto: CreateTemplateDTO = {
28+
name: templateName,
29+
isDefault: false,
30+
fields: [
31+
{
32+
typeName: 'author',
33+
typeClass: MetadataFieldTypeClass.Compound,
34+
multiple: true,
35+
value: [
36+
{
37+
authorName: {
38+
typeName: 'authorName',
39+
typeClass: MetadataFieldTypeClass.Primitive,
40+
value: 'Belicheck, Bill'
41+
},
42+
authorAffiliation: {
43+
typeName: 'authorIdentifierScheme',
44+
typeClass: MetadataFieldTypeClass.Primitive,
45+
value: 'ORCID'
46+
}
47+
}
48+
]
49+
}
50+
],
51+
instructions: [
52+
{
53+
instructionField: 'author',
54+
instructionText: 'The author data'
55+
}
56+
]
57+
}
58+
59+
await createTemplate.execute(templateDto, collectionIdOrAlias)
60+
const templatesAfterCreate = await getTemplatesByCollectionId.execute(collectionIdOrAlias)
61+
const createdTemplate = templatesAfterCreate.find((template) => template.name === templateName)
62+
63+
if (!createdTemplate) {
64+
throw new Error('Created template was not found in collection templates.')
65+
}
66+
67+
await setTemplateAsDefault.execute(createdTemplate.id, collectionIdOrAlias)
68+
await unsetTemplateAsDefault.execute(collectionIdOrAlias)
69+
70+
const templatesAfterRemove = await getTemplatesByCollectionId.execute(collectionIdOrAlias)
71+
const hasDefaultTemplate = templatesAfterRemove.some((template) => template.isDefault)
72+
73+
expect(hasDefaultTemplate).toBe(false)
74+
75+
await deleteDatasetTemplateViaApi(createdTemplate.id)
76+
})
77+
})

0 commit comments

Comments
 (0)