From 28ae0eebadc9f210adbcb5b9c1ed7f247008af7e Mon Sep 17 00:00:00 2001 From: Ludovic Date: Thu, 27 Apr 2023 16:53:51 +0200 Subject: [PATCH 01/14] feat: region tests --- api/__tests__/routes/region.test.ts | 357 ++++++++++++++++++++++++++++ 1 file changed, 357 insertions(+) create mode 100644 api/__tests__/routes/region.test.ts diff --git a/api/__tests__/routes/region.test.ts b/api/__tests__/routes/region.test.ts new file mode 100644 index 000000000..114516bd1 --- /dev/null +++ b/api/__tests__/routes/region.test.ts @@ -0,0 +1,357 @@ +import { describe, test } from "@jest/globals"; +import { AuthenticationLevel, Testrunner } from "../utilities/Testrunner"; +import request from "supertest"; +import app from "../../src/main"; +import { + deleteDatabaseData, + initialiseDatabase, + restoreTables, +} from "../mock/database"; +import { + badRequestResponse, + forbiddenResponse, + notFoundResponse, +} from "../utilities/constants"; + +describe("Region tests", () => { + let runner: Testrunner; + + beforeAll(async () => { + const server = request(app); + runner = new Testrunner(server); + + await deleteDatabaseData(); + await initialiseDatabase(); + + runner.authLevel(AuthenticationLevel.SUPER_STUDENT); + }); + + afterEach(async () => { + await restoreTables("region", "user_region"); + }); + + describe("Succesful requests", () => { + test("POST /region", async () => { + const newRegion = { + name: "new Region", + }; + + const expectedRegion = { + name: "new Region", + deleted: false, + users: [], + }; + + await runner.post({ + url: "/region", + data: newRegion, + expectedResponse: expectedRegion, + }); + }); + + test("GET /region", async () => { + const expected = [ + { + deleted: false, + id: 1, + name: "Region 1", + users: [ + { + id: 1, + region_id: 1, + user: { + address_id: 1, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "student@trottoir.be", + first_name: "Dirk", + id: 1, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Student", + phone: "0123456789", + student: true, + super_student: false, + }, + user_id: 1, + }, + ], + }, + { + deleted: false, + id: 2, + name: "Region 2", + users: [ + { + id: 2, + region_id: 2, + user: { + address_id: 2, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "superstudent@trottoir.be", + first_name: "Toon", + id: 2, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Superstudent", + phone: "9876543210", + student: false, + super_student: true, + }, + user_id: 2, + }, + ], + }, + { deleted: false, id: 3, name: "Region 3", users: [] }, + ]; + + await runner.get({ url: "/region", expectedData: expected }); + }); + + test("GET /region/:id", async () => { + const expected = [ + { id: 3, name: "Region 3", deleted: false, users: [] }, + ]; + + await runner.get({ url: "/region/3", expectedData: expected }); + }); + + test("PATCH /region/:id", async () => { + const newRegion = { + id: 3, + name: "Updated Region 3", + }; + + const expectedRegion = { + id: 3, + name: "Updated Region 3", + deleted: false, + users: [], + }; + + await runner.patch({ + url: "/region/3", + data: newRegion, + expectedResponse: expectedRegion, + }); + }); + + test("DELETE /region/:id", async () => { + await runner.delete({ url: "/region/1" }); + + // verify that the region is truly deleted + const expected = [ + { + deleted: false, + id: 2, + name: "Region 2", + users: [ + { + id: 2, + region_id: 2, + user: { + address_id: 2, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "superstudent@trottoir.be", + first_name: "Toon", + id: 2, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Superstudent", + phone: "9876543210", + student: false, + super_student: true, + }, + user_id: 2, + }, + ], + }, + { deleted: false, id: 3, name: "Region 3", users: [] }, + ]; + await runner.get({ + url: "/region", + expectedData: expected, + }); + }); + + afterAll(() => { + app.close(); + }); + }); + + describe("Unsuccesful requests", () => { + let runner: Testrunner; + beforeAll(async () => { + const server = request(app); + runner = new Testrunner(server); + + await deleteDatabaseData(); + await initialiseDatabase(); + }); + + describe("Must be correctly authorized to use any path", () => { + const newRegion = { + name: "new Region", + }; + + describe("Cannot reach any path without authorisation", () => { + beforeEach(() => { + runner.authLevel(AuthenticationLevel.UNAUTHORIZED); + }); + + test("Cannot reach GET /region", async () => { + await runner.get({ + url: "/region", + expectedData: [forbiddenResponse], + statusCode: 403, + }); + }); + + test("Cannot reach GET /region/:id", async () => { + await runner.get({ + url: "/region/1", + expectedData: [forbiddenResponse], + statusCode: 403, + }); + }); + + test("Cannot reach POST /region", async () => { + await runner.post({ + url: "/region", + data: newRegion, + expectedResponse: forbiddenResponse, + statusCode: 403, + }); + }); + + test("Cannot reach PATCH /region/:id", async () => { + await runner.patch({ + url: "/region/1", + data: newRegion, + expectedResponse: forbiddenResponse, + statusCode: 403, + }); + }); + + test("Cannot reach DELETE /region/:id", async () => { + await runner.delete({ + url: "/region/1", + statusCode: 403, + }); + }); + }); + + describe("Cannot reach any path as a student", () => { + beforeEach(() => { + runner.authLevel(AuthenticationLevel.STUDENT); + }); + + test("Cannot reach GET /region", async () => { + await runner.get({ + url: "/region", + expectedData: [forbiddenResponse], + statusCode: 403, + }); + }); + + test("Cannot reach POST /region", async () => { + await runner.post({ + url: "/region", + data: newRegion, + expectedResponse: forbiddenResponse, + statusCode: 403, + }); + }); + + test("Cannot reach PATCH /region/:id", async () => { + await runner.patch({ + url: "/region/1", + data: newRegion, + expectedResponse: forbiddenResponse, + statusCode: 403, + }); + }); + + test("Cannot reach DELETE /region/:id", async () => { + await runner.delete({ + url: "/region/1", + statusCode: 403, + }); + }); + }); + + describe("The requested path must exist", () => { + beforeEach(() => { + runner.authLevel(AuthenticationLevel.ADMINISTRATOR); + }); + + test("Find a nonexistent region", async () => { + await runner.get({ + url: "/region/0", + expectedData: [notFoundResponse], + statusCode: 404, + }); + }); + + test("Find a nonexistent region", async () => { + await runner.get({ + url: "/region/-1", + expectedData: [notFoundResponse], + statusCode: 404, + }); + }); + + test("Update a nonexistent region", async () => { + await runner.get({ + url: "/region/0", + expectedData: [notFoundResponse], + statusCode: 404, + }); + }); + test("Delete a nonexistent region", async () => { + await runner.delete({ url: "/region/0", statusCode: 404 }); + }); + }); + + describe("The type of region id must be correct", () => { + beforeEach(() => { + runner.authLevel(AuthenticationLevel.ADMINISTRATOR); + }); + + test("GET request", async () => { + await runner.get({ + url: "/region/wrongtype", + expectedData: [badRequestResponse], + statusCode: 400, + }); + }); + + test("PATCH request", async () => { + const newRegion = { + foo: "wrong name Region", + }; + + await runner.patch({ + url: "/region/wrongtype", + data: newRegion, + expectedResponse: badRequestResponse, + statusCode: 400, + }); + }); + + test("DELETE request", async () => { + await runner.delete({ + url: "/region/wrongtype", + statusCode: 400, + }); + }); + }); + }); + + afterAll(() => { + app.close(); + }); + }); +}); From a68aa861e127381ab90617bbdabe0d55b79ebbbb Mon Sep 17 00:00:00 2001 From: Ludovic Date: Wed, 3 May 2023 15:59:28 +0200 Subject: [PATCH 02/14] fix: change test --- api/__tests__/routes/region.test.ts | 76 +++++++++++++++++++++++++++-- 1 file changed, 72 insertions(+), 4 deletions(-) diff --git a/api/__tests__/routes/region.test.ts b/api/__tests__/routes/region.test.ts index 114516bd1..6db3ea57f 100644 --- a/api/__tests__/routes/region.test.ts +++ b/api/__tests__/routes/region.test.ts @@ -176,6 +176,75 @@ describe("Region tests", () => { }); }); + //TODO: fix, voor admin + // test("SOFT DELETE /region/:id", async () => { + // const regionSoft = { + // hardDelete: false, + // }; + // await runner.delete({ url: "/region/3", data: regionSoft }); + + // // verify that the region is truly deleted + // const expected = [ + // { + // deleted: false, + // id: 1, + // name: "Region 1", + // users: [ + // { + // id: 1, + // region_id: 1, + // user: { + // address_id: 1, + // admin: false, + // date_added: "2023-05-04T12:00:00.000Z", + // deleted: false, + // email: "student@trottoir.be", + // first_name: "Dirk", + // id: 1, + // last_login: "2023-05-04T12:00:00.000Z", + // last_name: "De Student", + // phone: "0123456789", + // student: true, + // super_student: false, + // }, + // user_id: 1, + // }, + // ], + // }, + // { + // deleted: false, + // id: 2, + // name: "Region 2", + // users: [ + // { + // id: 2, + // region_id: 2, + // user: { + // address_id: 2, + // admin: false, + // date_added: "2023-05-04T12:00:00.000Z", + // deleted: false, + // email: "superstudent@trottoir.be", + // first_name: "Toon", + // id: 2, + // last_login: "2023-05-04T12:00:00.000Z", + // last_name: "De Superstudent", + // phone: "9876543210", + // student: false, + // super_student: true, + // }, + // user_id: 2, + // }, + // ], + // }, + // { deleted: true, id: 3, name: "Region 3", users: [] }, + // ]; + // await runner.get({ + // url: "/region?deleted=true", + // expectedData: expected, + // }); + // }); + afterAll(() => { app.close(); }); @@ -293,9 +362,7 @@ describe("Region tests", () => { expectedData: [notFoundResponse], statusCode: 404, }); - }); - test("Find a nonexistent region", async () => { await runner.get({ url: "/region/-1", expectedData: [notFoundResponse], @@ -304,9 +371,10 @@ describe("Region tests", () => { }); test("Update a nonexistent region", async () => { - await runner.get({ + await runner.patch({ url: "/region/0", - expectedData: [notFoundResponse], + data: newRegion, + expectedResponse: notFoundResponse, statusCode: 404, }); }); From 285fb98c19badee879b86ea8314666766ef37488 Mon Sep 17 00:00:00 2001 From: Ludovic Date: Wed, 3 May 2023 17:18:35 +0200 Subject: [PATCH 03/14] feat: user_region tests --- api/__tests__/routes/user_region.test.ts | 404 +++++++++++++++++++++++ api/__tests__/utilities/constants.ts | 4 + 2 files changed, 408 insertions(+) create mode 100644 api/__tests__/routes/user_region.test.ts diff --git a/api/__tests__/routes/user_region.test.ts b/api/__tests__/routes/user_region.test.ts new file mode 100644 index 000000000..1b075797a --- /dev/null +++ b/api/__tests__/routes/user_region.test.ts @@ -0,0 +1,404 @@ +import { describe, test } from "@jest/globals"; +import { AuthenticationLevel, Testrunner } from "../utilities/Testrunner"; +import request from "supertest"; +import app from "../../src/main"; +import { + deleteDatabaseData, + initialiseDatabase, + restoreTables, +} from "../mock/database"; +import { + badRequestResponse, + forbiddenResponse, + methodNotAllowedResponse, + notFoundResponse, +} from "../utilities/constants"; + +describe("User_region tests", () => { + let runner: Testrunner; + + beforeAll(async () => { + const server = request(app); + runner = new Testrunner(server); + + await deleteDatabaseData(); + await initialiseDatabase(); + + runner.authLevel(AuthenticationLevel.SUPER_STUDENT); + }); + + afterEach(async () => { + await restoreTables("region", "user_region"); + }); + + describe("Succesful requests", () => { + test("POST /user_region", async () => { + const new_user_region = { + user_id: 1, + region_id: 3, + }; + + const expected = { + region: { deleted: false, id: 3, name: "Region 3" }, + region_id: 3, + user: { + address: { + city: "Sydney", + id: 1, + latitude: -33.865143, + longitude: 151.2099, + number: 42, + street: "Wallaby Way", + zip_code: 2000, + }, + address_id: 1, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "student@trottoir.be", + first_name: "Dirk", + id: 1, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Student", + phone: "0123456789", + student: true, + super_student: false, + }, + user_id: 1, + }; + await runner.post({ + url: "/user_region", + data: new_user_region, + expectedResponse: expected, + }); + + //check if user is added to region + + const expectedRegion = [ + { + deleted: false, + id: 3, + name: "Region 3", + users: [ + { + id: 3, + region_id: 3, + user: { + address_id: 1, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "student@trottoir.be", + first_name: "Dirk", + id: 1, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Student", + phone: "0123456789", + student: true, + super_student: false, + }, + user_id: 1, + }, + ], + }, + ]; + + await runner.get({ + url: "/region/3", + expectedData: expectedRegion, + }); + }); + + test("GET /user_region", async () => { + const expected = [ + { + id: 1, + region: { deleted: false, id: 1, name: "Region 1" }, + region_id: 1, + user: { + address: { + city: "Sydney", + id: 1, + latitude: -33.865143, + longitude: 151.2099, + number: 42, + street: "Wallaby Way", + zip_code: 2000, + }, + address_id: 1, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "student@trottoir.be", + first_name: "Dirk", + id: 1, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Student", + phone: "0123456789", + student: true, + super_student: false, + }, + user_id: 1, + }, + { + id: 2, + region: { deleted: false, id: 2, name: "Region 2" }, + region_id: 2, + user: { + address: { + city: "Ghent", + id: 2, + latitude: 51.04732, + longitude: 3.7282, + number: 25, + street: "Sint-Pietersnieuwstraat", + zip_code: 9000, + }, + address_id: 2, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "superstudent@trottoir.be", + first_name: "Toon", + id: 2, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Superstudent", + phone: "9876543210", + student: false, + super_student: true, + }, + user_id: 2, + }, + ]; + + await runner.get({ url: "/user_region", expectedData: expected }); + }); + + test("GET /user_region/:id", async () => { + const expected = [ + { + id: 1, + region: { deleted: false, id: 1, name: "Region 1" }, + region_id: 1, + user: { + address: { + city: "Sydney", + id: 1, + latitude: -33.865143, + longitude: 151.2099, + number: 42, + street: "Wallaby Way", + zip_code: 2000, + }, + address_id: 1, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "student@trottoir.be", + first_name: "Dirk", + id: 1, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Student", + phone: "0123456789", + student: true, + super_student: false, + }, + user_id: 1, + }, + ]; + + await runner.get({ url: "/user_region/1", expectedData: expected }); + }); + + test("DELETE /user_region/:id", async () => { + await runner.delete({ url: "/user_region/1" }); + + // verify that the user_region is truly deleted + const expected = [ + { + id: 2, + region: { deleted: false, id: 2, name: "Region 2" }, + region_id: 2, + user: { + address: { + city: "Ghent", + id: 2, + latitude: 51.04732, + longitude: 3.7282, + number: 25, + street: "Sint-Pietersnieuwstraat", + zip_code: 9000, + }, + address_id: 2, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "superstudent@trottoir.be", + first_name: "Toon", + id: 2, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Superstudent", + phone: "9876543210", + student: false, + super_student: true, + }, + user_id: 2, + }, + ]; + await runner.get({ + url: "/user_region", + expectedData: expected, + }); + }); + + afterAll(() => { + app.close(); + }); + }); + + describe("Unsuccesful requests", () => { + let runner: Testrunner; + beforeAll(async () => { + const server = request(app); + runner = new Testrunner(server); + + await deleteDatabaseData(); + await initialiseDatabase(); + }); + + describe("Must be correctly authorized to use any path", () => { + const new_user_region = { + user_id: 1, + region_id: 3, + }; + + describe("Cannot reach any path without authorisation", () => { + beforeEach(() => { + runner.authLevel(AuthenticationLevel.UNAUTHORIZED); + }); + + test("Cannot reach GET /user_region", async () => { + await runner.get({ + url: "/user_region", + expectedData: [forbiddenResponse], + statusCode: 403, + }); + }); + + test("Cannot reach GET /user_region/:id", async () => { + await runner.get({ + url: "/user_region/1", + expectedData: [forbiddenResponse], + statusCode: 403, + }); + }); + + test("Cannot reach POST /user_region", async () => { + await runner.post({ + url: "/user_region", + data: new_user_region, + expectedResponse: forbiddenResponse, + statusCode: 403, + }); + }); + + test("Cannot reach DELETE /user_region/:id", async () => { + await runner.delete({ + url: "/user_region/1", + statusCode: 403, + }); + }); + }); + describe("Cannot reach any path as a student", () => { + beforeEach(() => { + runner.authLevel(AuthenticationLevel.STUDENT); + }); + + test("Cannot reach GET /user_region", async () => { + await runner.get({ + url: "/user_region", + expectedData: [forbiddenResponse], + statusCode: 403, + }); + }); + + test("Cannot reach POST /user_region", async () => { + await runner.post({ + url: "/user_region", + data: new_user_region, + expectedResponse: forbiddenResponse, + statusCode: 403, + }); + }); + + test("Cannot reach DELETE /user_region/:id", async () => { + await runner.delete({ + url: "/user_region/1", + statusCode: 403, + }); + }); + }); + }); + describe("The requested path must exist", () => { + beforeEach(() => { + runner.authLevel(AuthenticationLevel.ADMINISTRATOR); + }); + + test("Find a nonexistent user_region", async () => { + await runner.get({ + url: "/user_region/0", + expectedData: [notFoundResponse], + statusCode: 404, + }); + }); + + test("Delete a nonexistent user_region", async () => { + await runner.delete({ url: "/user_region/0", statusCode: 404 }); + }); + }); + describe("The type of user_region id must be correct", () => { + beforeEach(() => { + runner.authLevel(AuthenticationLevel.ADMINISTRATOR); + }); + + test("GET request", async () => { + await runner.get({ + url: "/user_region/wrongtype", + expectedData: [badRequestResponse], + statusCode: 400, + }); + }); + + test("DELETE request", async () => { + await runner.delete({ + url: "/user_region/wrongtype", + statusCode: 400, + }); + }); + }); + + describe("Method has to be allowed", () => { + beforeEach(() => { + runner.authLevel(AuthenticationLevel.ADMINISTRATOR); + }); + + test("PATCH /user_region/:id", async () => { + const new_user_region = { + user_id: 1, + region_id: 2, + }; + + await runner.patch({ + url: "/user_region/1", + data: new_user_region, + expectedResponse: methodNotAllowedResponse, + statusCode: 405, + }); + }); + }); + + afterAll(() => { + app.close(); + }); + }); +}); diff --git a/api/__tests__/utilities/constants.ts b/api/__tests__/utilities/constants.ts index 5f4bec655..cd32d4915 100644 --- a/api/__tests__/utilities/constants.ts +++ b/api/__tests__/utilities/constants.ts @@ -25,3 +25,7 @@ export const badRequestForeignKey = { message: "Bad Request", detail: "Foreign key constraint failed", }; + +export const methodNotAllowedResponse = { + message: "Method not allowed", +}; From f6f3d86ff014e7f7b9aaf7c227a6ec7449984de2 Mon Sep 17 00:00:00 2001 From: Ludovic Date: Thu, 4 May 2023 13:30:09 +0200 Subject: [PATCH 04/14] fix: tsc --- api/__tests__/routes/region.test.ts | 131 ++++++++++++----------- api/__tests__/routes/user_region.test.ts | 2 +- 2 files changed, 69 insertions(+), 64 deletions(-) diff --git a/api/__tests__/routes/region.test.ts b/api/__tests__/routes/region.test.ts index 6db3ea57f..572fc28dc 100644 --- a/api/__tests__/routes/region.test.ts +++ b/api/__tests__/routes/region.test.ts @@ -27,7 +27,7 @@ describe("Region tests", () => { }); afterEach(async () => { - await restoreTables("region", "user_region"); + await restoreTables(); }); describe("Succesful requests", () => { @@ -176,72 +176,77 @@ describe("Region tests", () => { }); }); - //TODO: fix, voor admin - // test("SOFT DELETE /region/:id", async () => { - // const regionSoft = { - // hardDelete: false, - // }; - // await runner.delete({ url: "/region/3", data: regionSoft }); - - // // verify that the region is truly deleted - // const expected = [ - // { - // deleted: false, - // id: 1, - // name: "Region 1", - // users: [ - // { - // id: 1, - // region_id: 1, - // user: { - // address_id: 1, - // admin: false, - // date_added: "2023-05-04T12:00:00.000Z", - // deleted: false, - // email: "student@trottoir.be", - // first_name: "Dirk", + // describe("Routes for admin", () => { + // beforeEach(() => { + // runner.authLevel(AuthenticationLevel.ADMINISTRATOR); + // }); + + // test("SOFT DELETE /region/:id", async () => { + // const regionSoft = { + // hardDelete:false, + // }; + // await runner.delete({ url: "/region/3", data: regionSoft }); + + // // verify that the region is truly soft deleted + // const expected = [ + // { + // deleted: false, + // id: 1, + // name: "Region 1", + // users: [ + // { // id: 1, - // last_login: "2023-05-04T12:00:00.000Z", - // last_name: "De Student", - // phone: "0123456789", - // student: true, - // super_student: false, + // region_id: 1, + // user: { + // address_id: 1, + // admin: false, + // date_added: "2023-05-04T12:00:00.000Z", + // deleted: false, + // email: "student@trottoir.be", + // first_name: "Dirk", + // id: 1, + // last_login: "2023-05-04T12:00:00.000Z", + // last_name: "De Student", + // phone: "0123456789", + // student: true, + // super_student: false, + // }, + // user_id: 1, // }, - // user_id: 1, - // }, - // ], - // }, - // { - // deleted: false, - // id: 2, - // name: "Region 2", - // users: [ - // { - // id: 2, - // region_id: 2, - // user: { - // address_id: 2, - // admin: false, - // date_added: "2023-05-04T12:00:00.000Z", - // deleted: false, - // email: "superstudent@trottoir.be", - // first_name: "Toon", + // ], + // }, + // { + // deleted: false, + // id: 2, + // name: "Region 2", + // users: [ + // { // id: 2, - // last_login: "2023-05-04T12:00:00.000Z", - // last_name: "De Superstudent", - // phone: "9876543210", - // student: false, - // super_student: true, + // region_id: 2, + // user: { + // address_id: 2, + // admin: false, + // date_added: "2023-05-04T12:00:00.000Z", + // deleted: false, + // email: "superstudent@trottoir.be", + // first_name: "Toon", + // id: 2, + // last_login: "2023-05-04T12:00:00.000Z", + // last_name: "De Superstudent", + // phone: "9876543210", + // student: false, + // super_student: true, + // }, + // user_id: 2, // }, - // user_id: 2, - // }, - // ], - // }, - // { deleted: true, id: 3, name: "Region 3", users: [] }, - // ]; - // await runner.get({ - // url: "/region?deleted=true", - // expectedData: expected, + // ], + // }, + // { deleted: true, id: 3, name: "Region 3", users: [] }, + // ]; + // await runner.get({ + // url: "/region?deleted=true", + // expectedData: expected, + // }); // }); // }); diff --git a/api/__tests__/routes/user_region.test.ts b/api/__tests__/routes/user_region.test.ts index 1b075797a..61075ad5f 100644 --- a/api/__tests__/routes/user_region.test.ts +++ b/api/__tests__/routes/user_region.test.ts @@ -28,7 +28,7 @@ describe("User_region tests", () => { }); afterEach(async () => { - await restoreTables("region", "user_region"); + await restoreTables(); }); describe("Succesful requests", () => { From 35e7edbdfea9cf807b531f9eac31e1347d1a490a Mon Sep 17 00:00:00 2001 From: Ludovic Date: Fri, 5 May 2023 11:25:56 +0200 Subject: [PATCH 05/14] feat: soft delete --- api/__tests__/routes/region.test.ts | 148 ++++++++++++++-------------- api/src/routes/region.ts | 21 +++- 2 files changed, 90 insertions(+), 79 deletions(-) diff --git a/api/__tests__/routes/region.test.ts b/api/__tests__/routes/region.test.ts index 572fc28dc..b6c60b85e 100644 --- a/api/__tests__/routes/region.test.ts +++ b/api/__tests__/routes/region.test.ts @@ -27,7 +27,7 @@ describe("Region tests", () => { }); afterEach(async () => { - await restoreTables(); + await restoreTables("region", "user_region"); }); describe("Succesful requests", () => { @@ -176,79 +176,79 @@ describe("Region tests", () => { }); }); - // describe("Routes for admin", () => { - // beforeEach(() => { - // runner.authLevel(AuthenticationLevel.ADMINISTRATOR); - // }); - - // test("SOFT DELETE /region/:id", async () => { - // const regionSoft = { - // hardDelete:false, - // }; - // await runner.delete({ url: "/region/3", data: regionSoft }); - - // // verify that the region is truly soft deleted - // const expected = [ - // { - // deleted: false, - // id: 1, - // name: "Region 1", - // users: [ - // { - // id: 1, - // region_id: 1, - // user: { - // address_id: 1, - // admin: false, - // date_added: "2023-05-04T12:00:00.000Z", - // deleted: false, - // email: "student@trottoir.be", - // first_name: "Dirk", - // id: 1, - // last_login: "2023-05-04T12:00:00.000Z", - // last_name: "De Student", - // phone: "0123456789", - // student: true, - // super_student: false, - // }, - // user_id: 1, - // }, - // ], - // }, - // { - // deleted: false, - // id: 2, - // name: "Region 2", - // users: [ - // { - // id: 2, - // region_id: 2, - // user: { - // address_id: 2, - // admin: false, - // date_added: "2023-05-04T12:00:00.000Z", - // deleted: false, - // email: "superstudent@trottoir.be", - // first_name: "Toon", - // id: 2, - // last_login: "2023-05-04T12:00:00.000Z", - // last_name: "De Superstudent", - // phone: "9876543210", - // student: false, - // super_student: true, - // }, - // user_id: 2, - // }, - // ], - // }, - // { deleted: true, id: 3, name: "Region 3", users: [] }, - // ]; - // await runner.get({ - // url: "/region?deleted=true", - // expectedData: expected, - // }); - // }); - // }); + describe("path for admin", () => { + beforeEach(() => { + runner.authLevel(AuthenticationLevel.ADMINISTRATOR); + }); + + test("SOFT DELETE /region/:id", async () => { + const regionSoft = { + hardDelete: false, + }; + await runner.delete({ url: "/region/3", data: regionSoft }); + + // verify that the region is truly soft deleted + const expected = [ + { + deleted: false, + id: 1, + name: "Region 1", + users: [ + { + id: 1, + region_id: 1, + user: { + address_id: 1, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "student@trottoir.be", + first_name: "Dirk", + id: 1, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Student", + phone: "0123456789", + student: true, + super_student: false, + }, + user_id: 1, + }, + ], + }, + { + deleted: false, + id: 2, + name: "Region 2", + users: [ + { + id: 2, + region_id: 2, + user: { + address_id: 2, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "superstudent@trottoir.be", + first_name: "Toon", + id: 2, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Superstudent", + phone: "9876543210", + student: false, + super_student: true, + }, + user_id: 2, + }, + ], + }, + { deleted: true, id: 3, name: "Region 3", users: [] }, + ]; + await runner.get({ + url: "/region?deleted=true", + expectedData: expected, + }); + }); + }); afterAll(() => { app.close(); diff --git a/api/src/routes/region.ts b/api/src/routes/region.ts index 4f0fba97b..9db4665c6 100644 --- a/api/src/routes/region.ts +++ b/api/src/routes/region.ts @@ -77,11 +77,22 @@ export class RegionRouting extends Routing { @Auth.authorization({ superStudent: true }) async deleteOne(req: CustomRequest, res: express.Response) { - await prisma.region.delete({ - where: { - id: Parser.number(req.params["id"]), - }, - }); + if (Parser.bool(req.body["hardDelete"], false)) { + await prisma.region.delete({ + where: { + id: Parser.number(req.params["id"]), + }, + }); + } else { + await prisma.region.update({ + data: { + deleted: true, + }, + where: { + id: Parser.number(req.params["id"]), + }, + }); + } return res.status(200).json({}); } From 90ddfc0c4cf5354a05dcede71e8db765fb50c023 Mon Sep 17 00:00:00 2001 From: Ludovic Date: Fri, 5 May 2023 11:30:23 +0200 Subject: [PATCH 06/14] fix: tsc --- api/__tests__/routes/region.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/__tests__/routes/region.test.ts b/api/__tests__/routes/region.test.ts index b6c60b85e..21f1df9b0 100644 --- a/api/__tests__/routes/region.test.ts +++ b/api/__tests__/routes/region.test.ts @@ -27,7 +27,7 @@ describe("Region tests", () => { }); afterEach(async () => { - await restoreTables("region", "user_region"); + await restoreTables(); }); describe("Succesful requests", () => { From e33185d0b3051a671c6618f990603cbefc1bd259 Mon Sep 17 00:00:00 2001 From: Ludovic Date: Fri, 5 May 2023 11:35:38 +0200 Subject: [PATCH 07/14] chore: afterall --- api/__tests__/routes/region.test.ts | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/api/__tests__/routes/region.test.ts b/api/__tests__/routes/region.test.ts index 21f1df9b0..d7a6762fd 100644 --- a/api/__tests__/routes/region.test.ts +++ b/api/__tests__/routes/region.test.ts @@ -249,10 +249,6 @@ describe("Region tests", () => { }); }); }); - - afterAll(() => { - app.close(); - }); }); describe("Unsuccesful requests", () => { @@ -422,9 +418,9 @@ describe("Region tests", () => { }); }); }); + }); - afterAll(() => { - app.close(); - }); + afterAll(() => { + app.close(); }); }); From a48a9d3c3599c44ef9f13748cbcf23dc075fe0f7 Mon Sep 17 00:00:00 2001 From: Ludovic Date: Fri, 5 May 2023 19:31:15 +0200 Subject: [PATCH 08/14] chore: describe wegdoen --- api/__tests__/routes/region.test.ts | 127 +++++++++++++--------------- 1 file changed, 61 insertions(+), 66 deletions(-) diff --git a/api/__tests__/routes/region.test.ts b/api/__tests__/routes/region.test.ts index d7a6762fd..9426adceb 100644 --- a/api/__tests__/routes/region.test.ts +++ b/api/__tests__/routes/region.test.ts @@ -176,77 +176,72 @@ describe("Region tests", () => { }); }); - describe("path for admin", () => { - beforeEach(() => { - runner.authLevel(AuthenticationLevel.ADMINISTRATOR); - }); + test("SOFT DELETE /region/:id", async () => { + runner.authLevel(AuthenticationLevel.ADMINISTRATOR); + const regionSoft = { + hardDelete: false, + }; + await runner.delete({ url: "/region/3", data: regionSoft }); - test("SOFT DELETE /region/:id", async () => { - const regionSoft = { - hardDelete: false, - }; - await runner.delete({ url: "/region/3", data: regionSoft }); - - // verify that the region is truly soft deleted - const expected = [ - { - deleted: false, - id: 1, - name: "Region 1", - users: [ - { + // verify that the region is truly soft deleted + const expected = [ + { + deleted: false, + id: 1, + name: "Region 1", + users: [ + { + id: 1, + region_id: 1, + user: { + address_id: 1, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "student@trottoir.be", + first_name: "Dirk", id: 1, - region_id: 1, - user: { - address_id: 1, - admin: false, - date_added: "2023-05-04T12:00:00.000Z", - deleted: false, - email: "student@trottoir.be", - first_name: "Dirk", - id: 1, - last_login: "2023-05-04T12:00:00.000Z", - last_name: "De Student", - phone: "0123456789", - student: true, - super_student: false, - }, - user_id: 1, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Student", + phone: "0123456789", + student: true, + super_student: false, }, - ], - }, - { - deleted: false, - id: 2, - name: "Region 2", - users: [ - { + user_id: 1, + }, + ], + }, + { + deleted: false, + id: 2, + name: "Region 2", + users: [ + { + id: 2, + region_id: 2, + user: { + address_id: 2, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "superstudent@trottoir.be", + first_name: "Toon", id: 2, - region_id: 2, - user: { - address_id: 2, - admin: false, - date_added: "2023-05-04T12:00:00.000Z", - deleted: false, - email: "superstudent@trottoir.be", - first_name: "Toon", - id: 2, - last_login: "2023-05-04T12:00:00.000Z", - last_name: "De Superstudent", - phone: "9876543210", - student: false, - super_student: true, - }, - user_id: 2, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Superstudent", + phone: "9876543210", + student: false, + super_student: true, }, - ], - }, - { deleted: true, id: 3, name: "Region 3", users: [] }, - ]; - await runner.get({ - url: "/region?deleted=true", - expectedData: expected, - }); + user_id: 2, + }, + ], + }, + { deleted: true, id: 3, name: "Region 3", users: [] }, + ]; + await runner.get({ + url: "/region?deleted=true", + expectedData: expected, }); }); }); From 153f3313e1c78b2132d9246c1177eea083c1d3fb Mon Sep 17 00:00:00 2001 From: Ludovic Date: Fri, 5 May 2023 19:32:53 +0200 Subject: [PATCH 09/14] feat: add patch test student --- api/__tests__/routes/user_region.test.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/api/__tests__/routes/user_region.test.ts b/api/__tests__/routes/user_region.test.ts index 61075ad5f..1eab75d5e 100644 --- a/api/__tests__/routes/user_region.test.ts +++ b/api/__tests__/routes/user_region.test.ts @@ -337,6 +337,15 @@ describe("User_region tests", () => { statusCode: 403, }); }); + + test("Cannot reach PATCH /user_region/:id", async () => { + await runner.patch({ + url: "/user_region/1", + data: new_user_region, + expectedResponse: methodNotAllowedResponse, + statusCode: 405, + }); + }); }); }); describe("The requested path must exist", () => { From 96b58e106ed51c428f68328c3e0cc95220a63f5f Mon Sep 17 00:00:00 2001 From: Jozef Jankaj Date: Wed, 10 May 2023 11:57:00 +0200 Subject: [PATCH 10/14] Update validators, add deleted field to region All validators have been updated to correctly refer to the id in params, using the correct celebrate syntax --- api/__tests__/routes/region.test.ts | 12 +--- api/__tests__/routes/user_region.test.ts | 7 +- api/src/routes/region.ts | 8 ++- api/src/validators/action.validator.ts | 22 +++--- api/src/validators/address.validator.ts | 32 +++++---- api/src/validators/building.validator.ts | 36 +++++----- api/src/validators/garbage.validator.ts | 26 ++++--- api/src/validators/mailtemplate.validator.ts | 26 ++++--- api/src/validators/progress.validator.ts | 68 +++++++++++-------- api/src/validators/region.validator.ts | 25 ++++--- api/src/validators/round.validator.ts | 22 +++--- .../validators/round_building.validator.ts | 24 ++++--- api/src/validators/schedule.validator.ts | 30 ++++---- api/src/validators/syndicus.validator.ts | 22 +++--- api/src/validators/user.validator.ts | 46 +++++++------ 15 files changed, 231 insertions(+), 175 deletions(-) diff --git a/api/__tests__/routes/region.test.ts b/api/__tests__/routes/region.test.ts index 9426adceb..54a67aaec 100644 --- a/api/__tests__/routes/region.test.ts +++ b/api/__tests__/routes/region.test.ts @@ -354,13 +354,7 @@ describe("Region tests", () => { test("Find a nonexistent region", async () => { await runner.get({ - url: "/region/0", - expectedData: [notFoundResponse], - statusCode: 404, - }); - - await runner.get({ - url: "/region/-1", + url: "/region/50", expectedData: [notFoundResponse], statusCode: 404, }); @@ -368,14 +362,14 @@ describe("Region tests", () => { test("Update a nonexistent region", async () => { await runner.patch({ - url: "/region/0", + url: "/region/50", data: newRegion, expectedResponse: notFoundResponse, statusCode: 404, }); }); test("Delete a nonexistent region", async () => { - await runner.delete({ url: "/region/0", statusCode: 404 }); + await runner.delete({ url: "/region/50", statusCode: 404 }); }); }); diff --git a/api/__tests__/routes/user_region.test.ts b/api/__tests__/routes/user_region.test.ts index 1eab75d5e..6f6b3cc81 100644 --- a/api/__tests__/routes/user_region.test.ts +++ b/api/__tests__/routes/user_region.test.ts @@ -355,14 +355,17 @@ describe("User_region tests", () => { test("Find a nonexistent user_region", async () => { await runner.get({ - url: "/user_region/0", + url: "/user_region/50", expectedData: [notFoundResponse], statusCode: 404, }); }); test("Delete a nonexistent user_region", async () => { - await runner.delete({ url: "/user_region/0", statusCode: 404 }); + await runner.delete({ + url: "/user_region/50", + statusCode: 404, + }); }); }); describe("The type of user_region id must be correct", () => { diff --git a/api/src/routes/region.ts b/api/src/routes/region.ts index 84f6dfd4f..c66a28b0b 100644 --- a/api/src/routes/region.ts +++ b/api/src/routes/region.ts @@ -4,9 +4,9 @@ import { Parser } from "../parser"; import { prisma } from "../prisma"; import { Auth } from "../auth/auth"; import { Prisma } from "@selab-2/groep-1-orm"; -import RegionInclude = Prisma.RegionInclude; import { RegionValidator } from "../validators/region.validator"; import { Validator } from "../validators/validator"; +import RegionInclude = Prisma.RegionInclude; export class RegionRouting extends Routing { private static includes: RegionInclude = { @@ -19,6 +19,11 @@ export class RegionRouting extends Routing { @Auth.authorization({ superStudent: true }) async getAll(req: CustomRequest, res: express.Response) { + let deleted: boolean | undefined = false; + if (req.user?.admin && Parser.bool(req.query["deleted"], false)) { + deleted = undefined; + } + const result = await prisma.region.findMany({ take: Parser.number(req.query["take"], 1024), skip: Parser.number(req.query["skip"], 0), @@ -32,6 +37,7 @@ export class RegionRouting extends Routing { }, } : {}, + deleted: deleted, }, include: RegionRouting.includes, }); diff --git a/api/src/validators/action.validator.ts b/api/src/validators/action.validator.ts index 3080bd2a0..e28f9e06c 100644 --- a/api/src/validators/action.validator.ts +++ b/api/src/validators/action.validator.ts @@ -26,15 +26,19 @@ export class ActionValidator extends Validator { } updateOneValidator() { - return celebrate({ - params: Joi.object({ - id: Joi.number().positive().required(), - }), - body: Joi.object({ - id: Joi.ref("params.id"), - description: Joi.string().trim().min(1), - }), - }); + return celebrate( + { + params: Joi.object({ + id: Joi.number().positive().required(), + }), + body: Joi.object({ + id: Joi.ref("$params.id"), + description: Joi.string().trim().min(1), + }), + }, + undefined, + { reqContext: true }, + ); } createOneValidator() { diff --git a/api/src/validators/address.validator.ts b/api/src/validators/address.validator.ts index 9ec3636dc..9969504f8 100644 --- a/api/src/validators/address.validator.ts +++ b/api/src/validators/address.validator.ts @@ -26,20 +26,24 @@ export class AddressValidator extends Validator { } updateOneValidator() { - return celebrate({ - params: Joi.object({ - id: Joi.number().positive().required(), - }), - body: Joi.object({ - id: Joi.ref("params.id"), - street: Joi.string().min(1), - city: Joi.string().min(1), - zip_code: Joi.number().positive(), - number: Joi.number().positive(), - longitude: Joi.number().min(-180).max(180), - latitude: Joi.number().min(-90).max(90), - }), - }); + return celebrate( + { + params: Joi.object({ + id: Joi.number().positive().required(), + }), + body: Joi.object({ + id: Joi.ref("$params.id"), + street: Joi.string().min(1), + city: Joi.string().min(1), + zip_code: Joi.number().positive(), + number: Joi.number().positive(), + longitude: Joi.number().min(-180).max(180), + latitude: Joi.number().min(-90).max(90), + }), + }, + undefined, + { reqContext: true }, + ); } deleteOneValidator() { diff --git a/api/src/validators/building.validator.ts b/api/src/validators/building.validator.ts index f218cd9f9..7aa412810 100644 --- a/api/src/validators/building.validator.ts +++ b/api/src/validators/building.validator.ts @@ -44,22 +44,26 @@ export class BuildingValidator extends Validator { } updateOneValidator() { - return celebrate({ - params: Joi.object({ - id: Joi.number().positive().required(), - }), - body: Joi.object({ - id: Joi.ref("params.id"), - name: Joi.string().min(1), - ivago_id: Joi.string().min(1), - address_id: Joi.number().positive(), - manual_id: Joi.number().positive(), - syndicus_id: Joi.number().positive(), - deleted: Joi.bool(), - hash: Joi.string().forbidden(), - expected_time: Joi.number().positive(), - }), - }); + return celebrate( + { + params: Joi.object({ + id: Joi.number().positive().required(), + }), + body: Joi.object({ + id: Joi.ref("$params.id"), + name: Joi.string().min(1), + ivago_id: Joi.string().min(1), + address_id: Joi.number().positive(), + manual_id: Joi.number().positive(), + syndicus_id: Joi.number().positive(), + deleted: Joi.bool(), + hash: Joi.string().forbidden(), + expected_time: Joi.number().positive(), + }), + }, + undefined, + { reqContext: true }, + ); } deleteOneValidator() { diff --git a/api/src/validators/garbage.validator.ts b/api/src/validators/garbage.validator.ts index e651d1968..ee95f5ff7 100644 --- a/api/src/validators/garbage.validator.ts +++ b/api/src/validators/garbage.validator.ts @@ -40,17 +40,21 @@ export class GarbageValidator extends Validator { } updateOneValidator(): express.RequestHandler { - return celebrate({ - params: Joi.object({ - id: Joi.number().positive().required(), - }), - body: Joi.object({ - id: Joi.ref("params.id"), - pickup_time: Joi.date().iso(), - action_id: Joi.number().positive(), - building_id: Joi.number().positive(), - }), - }); + return celebrate( + { + params: Joi.object({ + id: Joi.number().positive().required(), + }), + body: Joi.object({ + id: Joi.ref("$params.id"), + pickup_time: Joi.date().iso(), + action_id: Joi.number().positive(), + building_id: Joi.number().positive(), + }), + }, + undefined, + { reqContext: true }, + ); } deleteOneValidator(): express.RequestHandler { diff --git a/api/src/validators/mailtemplate.validator.ts b/api/src/validators/mailtemplate.validator.ts index 8f2b7e8dc..9154ec5d5 100644 --- a/api/src/validators/mailtemplate.validator.ts +++ b/api/src/validators/mailtemplate.validator.ts @@ -34,17 +34,21 @@ export class MailTemplateValidator extends Validator { } updateOneValidator() { - return celebrate({ - params: Joi.object({ - id: Joi.number().positive().required(), - }), - body: Joi.object({ - id: Joi.ref("params.id"), - name: Joi.string().trim().min(1), - mail_subject: Joi.string().trim().min(1), - content: Joi.string().trim().min(1), - }), - }); + return celebrate( + { + params: Joi.object({ + id: Joi.number().positive().required(), + }), + body: Joi.object({ + id: Joi.ref("$params.id"), + name: Joi.string().trim().min(1), + mail_subject: Joi.string().trim().min(1), + content: Joi.string().trim().min(1), + }), + }, + undefined, + { reqContext: true }, + ); } deleteOneValidator() { diff --git a/api/src/validators/progress.validator.ts b/api/src/validators/progress.validator.ts index 7ace0b2bf..62f3d546e 100644 --- a/api/src/validators/progress.validator.ts +++ b/api/src/validators/progress.validator.ts @@ -33,7 +33,7 @@ export class ProgressValidator extends Validator { createOneValidator() { return celebrate({ body: Joi.object({ - report: Joi.string().trim().min(1).required(), + report: Joi.string().trim().required(), arrival: Joi.date().iso(), departure: Joi.date().iso(), building_id: Joi.number().positive().required(), @@ -44,20 +44,24 @@ export class ProgressValidator extends Validator { } updateOneValidator() { - return celebrate({ - params: Joi.object({ - id: Joi.number().positive().required(), - }), - body: Joi.object({ - id: Joi.ref("params.id"), - report: Joi.string().trim(), - arrival: Joi.date().iso(), - departure: Joi.date().iso(), - building_id: Joi.number().positive(), - schedule_id: Joi.number().positive(), - deleted: Joi.bool(), - }), - }); + return celebrate( + { + params: Joi.object({ + id: Joi.number().positive().required(), + }), + body: Joi.object({ + id: Joi.ref("$params.id"), + report: Joi.string().trim(), + arrival: Joi.date().iso(), + departure: Joi.date().iso(), + building_id: Joi.number().positive(), + schedule_id: Joi.number().positive(), + deleted: Joi.bool(), + }), + }, + undefined, + { reqContext: true }, + ); } deleteOneValidator() { @@ -99,21 +103,25 @@ export class ProgressImageValidator extends Validator { } updateOneValidator() { - return celebrate({ - params: Joi.object({ - id: Joi.number().positive().required(), - image_id: Joi.number().positive().required(), - }), - body: Joi.object({ - id: Joi.forbidden(), - type: Joi.string() - .trim() - .valid("ARRIVAL", "DEPARTURE", "GARBAGE"), - description: Joi.string().trim().min(1), - image_id: Joi.number().positive(), - progress_id: Joi.number().positive(), - }), - }); + return celebrate( + { + params: Joi.object({ + id: Joi.number().positive().required(), + image_id: Joi.number().positive().required(), + }), + body: Joi.object({ + id: Joi.ref("$params.id"), + type: Joi.string() + .trim() + .valid("ARRIVAL", "DEPARTURE", "GARBAGE"), + description: Joi.string().trim().min(1), + image_id: Joi.number().positive(), + progress_id: Joi.number().positive(), + }), + }, + undefined, + { reqContext: true }, + ); } deleteOneValidator() { diff --git a/api/src/validators/region.validator.ts b/api/src/validators/region.validator.ts index 7388f6bda..236a9688b 100644 --- a/api/src/validators/region.validator.ts +++ b/api/src/validators/region.validator.ts @@ -1,5 +1,5 @@ import { Validator } from "./validator"; -import { celebrate } from "celebrate"; +import { celebrate, Segments } from "celebrate"; import Joi from "joi"; export class RegionValidator extends Validator { @@ -10,6 +10,7 @@ export class RegionValidator extends Validator { skip: Joi.number(), name: Joi.string().trim().min(1), user_id: Joi.number(), + deleted: Joi.bool(), }), }); } @@ -31,15 +32,19 @@ export class RegionValidator extends Validator { } updateOneValidator() { - return celebrate({ - params: Joi.object({ - id: Joi.number().positive().required(), - }), - body: Joi.object({ - id: Joi.ref("params.id"), - name: Joi.string().min(1).required(), - }), - }); + return celebrate( + { + params: Joi.object({ + id: Joi.number().positive().required(), + }), + body: Joi.object({ + id: Joi.ref("$params.id"), + name: Joi.string().min(1).required(), + }), + }, + undefined, + { reqContext: true }, + ); } deleteOneValidator() { diff --git a/api/src/validators/round.validator.ts b/api/src/validators/round.validator.ts index d873b5913..ccce0923c 100644 --- a/api/src/validators/round.validator.ts +++ b/api/src/validators/round.validator.ts @@ -32,15 +32,19 @@ export class RoundValidator extends Validator { } updateOneValidator() { - return celebrate({ - params: Joi.object({ - id: Joi.number().positive().required(), - }), - body: Joi.object({ - id: Joi.ref("params.id"), - name: Joi.string().trim().min(1), - }), - }); + return celebrate( + { + params: Joi.object({ + id: Joi.number().positive().required(), + }), + body: Joi.object({ + id: Joi.ref("$params.id"), + name: Joi.string().trim().min(1), + }), + }, + undefined, + { reqContext: true }, + ); } deleteOneValidator() { diff --git a/api/src/validators/round_building.validator.ts b/api/src/validators/round_building.validator.ts index 8722f456b..7b702a9c1 100644 --- a/api/src/validators/round_building.validator.ts +++ b/api/src/validators/round_building.validator.ts @@ -37,16 +37,20 @@ export class RoundBuildingValidator extends Validator { } updateOneValidator() { - return celebrate({ - params: Joi.object({ - id: Joi.number().positive().required(), - }), - body: Joi.object({ - id: Joi.ref("params.id"), - round_id: Joi.number().positive(), - building_id: Joi.number().positive(), - }), - }); + return celebrate( + { + params: Joi.object({ + id: Joi.number().positive().required(), + }), + body: Joi.object({ + id: Joi.ref("$params.id"), + round_id: Joi.number().positive(), + building_id: Joi.number().positive(), + }), + }, + undefined, + { reqContext: true }, + ); } deleteOneValidator() { diff --git a/api/src/validators/schedule.validator.ts b/api/src/validators/schedule.validator.ts index a0fd81a32..4a4aa705a 100644 --- a/api/src/validators/schedule.validator.ts +++ b/api/src/validators/schedule.validator.ts @@ -46,20 +46,24 @@ export class ScheduleValidator extends Validator { } updateOneValidator() { - return celebrate({ - params: Joi.object({ - id: Joi.number().positive().required(), - }), + return celebrate( + { + params: Joi.object({ + id: Joi.number().positive().required(), + }), - body: Joi.object({ - id: Joi.ref("params.id"), - day: Joi.date().iso(), - user_id: Joi.number().positive(), - round_id: Joi.number().positive(), - start: Joi.string().isoDate(), - end: Joi.string().isoDate(), - }), - }); + body: Joi.object({ + id: Joi.ref("$params.id"), + day: Joi.date().iso(), + user_id: Joi.number().positive(), + round_id: Joi.number().positive(), + start: Joi.string().isoDate(), + end: Joi.string().isoDate(), + }), + }, + undefined, + { reqContext: true }, + ); } deleteOneValidator() { diff --git a/api/src/validators/syndicus.validator.ts b/api/src/validators/syndicus.validator.ts index 4f3634ee3..4daba6090 100644 --- a/api/src/validators/syndicus.validator.ts +++ b/api/src/validators/syndicus.validator.ts @@ -38,16 +38,20 @@ export class SyndicusValidator extends Validator { } updateOneValidator() { - return celebrate({ - params: Joi.object({ - id: Joi.number().positive().required(), - }), + return celebrate( + { + params: Joi.object({ + id: Joi.number().positive().required(), + }), - body: Joi.object({ - id: Joi.ref("params.id"), - user_id: Joi.number().positive(), - }), - }); + body: Joi.object({ + id: Joi.ref("$params.id"), + user_id: Joi.number().positive(), + }), + }, + undefined, + { reqContext: true }, + ); } deleteOneValidator() { diff --git a/api/src/validators/user.validator.ts b/api/src/validators/user.validator.ts index f422c3ea3..b4e582e49 100644 --- a/api/src/validators/user.validator.ts +++ b/api/src/validators/user.validator.ts @@ -72,28 +72,32 @@ export class UserValidator extends Validator { } updateOneValidator() { - return celebrate({ - params: Joi.object({ - id: Joi.number().positive().required(), - }), - body: { - id: Joi.ref("params.id"), - email: Joi.string().email(), - first_name: Joi.string().min(1), - last_name: Joi.string().min(1), - date_added: Joi.date(), - last_login: Joi.date().less(Joi.ref("date_added")), - phone: Joi.string() - .min(1) - // accept a potential + sign at the beginning of the number and at least 1 digit - .regex(/^\\+?d\\+$/), - address_id: Joi.number().positive(), - student: Joi.boolean(), - super_student: Joi.boolean(), - admin: Joi.boolean(), - password: Joi.string().min(1), + return celebrate( + { + params: Joi.object({ + id: Joi.number().positive().required(), + }), + body: { + id: Joi.ref("$params.id"), + email: Joi.string().email(), + first_name: Joi.string().min(1), + last_name: Joi.string().min(1), + date_added: Joi.date(), + last_login: Joi.date().less(Joi.ref("date_added")), + phone: Joi.string() + .min(1) + // accept a potential + sign at the beginning of the number and at least 1 digit + .regex(/^\\+?d\\+$/), + address_id: Joi.number().positive(), + student: Joi.boolean(), + super_student: Joi.boolean(), + admin: Joi.boolean(), + password: Joi.string().min(1), + }, }, - }); + undefined, + { reqContext: true }, + ); } deleteOneValidator() { From ad1ccad4a3e531f6d3d5079805f13677dec866b1 Mon Sep 17 00:00:00 2001 From: Ludovic Date: Wed, 10 May 2023 15:04:46 +0200 Subject: [PATCH 11/14] chore:region, update delete test --- api/__tests__/routes/region.test.ts | 75 ++++++++++++++++++++++++++--- 1 file changed, 69 insertions(+), 6 deletions(-) diff --git a/api/__tests__/routes/region.test.ts b/api/__tests__/routes/region.test.ts index 54a67aaec..3f37d4e3c 100644 --- a/api/__tests__/routes/region.test.ts +++ b/api/__tests__/routes/region.test.ts @@ -138,10 +138,37 @@ describe("Region tests", () => { }); test("DELETE /region/:id", async () => { + runner.authLevel(AuthenticationLevel.ADMINISTRATOR); await runner.delete({ url: "/region/1" }); - // verify that the region is truly deleted + // verify that the region is soft truly deleted (admin) const expected = [ + { + deleted: true, + id: 1, + name: "Region 1", + users: [ + { + id: 1, + region_id: 1, + user: { + address_id: 1, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "student@trottoir.be", + first_name: "Dirk", + id: 1, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Student", + phone: "0123456789", + student: true, + super_student: false, + }, + user_id: 1, + }, + ], + }, { deleted: false, id: 2, @@ -171,19 +198,56 @@ describe("Region tests", () => { { deleted: false, id: 3, name: "Region 3", users: [] }, ]; await runner.get({ - url: "/region", + url: "/region?deleted=true", expectedData: expected, }); + + runner.authLevel(AuthenticationLevel.SUPER_STUDENT); + // verify that the region is soft truly deleted (superstudent) + const expectedSuperStudent = [ + { + deleted: false, + id: 2, + name: "Region 2", + users: [ + { + id: 2, + region_id: 2, + user: { + address_id: 2, + admin: false, + date_added: "2023-05-04T12:00:00.000Z", + deleted: false, + email: "superstudent@trottoir.be", + first_name: "Toon", + id: 2, + last_login: "2023-05-04T12:00:00.000Z", + last_name: "De Superstudent", + phone: "9876543210", + student: false, + super_student: true, + }, + user_id: 2, + }, + ], + }, + { deleted: false, id: 3, name: "Region 3", users: [] }, + ]; + await runner.get({ + url: "/region", + expectedData: expectedSuperStudent, + }); + }); - test("SOFT DELETE /region/:id", async () => { + test("DELETE /region/:id", async () => { runner.authLevel(AuthenticationLevel.ADMINISTRATOR); const regionSoft = { - hardDelete: false, + hardDelete: true, }; await runner.delete({ url: "/region/3", data: regionSoft }); - // verify that the region is truly soft deleted + // verify that the region is truly deleted const expected = [ { deleted: false, @@ -237,7 +301,6 @@ describe("Region tests", () => { }, ], }, - { deleted: true, id: 3, name: "Region 3", users: [] }, ]; await runner.get({ url: "/region?deleted=true", From e32b6aa2bdf4a798c8624141d502b6f43ad43935 Mon Sep 17 00:00:00 2001 From: Ludovic Date: Wed, 10 May 2023 15:09:29 +0200 Subject: [PATCH 12/14] fix: afterAll --- api/__tests__/routes/region.test.ts | 1 - api/__tests__/routes/user_region.test.ts | 10 +++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/api/__tests__/routes/region.test.ts b/api/__tests__/routes/region.test.ts index 3f37d4e3c..71e7df973 100644 --- a/api/__tests__/routes/region.test.ts +++ b/api/__tests__/routes/region.test.ts @@ -237,7 +237,6 @@ describe("Region tests", () => { url: "/region", expectedData: expectedSuperStudent, }); - }); test("DELETE /region/:id", async () => { diff --git a/api/__tests__/routes/user_region.test.ts b/api/__tests__/routes/user_region.test.ts index 6f6b3cc81..52b90f2b2 100644 --- a/api/__tests__/routes/user_region.test.ts +++ b/api/__tests__/routes/user_region.test.ts @@ -250,10 +250,6 @@ describe("User_region tests", () => { expectedData: expected, }); }); - - afterAll(() => { - app.close(); - }); }); describe("Unsuccesful requests", () => { @@ -408,9 +404,9 @@ describe("User_region tests", () => { }); }); }); + }); - afterAll(() => { - app.close(); - }); + afterAll(() => { + app.close(); }); }); From 020173d76ee8ba7521db29ced3988568be0e91af Mon Sep 17 00:00:00 2001 From: Ludovic Date: Wed, 10 May 2023 15:15:59 +0200 Subject: [PATCH 13/14] chore: rename var --- api/__tests__/routes/region.test.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/api/__tests__/routes/region.test.ts b/api/__tests__/routes/region.test.ts index 71e7df973..3e4d07cb5 100644 --- a/api/__tests__/routes/region.test.ts +++ b/api/__tests__/routes/region.test.ts @@ -137,11 +137,11 @@ describe("Region tests", () => { }); }); - test("DELETE /region/:id", async () => { + test("SOFT DELETE /region/:id", async () => { runner.authLevel(AuthenticationLevel.ADMINISTRATOR); await runner.delete({ url: "/region/1" }); - // verify that the region is soft truly deleted (admin) + // verify that the region is soft deleted (admin) const expected = [ { deleted: true, From b64529a408d267beced82d6741ff5e276f8092f3 Mon Sep 17 00:00:00 2001 From: Ludovic Date: Wed, 10 May 2023 15:18:09 +0200 Subject: [PATCH 14/14] chore: rename var --- api/__tests__/routes/region.test.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/api/__tests__/routes/region.test.ts b/api/__tests__/routes/region.test.ts index 3e4d07cb5..b5eb797ea 100644 --- a/api/__tests__/routes/region.test.ts +++ b/api/__tests__/routes/region.test.ts @@ -203,7 +203,7 @@ describe("Region tests", () => { }); runner.authLevel(AuthenticationLevel.SUPER_STUDENT); - // verify that the region is soft truly deleted (superstudent) + // verify that the region is soft deleted (superstudent) const expectedSuperStudent = [ { deleted: false, @@ -241,10 +241,10 @@ describe("Region tests", () => { test("DELETE /region/:id", async () => { runner.authLevel(AuthenticationLevel.ADMINISTRATOR); - const regionSoft = { + const regionHard = { hardDelete: true, }; - await runner.delete({ url: "/region/3", data: regionSoft }); + await runner.delete({ url: "/region/3", data: regionHard }); // verify that the region is truly deleted const expected = [