Skip to content

Commit

Permalink
feat(#9237): Add unit tests for getResources in remote mode
Browse files Browse the repository at this point in the history
  • Loading branch information
sugat009 committed Jul 23, 2024
1 parent 8fbc245 commit a99de72
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 13 deletions.
20 changes: 10 additions & 10 deletions shared-libs/cht-datasource/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,16 +86,16 @@ export const getDatasource = (ctx: DataContext) => {
*/
getByUuidWithLineage: (uuid: string) => ctx.bind(Person.v1.getWithLineage)(Qualifier.byUuid(uuid)),

/**
* Returns an array of persons for the provided page specifications.
* @param personType the type of persons to return
* @param limit the maximum number of persons to return. Default is 100.
* @param skip the number of persons to skip. Default is 0.
* @returns an array of persons for the provided page specifications
* @throws Error if no type is provided or if the type is not for a person
* @throws Error if the provided limit is `<= 0`
* @throws Error if the provided skip is `< 0`
*/
/**
* Returns an array of people for the provided page specifications.
* @param personType the type of people to return
* @param limit the maximum number of people to return. Default is 100.
* @param skip the number of people to skip. Default is 0.
* @returns an array of people for the provided page specifications
* @throws Error if no type is provided or if the type is not for a person
* @throws Error if the provided limit is `<= 0`
* @throws Error if the provided skip is `< 0`
*/
getPage: (personType: string, limit = 100, skip = 0) => ctx.bind(Person.v1.getPage)(
Qualifier.byContactType(personType), limit, skip
),
Expand Down
4 changes: 2 additions & 2 deletions shared-libs/cht-datasource/src/person.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,9 +93,9 @@ export namespace v1 {
export const getWithLineage = getPerson(Local.Person.v1.getWithLineage, Remote.Person.v1.getWithLineage);

/**
* Returns a function for retrieving a paged array of persons from the given data context.
* Returns a function for retrieving a paged array of people from the given data context.
* @param context the current data context
* @returns a function for retrieving a paged array of persons
* @returns a function for retrieving a paged array of people
* @throws Error if a data context is not provided
*/
export const getPage = getPeople(Local.Person.v1.getPage, Remote.Person.v1.getPage);
Expand Down
2 changes: 1 addition & 1 deletion shared-libs/cht-datasource/src/remote/libs/data-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ export const getResources = (context: RemoteDataContext, path: string) => async
): Promise<T> => {
const params = new URLSearchParams(queryParams).toString();
try {
const response = await fetch(`${context.url}/${path}}?${params}`);
const response = await fetch(`${context.url}/${path}?${params}`);
if (!response.ok) {
throw new Error(response.statusText);
}
Expand Down
55 changes: 55 additions & 0 deletions shared-libs/cht-datasource/test/remote/libs/data-context.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import sinon, { SinonStub } from 'sinon';
import {
assertRemoteDataContext,
getResource,
getResources,
getRemoteDataContext,
isRemoteDataContext,
RemoteDataContext
Expand Down Expand Up @@ -149,4 +150,58 @@ describe('remote context lib', () => {
expect(fetchResponse.json.notCalled).to.be.true;
});
});

describe('getResources', () => {
let params: Record<string, string>;
let stringifiedParams: string;

beforeEach(() => {
params = {abc: 'xyz'};
stringifiedParams = new URLSearchParams(params).toString();
});

it('fetches a resource with a path', async () => {
const path = 'path';
const resource = { hello: 'world' };
fetchResponse.json.resolves(resource);

const response = await getResources(context, path)(params);

expect(response).to.equal(resource);
expect(fetchStub.calledOnceWithExactly(`${context.url}/${path}?${stringifiedParams}`)).to.be.true;
expect(fetchResponse.json.calledOnceWithExactly()).to.be.true;
});

it('throws an error if the resource fetch rejects', async () => {
const path = 'path';
const expectedError = new Error('unexpected error');
fetchStub.rejects(expectedError);

await expect(getResources(context, path)(params)).to.be.rejectedWith(expectedError);

expect(fetchStub.calledOnceWithExactly(`${context.url}/${path}?${stringifiedParams}`)).to.be.true;
expect(loggerError.calledOnceWithExactly(
`Failed to fetch resources from ${context.url}/${path} with params: ${stringifiedParams}`,
expectedError
)).to.be.true;
expect(fetchResponse.json.notCalled).to.be.true;
});

it('throws an error if the resource fetch resolves an error status', async () => {
const path = 'path';
fetchResponse.ok = false;
fetchResponse.status = 501;
fetchResponse.statusText = 'Not Implemented';

await expect(getResources(context, path)(params)).to.be.rejectedWith(fetchResponse.statusText);

expect(fetchStub.calledOnceWithExactly(`${context.url}/${path}?${stringifiedParams}`)).to.be.true;
expect(loggerError.calledOnce).to.be.true;
expect(loggerError.args[0]).to.deep.equal([
`Failed to fetch resources from ${context.url}/${path} with params: ${stringifiedParams}`,
new Error(fetchResponse.statusText)
]);
expect(fetchResponse.json.notCalled).to.be.true;
});
});
});

0 comments on commit a99de72

Please sign in to comment.