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

Support publish dataset with update current version #166

Merged
merged 2 commits into from
Jul 31, 2024
Merged
Show file tree
Hide file tree
Changes from all 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: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ node_modules
# intellij
.idea

# Visual Studio
/.vscode

# unit tests
coverage

Expand Down
7 changes: 4 additions & 3 deletions docs/useCases.md
Original file line number Diff line number Diff line change
Expand Up @@ -478,15 +478,16 @@ publishDataset.execute(datasetId, versionUpdateType)
_See [use case](../src/datasets/domain/useCases/PublishDataset.ts) implementation_.

The above example publishes the dataset with the specified identifier and performs a minor version update. If the response
is successful, the use case does not return the dataset object, but the HTTP status code `200`. Otherwise, it throws an error.
If you want to perform a major version update, you must set the `versionUpdateType` parameter to `VersionUpdateType.MAJOR`.

is successful, the use case does not return the dataset object, but the HTTP status code `200`. Otherwise, it throws an error.\
If you want to perform a major version update, you must set the `versionUpdateType` parameter to `VersionUpdateType.MAJOR`.\
Superusers can pass `VersionUpdateType.UPDATE_CURRENT` to update metadata without changing the version number. This will overwrite the latest published version and therefore will only work for a dataset that has been published at least once. \*Note that this will only work also if there were no file changes in the update.\
The `datasetId` parameter can be a string, for persistent identifiers, or a number, for numeric identifiers.
Copy link
Contributor

Choose a reason for hiding this comment

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

I know we haven't worked on permissions yet generally, but it could be good to add a comment that UPDATE_CURRENT is only available to 'superuser' accounts, since it's more of a special case than other permissions logic. But if we want to wait till later, that's ok.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Hi @ekraffmiller , I think that is exactly what I added in the docs here:

Superusers can pass VersionUpdateType.UPDATE_CURRENT to update metadata without changing the version number. This will overwrite the latest published version and therefore will only work for a dataset that has been published at least once. *Note that this will only work also if there were no file changes in the update.

Or were you thinking about something different? I ask about this on the dv-rearchitecture-frontend channel.

Copy link
Contributor

Choose a reason for hiding this comment

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

Oh, I'm sorry, I misread that comment in the doc! Yes, that looks perfect. :)


The `versionUpdateType` parameter can be a [VersionUpdateType](../src/datasets/domain/models/VersionUpdateType.ts) enum value, which can be one of the following:

- `VersionUpdateType.MINOR`
- `VersionUpdateType.MAJOR`
- `VersionUpdateType.UPDATE_CURRENT`

## Files

