Skip to content
Draft
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
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ import {
} from "@sims/test-utils";
import { InstitutionDetailAPIOutDTO } from "../../models/institution.dto";
import { getISODateOnlyString } from "@sims/utilities";
import {
BC_PROVINCE_CODE,
CANADA_COUNTRY_CODE,
INSTITUTION_TYPE_BC_PRIVATE,
} from "@sims/sims-db/constant";
import {
InstitutionClassification,
InstitutionMedicalSchoolStatus,
InstitutionOrganizationStatus,
} from "@sims/sims-db";

describe("InstitutionAESTController(e2e)-getInstitutionDetailById", () => {
let app: INestApplication;
Expand All @@ -26,12 +36,25 @@ describe("InstitutionAESTController(e2e)-getInstitutionDetailById", () => {

it("Should return institution details when an institution with given institution id exist.", async () => {
// Arrange
const institution = await db.institution.save(createFakeInstitution());
const mailingAddress = institution.institutionAddress.mailingAddress;
const institutionType = await db.institutionType.findOne({
select: { id: true, name: true },
where: { id: institution.institutionType.id },
where: { id: INSTITUTION_TYPE_BC_PRIVATE },
});
const institution = await db.institution.save(
createFakeInstitution(
{ institutionType },
{
initialValues: {
country: CANADA_COUNTRY_CODE,
province: BC_PROVINCE_CODE,
classification: InstitutionClassification.Private,
organizationStatus: InstitutionOrganizationStatus.Profit,
medicalSchoolStatus: InstitutionMedicalSchoolStatus.No,
},
},
),
);
const mailingAddress = institution.institutionAddress.mailingAddress;
const expectedInstitutionDetails: InstitutionDetailAPIOutDTO = {
legalOperatingName: institution.legalOperatingName,
operatingName: institution.operatingName,
Expand Down Expand Up @@ -60,6 +83,11 @@ describe("InstitutionAESTController(e2e)-getInstitutionDetailById", () => {
isBCPrivate: true,
isBCPublic: false,
hasBusinessGuid: true,
country: CANADA_COUNTRY_CODE,
province: BC_PROVINCE_CODE,
classification: InstitutionClassification.Private,
organizationStatus: InstitutionOrganizationStatus.Profit,
medicalSchoolStatus: InstitutionMedicalSchoolStatus.No,
};
const endpoint = `/aest/institution/${institution.id}`;
const token = await getAESTToken(AESTGroups.Operations);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
import { HttpStatus, INestApplication } from "@nestjs/common";
import * as request from "supertest";
import {
BEARER_AUTH_TYPE,
createTestingAppModule,
getInstitutionToken,
InstitutionTokenTypes,
mockInstitutionUserAuthorization,
} from "../../../../testHelpers";
import {
E2EDataSources,
createE2EDataSources,
createFakeInstitution,
} from "@sims/test-utils";
import {
InstitutionClassification,
InstitutionMedicalSchoolStatus,
InstitutionOrganizationStatus,
InstitutionUserTypes,
} from "@sims/sims-db";
import {
CANADA_COUNTRY_CODE,
BC_PROVINCE_CODE,
INSTITUTION_TYPE_BC_PUBLIC,
} from "@sims/sims-db/constant";
import { getISODateOnlyString } from "@sims/utilities";
import { InstitutionUserAuthorizations } from "../../../../services";
import { TestingModule } from "@nestjs/testing";

describe("InstitutionInstitutionsController(e2e)-getInstitutionDetail", () => {
let app: INestApplication;
let db: E2EDataSources;
let appModule: TestingModule;
const endpoint = "/institutions/institution";

beforeAll(async () => {
const { nestApplication, module, dataSource } =
await createTestingAppModule();
app = nestApplication;
appModule = module;
db = createE2EDataSources(dataSource);
});

it("Should return details of the institution associated to the institution user from the user token when the institution is already set up.", async () => {
// Arrange
const institutionType = await db.institutionType.findOne({
select: { id: true, name: true },
where: { id: INSTITUTION_TYPE_BC_PUBLIC },
});
const institution = await db.institution.save(
createFakeInstitution(
{ institutionType },
{
initialValues: {
country: CANADA_COUNTRY_CODE,
province: BC_PROVINCE_CODE,
classification: InstitutionClassification.Public,
organizationStatus: InstitutionOrganizationStatus.NotForProfit,
medicalSchoolStatus: InstitutionMedicalSchoolStatus.No,
},
},
),
);
const mailingAddress = institution.institutionAddress.mailingAddress;
const expectedInstitutionDetails = {
legalOperatingName: institution.legalOperatingName,
operatingName: institution.operatingName,
primaryPhone: institution.primaryPhone,
primaryEmail: institution.primaryEmail,
website: institution.website,
regulatingBody: institution.regulatingBody,
otherRegulatingBody: institution.otherRegulatingBody ?? null,
institutionType: institutionType.id,
institutionTypeName: institutionType.name,
establishedDate: getISODateOnlyString(institution.establishedDate),
primaryContactEmail: institution.institutionPrimaryContact.email,
primaryContactFirstName: institution.institutionPrimaryContact.firstName,
primaryContactLastName: institution.institutionPrimaryContact.lastName,
primaryContactPhone: institution.institutionPrimaryContact.phone,
mailingAddress: {
addressLine1: mailingAddress.addressLine1,
addressLine2: mailingAddress.addressLine2,
provinceState: mailingAddress.provinceState,
country: mailingAddress.country,
city: mailingAddress.city,
postalCode: mailingAddress.postalCode,
canadaPostalCode: mailingAddress.postalCode,
selectedCountry: mailingAddress.selectedCountry,
},
isBCPrivate: false,
isBCPublic: true,
hasBusinessGuid: true,
country: CANADA_COUNTRY_CODE,
province: BC_PROVINCE_CODE,
classification: InstitutionClassification.Public,
organizationStatus: InstitutionOrganizationStatus.NotForProfit,
medicalSchoolStatus: InstitutionMedicalSchoolStatus.No,
};
// Mock institution user authorization so that the user token will return the fake institution id and mocked roles.
await mockInstitutionUserAuthorization(
appModule,
new InstitutionUserAuthorizations(institution.id, [
{
locationId: null,
userRole: null,
userType: InstitutionUserTypes.admin,
},
]),
);
const institutionUserToken = await getInstitutionToken(
InstitutionTokenTypes.CollegeFUser,
);

// Act/Assert
await request(app.getHttpServer())
.get(endpoint)
.auth(institutionUserToken, BEARER_AUTH_TYPE)
.expect(HttpStatus.OK)
.expect(expectedInstitutionDetails);
});

afterAll(async () => {
await app?.close();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,13 @@ export class InstitutionControllerService {
isBCPrivate,
isBCPublic,
hasBusinessGuid: !!institutionDetail.businessGuid,
// Fallback to undefined is to avoid returning null which is causing issues at the consumer side
// and eventually all these fields should become mandatory.
country: institutionDetail.country ?? undefined,
province: institutionDetail.province ?? undefined,
classification: institutionDetail.classification ?? undefined,
organizationStatus: institutionDetail.organizationStatus ?? undefined,
medicalSchoolStatus: institutionDetail.medicalSchoolStatus ?? undefined,
};
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import {
IsDateString,
IsEnum,
IsNotEmpty,
IsOptional,
IsPositive,
Length,
MaxLength,
ValidateIf,
ValidateNested,
Expand All @@ -18,8 +20,13 @@ import {
import {
OPERATING_NAME_MAX_LENGTH,
LEGAL_OPERATING_NAME_MAX_LENGTH,
InstitutionClassification,
InstitutionOrganizationStatus,
InstitutionMedicalSchoolStatus,
} from "@sims/sims-db";
import { OTHER_REGULATING_BODY_MAX_LENGTH } from "../../../constants";
import { CANADA_COUNTRY_CODE } from "@sims/sims-db/constant";
import { AllowIf } from "../../../utilities/class-validation";

/**
* DTO for institution creation by the institution user during the on board process
Expand Down Expand Up @@ -107,17 +114,43 @@ export class InstitutionProfileAPIInDTO extends InstitutionContactAPIInDTO {
website: string;
@IsNotEmpty()
regulatingBody: string;
@ValidateIf((e) => e.regulatingBody === "other")
@ValidateIf(
(input: InstitutionProfileAPIInDTO) => input.regulatingBody === "other",
)
@IsNotEmpty()
@MaxLength(OTHER_REGULATING_BODY_MAX_LENGTH)
otherRegulatingBody: string;
@IsDateString()
establishedDate: string;
@IsPositive()
institutionType: number;
@Length(2, 2)
country: string;
@ValidateIf(
(input: InstitutionProfileAPIInDTO) =>
input.country === CANADA_COUNTRY_CODE || !!input.province,
)
@AllowIf(
(input: InstitutionProfileAPIInDTO) =>
input.country === CANADA_COUNTRY_CODE,
)
@IsNotEmpty()
@Length(2, 2)
province?: string;
@IsEnum(InstitutionClassification)
classification: InstitutionClassification;
@IsEnum(InstitutionOrganizationStatus)
organizationStatus: InstitutionOrganizationStatus;
@IsEnum(InstitutionMedicalSchoolStatus)
medicalSchoolStatus: InstitutionMedicalSchoolStatus;
}

export class InstitutionProfileAPIOutDTO extends InstitutionContactAPIOutDTO {
export class InstitutionDetailAPIOutDTO {
primaryContactEmail: string;
primaryContactFirstName: string;
primaryContactLastName: string;
primaryContactPhone: string;
mailingAddress: AddressDetailsAPIOutDTO;
operatingName: string;
primaryPhone: string;
primaryEmail: string;
Expand All @@ -126,9 +159,6 @@ export class InstitutionProfileAPIOutDTO extends InstitutionContactAPIOutDTO {
otherRegulatingBody?: string;
establishedDate: string;
institutionType: number;
}

export class InstitutionDetailAPIOutDTO extends InstitutionProfileAPIOutDTO {
legalOperatingName: string;
institutionTypeName?: string;
isBCPrivate: boolean;
Expand All @@ -138,6 +168,11 @@ export class InstitutionDetailAPIOutDTO extends InstitutionProfileAPIOutDTO {
* associated with, if not it is a basic BCeID institution.
*/
hasBusinessGuid: boolean;
country?: string;
province?: string;
classification?: InstitutionClassification;
organizationStatus?: InstitutionOrganizationStatus;
medicalSchoolStatus?: InstitutionMedicalSchoolStatus;
}

export class InstitutionBasicAPIOutDTO {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { AddressInfo } from "@sims/sims-db";
import {
AddressInfo,
InstitutionClassification,
InstitutionMedicalSchoolStatus,
InstitutionOrganizationStatus,
} from "@sims/sims-db";

export interface UpdateInstitution {
operatingName?: string;
Expand All @@ -14,6 +19,11 @@ export interface UpdateInstitution {
primaryContactLastName: string;
primaryContactPhone: string;
mailingAddress: AddressInfo;
country?: string;
province?: string;
classification?: InstitutionClassification;
organizationStatus?: InstitutionOrganizationStatus;
medicalSchoolStatus?: InstitutionMedicalSchoolStatus;
}

export interface InstitutionFormModel {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -853,6 +853,11 @@ export class InstitutionService extends RecordDataModelService<Institution> {
institution.institutionType = {
id: updateInstitution.institutionType,
} as InstitutionType;
institution.country = updateInstitution.country;
institution.province = updateInstitution.province ?? null;
institution.classification = updateInstitution.classification;
institution.organizationStatus = updateInstitution.organizationStatus;
institution.medicalSchoolStatus = updateInstitution.medicalSchoolStatus;
}
institution.institutionPrimaryContact = {
firstName: updateInstitution.primaryContactFirstName,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export async function mockInstitutionUserAuthorization(
);
jest
.spyOn(institutionUserAuthService, "getAuthorizationsByUserName")
.mockImplementation(() => {
.mockImplementationOnce(() => {
return Promise.resolve(institutionUserAuthorizations);
});
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,17 @@ SET
ELSE NULL
END,
classification = CASE
-- Update for Canadian public institution types(BC Public, Out of Province Public) to Public.
-- Update for Canadian private institution types(BC Private, Out of Province Private) to Private.
WHEN institution_type_id IN (1, 3) THEN 'Public'
WHEN institution_type_id IN (2, 7) THEN 'Private'
-- Update for Canadian public institution types(BC Public, Out of Province Public) to public.
-- Update for Canadian private institution types(BC Private, Out of Province Private) to private.
WHEN institution_type_id IN (1, 3) THEN 'public'
WHEN institution_type_id IN (2, 7) THEN 'private'
ELSE NULL
END,
medical_school_status = CASE
-- Update for International Medical institution type to Yes.
-- Update for International institution type to No.
WHEN institution_type_id = 6 THEN 'Yes'
WHEN institution_type_id = 5 THEN 'No'
-- Update for International Medical institution type to yes.
-- Update for International institution type to no.
WHEN institution_type_id = 6 THEN 'yes'
WHEN institution_type_id = 5 THEN 'no'
ELSE NULL
END,
updated_at = NOW(),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ CREATE TABLE sims.system_lookup_configurations(
lookup_category VARCHAR(100) NOT NULL,
lookup_key VARCHAR(100) NOT NULL,
lookup_value VARCHAR(500) NOT NULL,
lookup_priority SMALLINT NOT NULL,
-- Audit columns.
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
Expand All @@ -22,6 +23,8 @@ COMMENT ON COLUMN sims.system_lookup_configurations.lookup_key IS 'Lookup key of

COMMENT ON COLUMN sims.system_lookup_configurations.lookup_value IS 'Lookup value of a lookup data.';

COMMENT ON COLUMN sims.system_lookup_configurations.lookup_priority IS 'Lookup priority to order the lookup data.';

COMMENT ON COLUMN sims.system_lookup_configurations.created_at IS 'Record creation timestamp.';

COMMENT ON COLUMN sims.system_lookup_configurations.updated_at IS 'Record update timestamp.';
Expand Down
Loading