mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-26 18:42:49 +00:00
116 lines
3.7 KiB
TypeScript
116 lines
3.7 KiB
TypeScript
import { BadRequestException } from "@nestjs/common";
|
|
|
|
import { CompaniesService } from "./companies.service";
|
|
import { Company, CompanyStatus } from "./entities/company.entity";
|
|
import {
|
|
CompanyProfile,
|
|
ProfileStatus,
|
|
ProfileType,
|
|
} from "./entities/company-profile.entity";
|
|
|
|
/**
|
|
* A rejection hands the role back to the customer: they fix what was flagged
|
|
* and resubmit (`reapplyCompanyProfile` → Pending). The reviewer used to be
|
|
* able to skip that entirely and approve straight out of Rejected — granting
|
|
* the role over the documents that were just refused, while the customer's
|
|
* "please fix this" note was still on their screen.
|
|
*/
|
|
function makeService(status: ProfileStatus) {
|
|
const profile: Partial<CompanyProfile> = {
|
|
id: "profile-1",
|
|
companyId: "company-1",
|
|
type: ProfileType.importer,
|
|
status,
|
|
reference: null,
|
|
reviewNote: status === ProfileStatus.Rejected ? "Licence expired" : null,
|
|
};
|
|
const company = {
|
|
id: "company-1",
|
|
status: CompanyStatus.Pending,
|
|
attributes: {},
|
|
};
|
|
|
|
const written: Partial<CompanyProfile>[] = [];
|
|
const profileRepo = {
|
|
update: jest.fn(async (_id: string, patch: Partial<CompanyProfile>) => {
|
|
written.push(patch);
|
|
Object.assign(profile, patch);
|
|
return null;
|
|
}),
|
|
findOne: jest.fn(async () => profile),
|
|
};
|
|
const companyRepo = { findOne: jest.fn(async () => company), update: jest.fn() };
|
|
|
|
const companyProfilesRepo = {
|
|
findById: jest.fn(async () => profile),
|
|
generateReference: jest.fn(async () => "IM-A00001"),
|
|
};
|
|
const profilesRepo = {
|
|
// Onboarding submitted — the other gate in this method is not what these
|
|
// tests are about.
|
|
findByCompanyId: jest.fn(async () => [{ onboardingCompleted: true }]),
|
|
};
|
|
const filesService = { findWithOpenChangeRequest: jest.fn(async () => []) };
|
|
const dataSource = {
|
|
transaction: jest.fn(async (cb: (m: unknown) => Promise<unknown>) =>
|
|
cb({
|
|
findOne: jest.fn(async () => company),
|
|
getRepository: (entity: unknown) =>
|
|
entity === Company ? companyRepo : profileRepo,
|
|
}),
|
|
),
|
|
};
|
|
const companyNotifier = { profileStatusChanged: jest.fn(), companyApproved: jest.fn() };
|
|
|
|
const service = new CompaniesService(
|
|
{} as never,
|
|
companyProfilesRepo as never,
|
|
{} as never,
|
|
{} as never,
|
|
profilesRepo as never,
|
|
{} as never,
|
|
filesService as never,
|
|
{} as never,
|
|
{} as never,
|
|
companyNotifier as never,
|
|
dataSource as never,
|
|
{} as never,
|
|
);
|
|
|
|
return { service, profile, written, companyProfilesRepo };
|
|
}
|
|
|
|
describe("approving an operational role", () => {
|
|
it("refuses to approve a role the customer has not resubmitted", async () => {
|
|
const { service, companyProfilesRepo } = makeService(ProfileStatus.Rejected);
|
|
|
|
await expect(
|
|
service.setCompanyProfileStatus("profile-1", ProfileStatus.Active),
|
|
).rejects.toBeInstanceOf(BadRequestException);
|
|
// Refused before any reference could be minted against the rejected role.
|
|
expect(companyProfilesRepo.generateReference).not.toHaveBeenCalled();
|
|
});
|
|
|
|
it("lets a reviewer undo their own rejection, and drops the note with it", async () => {
|
|
const { service, written } = makeService(ProfileStatus.Rejected);
|
|
|
|
await service.setCompanyProfileStatus("profile-1", ProfileStatus.Pending);
|
|
|
|
expect(written[0]).toMatchObject({
|
|
status: ProfileStatus.Pending,
|
|
reviewNote: null,
|
|
});
|
|
});
|
|
|
|
it("still approves a role that is awaiting its first decision", async () => {
|
|
const { service, written } = makeService(ProfileStatus.Pending);
|
|
|
|
await service.setCompanyProfileStatus("profile-1", ProfileStatus.Active);
|
|
|
|
expect(written[0]).toMatchObject({
|
|
status: ProfileStatus.Active,
|
|
reference: "IM-A00001",
|
|
});
|
|
});
|
|
});
|