Skip to content

Commit

Permalink
Merge pull request #105 from IQSS/102-getDatasetCitation-deaccessioned
Browse files Browse the repository at this point in the history
102 get dataset citation deaccessioned
  • Loading branch information
GPortas authored Dec 20, 2023
2 parents 78dabf6 + 302daff commit a16dd1c
Show file tree
Hide file tree
Showing 8 changed files with 106 additions and 13 deletions.
2 changes: 1 addition & 1 deletion src/datasets/domain/repositories/IDatasetsRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export interface IDatasetsRepository {
getDatasetSummaryFieldNames(): Promise<string[]>;
getDataset(datasetId: number | string, datasetVersionId: string, includeDeaccessioned: boolean): Promise<Dataset>;
getPrivateUrlDataset(token: string): Promise<Dataset>;
getDatasetCitation(datasetId: number, datasetVersionId: string): Promise<string>;
getDatasetCitation(datasetId: number, datasetVersionId: string, includeDeaccessioned: boolean): Promise<string>;
getPrivateUrlDatasetCitation(token: string): Promise<string>;
getDatasetUserPermissions(datasetId: number | string): Promise<DatasetUserPermissions>;
getDatasetLocks(datasetId: number | string): Promise<DatasetLock[]>;
Expand Down
3 changes: 2 additions & 1 deletion src/datasets/domain/useCases/GetDatasetCitation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@ export class GetDatasetCitation implements UseCase<string> {
async execute(
datasetId: number,
datasetVersionId: string | DatasetNotNumberedVersion = DatasetNotNumberedVersion.LATEST,
includeDeaccessioned: boolean = false,
): Promise<string> {
return await this.datasetsRepository.getDatasetCitation(datasetId, datasetVersionId);
return await this.datasetsRepository.getDatasetCitation(datasetId, datasetVersionId, includeDeaccessioned)
}
}
9 changes: 7 additions & 2 deletions src/datasets/infra/repositories/DatasetsRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { transformDatasetUserPermissionsResponseToDatasetUserPermissions } from
import { DatasetLock } from '../../domain/models/DatasetLock';
import { transformDatasetLocksResponseToDatasetLocks } from './transformers/datasetLocksTransformers';


export class DatasetsRepository extends ApiRepository implements IDatasetsRepository {
private readonly datasetsResourceName: string = 'datasets';

Expand Down Expand Up @@ -45,10 +46,14 @@ export class DatasetsRepository extends ApiRepository implements IDatasetsReposi
});
}

