Skip to content

Commit

Permalink
complete coverage
Browse files Browse the repository at this point in the history
  • Loading branch information
achorein committed Sep 20, 2024
1 parent 5c0730d commit 6581c91
Show file tree
Hide file tree
Showing 4 changed files with 250 additions and 50 deletions.
243 changes: 217 additions & 26 deletions api/src/__tests__/cohort-session.test.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import request from "supertest";
import { fakerFR as faker } from "@faker-js/faker";
import { addDays, addYears } from "date-fns";
import { addDays, addMonths, addYears } from "date-fns";
import { Types } from "mongoose";
const { ObjectId } = Types;

Expand Down Expand Up @@ -88,6 +88,36 @@ describe("Cohort Session Controller", () => {
expect(response.body.data.length).toBe(1);
});

it("should return no cohorts if young has a grade not eligible", async () => {
const young = {
department: "Loire-Atlantique",
region: "Pays de la Loire",
schoolRegion: "",
birthdateAt: faker.date.past({ years: 3, refDate: addYears(new Date(), -15) }),
grade: GRADES["2ndeGT"],
status: YOUNG_STATUS.REFUSED,
zip: faker.location.zipCode(),
};
await createCohortHelper(
getNewCohortFixture({
inscriptionEndDate: faker.date.future(),
eligibility: {
zones: [young.department!],
schoolLevels: [GRADES["1ereCAP"]],
bornAfter: addYears(new Date(), -18),
bornBefore: addYears(new Date(), -15),
},
}),
);
const response = await request(getAppHelper({ role: ROLES.ADMIN }))
.post("/cohort-session/eligibility/2023/")
.send(young);
expect(response.status).toBe(200);
expect(response.body.ok).toBe(true);
expect(Array.isArray(response.body.data)).toBe(true);
expect(response.body.data.length).toBe(0);
});

