diff --git a/docs/useCases.md b/docs/useCases.md index e8d7be92..2cc3a229 100644 --- a/docs/useCases.md +++ b/docs/useCases.md @@ -75,6 +75,7 @@ The different use cases currently available in the package are classified below, - [Get Dataverse Backend Version](#get-dataverse-backend-version) - [Get Maximum Embargo Duration In Months](#get-maximum-embargo-duration-in-months) - [Get ZIP Download Limit](#get-zip-download-limit) + - [Get Application Terms of Use](#get-application-terms-of-use) - [Contact](#Contact) - [Send Feedback to Object Contacts](#send-feedback-to-object-contacts) @@ -1781,6 +1782,26 @@ getZipDownloadLimit.execute().then((downloadLimit: number) => { _See [use case](../src/info/domain/useCases/GetZipDownloadLimit.ts) implementation_. +#### Get Application Terms of Use + +Returns the Application Terms of Use. If you have enabled Internationalization you can pass a two-character language code (e.g. “en”) as the lang parameter. + +##### Example call: + +```typescript +import { getApplicationTermsOfUse } from '@iqss/dataverse-client-javascript' + +/* ... */ + +getApplicationTermsOfUse.execute().then((termsOfUse: string) => { + /* ... */ +}) + +/* ... */ +``` + +_See [use case](../src/info/domain/useCases/GetApplicationTermsOfUse.ts) implementation_. + ## Contact #### Send Feedback to Object Contacts diff --git a/src/info/domain/repositories/IDataverseInfoRepository.ts b/src/info/domain/repositories/IDataverseInfoRepository.ts index 2adbb89a..0ec6c747 100644 --- a/src/info/domain/repositories/IDataverseInfoRepository.ts +++ b/src/info/domain/repositories/IDataverseInfoRepository.ts @@ -4,4 +4,5 @@ export interface IDataverseInfoRepository { getDataverseVersion(): Promise getZipDownloadLimit(): Promise getMaxEmbargoDurationInMonths(): Promise + getApplicationTermsOfUse(lang?: string): Promise } diff --git a/src/info/domain/useCases/GetApplicationTermsOfUse.ts b/src/info/domain/useCases/GetApplicationTermsOfUse.ts new file mode 100644 index 00000000..85821fe7 --- /dev/null +++ b/src/info/domain/useCases/GetApplicationTermsOfUse.ts @@ -0,0 +1,20 @@ +import { UseCase } from '../../../core/domain/useCases/UseCase' +import { IDataverseInfoRepository } from '../repositories/IDataverseInfoRepository' + +export class GetApplicationTermsOfUse implements UseCase { + private dataverseInfoRepository: IDataverseInfoRepository + + constructor(dataverseInfoRepository: IDataverseInfoRepository) { + this.dataverseInfoRepository = dataverseInfoRepository + } + + /** + * Returns a string containing the application terms of use. + * + * @param {string} [lang] - Optional language parameter to specify the language of the terms of use. + * @returns {Promise} + */ + async execute(lang?: string): Promise { + return await this.dataverseInfoRepository.getApplicationTermsOfUse(lang) + } +} diff --git a/src/info/index.ts b/src/info/index.ts index 32513ad1..049cc48d 100644 --- a/src/info/index.ts +++ b/src/info/index.ts @@ -2,11 +2,18 @@ import { DataverseInfoRepository } from './infra/repositories/DataverseInfoRepos import { GetDataverseVersion } from './domain/useCases/GetDataverseVersion' import { GetZipDownloadLimit } from './domain/useCases/GetZipDownloadLimit' import { GetMaxEmbargoDurationInMonths } from './domain/useCases/GetMaxEmbargoDurationInMonths' +import { GetApplicationTermsOfUse } from './domain/useCases/GetApplicationTermsOfUse' const dataverseInfoRepository = new DataverseInfoRepository() const getDataverseVersion = new GetDataverseVersion(dataverseInfoRepository) const getZipDownloadLimit = new GetZipDownloadLimit(dataverseInfoRepository) const getMaxEmbargoDurationInMonths = new GetMaxEmbargoDurationInMonths(dataverseInfoRepository) +const getApplicationTermsOfUse = new GetApplicationTermsOfUse(dataverseInfoRepository) -export { getDataverseVersion, getZipDownloadLimit, getMaxEmbargoDurationInMonths } +export { + getDataverseVersion, + getZipDownloadLimit, + getMaxEmbargoDurationInMonths, + getApplicationTermsOfUse +} diff --git a/src/info/infra/repositories/DataverseInfoRepository.ts b/src/info/infra/repositories/DataverseInfoRepository.ts index 71ba653b..c4de4a22 100644 --- a/src/info/infra/repositories/DataverseInfoRepository.ts +++ b/src/info/infra/repositories/DataverseInfoRepository.ts @@ -39,4 +39,20 @@ export class DataverseInfoRepository extends ApiRepository implements IDataverse build: responseData.build } } + + public async getApplicationTermsOfUse(lang?: string): Promise { + return this.doGet( + this.buildApiEndpoint(this.infoResourceName, `applicationTermsOfUse`), + false, + { + ...(lang ? { lang } : {}) + } + ) + .then((response: AxiosResponse<{ data: { message: string } }>) => { + return response.data.data.message + }) + .catch((error) => { + throw error + }) + } } diff --git a/test/integration/info/DataverseInfoRepository.test.ts b/test/integration/info/DataverseInfoRepository.test.ts index ed3e5d98..4fec4669 100644 --- a/test/integration/info/DataverseInfoRepository.test.ts +++ b/test/integration/info/DataverseInfoRepository.test.ts @@ -4,7 +4,11 @@ import { DataverseApiAuthMechanism } from '../../../src/core/infra/repositories/ApiConfig' import { TestConstants } from '../../testHelpers/TestConstants' -import { setMaxEmbargoDurationInMonthsViaApi } from '../../testHelpers/info/infoHelper' +import { + deleteApplicationTermsOfUseViaApi, + setApplicationTermsOfUseViaApi, + setMaxEmbargoDurationInMonthsViaApi +} from '../../testHelpers/info/infoHelper' import { ReadError } from '../../../src/core/domain/repositories/ReadError' describe('DataverseInfoRepository', () => { @@ -49,4 +53,24 @@ describe('DataverseInfoRepository', () => { expect(actual).toBe(testMaxEmbargoDurationInMonths) }) }) + + describe('getApplicationTermsOfUse', () => { + test('should return no terms message when terms are not set', async () => { + const defaultNoTermsOfUseMessage = + 'There are no Terms of Use for this Dataverse installation.' + const actual = await sut.getApplicationTermsOfUse() + + expect(actual).toBe(defaultNoTermsOfUseMessage) + }) + + test('should return terms when terms are set', async () => { + const testTermsOfUse = 'Be excellent to each other.' + await setApplicationTermsOfUseViaApi(testTermsOfUse) + const actual = await sut.getApplicationTermsOfUse() + + expect(actual).toBe(testTermsOfUse) + + await deleteApplicationTermsOfUseViaApi() + }) + }) }) diff --git a/test/testHelpers/info/infoHelper.ts b/test/testHelpers/info/infoHelper.ts index eacfa6d4..121e9489 100644 --- a/test/testHelpers/info/infoHelper.ts +++ b/test/testHelpers/info/infoHelper.ts @@ -12,3 +12,19 @@ export const setMaxEmbargoDurationInMonthsViaApi = async ( } ) } + +export const setApplicationTermsOfUseViaApi = async ( + applicationTermsOfUse: string +): Promise => { + return await axios.put( + `${TestConstants.TEST_API_URL}/admin/settings/:ApplicationTermsOfUse`, + applicationTermsOfUse, + { + headers: { 'Content-Type': 'text/plain' } + } + ) +} + +export const deleteApplicationTermsOfUseViaApi = async (): Promise => { + return await axios.delete(`${TestConstants.TEST_API_URL}/admin/settings/:ApplicationTermsOfUse`) +} diff --git a/test/unit/info/DataverseInfoRepository.test.ts b/test/unit/info/DataverseInfoRepository.test.ts index 3ab062f5..fd6dd138 100644 --- a/test/unit/info/DataverseInfoRepository.test.ts +++ b/test/unit/info/DataverseInfoRepository.test.ts @@ -123,4 +123,69 @@ describe('DataverseInfoRepository', () => { expect(error).toBeInstanceOf(Error) }) }) + + describe('getApplicationTermsOfUse', () => { + test('should return terms of use on successful response', async () => { + const testTermsOfUse = 'Be excellent to each other.' + const testSuccessfulResponse = { + data: { + status: 'OK', + data: { + message: testTermsOfUse + } + } + } + jest.spyOn(axios, 'get').mockResolvedValue(testSuccessfulResponse) + + const actual = await sut.getApplicationTermsOfUse() + + expect(axios.get).toHaveBeenCalledWith( + `${TestConstants.TEST_API_URL}/info/applicationTermsOfUse`, + TestConstants.TEST_EXPECTED_UNAUTHENTICATED_REQUEST_CONFIG + ) + expect(actual).toMatch(testTermsOfUse) + }) + + test('should return terms of use on successful response with lang', async () => { + const testLang = 'en' + const testTermsOfUse = 'Be excellent to each other.' + const testSuccessfulResponse = { + data: { + status: 'OK', + data: { + message: testTermsOfUse + } + } + } + jest.spyOn(axios, 'get').mockResolvedValue(testSuccessfulResponse) + + const actual = await sut.getApplicationTermsOfUse(testLang) + + expect(axios.get).toHaveBeenCalledWith( + `${TestConstants.TEST_API_URL}/info/applicationTermsOfUse`, + { + params: { + lang: testLang + }, + headers: { + 'Content-Type': 'application/json' + } + } + ) + expect(actual).toMatch(testTermsOfUse) + }) + + test('should return error result on error response', async () => { + jest.spyOn(axios, 'get').mockRejectedValue(TestConstants.TEST_ERROR_RESPONSE) + + let error: ReadError | undefined + await sut.getApplicationTermsOfUse().catch((e) => (error = e)) + + expect(axios.get).toHaveBeenCalledWith( + `${TestConstants.TEST_API_URL}/info/applicationTermsOfUse`, + TestConstants.TEST_EXPECTED_UNAUTHENTICATED_REQUEST_CONFIG + ) + expect(error).toBeInstanceOf(Error) + }) + }) }) diff --git a/test/unit/info/GetApplicationTermsOfUse.test.ts b/test/unit/info/GetApplicationTermsOfUse.test.ts new file mode 100644 index 00000000..6be53131 --- /dev/null +++ b/test/unit/info/GetApplicationTermsOfUse.test.ts @@ -0,0 +1,29 @@ +import { ReadError } from '../../../src/core/domain/repositories/ReadError' +import { IDataverseInfoRepository } from '../../../src/info/domain/repositories/IDataverseInfoRepository' +import { GetApplicationTermsOfUse } from '../../../src/info/domain/useCases/GetApplicationTermsOfUse' + +describe('execute', () => { + test('should return successful result with terms of use on repository success', async () => { + const testTermsOfUse = 'Be excellent to each other.' + const dataverseInfoRepositoryStub: IDataverseInfoRepository = {} as IDataverseInfoRepository + dataverseInfoRepositoryStub.getApplicationTermsOfUse = jest + .fn() + .mockResolvedValue(testTermsOfUse) + const sut = new GetApplicationTermsOfUse(dataverseInfoRepositoryStub) + + const actual = await sut.execute() + + expect(actual).toBe(testTermsOfUse) + }) + + test('should return error result on repository error', async () => { + const dataverseInfoRepositoryStub: IDataverseInfoRepository = {} as IDataverseInfoRepository + const testReadError = new ReadError() + dataverseInfoRepositoryStub.getApplicationTermsOfUse = jest + .fn() + .mockRejectedValue(testReadError) + const sut = new GetApplicationTermsOfUse(dataverseInfoRepositoryStub) + + await expect(sut.execute()).rejects.toThrow(ReadError) + }) +})