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

178 publish collection use case #182

Merged
merged 9 commits into from
Sep 10, 2024
Merged
23 changes: 23 additions & 0 deletions docs/useCases.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ The different use cases currently available in the package are classified below,
- [Get User Permissions on a Collection](#get-user-permissions-on-a-collection)
- [Collections write use cases](#collections-write-use-cases)
- [Create a Collection](#create-a-collection)
- [Publish a Collection](#publish-a-collection)
- [Datasets](#Datasets)
- [Datasets read use cases](#datasets-read-use-cases)
- [Get a Dataset](#get-a-dataset)
Expand Down Expand Up @@ -192,6 +193,28 @@ The above example creates the new collection in the `root` collection since no c

The use case returns a number, which is the identifier of the created collection.

#### Publish a Collection

Publishes a Collection, given the collection identifier.

##### Example call:

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

/* ... */

const collectionIdOrAlias = 12345

publishCollection.execute(collectionIdOrAlias)

/* ... */
```

The `collectionIdOrAlias` is a generic collection identifier, which can be either a string (for queries by CollectionAlias), or a number (for queries by CollectionId).

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

## Datasets

### Datasets Read Use Cases
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface ICollectionsRepository {
collectionDTO: CollectionDTO,
parentCollectionId: number | string
): Promise<number>
publishCollection(collectionIdOrAlias: number | string): Promise<void>
getCollectionFacets(collectionIdOrAlias: number | string): Promise<CollectionFacet[]>
getCollectionUserPermissions(
collectionIdOrAlias: number | string
Expand Down
20 changes: 20 additions & 0 deletions src/collections/domain/useCases/PublishCollection.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { UseCase } from '../../../core/domain/useCases/UseCase'
import { ICollectionsRepository } from '../repositories/ICollectionsRepository' // Assuming Axios for HTTP requests

export class PublishCollection implements UseCase<void> {
private collectionsRepository: ICollectionsRepository

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

/**
* Publishes a collection, given its identifier and the type of version update type.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the last part "and the type of version update type." should be removed!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@GPortas thanks for finding that, done!

*
* @param {number | string} [collectionIdOrAlias] - The collection identifier, which can be a string (for collection alias), or a number (for numeric identifiers).
* @returns {Promise<void>} - This method does not return anything upon successful completion.
*/
async execute(collectionIdOrAlias: number | string): Promise<void> {
return await this.collectionsRepository.publishCollection(collectionIdOrAlias)
}
}
10 changes: 9 additions & 1 deletion src/collections/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,23 @@ import { GetCollectionFacets } from './domain/useCases/GetCollectionFacets'
import { GetCollectionUserPermissions } from './domain/useCases/GetCollectionUserPermissions'

import { CollectionsRepository } from './infra/repositories/CollectionsRepository'
import { PublishCollection } from './domain/useCases/PublishCollection'

const collectionsRepository = new CollectionsRepository()

const getCollection = new GetCollection(collectionsRepository)
const createCollection = new CreateCollection(collectionsRepository)
const getCollectionFacets = new GetCollectionFacets(collectionsRepository)
const getCollectionUserPermissions = new GetCollectionUserPermissions(collectionsRepository)
const publishCollection = new PublishCollection(collectionsRepository)

export { getCollection, createCollection, getCollectionFacets, getCollectionUserPermissions }
export {
getCollection,
createCollection,
getCollectionFacets,
getCollectionUserPermissions,
publishCollection
}
export { Collection, CollectionInputLevel } from './domain/models/Collection'
export { CollectionFacet } from './domain/models/CollectionFacet'
export { CollectionUserPermissions } from './domain/models/CollectionUserPermissions'
Expand Down
10 changes: 10 additions & 0 deletions src/collections/infra/repositories/CollectionsRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,16 @@ export class CollectionsRepository extends ApiRepository implements ICollections
throw error
})
}
public async publishCollection(collectionIdOrAlias: string | number): Promise<void> {
return this.doPost(
`/${this.collectionsResourceName}/${collectionIdOrAlias}/actions/:publish`,
{}
)
.then(() => undefined)
.catch((error) => {
throw error
})
}

public async getCollectionUserPermissions(
collectionIdOrAlias: number | string
Expand Down
47 changes: 47 additions & 0 deletions test/functional/collections/PublishCollection.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { ApiConfig, createCollection, publishCollection, WriteError } from '../../../src'
import { TestConstants } from '../../testHelpers/TestConstants'
import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig'
import {
createCollectionDTO,
deleteCollectionViaApi
} from '../../testHelpers/collections/collectionHelper'

const testNewCollection = createCollectionDTO('test-publish-collection')

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

test('should successfully publish a collection with id', async () => {
const createdCollectiontIdentifier = await createCollection.execute(testNewCollection)

const response = await publishCollection.execute(createdCollectiontIdentifier)

expect(response).toBeUndefined()
await deleteCollectionViaApi(testNewCollection.alias)
})
test('should successfully publish a collection with alias', async () => {
await createCollection.execute(testNewCollection)

const response = await publishCollection.execute(testNewCollection.alias)

expect(response).toBeUndefined()
await deleteCollectionViaApi(testNewCollection.alias)
})

test('should throw an error when trying to publish a collection that does not exist', async () => {
const nonExistentTestCollectionId = 4567
const expectedError = new WriteError(
`[404] Can't find dataverse with identifier='${nonExistentTestCollectionId}'`
)

await expect(publishCollection.execute(nonExistentTestCollectionId)).rejects.toThrow(
expectedError
)
})
})
17 changes: 17 additions & 0 deletions test/integration/collections/CollectionsRepository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,23 @@ describe('CollectionsRepository', () => {
})
})

describe('publishCollection', () => {
const testPublishCollectionAlias = 'publishCollection-test'

afterAll(async () => {
await deleteCollectionViaApi(testPublishCollectionAlias)
})

test('should publish a collection', async () => {
const newCollectionDTO = createCollectionDTO(testPublishCollectionAlias)
const actualId = await sut.createCollection(newCollectionDTO)
await sut.publishCollection(actualId)
const createdCollection = await sut.getCollection(actualId)

expect(createdCollection.isReleased).toBe(true)
expect(createdCollection.name).toBe(newCollectionDTO.name)
})
})
describe('createCollection', () => {
const testCreateCollectionAlias1 = 'createCollection-test-1'
const testCreateCollectionAlias2 = 'createCollection-test-2'
Expand Down
23 changes: 23 additions & 0 deletions test/unit/collections/PublishCollection.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { ICollectionsRepository } from '../../../src/collections/domain/repositories/ICollectionsRepository'
import { PublishCollection } from '../../../src/collections/domain/useCases/PublishCollection'
import { WriteError } from '../../../src'

describe('execute', () => {
test('should return undefined on repository success', async () => {
const collectionsRepositoryStub: ICollectionsRepository = {} as ICollectionsRepository
collectionsRepositoryStub.publishCollection = jest.fn().mockResolvedValue(undefined)
const sut = new PublishCollection(collectionsRepositoryStub)

const actual = await sut.execute(1)

expect(actual).toEqual(undefined)
})

test('should return error result on repository error', async () => {
const collectionsRepositoryStub: ICollectionsRepository = {} as ICollectionsRepository
collectionsRepositoryStub.publishCollection = jest.fn().mockRejectedValue(new WriteError())
const sut = new PublishCollection(collectionsRepositoryStub)

await expect(sut.execute(1)).rejects.toThrow(WriteError)
})
})
Loading