Expand Down
3 changes: 2 additions & 1 deletion src/datasets/domain/models/Dataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -186,5 +186,6 @@ interface Software extends DatasetMetadataSubField {

export enum VersionUpdateType {
MAJOR = 'major',
MINOR = 'minor'
MINOR = 'minor',
UPDATE_CURRENT = 'updatecurrent'
}
2 changes: 1 addition & 1 deletion src/datasets/domain/useCases/PublishDataset.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export class PublishDataset implements UseCase<void> {
* Publishes a dataset, given its identifier and the type of version update type.
*
* @param {number | string} [datasetId] - The dataset identifier, which can be a string (for persistent identifiers), or a number (for numeric identifiers).
* @param {VersionUpdateType} versionUpdateType - Specifies the type of version update, 'major' or 'minor'.
* @param {VersionUpdateType} versionUpdateType - Specifies the type of version update, 'major', 'minor' or 'updatecurrent'
* @returns {Promise<void>} - This method does not return anything upon successful completion.
*/
async execute(datasetId: number | string, versionUpdateType: VersionUpdateType): Promise<void> {
Expand Down
35 changes: 35 additions & 0 deletions test/functional/datasets/PublishDataset.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import {
ApiConfig,
createDataset,
publishDataset,
updateDataset,
VersionUpdateType,
WriteError
} from '../../../src'
Expand Down Expand Up @@ -72,6 +73,28 @@ describe('execute', () => {
await deletePublishedDatasetViaApi(createdDatasetIdentifiers.persistentId)
})

test('should successfully publish a dataset with update current version', async () => {
const createdDatasetIdentifiers = await createDataset.execute(testNewDataset)

const firstPublishResponse = await publishDataset.execute(
createdDatasetIdentifiers.persistentId,
VersionUpdateType.MAJOR
)
await waitForNoLocks(createdDatasetIdentifiers.numericId, 10)

await updateDataset.execute(createdDatasetIdentifiers.numericId, testNewDataset)

const secondPublishResponse = await publishDataset.execute(
createdDatasetIdentifiers.persistentId,
VersionUpdateType.UPDATE_CURRENT
)
await waitForNoLocks(createdDatasetIdentifiers.numericId, 10)

expect(firstPublishResponse).toBeUndefined()
expect(secondPublishResponse).toBeUndefined()
await deletePublishedDatasetViaApi(createdDatasetIdentifiers.persistentId)
})

test('should throw an error when trying to publish a dataset that does not exist', async () => {
const nonExistentTestDatasetId = 'non-existent-dataset'
const expectedError = new WriteError(
Expand All @@ -82,4 +105,16 @@ describe('execute', () => {
publishDataset.execute(nonExistentTestDatasetId, VersionUpdateType.MAJOR)
).rejects.toThrow(expectedError)
})

test('should throw an error when trying to publish with the current version a dataset that has never been published before', async () => {
const createdDatasetIdentifiers = await createDataset.execute(testNewDataset)

await waitForNoLocks(createdDatasetIdentifiers.numericId, 10)

await expect(
publishDataset.execute(createdDatasetIdentifiers.numericId, VersionUpdateType.UPDATE_CURRENT)
).rejects.toBeInstanceOf(WriteError)

await deletePublishedDatasetViaApi(createdDatasetIdentifiers.persistentId)
})
})
58 changes: 58 additions & 0 deletions test/integration/datasets/DatasetsRepository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,64 @@ describe('DatasetsRepository', () => {
})
})

describe('publish dataset with current version', () => {
let testDatasetIds: CreatedDatasetIdentifiers

beforeEach(async () => {
testDatasetIds = await createDataset.execute(TestConstants.TEST_NEW_DATASET_DTO)
})

afterEach(async () => {
await deletePublishedDatasetViaApi(testDatasetIds.persistentId)
})

test('should update current dataset version keeping same version number', async () => {
const expectedMajorVersion = 1

await waitForNoLocks(testDatasetIds.numericId, 10)

// Dataset is in draft, so we need to publish it first
await sut.publishDataset(testDatasetIds.numericId, VersionUpdateType.MAJOR)
await waitForNoLocks(testDatasetIds.numericId, 10)

const datasetAfterFirstPublish = await sut.getDataset(
testDatasetIds.numericId,
DatasetNotNumberedVersion.LATEST,
false
)

// Update dataset
const metadataBlocksRepository = new MetadataBlocksRepository()
const citationMetadataBlock = await metadataBlocksRepository.getMetadataBlockByName(
'citation'
)
await sut.updateDataset(testDatasetIds.numericId, TestConstants.TEST_NEW_DATASET_DTO, [
citationMetadataBlock
])

// Update current version
await sut.publishDataset(testDatasetIds.numericId, VersionUpdateType.UPDATE_CURRENT)
await waitForNoLocks(testDatasetIds.numericId, 10)

const datasetAfterUpdatingCurrentVersion = await sut.getDataset(
testDatasetIds.numericId,
DatasetNotNumberedVersion.LATEST,
false
)

expect(datasetAfterFirstPublish.versionInfo.majorNumber).toBe(expectedMajorVersion)
expect(datasetAfterUpdatingCurrentVersion.versionInfo.majorNumber).toBe(expectedMajorVersion)
})

test('should return error when trying to publish with the current version a dataset that has never been published before', async () => {
await waitForNoLocks(testDatasetIds.numericId, 10)

await expect(
sut.publishDataset(testDatasetIds.numericId, VersionUpdateType.UPDATE_CURRENT)
).rejects.toBeInstanceOf(WriteError)
})
})

describe('updateDataset', () => {
test('should update an existing dataset with the provided dataset citation fields', async () => {
const testDataset = {
Expand Down
Loading