Skip to content

Commit

Permalink
#3132 - Institution Designation Ministry Specific Report (e2e tests) (#…
Browse files Browse the repository at this point in the history
…3374)

### As a part of this PR, the following were completed:

- **Wrote the following e2e test:**

ReportAestController(e2e)-exportReport
√ Should generate the Institution Designation report when a report
generation request is made with the appropriate date range filters.

**Note:** There is a code refactor for
`saveFakeDesignationAgreementLocation`.

- Fix for the ministry reports dropdown that was getting cut off because
of CSS style set to `overflow: hidden`. Changed the style to `overflow:
visible`.

- SQL query fix fetching the Institution Designation Report. The fix
involves ensuring that the `startDate` and the `endDate` are
appropriately converted to UTC ensuring that the comparison for these
date range filters happens correctly as the values saved in the database
for the `assessedDate` and the `endDate` columns are in UTC.

**SQL Query:**

```sql
SELECT
	institutions.operating_name AS "Institution Operating Name",
	institution_locations.name AS "Location Name",
	institution_locations.institution_code AS "Location Code",
	institution_type.name AS "Institution Type",
	designation_agreements.designation_status AS "Designation Status",
	CAST(
        CAST(designation_agreements.assessed_date AS date) AS varchar
      ) AS "Assessed Date",
	CAST(designation_agreements.end_date AS varchar) AS "Expiry Date",
	designation_agreement_locations.requested AS "Request for designation",
	designation_agreement_locations.approved AS "Approved for designation",
	CONCAT(
        institution_locations.primary_contact ->> 'firstName',
	' ',
	institution_locations.primary_contact ->> 'lastName'
      ) AS "Location Contact",
	institution_locations.primary_contact ->> 'email' AS "Contact Email"
FROM
	sims.institution_locations institution_locations
INNER JOIN sims.institutions institutions ON
	institution_locations.institution_id = institutions.id
INNER JOIN sims.institution_type institution_type ON
	institution_type.id = institutions.institution_type_id
INNER JOIN sims.designation_agreement_locations designation_agreement_locations ON
	designation_agreement_locations.location_id = institution_locations.id
INNER JOIN sims.designation_agreements designation_agreements ON
	designation_agreements.id = designation_agreement_locations.designation_agreement_id
WHERE
      (
        designation_agreements.assessed_date >= CAST(:startDate as timestamptz)
        AND designation_agreements.assessed_date < CAST(:endDate as timestamptz) + INTERVAL ''1 DAY''
      )
      OR (
        designation_agreements.end_date >= CAST(:startDate as timestamptz)
        AND designation_agreements.end_date < CAST(:endDate as timestamptz) + INTERVAL ''1 DAY''
      )
ORDER BY
	institutions.operating_name ASC,
	institution_locations.institution_code ASC,
	designation_agreements.designation_status ASC,
	designation_agreements.assessed_date DESC,
	designation_agreements.end_date DESC;
```

### Screenshot of the e2e test:

<img width="1176" alt="image"
src="https://github.com/bcgov/SIMS/assets/7859295/842ab8b0-b8d0-4b2b-82ea-a12538e7c6d2">

### Screenshot for the ministry reports dropdown fix:

**Before the fix:**

<img width="1920" alt="image"
src="https://github.com/bcgov/SIMS/assets/7859295/ac98dbe1-84cd-48ce-a73e-7682381c0644">


-------------------------------------------------------------------------------------------------------------------------

**After the fix:**

<img width="1920" alt="image"
src="https://github.com/bcgov/SIMS/assets/7859295/15b2914d-cb46-4259-8079-9a00d02d56f4">

---------

Co-authored-by: Andrew Boni Signori <[email protected]>
  • Loading branch information
