Skip to content

Commit 39031e4

Browse files
authored
#4041 - Ignore Cancelled Legacy Applications on SIMS Validations and Calculations (#4042)
Ignore Cancelled Legacy Applications on SIMS Validations and Calculations
1 parent 0b0f97f commit 39031e4

File tree

7 files changed

+459
-7
lines changed

7 files changed

+459
-7
lines changed

sources/packages/backend/apps/api/src/route-controllers/application/_tests_/application.students.controller.submitApplication.e2e-spec.ts

+193-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ import { SystemUsersService } from "@sims/services";
3232
import { FormNames, FormService } from "../../../services";
3333
import { AppStudentsModule } from "../../../app.students.module";
3434
import { createFakeSFASPartTimeApplication } from "@sims/test-utils/factories/sfas-part-time-application";
35+
import { createFakeSFASApplication } from "@sims/test-utils/factories/sfas-application";
3536

3637
describe("ApplicationStudentsController(e2e)-submitApplication", () => {
3738
let app: INestApplication;
@@ -154,7 +155,7 @@ describe("ApplicationStudentsController(e2e)-submitApplication", () => {
154155
});
155156
});
156157

157-
it("Should throw study dates overlap error when an application submitted for a student via the SFAS system has overlapping study start or study end dates with another application.", async () => {
158+
it("Should throw study dates overlap error when a part-time application submitted for a student via the SFAS system has overlapping study start or study end dates with another application.", async () => {
158159
// Arrange
159160
const student = await saveFakeStudent(db.dataSource);
160161
const sfasIndividual = await saveFakeSFASIndividual(db.dataSource, {
@@ -251,6 +252,99 @@ describe("ApplicationStudentsController(e2e)-submitApplication", () => {
251252
});
252253
});
253254

255+
it("Should throw study dates overlap error when a full-time application is submitted for a student via the SFAS system has overlapping study start or study end dates with another application.", async () => {
256+
// Arrange
257+
const student = await saveFakeStudent(db.dataSource);
258+
const sfasIndividual = await saveFakeSFASIndividual(db.dataSource, {
259+
initialValues: {
260+
lastName: student.user.lastName,
261+
birthDate: student.birthDate,
262+
sin: student.sinValidation.sin,
263+
},
264+
});
265+
266+
const sfasFullTimeApplication = createFakeSFASApplication(
267+
{ individual: sfasIndividual },
268+
{
269+
initialValues: {
270+
startDate: getISODateOnlyString(new Date()),
271+
endDate: getISODateOnlyString(addDays(50)),
272+
},
273+
},
274+
);
275+
await db.sfasApplication.save(sfasFullTimeApplication);
276+
// Create a fake offering for the second application.
277+
const auditUser = await db.user.save(createFakeUser());
278+
279+
// SIMS Offering having overlapping study period with SFAS.
280+
const simsApplicationOfferingInitialValues = {
281+
studyStartDate: getISODateOnlyString(addDays(40)),
282+
studyEndDate: getISODateOnlyString(addDays(90)),
283+
offeringIntensity: OfferingIntensity.partTime,
284+
};
285+
const fakeOffering = createFakeEducationProgramOffering(
286+
{
287+
auditUser,
288+
},
289+
{
290+
initialValues: simsApplicationOfferingInitialValues,
291+
},
292+
);
293+
const savedOffering = await db.educationProgramOffering.save(fakeOffering);
294+
const simsApplication = createFakeApplication(
295+
{
296+
student,
297+
location: fakeOffering.institutionLocation,
298+
},
299+
{
300+
initialValue: {
301+
data: {},
302+
applicationStatus: ApplicationStatus.Draft,
303+
applicationStatusUpdatedOn: new Date(),
304+
creator: systemUsersService.systemUser,
305+
createdAt: new Date(),
306+
} as Application,
307+
},
308+
);
309+
const secondDraftApplication = await db.application.save(simsApplication);
310+
const applicationData = {
311+
selectedOfferingDate: simsApplicationOfferingInitialValues.studyStartDate,
312+
selectedOfferingEndDate:
313+
simsApplicationOfferingInitialValues.studyEndDate,
314+
howWillYouBeAttendingTheProgram:
315+
simsApplicationOfferingInitialValues.offeringIntensity,
316+
selectedProgram: savedOffering.educationProgram.id,
317+
selectedOffering: savedOffering.id,
318+
};
319+
const payload = {
320+
associatedFiles: [],
321+
data: applicationData,
322+
programYearId: simsApplication.programYear.id,
323+
} as SaveApplicationAPIInDTO;
324+
const endpoint = `/students/application/${secondDraftApplication.id}/submit`;
325+
const token = await getStudentToken(
326+
FakeStudentUsersTypes.FakeStudentUserType1,
327+
);
328+
const dryRunSubmissionMock = jest.fn().mockResolvedValue({
329+
valid: true,
330+
formName: FormNames.Application,
331+
data: { data: applicationData },
332+
});
333+
formService.dryRunSubmission = dryRunSubmissionMock;
334+
await mockUserLoginInfo(appModule, student);
335+
// Act/Assert
336+
await request(app.getHttpServer())
337+
.patch(endpoint)
338+
.send(payload)
339+
.auth(token, BEARER_AUTH_TYPE)
340+
.expect(HttpStatus.UNPROCESSABLE_ENTITY)
341+
.expect({
342+
message:
343+
"There is an existing application already with overlapping study period or a pending PIR.",
344+
errorType: "STUDY_DATE_OVERLAP_ERROR",
345+
});
346+
});
347+
254348
it("Should submit an application for a student when the application study dates do not have any overlap with the study dates of any existing application.", async () => {
255349
// Arrange
256350
const student = await saveFakeStudent(db.dataSource);
@@ -341,6 +435,104 @@ describe("ApplicationStudentsController(e2e)-submitApplication", () => {
341435
.expect({});
342436
});
343437

438+
it(
439+
"Should submit an application for a student when there is a cancelled full-time application in SFAS with overlapping study dates" +
440+
" ignoring the cancelled SFAS application.",
441+
async () => {
442+
// Arrange
443+
const student = await saveFakeStudent(db.dataSource);
444+
const sfasIndividual = await saveFakeSFASIndividual(db.dataSource, {
445+
initialValues: {
446+
lastName: student.user.lastName,
447+
birthDate: student.birthDate,
448+
sin: student.sinValidation.sin,
449+
},
450+
});
451+
// Cancelled SFAS full time application with overlapping study dates.
452+
const sfasFullTimeApplication = createFakeSFASApplication(
453+
{ individual: sfasIndividual },
454+
{
455+
initialValues: {
456+
startDate: getISODateOnlyString(new Date()),
457+
endDate: getISODateOnlyString(addDays(50)),
458+
// The SFAS application is cancelled.
459+
applicationCancelDate: getISODateOnlyString(new Date()),
460+
},
461+
},
462+
);
463+
await db.sfasApplication.save(sfasFullTimeApplication);
464+
465+
// SIMS Offering having overlapping study period with SFAS.
466+
const simsApplicationOfferingInitialValues = {
467+
studyStartDate: getISODateOnlyString(addDays(30)),
468+
studyEndDate: getISODateOnlyString(addDays(90)),
469+
offeringIntensity: OfferingIntensity.partTime,
470+
};
471+
const simsApplication = createFakeApplication(
472+
{
473+
student,
474+
},
475+
{
476+
initialValue: {
477+
data: {},
478+
applicationStatus: ApplicationStatus.Draft,
479+
applicationStatusUpdatedOn: new Date(),
480+
creator: systemUsersService.systemUser,
481+
createdAt: new Date(),
482+
} as Application,
483+
},
484+
);
485+
const simsDraftApplication = await db.application.save(simsApplication);
486+
const auditUser = await db.user.save(createFakeUser());
487+
const simsApplicationOffering = await db.educationProgramOffering.save(
488+
createFakeEducationProgramOffering(
489+
{
490+
auditUser,
491+
institutionLocation: simsApplication.location,
492+
},
493+
{
494+
initialValues: simsApplicationOfferingInitialValues,
495+
},
496+
),
497+
);
498+
const secondApplicationProgram = simsApplicationOffering.educationProgram;
499+
const applicationData = {
500+
selectedOfferingDate:
501+
simsApplicationOfferingInitialValues.studyStartDate,
502+
selectedOfferingEndDate:
503+
simsApplicationOfferingInitialValues.studyEndDate,
504+
howWillYouBeAttendingTheProgram:
505+
simsApplicationOfferingInitialValues.offeringIntensity,
506+
selectedProgram: secondApplicationProgram.id,
507+
selectedOffering: simsApplicationOffering.id,
508+
selectedLocation: simsApplication.location.id,
509+
};
510+
const payload = {
511+
associatedFiles: [],
512+
data: applicationData,
513+
programYearId: simsApplication.programYear.id,
514+
} as SaveApplicationAPIInDTO;
515+
const endpoint = `/students/application/${simsDraftApplication.id}/submit`;
516+
const token = await getStudentToken(
517+
FakeStudentUsersTypes.FakeStudentUserType1,
518+
);
519+
const dryRunSubmissionMock = jest.fn().mockResolvedValue({
520+
valid: true,
521+
formName: FormNames.Application,
522+
data: { data: applicationData },
523+
});
524+
formService.dryRunSubmission = dryRunSubmissionMock;
525+
await mockUserLoginInfo(appModule, student);
526+
// Act/Assert
527+
await request(app.getHttpServer())
528+
.patch(endpoint)
529+
.send(payload)
530+
.auth(token, BEARER_AUTH_TYPE)
531+
.expect(HttpStatus.OK)
532+
.expect({});
533+
},
534+
);
535+
344536
afterAll(async () => {
345537
await app?.close();
346538
});

0 commit comments

Comments
 (0)