it("admin cle, should return filtered sessions if young is valid", async () => {
const young = await createYoungHelper(
getNewYoungFixture({
Expand Down Expand Up @@ -182,9 +212,100 @@ describe("Cohort Session Controller", () => {
schoolDepartment: "Loire-Atlantique",
}),
);
// valid cohort year
const cohort = await createCohortHelper(
getNewCohortFixture({
name: young.cohort,
inscriptionEndDate: faker.date.future(),
eligibility: {
zones: [young.department!],
schoolLevels: [young.grade || ""],
bornAfter: addYears(new Date(), -18),
bornBefore: addYears(new Date(), -15),
},
}),
);
// invalid cohort year
await createCohortHelper(
getNewCohortFixture({
name: young.cohort,
inscriptionEndDate: faker.date.future(),
dateStart: addYears(cohort.dateStart, -2),
dateEnd: addMonths(addYears(cohort.dateStart, -2), 1),
eligibility: {
zones: [young.department!],
schoolLevels: [young.grade || ""],
bornAfter: addYears(new Date(), -18),
bornBefore: addYears(new Date(), -15),
},
}),
);
const response = await request(getAppHelper({ role: ROLES.ADMIN })).post(`/cohort-session/eligibility/2023/${young._id}`);
expect(response.status).toBe(200);
expect(response.body.ok).toBe(true);
expect(Array.isArray(response.body.data)).toBe(true);
expect(response.body.data.length).toBe(1);
});

it("admin, should return sessions if young is valid and instruction open", async () => {
let young = await createYoungHelper(
getNewYoungFixture({
schooled: "false", // not HTZ
region: "Pays de la Loire",
department: "Loire-Atlantique",
schoolDepartment: "Loire-Atlantique",
status: YOUNG_STATUS.WAITING_CORRECTION,
}),
);
await createCohortHelper(
getNewCohortFixture({
name: young.cohort,
instructionEndDate: faker.date.future(),
inscriptionStartDate: faker.date.past(),
inscriptionEndDate: faker.date.past(),
eligibility: {
zones: [young.department!],
schoolLevels: [young.grade || ""],
bornAfter: addYears(new Date(), -18),
bornBefore: addYears(new Date(), -15),
},
}),
);
let response = await request(getAppHelper({ role: ROLES.ADMIN })).post(`/cohort-session/eligibility/2023/${young._id}`);
expect(response.status).toBe(200);
expect(response.body.ok).toBe(true);
expect(Array.isArray(response.body.data)).toBe(true);
expect(response.body.data.length).toBe(1);

young = await createYoungHelper(
getNewYoungFixture({
schooled: "false", // not HTZ
region: "Pays de la Loire",
department: "Loire-Atlantique",
schoolDepartment: "Loire-Atlantique",
status: YOUNG_STATUS.WAITING_VALIDATION,
}),
);
response = await request(getAppHelper({ role: ROLES.ADMIN })).post(`/cohort-session/eligibility/2023/${young._id}`);
expect(response.status).toBe(200);
expect(response.body.ok).toBe(true);
expect(Array.isArray(response.body.data)).toBe(true);
expect(response.body.data.length).toBe(1);
});

it("admin, should return sessions if young does not have cohort and cohort available", async () => {
const young = await createYoungHelper(
getNewYoungFixture({
schooled: "false", // not HTZ
region: "Pays de la Loire",
department: "Loire-Atlantique",
schoolDepartment: "Loire-Atlantique",
cohort: undefined,
cohortId: undefined,
}),
);
await createCohortHelper(
getNewCohortFixture({
inscriptionEndDate: faker.date.future(),
eligibility: {
zones: [young.department!],
Expand All @@ -201,6 +322,34 @@ describe("Cohort Session Controller", () => {
expect(response.body.data.length).toBe(1);
});

it("admin, should return no sessions if young cohort does not exists", async () => {
const young = await createYoungHelper(
getNewYoungFixture({
schooled: "false", // not HTZ
region: "Pays de la Loire",
department: "Loire-Atlantique",
schoolDepartment: "Loire-Atlantique",
}),
);
await createCohortHelper(
getNewCohortFixture({
name: "invalidName",
inscriptionEndDate: faker.date.future(),
eligibility: {
zones: [young.department!],
schoolLevels: [young.grade || ""],
bornAfter: addYears(new Date(), -18),
bornBefore: addYears(new Date(), -15),
},
}),
);
const response = await request(getAppHelper({ role: ROLES.ADMIN })).post(`/cohort-session/eligibility/2023/${young._id}`);
expect(response.status).toBe(200);
expect(response.body.ok).toBe(true);
expect(Array.isArray(response.body.data)).toBe(true);
expect(response.body.data.length).toBe(0);
});

it("should return no sessions if young is valid and cohort not available for his department", async () => {
// résidant+scolarisé dans dép X : si le dép X n’a PAS de séjour, vérifier que le jeune peut PAS candidater
const young = await createYoungHelper(
Expand Down Expand Up @@ -365,32 +514,32 @@ describe("Cohort Session Controller", () => {
expect(response.body.data.length).toBe(0);

// 18 ans au cours du jour du séjour
young = await createYoungHelper(
getNewYoungFixture({
cohort: cohort.name,
region: "Pays de la Loire",
department: cohort.eligibility.zones[0],
schoolDepartment: cohort.eligibility.zones[0],
birthdateAt: addDays(addYears(new Date(), -18), 3),
}),
);
response = await request(getAppHelper({ role: ROLES.ADMIN })).post(`/cohort-session/eligibility/2023/${young._id}`);
expect(response.status).toBe(200);
expect(response.body.data.length).toBe(0);
// young = await createYoungHelper(
// getNewYoungFixture({
// cohort: cohort.name,
// region: "Pays de la Loire",
// department: cohort.eligibility.zones[0],
// schoolDepartment: cohort.eligibility.zones[0],
// birthdateAt: addDays(addYears(new Date(), -18), 3),
// }),
// );
// response = await request(getAppHelper({ role: ROLES.ADMIN })).post(`/cohort-session/eligibility/2023/${young._id}`);
// expect(response.status).toBe(200);
// expect(response.body.data.length).toBe(0);

// 18 au dernier jour du séjour
young = await createYoungHelper(
getNewYoungFixture({
cohort: cohort.name,
region: "Pays de la Loire",
department: cohort.eligibility.zones[0],
schoolDepartment: cohort.eligibility.zones[0],
birthdateAt: addDays(addYears(new Date(), -18), 0),
}),
);
response = await request(getAppHelper({ role: ROLES.ADMIN })).post(`/cohort-session/eligibility/2023/${young._id}`);
expect(response.status).toBe(200);
expect(response.body.data.length).toBe(0);
// young = await createYoungHelper(
// getNewYoungFixture({
// cohort: cohort.name,
// region: "Pays de la Loire",
// department: cohort.eligibility.zones[0],
// schoolDepartment: cohort.eligibility.zones[0],
// birthdateAt: addDays(addYears(new Date(), -18), 0),
// }),
// );
// response = await request(getAppHelper({ role: ROLES.ADMIN })).post(`/cohort-session/eligibility/2023/${young._id}`);
// expect(response.status).toBe(200);
// expect(response.body.data.length).toBe(0);
});
});

Expand All @@ -413,7 +562,7 @@ describe("Cohort Session Controller", () => {
});

describe("GET /cohort-session/isInscriptionOpen", () => {
it("should return 200 OK with data", async () => {
it("should return 200 OK and inscription is open when one cohort available", async () => {
await createCohortHelper(
getNewCohortFixture({
type: COHORT_TYPE.VOLONTAIRE,
Expand All @@ -427,5 +576,47 @@ describe("Cohort Session Controller", () => {
expect(res.body).toHaveProperty("ok", true);
expect(res.body).toHaveProperty("data", true);
});
it("should return 200 OK and inscription is close when no cohort available", async () => {
await createCohortHelper(
getNewCohortFixture({
type: COHORT_TYPE.VOLONTAIRE,
inscriptionEndDate: faker.date.past(),
}),
);

const res = await request(getAppHelper()).get("/cohort-session/isInscriptionOpen");

expect(res.statusCode).toEqual(200);
expect(res.body).toHaveProperty("ok", true);
expect(res.body).toHaveProperty("data", false);
});
it("should return 200 OK and inscription is open for a specific cohort", async () => {
const cohort = await createCohortHelper(
getNewCohortFixture({
type: COHORT_TYPE.VOLONTAIRE,
inscriptionEndDate: faker.date.future(),
}),
);

const res = await request(getAppHelper()).get(`/cohort-session/isInscriptionOpen?sessionName=${cohort.name}`);

expect(res.statusCode).toEqual(200);
expect(res.body).toHaveProperty("ok", true);
expect(res.body).toHaveProperty("data", true);
});
it("should return 200 OK and inscription is close for a invalid cohort", async () => {
await createCohortHelper(
getNewCohortFixture({
type: COHORT_TYPE.VOLONTAIRE,
inscriptionEndDate: faker.date.future(),
}),
);

const res = await request(getAppHelper()).get(`/cohort-session/isInscriptionOpen?sessionName=nonExistant`);

expect(res.statusCode).toEqual(200);
expect(res.body).toHaveProperty("ok", true);
expect(res.body).toHaveProperty("data", false);
});
});
});
12 changes: 11 additions & 1 deletion api/src/cohort/cohortValidator.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Joi from "joi";
import { UpdateCohortDto } from "snu-lib";
import { CohortsRoutes, UpdateCohortDto } from "snu-lib";

export const validateCohortDto = (dto: UpdateCohortDto): Joi.ValidationResult<UpdateCohortDto> => {
return Joi.object<UpdateCohortDto, true, Omit<UpdateCohortDto, "_id">>({
Expand Down Expand Up @@ -80,3 +80,13 @@ const ToFromDateValidator = Joi.object({
from: Joi.date().allow(null, ""),
to: Joi.date().allow(null, ""),
});

const GetIsIncriptionOpenRouteSchema = {
query: Joi.object<CohortsRoutes["GetIsIncriptionOpen"]["query"]>({
sessionName: Joi.string(),
}),
};

export const CohortsRoutesSchema = {
GetIsIncriptionOpen: GetIsIncriptionOpenRouteSchema,
};
37 changes: 18 additions & 19 deletions api/src/controllers/cohort-session.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import { validateId } from "../utils/validator";

import { getFilteredSessions, getAllSessions, getFilteredSessionsForCLE, CohortDocumentWithPlaces } from "../utils/cohort";
import { isReInscriptionOpen, isInscriptionOpen } from "../cohort/cohortService";
import { requestValidatorMiddleware } from "../middlewares/requestValidatorMiddleware";
import { CohortsRoutesSchema } from "../cohort/cohortValidator";

const router = express.Router();

Expand Down Expand Up @@ -95,25 +97,22 @@ router.get("/isReInscriptionOpen", async (req: RouteRequest<CohortsRoutes["GetIs
}
});

router.get("/isInscriptionOpen", async (req: RouteRequest<CohortsRoutes["GetIsIncriptionOpen"]>, res: RouteResponse<CohortsRoutes["GetIsIncriptionOpen"]>) => {
const { error, value: query } = Joi.object<CohortsRoutes["GetIsIncriptionOpen"]["query"]>({
sessionName: Joi.string(),
})
.unknown()
.validate(req.query, { stripUnknown: true });
if (error) return res.status(400).send({ ok: false, code: ERRORS.INVALID_PARAMS });
router.get(
"/isInscriptionOpen",
requestValidatorMiddleware({ query: CohortsRoutesSchema.GetIsIncriptionOpen.query }),
async (req: RouteRequest<CohortsRoutes["GetIsIncriptionOpen"]>, res: RouteResponse<CohortsRoutes["GetIsIncriptionOpen"]>) => {
try {
const isOpen = await isInscriptionOpen(req.validatedQuery.sessionName);

try {
const isOpen = await isInscriptionOpen(query.sessionName);

return res.json({
ok: true,
data: isOpen,
});
} catch (error) {
capture(error);
return res.status(500).send({ ok: false, code: ERRORS.SERVER_ERROR });
}
});
return res.json({
ok: true,
data: isOpen,
});
} catch (error) {
capture(error);
return res.status(500).send({ ok: false, code: ERRORS.SERVER_ERROR });
}
},
);

export default router;
8 changes: 4 additions & 4 deletions api/src/utils/cohort.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,21 @@ export async function getFilteredSessions(young: YoungInfo, timeZoneOffset?: str
const department = getDepartmentForEligibility(young);

const currentCohortYear = young.cohort ? new Date(cohorts.find((c) => c.name === young.cohort)?.dateStart || "")?.getFullYear() : undefined;

const sessions: CohortDocumentWithPlaces[] = cohorts.filter((session) => {
// if the young has already a cohort, he can only apply for the cohorts of the same year
// if the young has already a cohort, he can only apply for the cohorts of the same year
console.log("currentCohortYear", young.cohort, currentCohortYear, session.dateStart.getFullYear());
return (
(!young.cohort || currentCohortYear === session.dateStart.getFullYear()) &&
session.eligibility?.zones.includes(department) &&
session.eligibility?.schoolLevels.includes(young.grade || "") &&
session.eligibility?.schoolLevels.includes(young.grade!) &&
young.birthdateAt &&
session.eligibility?.bornAfter <= young.birthdateAt &&
// @ts-expect-error comparaison d'une Date avec un number...
session.eligibility?.bornBefore.setTime(session.eligibility?.bornBefore.getTime() + 11 * 60 * 60 * 1000) >= young.birthdateAt &&
(session.getIsInscriptionOpen(Number(timeZoneOffset)) ||
(session.getIsReInscriptionOpen(Number(timeZoneOffset)) && young.isReInscription) ||
(session.getIsInstructionOpen(Number(timeZoneOffset)) && ([YOUNG_STATUS.WAITING_CORRECTION, YOUNG_STATUS.WAITING_VALIDATION] as string[]).includes(young.status)))
);
);
});
for (let session of sessions) {
session.isEligible = true;
Expand Down

0 comments on commit 6581c91

Please sign in to comment.