sh16011993 and andrewsignori-aot authored Jun 5, 2024
1 parent 62932a0 commit 8f70c75
Show file tree
Hide file tree
Showing 9 changed files with 250 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ describe("InstitutionLocationStudentsController(e2e)-getOptionsList", () => {

it("Should get the list of all designated institution location which should contain the only newly created designated location and not the newly created non designated location when student requests.", async () => {
// Arrange
const newDesignation = await saveFakeDesignationAgreementLocation(db, {
numberOfLocations: 2,
});
const [designatedLocation, nonDesignatedLocation] =
await saveFakeDesignationAgreementLocation(db, {
numberOfLocations: 2,
});
newDesignation.designationAgreementLocations;
// Setting the designation statuses.
designatedLocation.approved = true;
nonDesignatedLocation.approved = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import {
createFakeDisbursementFeedbackError,
getProviderInstanceForModule,
saveFakeApplicationDisbursements,
saveFakeDesignationAgreementLocation,
} from "@sims/test-utils";
import {
AESTGroups,
Expand All @@ -23,7 +24,7 @@ import {
DisbursementScheduleStatus,
OfferingIntensity,
} from "@sims/sims-db";
import { getISODateOnlyString } from "@sims/utilities";
import { addDays, getISODateOnlyString } from "@sims/utilities";
import { DataSource } from "typeorm";

describe("ReportAestController(e2e)-exportReport", () => {
Expand Down Expand Up @@ -147,4 +148,105 @@ describe("ReportAestController(e2e)-exportReport", () => {
);
});
});

it("Should generate the Institution Designation report when a report generation request is made with the appropriate date range filters.", async () => {
// Arrange
const designationAgreement = await saveFakeDesignationAgreementLocation(
db,
{
numberOfLocations: 2,
initialValues: {
endDate: getISODateOnlyString(addDays(30, new Date())),
},
},
);
const [
approvedDesignationAgreementLocation,
declinedDesignationAgreementLocation,
] = designationAgreement.designationAgreementLocations;
declinedDesignationAgreementLocation.approved = false;
await db.designationAgreementLocation.save(
declinedDesignationAgreementLocation,
);
const designatedInstitutionLocation =
approvedDesignationAgreementLocation.institutionLocation;
const nonDesignatedInstitutionLocation =
declinedDesignationAgreementLocation.institutionLocation;
const designatedPrimaryContact =
designatedInstitutionLocation.primaryContact;
const nonDesignatedPrimaryContact =
nonDesignatedInstitutionLocation.primaryContact;
const payload = {
reportName: "Institution_Designation_Report",
params: {
startDate: new Date(),
endDate: addDays(31, new Date()),
},
};
const dryRunSubmissionMock = jest.fn().mockResolvedValue({
valid: true,
formName: FormNames.ExportFinancialReports,
data: { data: payload },
});
formService.dryRunSubmission = dryRunSubmissionMock;
const endpoint = "/aest/report";
const ministryUserToken = await getAESTToken(
AESTGroups.BusinessAdministrators,
);

// Act/Assert
await request(app.getHttpServer())
.post(endpoint)
.send(payload)
.auth(ministryUserToken, BEARER_AUTH_TYPE)
.expect(HttpStatus.CREATED)
.then((response) => {
const fileContent = response.request.res["text"];
const parsedResult = parse(fileContent, {
header: true,
});
expect(parsedResult.data).toEqual(
expect.arrayContaining([
{
"Institution Operating Name":
designatedInstitutionLocation.institution.operatingName,
"Location Name": designatedInstitutionLocation.name,
"Location Code": designatedInstitutionLocation.institutionCode,
"Institution Type": "BC Private",
"Designation Status": designationAgreement.designationStatus,
"Assessed Date": "",
"Expiry Date": designationAgreement.endDate,
"Request for designation":
approvedDesignationAgreementLocation.requested.toString(),
"Approved for designation":
approvedDesignationAgreementLocation.approved.toString(),
"Location Contact":
designatedPrimaryContact.firstName +
" " +
designatedPrimaryContact.lastName,
"Contact Email": designatedPrimaryContact.email,
},
{
"Institution Operating Name":
nonDesignatedInstitutionLocation.institution.operatingName,
"Location Name": nonDesignatedInstitutionLocation.name,
"Location Code": nonDesignatedInstitutionLocation.institutionCode,
"Institution Type": "BC Private",
"Designation Status": designationAgreement.designationStatus,
"Assessed Date": "",
"Expiry Date": designationAgreement.endDate,
"Request for designation":
declinedDesignationAgreementLocation.requested.toString(),
"Approved for designation":
declinedDesignationAgreementLocation.approved.toString(),
"Location Contact":
nonDesignatedPrimaryContact.firstName +
" " +
nonDesignatedPrimaryContact.lastName,
"Contact Email": nonDesignatedPrimaryContact.email,
},
]),
);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { MigrationInterface, QueryRunner } from "typeorm";
import { getSQLFileData } from "../utilities/sqlLoader";

export class UpdateInstitutionDesignationReport1717564473617
implements MigrationInterface
{
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
getSQLFileData("Update-institution-designation-report.sql", "Reports"),
);
}

public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(
getSQLFileData(
"Rollback-update-institution-designation-report.sql",
"Reports",
),
);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
UPDATE
sims.report_configs
SET
report_sql = (
'SELECT
institutions.operating_name AS "Institution Operating Name",
institution_locations.name AS "Location Name",
institution_locations.institution_code AS "Location Code",
institution_type.name AS "Institution Type",
designation_agreements.designation_status AS "Designation Status",
CAST(
CAST(designation_agreements.assessed_date AS date) AS varchar
) AS "Assessed Date",
CAST(designation_agreements.end_date AS varchar) AS "Expiry Date",
designation_agreement_locations.requested AS "Request for designation",
designation_agreement_locations.approved AS "Approved for designation",
CONCAT(
institution_locations.primary_contact ->> ''firstName'',
'' '',
institution_locations.primary_contact ->> ''lastName''
) AS "Location Contact",
institution_locations.primary_contact ->> ''email'' AS "Contact Email"
FROM
sims.institution_locations institution_locations
INNER JOIN sims.institutions institutions ON institution_locations.institution_id = institutions.id
INNER JOIN sims.institution_type institution_type ON institution_type.id = institutions.institution_type_id
INNER JOIN sims.designation_agreement_locations designation_agreement_locations ON designation_agreement_locations.location_id = institution_locations.id
INNER JOIN sims.designation_agreements designation_agreements ON designation_agreements.id = designation_agreement_locations.designation_agreement_id
WHERE
designation_agreements.assessed_date BETWEEN :startDate
AND :endDate
OR designation_agreements.end_date BETWEEN :startDate
AND :endDate
ORDER BY
institutions.operating_name ASC,
institution_locations.institution_code ASC,
designation_agreements.designation_status ASC,
designation_agreements.assessed_date DESC,
designation_agreements.end_date DESC;'
)
WHERE
report_name = 'Institution_Designation_Report';
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
UPDATE
sims.report_configs
SET
report_sql = (
'SELECT
institutions.operating_name AS "Institution Operating Name",
institution_locations.name AS "Location Name",
institution_locations.institution_code AS "Location Code",
institution_type.name AS "Institution Type",
designation_agreements.designation_status AS "Designation Status",
CAST(
CAST(designation_agreements.assessed_date AS date) AS varchar
) AS "Assessed Date",
CAST(designation_agreements.end_date AS varchar) AS "Expiry Date",
designation_agreement_locations.requested AS "Request for designation",
designation_agreement_locations.approved AS "Approved for designation",
CONCAT(
institution_locations.primary_contact ->> ''firstName'',
'' '',
institution_locations.primary_contact ->> ''lastName''
) AS "Location Contact",
institution_locations.primary_contact ->> ''email'' AS "Contact Email"
FROM
sims.institution_locations institution_locations
INNER JOIN sims.institutions institutions ON institution_locations.institution_id = institutions.id
INNER JOIN sims.institution_type institution_type ON institution_type.id = institutions.institution_type_id
INNER JOIN sims.designation_agreement_locations designation_agreement_locations ON designation_agreement_locations.location_id = institution_locations.id
INNER JOIN sims.designation_agreements designation_agreements ON designation_agreements.id = designation_agreement_locations.designation_agreement_id
WHERE
(
designation_agreements.assessed_date >= CAST(:startDate as timestamptz)
AND designation_agreements.assessed_date < CAST(:endDate as timestamptz) + INTERVAL ''1 DAY''
)
OR (
designation_agreements.end_date >= CAST(:startDate as timestamptz)
AND designation_agreements.end_date < CAST(:endDate as timestamptz) + INTERVAL ''1 DAY''
)
ORDER BY
institutions.operating_name ASC,
institution_locations.institution_code ASC,
designation_agreements.designation_status ASC,
designation_agreements.assessed_date DESC,
designation_agreements.end_date DESC;'
)
WHERE
report_name = 'Institution_Designation_Report';
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
import { DesignationAgreementLocation } from "@sims/sims-db";
import {
DesignationAgreement,
DesignationAgreementLocation,
} from "@sims/sims-db";
import { E2EDataSources } from "../data-source/e2e-data-source";
import { createFakeDesignationAgreement } from "./designation-agreement";
import { createFakeInstitution } from "./institution";
import { createMultipleFakeInstitutionLocations } from "./institution-location";
import { createFakeUser } from "@sims/test-utils";

/**
* Create and save fake designation agreement location/s.
* Creates and saves fake designation agreement with location/s.
* @param db e2e data sources.
* @param options options,
* @param options related options.
* - `numberOfLocations` number of locations.
* @returns created and saved fake designation agreement location/s.
* - `initialValues` designation agreement initial values.
* @returns designation agreement with the created locations associated.
* */
export async function saveFakeDesignationAgreementLocation(
db: E2EDataSources,
options: {
numberOfLocations: number;
initialValues?: Partial<DesignationAgreement>;
},
): Promise<DesignationAgreementLocation[]> {
): Promise<DesignationAgreement> {
const fakeInstitution = await db.institution.save(createFakeInstitution());
// Create fake institution locations.
const fakeInstitutionLocations = await db.institutionLocation.save(
Expand All @@ -27,24 +32,20 @@ export async function saveFakeDesignationAgreementLocation(
),
);
const fakeUser = await db.user.save(createFakeUser());
const designationAgreement = await db.designationAgreement.save(
createFakeDesignationAgreement({
fakeInstitution,
fakeInstitutionLocations,
fakeUser,
}),
);

const designationAgreementLocations = fakeInstitutionLocations.map(
(fakeInstitutionLocation) => {
const designationAgreementLocation = new DesignationAgreementLocation();
designationAgreementLocation.designationAgreement = designationAgreement;
designationAgreementLocation.institutionLocation =
fakeInstitutionLocation;
designationAgreementLocation.requested = true;
designationAgreementLocation.approved = true;
return designationAgreementLocation;
},
return db.designationAgreement.save(
createFakeDesignationAgreement(
{
fakeInstitution,
fakeInstitutionLocations,
fakeUser,
},
{
initialValue: {
endDate: options.initialValues?.endDate,
assessedDate: options.initialValues?.assessedDate,
},
locationApprovedDesignationRequest: true,
},
),
);
return db.designationAgreementLocation.save(designationAgreementLocations);
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ import * as faker from "faker";
* @param options options,
* - `designationStatus` designation status, by default
* it is approved.
* - `locationApprovedDesignationRequest` if true, sets all
* the location designation requests to approved.
* @returns fake designation agreement.
* */
export function createFakeDesignationAgreement(
Expand All @@ -29,6 +31,7 @@ export function createFakeDesignationAgreement(
},
options?: {
initialValue?: Partial<DesignationAgreement>;
locationApprovedDesignationRequest?: boolean;
},
): DesignationAgreement {
const now = new Date();
Expand Down Expand Up @@ -75,19 +78,18 @@ export function createFakeDesignationAgreement(
addDays(-10, new Date()),
"YYYYMMDD",
);
fakeDesignationAgreement.endDate = formatDate(
addDays(90, new Date()),
"YYYYMMDD",
);
fakeDesignationAgreement.endDate =
options?.initialValue?.endDate ??
formatDate(addDays(90, new Date()), "YYYYMMDD");
fakeDesignationAgreement.designationAgreementLocations =
newFakeInstitutionLocations.map((location: InstitutionLocation) => {
const newLocation = new DesignationAgreementLocation();
newLocation.institutionLocation = location;
newLocation.requested = true;
newLocation.approved = options?.locationApprovedDesignationRequest;
newLocation.creator = newFakeUser;
newLocation.createdAt = now;
return newLocation;
});

return fakeDesignationAgreement;
}
2 changes: 1 addition & 1 deletion sources/packages/web/src/views/aest/Reports.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<full-page-container>
<full-page-container class="overflow-visible">
<template #header
><header-navigator title="Ministry" subTitle="Reports" />
</template>
Expand Down
2 changes: 1 addition & 1 deletion sources/packages/web/src/views/institution/Reports.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<full-page-container>
<full-page-container class="overflow-visible">
<template #header
><header-navigator title="Institution" subTitle="Reports" />
</template>
Expand Down

0 comments on commit 8f70c75

Please sign in to comment.