-
Notifications
You must be signed in to change notification settings - Fork 14
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
Enable application details for public institution user
- Loading branch information
Showing
18 changed files
with
403 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
136 changes: 136 additions & 0 deletions
136
...application/_tests_/application.institutions.controller.getApplicationDetails.e2e-spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
import { HttpStatus, INestApplication } from "@nestjs/common"; | ||
import * as request from "supertest"; | ||
import { DataSource } from "typeorm"; | ||
import { | ||
authorizeUserTokenForLocation, | ||
BEARER_AUTH_TYPE, | ||
createTestingAppModule, | ||
getAuthRelatedEntities, | ||
getInstitutionToken, | ||
INSTITUTION_BC_PUBLIC_ERROR_MESSAGE, | ||
INSTITUTION_STUDENT_DATA_ACCESS_ERROR_MESSAGE, | ||
InstitutionTokenTypes, | ||
} from "../../../testHelpers"; | ||
import { | ||
createFakeInstitutionLocation, | ||
saveFakeApplication, | ||
} from "@sims/test-utils"; | ||
import { Institution, InstitutionLocation } from "@sims/sims-db"; | ||
|
||
describe("ApplicationInstitutionsController(e2e)-getApplicationDetails", () => { | ||
let app: INestApplication; | ||
let appDataSource: DataSource; | ||
let collegeF: Institution; | ||
let collegeFLocation: InstitutionLocation; | ||
let collegeCLocation: InstitutionLocation; | ||
|
||
beforeAll(async () => { | ||
const { nestApplication, dataSource } = await createTestingAppModule(); | ||
app = nestApplication; | ||
appDataSource = dataSource; | ||
// College F. | ||
const { institution: collegeF } = await getAuthRelatedEntities( | ||
appDataSource, | ||
InstitutionTokenTypes.CollegeFUser, | ||
); | ||
collegeFLocation = createFakeInstitutionLocation(collegeF); | ||
await authorizeUserTokenForLocation( | ||
appDataSource, | ||
InstitutionTokenTypes.CollegeFUser, | ||
collegeFLocation, | ||
); | ||
// College C. | ||
const { institution: collegeC } = await getAuthRelatedEntities( | ||
appDataSource, | ||
InstitutionTokenTypes.CollegeCUser, | ||
); | ||
collegeCLocation = createFakeInstitutionLocation(collegeC); | ||
await authorizeUserTokenForLocation( | ||
appDataSource, | ||
InstitutionTokenTypes.CollegeCUser, | ||
collegeCLocation, | ||
); | ||
}); | ||
|
||
it("Should get the student application details when student has a submitted application for the institution.", async () => { | ||
// Arrange | ||
// Create new application. | ||
const savedApplication = await saveFakeApplication(appDataSource, { | ||
institutionLocation: collegeFLocation, | ||
}); | ||
|
||
const student = savedApplication.student; | ||
const endpoint = `/institutions/application/student/${student.id}/application/${savedApplication.id}`; | ||
const institutionUserToken = await getInstitutionToken( | ||
InstitutionTokenTypes.CollegeFUser, | ||
); | ||
|
||
// Act/Assert | ||
await request(app.getHttpServer()) | ||
.get(endpoint) | ||
.auth(institutionUserToken, BEARER_AUTH_TYPE) | ||
.expect(HttpStatus.OK) | ||
.expect({ | ||
data: {}, | ||
id: savedApplication.id, | ||
applicationStatus: savedApplication.applicationStatus, | ||
applicationNumber: savedApplication.applicationNumber, | ||
applicationFormName: "SFAA2022-23", | ||
applicationProgramYearID: savedApplication.programYearId, | ||
}); | ||
}); | ||
|
||
it("Should not have access to get the student application details when the student submitted an application to non-public institution.", async () => { | ||
// Arrange | ||
// Create new application. | ||
const savedApplication = await saveFakeApplication(appDataSource, { | ||
institutionLocation: collegeCLocation, | ||
}); | ||
|
||
const student = savedApplication.student; | ||
const endpoint = `/institutions/application/student/${student.id}/application/${savedApplication.id}`; | ||
const institutionUserTokenCUser = await getInstitutionToken( | ||
InstitutionTokenTypes.CollegeCUser, | ||
); | ||
|
||
// Act/Assert | ||
await request(app.getHttpServer()) | ||
.get(endpoint) | ||
.auth(institutionUserTokenCUser, BEARER_AUTH_TYPE) | ||
.expect(HttpStatus.FORBIDDEN) | ||
.expect({ | ||
statusCode: 403, | ||
message: INSTITUTION_BC_PUBLIC_ERROR_MESSAGE, | ||
error: "Forbidden", | ||
}); | ||
}); | ||
|
||
it("Should not get the student application details when application is submitted for different institution.", async () => { | ||
// Arrange | ||
// Create new application. | ||
const savedApplication = await saveFakeApplication(appDataSource, { | ||
institutionLocation: collegeCLocation, | ||
}); | ||
|
||
const student = savedApplication.student; | ||
const endpoint = `/institutions/application/student/${student.id}/application/${savedApplication.id}`; | ||
const institutionUserToken = await getInstitutionToken( | ||
InstitutionTokenTypes.CollegeFUser, | ||
); | ||
|
||
// Act/Assert | ||
await request(app.getHttpServer()) | ||
.get(endpoint) | ||
.auth(institutionUserToken, BEARER_AUTH_TYPE) | ||
.expect(HttpStatus.FORBIDDEN) | ||
.expect({ | ||
statusCode: 403, | ||
message: INSTITUTION_STUDENT_DATA_ACCESS_ERROR_MESSAGE, | ||
error: "Forbidden", | ||
}); | ||
}); | ||
|
||
afterAll(async () => { | ||
await app?.close(); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
...backend/apps/api/src/route-controllers/application/application.institutions.controller.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
import { Controller, Get, Param, ParseIntPipe } from "@nestjs/common"; | ||
import { ApplicationService } from "../../services"; | ||
import BaseController from "../BaseController"; | ||
import { ApplicationBaseAPIOutDTO } from "./models/application.dto"; | ||
import { | ||
AllowAuthorizedParty, | ||
HasStudentDataAccess, | ||
IsBCPublicInstitution, | ||
UserToken, | ||
} from "../../auth/decorators"; | ||
import { ApiTags } from "@nestjs/swagger"; | ||
import { ClientTypeBaseRoute } from "../../types"; | ||
import { ApplicationControllerService } from "./application.controller.service"; | ||
import { AuthorizedParties, IInstitutionUserToken } from "../../auth"; | ||
|
||
@AllowAuthorizedParty(AuthorizedParties.institution) | ||
@IsBCPublicInstitution() | ||
@Controller("application") | ||
@ApiTags(`${ClientTypeBaseRoute.Institution}-application`) | ||
export class ApplicationInstitutionsController extends BaseController { | ||
constructor( | ||
private readonly applicationService: ApplicationService, | ||
private readonly applicationControllerService: ApplicationControllerService, | ||
) { | ||
super(); | ||
} | ||
|
||
/** | ||
* API to fetch application details by applicationId. | ||
* This API will be used by institution users. | ||
* @param applicationId for the application. | ||
* @param studentId for the student. | ||
* @returns Application details. | ||
*/ | ||
@HasStudentDataAccess("studentId") | ||
@Get("student/:studentId/application/:applicationId") | ||
async getApplication( | ||
@UserToken() userToken: IInstitutionUserToken, | ||
@Param("applicationId", ParseIntPipe) applicationId: number, | ||
@Param("studentId", ParseIntPipe) studentId: number, | ||
): Promise<ApplicationBaseAPIOutDTO> { | ||
const application = await this.applicationService.getApplicationById( | ||
applicationId, | ||
{ | ||
loadDynamicData: true, | ||
studentId: studentId, | ||
institutionId: userToken.authorizations.institutionId, | ||
}, | ||
); | ||
application.data = | ||
await this.applicationControllerService.generateApplicationFormData( | ||
application.data, | ||
); | ||
return this.applicationControllerService.transformToApplicationDTO( | ||
application, | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
51 changes: 51 additions & 0 deletions
51
...packages/web/src/components/layouts/Institution/sidebar/InstitutionApplicationSideBar.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<template> | ||
<v-navigation-drawer app color="default" permanent> | ||
<v-list | ||
active-class="active-list-item" | ||
density="compact" | ||
bg-color="default" | ||
active-color="primary" | ||
class="no-wrap" | ||
:items="items" | ||
/> | ||
</v-navigation-drawer> | ||
</template> | ||
|
||
<script lang="ts"> | ||
import { ref, defineComponent } from "vue"; | ||
import { InstitutionRoutesConst } from "@/constants/routes/RouteConstants"; | ||
import { MenuItemModel } from "@/types"; | ||
export default defineComponent({ | ||
props: { | ||
studentId: { | ||
type: Number, | ||
required: true, | ||
}, | ||
applicationId: { | ||
type: Number, | ||
required: true, | ||
}, | ||
}, | ||
setup(props) { | ||
const items = ref<MenuItemModel[]>([ | ||
{ | ||
title: "Student", | ||
props: { | ||
prependIcon: "mdi-school-outline", | ||
to: { | ||
name: InstitutionRoutesConst.STUDENT_APPLICATION_DETAILS, | ||
params: { | ||
applicationId: props.applicationId, | ||
studentId: props.studentId, | ||
}, | ||
}, | ||
}, | ||
}, | ||
]); | ||
return { | ||
items, | ||
}; | ||
}, | ||
}); | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.