Skip to content

Commit 3446807

Browse files
authored
Merge pull request #263 from IQSS/feat/256-delete-collection-use-case
Delete Collection use case
2 parents e689f25 + 4325fe1 commit 3446807

File tree

15 files changed

+312
-6
lines changed

15 files changed

+312
-6
lines changed

.github/workflows/copy_labels.yml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
name: Copy labels from issue to pull request
2+
3+
on:
4+
pull_request:
5+
types: [opened]
6+
7+
jobs:
8+
copy-labels:
9+
runs-on: ubuntu-latest
10+
name: Copy labels from linked issues
11+
steps:
12+
- name: copy-labels
13+
uses: michalvankodev/[email protected]
14+
with:
15+
repo-token: ${{ secrets.GITHUB_TOKEN }}
16+
labels-to-exclude: |
17+
Size: 3
18+
Size: 10
19+
Size: 20
20+
Size: 33
21+
Size: 80
22+
Original size: 3
23+
Original size: 10
24+
Original size: 20
25+
Original size: 33
26+
Original size: 80

docs/useCases.md

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ The different use cases currently available in the package are classified below,
1919
- [Create a Collection](#create-a-collection)
2020
- [Update a Collection](#update-a-collection)
2121
- [Publish a Collection](#publish-a-collection)
22+
- [Delete a Collection](#delete-a-collection)
2223
- [Update Collection Featured Items](#update-collection-featured-items)
2324
- [Delete Collection Featured Items](#delete-collection-featured-items)
2425
- [Datasets](#Datasets)
@@ -320,6 +321,24 @@ The `collectionIdOrAlias` is a generic collection identifier, which can be eithe
320321

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

324+
### Delete a Collection
325+
326+
```typescript
327+
import { deleteCollection } from '@iqss/dataverse-client-javascript'
328+
329+
/* ... */
330+
331+
const collectionIdOrAlias = 12345
332+
333+
deleteCollection.execute(collectionIdOrAlias)
334+
335+
/* ... */
336+
```
337+
338+
The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId).
339+
340+
_See [use case](../src/collections/domain/useCases/DeleteCollection.ts)_ definition.
341+
323342
#### Update Collection Featured Items
324343

325344
Updates all featured items, given a collection identifier and a CollectionFeaturedItemsDTO.

src/collections/domain/models/Collection.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export interface Collection {
1515
contacts?: CollectionContact[]
1616
isMetadataBlockRoot: boolean
1717
isFacetRoot: boolean
18+
childCount: number
1819
}
1920

2021
export interface CollectionInputLevel {

src/collections/domain/repositories/ICollectionsRepository.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export interface ICollectionsRepository {
1414
parentCollectionId: number | string
1515
): Promise<number>
1616
publishCollection(collectionIdOrAlias: number | string): Promise<void>
17+
deleteCollection(collectionIdOrAlias: number | string): Promise<void>
1718
getCollectionFacets(collectionIdOrAlias: number | string): Promise<CollectionFacet[]>
1819
getCollectionUserPermissions(
1920
collectionIdOrAlias: number | 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 { ICollectionsRepository } from '../repositories/ICollectionsRepository'
3+
4+
export class DeleteCollection implements UseCase<void> {
5+
private collectionsRepository: ICollectionsRepository
6+
7+
constructor(collectionsRepository: ICollectionsRepository) {
8+
this.collectionsRepository = collectionsRepository
9+
}
10+
11+
/**
12+
* Deletes the Dataverse collection whose database ID or alias is given:
13+
*
14+
* @param {number | string} [collectionIdOrAlias] - A generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId)
15+
* @returns {Promise<void>} -This method does not return anything upon successful completion.
16+
*/
17+
async execute(collectionIdOrAlias: number | string): Promise<void> {
18+
return await this.collectionsRepository.deleteCollection(collectionIdOrAlias)
19+
}
20+
}

src/collections/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { GetCollectionFeaturedItems } from './domain/useCases/GetCollectionFeatu
99
import { CollectionsRepository } from './infra/repositories/CollectionsRepository'
1010
import { UpdateCollectionFeaturedItems } from './domain/useCases/UpdateCollectionFeaturedItems'
1111
import { DeleteCollectionFeaturedItems } from './domain/useCases/DeleteCollectionFeaturedItems'
12+
import { DeleteCollection } from './domain/useCases/DeleteCollection'
1213

1314
const collectionsRepository = new CollectionsRepository()
1415

@@ -22,6 +23,7 @@ const updateCollection = new UpdateCollection(collectionsRepository)
2223
const getCollectionFeaturedItems = new GetCollectionFeaturedItems(collectionsRepository)
2324
const updateCollectionFeaturedItems = new UpdateCollectionFeaturedItems(collectionsRepository)
2425
const deleteCollectionFeaturedItems = new DeleteCollectionFeaturedItems(collectionsRepository)
26+
const deleteCollection = new DeleteCollection(collectionsRepository)
2527

2628
export {
2729
getCollection,
@@ -33,7 +35,8 @@ export {
3335
updateCollection,
3436
getCollectionFeaturedItems,
3537
updateCollectionFeaturedItems,
36-
deleteCollectionFeaturedItems
38+
deleteCollectionFeaturedItems,
39+
deleteCollection
3740
}
3841
export { Collection, CollectionInputLevel } from './domain/models/Collection'
3942
export { CollectionFacet } from './domain/models/CollectionFacet'

src/collections/infra/repositories/CollectionsRepository.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,8 @@ export class CollectionsRepository extends ApiRepository implements ICollections
7070
collectionIdOrAlias: number | string = ROOT_COLLECTION_ID
7171
): Promise<Collection> {
7272
return this.doGet(`/${this.collectionsResourceName}/${collectionIdOrAlias}`, true, {
73-
returnOwners: true
73+
returnOwners: true,
74+
returnChildCount: true
7475
})
7576
.then((response) => transformCollectionResponseToCollection(response))
7677
.catch((error) => {
@@ -102,6 +103,7 @@ export class CollectionsRepository extends ApiRepository implements ICollections
102103
throw error
103104
})
104105
}
106+
105107
public async publishCollection(collectionIdOrAlias: string | number): Promise<void> {
106108
return this.doPost(
107109
`/${this.collectionsResourceName}/${collectionIdOrAlias}/actions/:publish`,
@@ -113,6 +115,14 @@ export class CollectionsRepository extends ApiRepository implements ICollections
113115
})
114116
}
115117

118+
public async deleteCollection(collectionIdOrAlias: number | string): Promise<void> {
119+
return this.doDelete(`/${this.collectionsResourceName}/${collectionIdOrAlias}`)
120+
.then(() => undefined)
121+
.catch((error) => {
122+
throw error
123+
})
124+
}
125+
116126
public async getCollectionUserPermissions(
117127
collectionIdOrAlias: number | string
118128
): Promise<CollectionUserPermissions> {

src/collections/infra/repositories/transformers/CollectionPayload.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ export interface CollectionPayload {
1313
dataverseType: string
1414
isMetadataBlockRoot: boolean
1515
isFacetRoot: boolean
16+
childCount: number
1617
}
1718

1819
export interface CollectionInputLevelPayload {

src/collections/infra/repositories/transformers/collectionTransformers.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ const transformPayloadToCollection = (collectionPayload: CollectionPayload): Col
5353
isMetadataBlockRoot: collectionPayload.isMetadataBlockRoot,
5454
isFacetRoot: collectionPayload.isFacetRoot,
5555
description: collectionPayload.description,
56+
childCount: collectionPayload.childCount,
5657
...(collectionPayload.isPartOf && {
5758
isPartOf: transformPayloadToOwnerNode(collectionPayload.isPartOf)
5859
}),
Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
import {
2+
ApiConfig,
3+
ReadError,
4+
WriteError,
5+
createCollection,
6+
deleteCollection,
7+
getCollection
8+
} from '../../../src'
9+
import { TestConstants } from '../../testHelpers/TestConstants'
10+
import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'
11+
import { createCollectionDTO } from '../../testHelpers/collections/collectionHelper'
12+
13+
describe('execute', () => {
14+
beforeEach(async () => {
15+
ApiConfig.init(
16+
TestConstants.TEST_API_URL,
17+
DataverseApiAuthMechanism.API_KEY,
18+
process.env.TEST_API_KEY
19+
)
20+
})
21+
22+
test('should successfully delete a collection', async () => {
23+
const testCollectionAlias = 'deleteCollection-functional-test'
24+
const testNewCollection = createCollectionDTO(testCollectionAlias)
25+
await createCollection.execute(testNewCollection)
26+
27+
expect.assertions(1)
28+
try {
29+
await deleteCollection.execute(testCollectionAlias)
30+
} catch (error) {
31+
throw new Error('Collection should be deleted')
32+
} finally {
33+
const expectedError = new ReadError(
34+
`[404] Can't find dataverse with identifier='${testCollectionAlias}'`
35+
)
36+
await expect(getCollection.execute(testCollectionAlias)).rejects.toThrow(expectedError)
37+
}
38+
})
39+
40+
test('should throw an error when the collection does not exist', async () => {
41+
expect.assertions(2)
42+
let writeError: WriteError | undefined = undefined
43+
try {
44+
await deleteCollection.execute(TestConstants.TEST_DUMMY_COLLECTION_ID)
45+
throw new Error('Use case should throw an error')
46+
} catch (error) {
47+
writeError = error as WriteError
48+
} finally {
49+
expect(writeError).toBeInstanceOf(WriteError)
50+
expect(writeError?.message).toEqual(
51+
`There was an error when writing the resource. Reason was: [404] Can't find dataverse with identifier='${TestConstants.TEST_DUMMY_COLLECTION_ID}'`
52+
)
53+
}
54+
})
55+
})

0 commit comments

Comments
 (0)