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

Dev -> test #76

Merged
merged 3 commits into from
Feb 3, 2025
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
1 change: 1 addition & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ CASE_IDIR_FIELD='idir field here'
CASE_SEARCHSPEC_IDIR_FIELD='idir field here'
CASE_SINCE_FIELD='since field here'
CASE_RESTRICTED_FIELD='restricted field here'
CASE_TYPE_FIELD='type field here'
INCIDENT_IDIR_FIELD='idir field here'
INCIDENT_SEARCHSPEC_IDIR_FIELD='idir field here'
INCIDENT_SINCE_FIELD='since field here'
Expand Down
5 changes: 5 additions & 0 deletions helm/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,11 @@ spec:
secretKeyRef:
name: visitz-api
key: INCIDENT_RESTRICTED_FIELD
- name: CASE_TYPE_FIELD
valueFrom:
secretKeyRef:
name: visitz-api
key: CASE_TYPE_FIELD
- name: VPI_APP_LABEL
value: {{ .Values.vpiAppBuildLabel.version }}
- name: VPI_APP_ENV
Expand Down
5 changes: 5 additions & 0 deletions src/common/constants/error-constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export const childServicesTypeError =
'Given case is not a Child Services case and cannot have Child/Youth visits.';

export const dateFormatError =
'Date / time must met the ISO-8601 standard, and cannot be in the future';
2 changes: 2 additions & 0 deletions src/common/constants/upstream-constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const postInPersonVisitsEndpointEnvVarName = 'IN_PERSON_VISITS_POST_ENDPOINT';
const attachmentsEndpointEnvVarName = 'ATTACHMENTS_ENDPOINT';
const idirUsernameHeaderField = 'x-idir-username';
const upstreamDateFormat = 'MM/dd/yyyy HH:mm:ss';
const caseChildServices = 'Child Services';
const childVisitType = 'In Person Child Youth';
const childVisitIdirFieldName = 'Login Name';
const childVisitEntityIdFieldName = 'Parent Id';
Expand Down Expand Up @@ -34,6 +35,7 @@ export {
attachmentsEndpointEnvVarName,
idirUsernameHeaderField,
upstreamDateFormat,
caseChildServices,
childVisitType,
childVisitIdirFieldName,
childVisitEntityIdFieldName,
Expand Down
1 change: 1 addition & 0 deletions src/configuration/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export default () => ({
idirField: process.env.CASE_IDIR_FIELD ?? undefined,
searchspecIdirField: process.env.CASE_SEARCHSPEC_IDIR_FIELD ?? undefined,
restrictedField: process.env.CASE_RESTRICTED_FIELD ?? undefined,
typeField: process.env.CASE_TYPE_FIELD ?? undefined,
},
incident: {
endpoint: encodeURI((process.env.INCIDENT_ENDPOINT ?? ' ').trim()),
Expand Down
7 changes: 5 additions & 2 deletions src/external-api/request-preparer/request-preparer.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ export class RequestPreparerService {
return [headers, params];
}

async sendGetRequest(url: string, headers, res: Response, params?) {
async sendGetRequest(url: string, headers, res?: Response, params?) {
let response;
try {
const token =
Expand Down Expand Up @@ -141,7 +141,10 @@ export class RequestPreparerService {
{ cause: error },
);
}
if (response.headers.hasOwnProperty(recordCountHeaderName)) {
if (
res !== undefined &&
response.headers.hasOwnProperty(recordCountHeaderName)
) {
res.setHeader(
recordCountHeaderName,
response.headers[recordCountHeaderName],
Expand Down
176 changes: 174 additions & 2 deletions src/helpers/in-person-visits/in-person-visits.service.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,14 @@ import { PostInPersonVisitDtoUpstream } from '../../dto/post-in-person-visit.dto
import { getMockRes } from '@jest-mock/express';
import configuration from '../../configuration/configuration';
import { JwtService } from '@nestjs/jwt';
import { caseChildServices } from '../../common/constants/upstream-constants';
import { BadRequestException, HttpException, HttpStatus } from '@nestjs/common';

describe('InPersonVisitsService', () => {
let service: InPersonVisitsService;
let requestPreparerService: RequestPreparerService;
let configService: ConfigService;
let typeFieldName: string | undefined;
const { res, mockClear } = getMockRes();

beforeEach(async () => {
Expand Down Expand Up @@ -57,6 +61,8 @@ describe('InPersonVisitsService', () => {
requestPreparerService = module.get<RequestPreparerService>(
RequestPreparerService,
);
configService = module.get<ConfigService>(ConfigService);
typeFieldName = configService.get('upstreamAuth.case.typeField');
mockClear();
});

Expand All @@ -83,6 +89,12 @@ describe('InPersonVisitsService', () => {
async (data, recordType, idPathParams, filterQueryParams) => {
const spy = jest
.spyOn(requestPreparerService, 'sendGetRequest')
.mockResolvedValueOnce({
data: { items: [{ [`${typeFieldName}`]: caseChildServices }] },
headers: {},
status: 200,
statusText: 'OK',
} as AxiosResponse<any, any>)
.mockResolvedValueOnce({
data: data,
headers: {},
Expand All @@ -97,10 +109,41 @@ describe('InPersonVisitsService', () => {
'idir',
filterQueryParams,
);
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledTimes(2);
expect(result).toEqual(new NestedInPersonVisitsEntity(data));
},
);

it.each([
[
RecordType.Case,
{ [idName]: 'test' } as IdPathParams,
{ [sinceParamName]: '2020-12-24' } as FilterQueryParams,
],
])(
'should return bad request exception on non-child services case',
async (recordType, idPathParams, filterQueryParams) => {
const caseTypeSpy = jest
.spyOn(requestPreparerService, 'sendGetRequest')
.mockResolvedValueOnce({
data: { items: [{ [`${typeFieldName}`]: 'randomCaseType' }] },
headers: {},
status: 200,
statusText: 'OK',
} as AxiosResponse<any, any>);

await expect(
service.getListInPersonVisitRecord(
recordType,
idPathParams,
res,
'idir',
filterQueryParams,
),
).rejects.toThrow(BadRequestException);
expect(caseTypeSpy).toHaveBeenCalledTimes(1);
},
);
});

describe('getSingleInPersonVisitRecord tests', () => {
Expand All @@ -115,6 +158,12 @@ describe('InPersonVisitsService', () => {
async (data, recordType, idPathParams) => {
const spy = jest
.spyOn(requestPreparerService, 'sendGetRequest')
.mockResolvedValueOnce({
data: { items: [{ [`${typeFieldName}`]: caseChildServices }] },
headers: {},
status: 200,
statusText: 'OK',
} as AxiosResponse<any, any>)
.mockResolvedValueOnce({
data: data,
headers: {},
Expand All @@ -128,10 +177,39 @@ describe('InPersonVisitsService', () => {
res,
'idir',
);
expect(spy).toHaveBeenCalledTimes(1);
expect(spy).toHaveBeenCalledTimes(2);
expect(result).toEqual(new InPersonVisitsEntity(data));
},
);

it.each([
[
RecordType.Case,
{ [idName]: 'test', [visitIdName]: 'test2' } as VisitIdPathParams,
],
])(
'should return bad request exception on non-child services case',
async (recordType, idPathParams) => {
const caseTypeSpy = jest
.spyOn(requestPreparerService, 'sendGetRequest')
.mockResolvedValueOnce({
data: { items: [{ [`${typeFieldName}`]: 'randomCaseType' }] },
headers: {},
status: 200,
statusText: 'OK',
} as AxiosResponse<any, any>);

await expect(
service.getSingleInPersonVisitRecord(
recordType,
idPathParams,
res,
'idir',
),
).rejects.toThrow(BadRequestException);
expect(caseTypeSpy).toHaveBeenCalledTimes(1);
},
);
});

describe('postSingleInPersonVisitRecord tests', () => {
Expand All @@ -156,15 +234,109 @@ describe('InPersonVisitsService', () => {
status: 200,
statusText: 'OK',
} as AxiosResponse<any, any>);
const caseTypeSpy = jest
.spyOn(requestPreparerService, 'sendGetRequest')
.mockResolvedValueOnce({
data: { items: [{ [`${typeFieldName}`]: caseChildServices }] },
headers: {},
status: 200,
statusText: 'OK',
} as AxiosResponse<any, any>);

const result = await service.postSingleInPersonVisitRecord(
recordType,
body,
'idir',
);
expect(spy).toHaveBeenCalledTimes(1);
expect(caseTypeSpy).toHaveBeenCalledTimes(1);
expect(result).toEqual(new NestedInPersonVisitsEntity(data));
},
);

it.each([
[
RecordType.Case,
new PostInPersonVisitDtoUpstream({
'Date of visit': '11/08/2024 08:24:11',
'Visit Details Value': VisitDetails.NotPrivateInHome,
'Visit Description': 'comment',
}),
],
])(
'should return bad request exception on non-child services case',
async (recordType, body) => {
const caseTypeSpy = jest
.spyOn(requestPreparerService, 'sendGetRequest')
.mockResolvedValueOnce({
data: { items: [{ [`${typeFieldName}`]: 'randomCaseType' }] },
headers: {},
status: 200,
statusText: 'OK',
} as AxiosResponse<any, any>);

await expect(
service.postSingleInPersonVisitRecord(recordType, body, 'idir'),
).rejects.toThrow(BadRequestException);
expect(caseTypeSpy).toHaveBeenCalledTimes(1);
},
);
});

describe('isChildCaseType tests', () => {
it('should return true when type field is a child services case', async () => {
const spy = jest
.spyOn(requestPreparerService, 'sendGetRequest')
.mockResolvedValueOnce({
data: { items: [{ [`${typeFieldName}`]: caseChildServices }] },
headers: {},
status: 200,
statusText: 'OK',
} as AxiosResponse<any, any>);

const isChildCase = await service.isChildCaseType('parentId', 'idir');
expect(spy).toHaveBeenCalledTimes(1);
expect(isChildCase).toBe(true);
});

it('should return false when type field is not a child services case', async () => {
const spy = jest
.spyOn(requestPreparerService, 'sendGetRequest')
.mockResolvedValueOnce({
data: { items: [{ [`${typeFieldName}`]: 'randomCaseType' }] },
headers: {},
status: 200,
statusText: 'OK',
} as AxiosResponse<any, any>);

const isChildCase = await service.isChildCaseType('parentId', 'idir');
expect(spy).toHaveBeenCalledTimes(1);
expect(isChildCase).toBe(false);
});

it('should return false when type field does not exist on case entity', async () => {
const spy = jest
.spyOn(requestPreparerService, 'sendGetRequest')
.mockResolvedValueOnce({
data: { items: [{ [`${typeFieldName}sss`]: 'randomCaseType' }] },
headers: {},
status: 200,
statusText: 'OK',
} as AxiosResponse<any, any>);

const isChildCase = await service.isChildCaseType('parentId', 'idir');
expect(spy).toHaveBeenCalledTimes(1);
expect(isChildCase).toBe(false);
});

it('should return false on upstream error', async () => {
const spy = jest
.spyOn(requestPreparerService, 'sendGetRequest')
.mockRejectedValueOnce(new HttpException({}, HttpStatus.NO_CONTENT));

const isChildCase = await service.isChildCaseType('parentId', 'idir');
expect(spy).toHaveBeenCalledTimes(1);
expect(isChildCase).toBe(false);
});
});
});
Loading