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

#1851 - Enable File Upload for Public Institution User #1893

Merged
merged 13 commits into from
Apr 25, 2023
Merged
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import { HttpStatus, INestApplication } from "@nestjs/common";
import * as request from "supertest";
import * as assert from "assert";
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove the assert as it is not used.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sonar is complaining about the same.

import { DataSource, Repository } from "typeorm";
import {
authorizeUserTokenForLocation,
BEARER_AUTH_TYPE,
createTestingAppModule,
getAuthRelatedEntities,
getInstitutionToken,
InstitutionTokenTypes,
} from "../../../../testHelpers";
import {
createFakeInstitutionLocation,
createFakeApplication,
saveFakeStudent,
saveFakeStudentFileUpload,
} from "@sims/test-utils";
import { Application, Institution, InstitutionLocation } from "@sims/sims-db";

describe("StudentInstitutionsController(e2e)-getStudentFileUploads", () => {
let app: INestApplication;
let appDataSource: DataSource;
let collegeC: Institution;
let collegeCLocation: InstitutionLocation;
let applicationRepo: Repository<Application>;

beforeAll(async () => {
const { nestApplication, dataSource } = await createTestingAppModule();
app = nestApplication;
appDataSource = dataSource;

const { institution } = await getAuthRelatedEntities(
appDataSource,
InstitutionTokenTypes.CollegeCUser,
andrewsignori-aot marked this conversation as resolved.
Show resolved Hide resolved
);
collegeC = institution;
collegeCLocation = createFakeInstitutionLocation(collegeC);
await authorizeUserTokenForLocation(
appDataSource,
InstitutionTokenTypes.CollegeCUser,
collegeCLocation,
);
applicationRepo = appDataSource.getRepository(Application);
});

it("Should get the student file uploads when student has at least one application submitted for the institution.", async () => {
andrepestana-aot marked this conversation as resolved.
Show resolved Hide resolved
// Student who has application submitted to institution.
andrepestana-aot marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

comment Arrange is missing.

const student = await saveFakeStudent(appDataSource);
const application = createFakeApplication({
location: collegeCLocation,
student,
});
await applicationRepo.save(application);

const institutionUserToken = await getInstitutionToken(
InstitutionTokenTypes.CollegeCUser,
);

// Save fake file upload for the student.
const studentUploadedFile = await saveFakeStudentFileUpload(appDataSource, {
student,
});

// Endpoint to test.
const endpoint = `/institutions/student/${student.id}/documents`;

// Assert.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment must be // Act/Assert

await request(app.getHttpServer())
.get(endpoint)
.auth(institutionUserToken, BEARER_AUTH_TYPE)
.expect(HttpStatus.OK)
.then((res) => {
ann-aot marked this conversation as resolved.
Show resolved Hide resolved
assert(res.body[0].fileName, studentUploadedFile.fileName);
assert(res.body[0].uniqueFileName, studentUploadedFile.uniqueFileName);
assert(res.body[0].groupName, "Ministry communications");
assert(res.body[0].fileOrigin, "Ministry");
});
});

afterAll(async () => {
await app?.close();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,12 @@ export class AESTStudentFileAPIOutDTO extends StudentUploadFileAPIOutDTO {
updatedAt: Date;
}

export class InstitutionStudentFileAPIOutDTO extends StudentUploadFileAPIOutDTO {
ann-aot marked this conversation as resolved.
Show resolved Hide resolved
metadata: StudentFileMetadataAPIOutDTO;
groupName: string;
updatedAt: Date;
}

export class StudentFileMetadataAPIOutDTO {
applicationNumber?: string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import {
Post,
} from "@nestjs/common";
import { ApiNotFoundResponse, ApiTags } from "@nestjs/swagger";
import { StudentService } from "../../services";
import { StudentService, StudentFileService } from "../../services";
import { ClientTypeBaseRoute } from "../../types";
import { AuthorizedParties } from "../../auth/authorized-parties.enum";
import { AllowAuthorizedParty, UserToken } from "../../auth/decorators";
Expand All @@ -16,6 +16,7 @@ import {
StudentSearchAPIInDTO,
SearchStudentAPIOutDTO,
StudentProfileAPIOutDTO,
InstitutionStudentFileAPIOutDTO,
} from "./models/student.dto";
import { IInstitutionUserToken } from "../../auth";
import { StudentControllerService } from "./student.controller.service";
Expand All @@ -29,6 +30,7 @@ import { StudentControllerService } from "./student.controller.service";
export class StudentInstitutionsController extends BaseController {
constructor(
private readonly studentService: StudentService,
private readonly fileService: StudentFileService,
private readonly studentControllerService: StudentControllerService,
) {
super();
Expand Down Expand Up @@ -68,4 +70,26 @@ export class StudentInstitutionsController extends BaseController {
): Promise<StudentProfileAPIOutDTO> {
return this.studentControllerService.getStudentProfile(studentId);
}

/**
* This controller returns all student documents uploaded by student uploader.
dheepak-aot marked this conversation as resolved.
Show resolved Hide resolved
* @param studentId student id.
* @returns list of student documents.
*/
@Get(":studentId/documents")
async getInstitutionStudentFiles(
@Param("studentId", ParseIntPipe) studentId: number,
): Promise<InstitutionStudentFileAPIOutDTO[]> {
dheepak-aot marked this conversation as resolved.
Show resolved Hide resolved
const studentDocuments = await this.fileService.getStudentUploadedFiles(
ann-aot marked this conversation as resolved.
Show resolved Hide resolved
studentId,
);
return studentDocuments.map((studentDocument) => ({
fileName: studentDocument.fileName,
uniqueFileName: studentDocument.uniqueFileName,
metadata: studentDocument.metadata,
groupName: studentDocument.groupName,
updatedAt: studentDocument.updatedAt,
fileOrigin: studentDocument.fileOrigin,
}));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import * as faker from "faker";
import { FileOriginType, Student, StudentFile, User } from "@sims/sims-db";
import { DataSource } from "typeorm";
import { createFakeStudent } from "./student";

/**
* Create fake student file upload object.
* @param student entity.
ann-aot marked this conversation as resolved.
Show resolved Hide resolved
* @returns created studentFile object.
*/
export function createFakeStudentFileUpload(student?: Student): StudentFile {
ann-aot marked this conversation as resolved.
Show resolved Hide resolved
const studentFile = new StudentFile();
studentFile.fileName = faker.system.fileName();
studentFile.uniqueFileName =
studentFile.fileName +
faker.random.number(5) +
andrewsignori-aot marked this conversation as resolved.
Show resolved Hide resolved
"." +
faker.system.fileType();
studentFile.groupName = "Ministry communications";
studentFile.mimeType = faker.system.mimeType();
studentFile.fileContent = Buffer.from(faker.random.words(50), "utf-8");
studentFile.student = student ?? createFakeStudent();
studentFile.creator = { id: student?.user.id } as User;
andrewsignori-aot marked this conversation as resolved.
Show resolved Hide resolved
studentFile.fileOrigin = FileOriginType.Ministry;
return studentFile;
}

/**
* Save fake student file upload.
* @param dataSource data source to persist studentFileUpload.
* @param relations student entity relations.
ann-aot marked this conversation as resolved.
Show resolved Hide resolved
* @returns persisted studentFile.
*/
export async function saveFakeStudentFileUpload(
dataSource: DataSource,
relations?: { student: Student },
): Promise<StudentFile> {
const studentFile = createFakeStudentFileUpload(relations?.student);
const studentFileRepo = dataSource.getRepository(StudentFile);
return studentFileRepo.save(studentFile);
}
1 change: 1 addition & 0 deletions sources/packages/backend/libs/test-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ export * from "./factories/application-exception-request";
export * from "./factories/student-scholastic-standing";
export * from "./factories/student-appeal";
export * from "./factories/student-appeal-request";
export * from "./factories/student-file-uploads";
export * from "./models/common.model";
Loading