public async getDatasetCitation(datasetId: number, datasetVersionId: string): Promise<string> {


public async getDatasetCitation(datasetId: number, datasetVersionId: string,
includeDeaccessioned: boolean): Promise<string> {

return this.doGet(
this.buildApiEndpoint(this.datasetsResourceName, `versions/${datasetVersionId}/citation`, datasetId),
true,
true, { includeDeaccessioned: includeDeaccessioned}
)
.then((response) => response.data.data.message)
.catch((error) => {
Expand Down
40 changes: 38 additions & 2 deletions test/integration/datasets/DatasetsRepository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {
createDatasetViaApi,
createPrivateUrlViaApi,
publishDatasetViaApi,
deaccessionDatasetViaApi,
waitForNoLocks
} from '../../testHelpers/datasets/datasetHelper';
import { ReadError } from '../../../src/core/domain/repositories/ReadError';
import { DatasetNotNumberedVersion, DatasetLockType } from '../../../src/datasets';
Expand Down Expand Up @@ -81,20 +83,54 @@ describe('DatasetsRepository', () => {
const actualDatasetCitation = await sut.getDatasetCitation(
TestConstants.TEST_CREATED_DATASET_ID,
latestVersionId,
false,
);
expect(typeof actualDatasetCitation).toBe('string');
});

test('should return error when dataset does not exist', async () => {
let error: ReadError = undefined;

await sut.getDatasetCitation(nonExistentTestDatasetId, latestVersionId).catch((e) => (error = e));
await sut.getDatasetCitation(nonExistentTestDatasetId, latestVersionId,false).catch((e) => (error = e));

assert.match(
error.message,
`There was an error when reading the resource. Reason was: [404] Dataset with ID ${nonExistentTestDatasetId} not found.`,
);
});
test('should return citation when dataset is deaccessioned', async () => {
let createdDatasetId = undefined;
await createDatasetViaApi()
.then((response) => (createdDatasetId = response.data.data.id))
.catch(() => {
assert.fail('Error while creating test Dataset');
});
// We publish the new test dataset we can deaccession it
await publishDatasetViaApi(createdDatasetId)
.then()
.catch(() => {
assert.fail('Error while publishing test Dataset');
});

await waitForNoLocks(createdDatasetId, 10)
.then()
.catch(() => {
assert.fail('Error while waiting for no locks');
});
await deaccessionDatasetViaApi(createdDatasetId,'1.0')
.then()
.catch((error) => {
console.log(JSON.stringify(error));
assert.fail('Error while deaccessioning test Dataset');
});

const actualDatasetCitation = await sut.getDatasetCitation(
createdDatasetId,
latestVersionId,
true,
);
expect(typeof actualDatasetCitation).toBe('string');

});
});

describe('Private URLs', () => {
Expand Down
14 changes: 14 additions & 0 deletions test/testHelpers/TestConstants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,27 @@ export class TestConstants {
'X-Dataverse-Key': TestConstants.TEST_DUMMY_API_KEY,
},
};
static readonly TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY_INCLUDE_DEACCESSIONED = {
params: { includeDeaccessioned: true },
headers: {
'Content-Type': 'application/json',
'X-Dataverse-Key': TestConstants.TEST_DUMMY_API_KEY,
},
};
static readonly TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE = {
withCredentials: true,
params: {},
headers: {
'Content-Type': 'application/json',
},
};
static readonly TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE_INCLUDE_DEACCESSIONED = {
withCredentials: true,
params: { includeDeaccessioned: true },
headers: {
'Content-Type': 'application/json',
},
};
static readonly TEST_EXPECTED_UNAUTHENTICATED_REQUEST_CONFIG = {
params: {},
headers: {
Expand Down
36 changes: 36 additions & 0 deletions test/testHelpers/datasets/datasetHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,46 @@ export const publishDatasetViaApi = async (datasetId: number): Promise<AxiosResp
);
};

export const deaccessionDatasetViaApi = async (datasetId: number, versionId: string): Promise<AxiosResponse> => {
const data = { deaccessionReason: 'Test reason.' };
return await axios.post(
`${TestConstants.TEST_API_URL}/datasets/${datasetId}/versions/${versionId}/deaccession`,
JSON.stringify(data),
DATAVERSE_API_REQUEST_HEADERS,
);
};

export const createPrivateUrlViaApi = async (datasetId: number): Promise<AxiosResponse> => {
return await axios.post(
`${TestConstants.TEST_API_URL}/datasets/${datasetId}/privateUrl`,
{},
DATAVERSE_API_REQUEST_HEADERS,
);
};

export const waitForNoLocks = async (datasetId: number, maxRetries = 20, delay = 1000): Promise<void> => {
let hasLocks = true;
let retry = 0;
while (hasLocks && retry < maxRetries) {
await axios
.get(`${TestConstants.TEST_API_URL}/datasets/${datasetId}/locks`)
.then((response) => {
const nLocks = response.data.data.length;
if (nLocks == 0) {
hasLocks = false;
}
})
.catch((error) => {
console.log(
`Error while waiting for no dataset locks: [${error.response.status}]${
error.response.data ? ` ${error.response.data.message}` : ''
}`,
);
});
await new Promise((resolve) => setTimeout(resolve, delay));
retry++;
}
if (hasLocks) {
throw new Error('Max retries reached.');
}
};
13 changes: 7 additions & 6 deletions test/unit/datasets/DatasetsRepository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,29 +232,30 @@ describe('DatasetsRepository', () => {
});

describe('getDatasetCitation', () => {
const testIncludeDeaccessioned = true;
test('should return citation when response is successful', async () => {
const axiosGetStub = sandbox.stub(axios, 'get').resolves(testCitationSuccessfulResponse);
const expectedApiEndpoint = `${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/${testVersionId}/citation`;

// API Key auth
let actual = await sut.getDatasetCitation(testDatasetModel.id, testVersionId);
let actual = await sut.getDatasetCitation(testDatasetModel.id, testVersionId, testIncludeDeaccessioned);

assert.calledWithExactly(
axiosGetStub,
expectedApiEndpoint,
TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY,
TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY_INCLUDE_DEACCESSIONED,
);
assert.match(actual, testCitation);

// Session cookie auth
ApiConfig.init(TestConstants.TEST_API_URL, DataverseApiAuthMechanism.SESSION_COOKIE);

actual = await sut.getDatasetCitation(testDatasetModel.id, testVersionId);
actual = await sut.getDatasetCitation(testDatasetModel.id, testVersionId, testIncludeDeaccessioned);

assert.calledWithExactly(
axiosGetStub,
expectedApiEndpoint,
TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE,
TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_SESSION_COOKIE_INCLUDE_DEACCESSIONED,
);
assert.match(actual, testCitation);
});
Expand All @@ -263,12 +264,12 @@ describe('DatasetsRepository', () => {
const axiosGetStub = sandbox.stub(axios, 'get').rejects(TestConstants.TEST_ERROR_RESPONSE);

let error: ReadError = undefined;
await sut.getDatasetCitation(1, testVersionId).catch((e) => (error = e));
await sut.getDatasetCitation(1, testVersionId,testIncludeDeaccessioned).catch((e) => (error = e));

assert.calledWithExactly(
axiosGetStub,
`${TestConstants.TEST_API_URL}/datasets/${testDatasetModel.id}/versions/${testVersionId}/citation`,
TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY,
TestConstants.TEST_EXPECTED_AUTHENTICATED_REQUEST_CONFIG_API_KEY_INCLUDE_DEACCESSIONED,
);
expect(error).to.be.instanceOf(Error);
});
Expand Down
2 changes: 1 addition & 1 deletion test/unit/datasets/GetDatasetCitation.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('execute', () => {
const actual = await sut.execute(testId);

assert.match(actual, testCitation);
assert.calledWithExactly(getDatasetCitationStub, testId, DatasetNotNumberedVersion.LATEST);
assert.calledWithExactly(getDatasetCitationStub, testId, DatasetNotNumberedVersion.LATEST, false);
});

test('should return error result on repository error', async () => {
Expand Down

0 comments on commit a16dd1c

Please sign in to comment.