From 1e2cafef1dc7cbbaf8f78c3d3d21fb6435b115f6 Mon Sep 17 00:00:00 2001 From: Ivymaster Date: Mon, 8 Jun 2026 12:26:43 +0200 Subject: [PATCH] Add API tests for tempus event creation feature --- .../specs/api/tempus/tempus.collisions.cy.js | 367 +++++++++++++++++- 1 file changed, 360 insertions(+), 7 deletions(-) diff --git a/tests/cypress/cypress/e2e/specs/api/tempus/tempus.collisions.cy.js b/tests/cypress/cypress/e2e/specs/api/tempus/tempus.collisions.cy.js index 2ca091e1b..38c44a645 100644 --- a/tests/cypress/cypress/e2e/specs/api/tempus/tempus.collisions.cy.js +++ b/tests/cypress/cypress/e2e/specs/api/tempus/tempus.collisions.cy.js @@ -1,5 +1,37 @@ const KALENDER_API = "/index.ci.php/api/frontend/v1/tempus"; +const getStudyPlansTree = () => + cy + .request({ + method: "GET", + url: `/index.ci.php/api/frontend/v1/lv/StgTree`, + }) + .then((response) => { + expect(response.status).to.eq(200); + expect(response.body).to.have.nested.property("meta.status", "success"); + expect(response.body.data).to.be.an("array"); + + return response.body.data; + }); + +const getCoursesByStudyPlan = (studyPlanId, semesterShortCode) => + cy + .request({ + method: "GET", + url: `/index.ci.php/api/frontend/v1/tempus/coursepicker/getByStg`, + qs: { + stg: studyPlanId, + studiensemester_kurzbz: semesterShortCode, + }, + }) + .then((response) => { + expect(response.status).to.eq(200); + expect(response.body).to.have.nested.property("meta.status", "success"); + expect(response.body.data).to.be.an("array"); + + return response.body.data; + }); + const getPlannerEvents = (startDate, endDate) => cy .request({ @@ -18,6 +50,18 @@ const getPlannerEvents = (startDate, endDate) => return response.body.data; }); +const createKalenderEvent = (lehreinheitId, startDateTime, endDateTime) => + cy.request({ + method: "POST", + url: `${KALENDER_API}/Kalender/addKalenderEvent`, + body: { + lehreinheit_id: lehreinheitId, + start_date: startDateTime, + end_date: endDateTime, + }, + failOnStatusCode: false, + }); + const updateKalenderEvent = (kalenderId, startDateTime, endDateTime) => cy.request({ method: "POST", @@ -52,9 +96,277 @@ describe("Tempus Kalender API", () => { cy.login(); }); + it("event creation works for non collision case", () => { + getStudyPlansTree().then((stgTree) => { + let studyPlan = stgTree.find( + (plan) => plan.name === "BIF (BIF) - Informatik/Computer Science", + ); + expect(studyPlan, "study plan for test event creation").to.exist; + + getCoursesByStudyPlan(studyPlan.studiengang_kz, "SS2026").then( + (courses) => { + let course = courses.find( + (course) => + course.lehrfach === "KREKO" && + course.lektoren.some((lector) => lector.kurzbz === "BoehmTh"), + ); + expect(course, "course for test event creation").to.exist; + + updateSettingsData(getSettingsData()).then((response) => { + getPlannerEvents("2026-06-08", "2026-06-08").then((events) => { + const lehreinheitId = course.unr; + expect(lehreinheitId, "lehreinheit id for test event creation").to + .exist; + + const startDateTime = `2026-06-08 18:35`; + const endDateTime = `2026-06-08 19:20`; + + createKalenderEvent( + lehreinheitId, + startDateTime, + endDateTime, + ).then((response) => { + console.log(response); + expect(response.status).to.eq(200); + expect(response.body).to.have.nested.property( + "meta.status", + "success", + ); + }); + }); + }); + }, + ); + }); + }); + + it("prohibited event creation due to zeitsperre collision", () => { + getStudyPlansTree().then((stgTree) => { + let studyPlan = stgTree.find( + (plan) => plan.name === "BMB (BMB) - Maschinenbau", + ); + expect(studyPlan, "study plan for test event creation").to.exist; + + getCoursesByStudyPlan(studyPlan.studiengang_kz, "SS2026").then( + (courses) => { + let course = courses.find( + (course) => + course.lehrfach === "ETMB" && + course.lektoren.some((lector) => lector.kurzbz === "CarralSa"), + ); + expect(course, "course for test event creation").to.exist; + + updateSettingsData(getSettingsData()).then((response) => { + getPlannerEvents("2026-06-08", "2026-06-08").then((events) => { + const lehreinheitId = course.unr; + expect(lehreinheitId, "lehreinheit id for test event creation").to + .exist; + + const startDateTime = `2026-06-08 18:35`; + const endDateTime = `2026-06-08 19:20`; + + createKalenderEvent( + lehreinheitId, + startDateTime, + endDateTime, + ).then((response) => { + console.log(response.body.errors); + expect(response.status).to.eq(500); + expect(response.body).to.have.nested.property( + "meta.status", + "error", + ); + expect(response.body.errors).to.be.an("array"); + + let hasTimeLockCollisionError = response.body.errors.some( + (error) => + error.message + .toLowerCase() + .includes("zeitsperre kollision") || + error.message.toLowerCase().includes("time lock collision"), + ); + expect( + hasTimeLockCollisionError, + "response contains time lock collision error", + ).to.be.true; + }); + }); + }); + }, + ); + }); + }); + + it("prohibited event creation due to student collision", () => { + getStudyPlansTree().then((stgTree) => { + let studyPlan = stgTree.find( + (plan) => plan.name === "BMB (BMB) - Maschinenbau", + ); + expect(studyPlan, "study plan for test event creation").to.exist; + + getCoursesByStudyPlan(studyPlan.studiengang_kz, "SS2026").then( + (courses) => { + let course = courses.find( + (course) => + course.lehrfach === "DYN2" && + course.lektoren.some((lector) => lector.kurzbz === "Froeh N"), + ); + expect(course, "course for test event creation").to.exist; + + updateSettingsData(getSettingsData()).then((response) => { + getPlannerEvents("2026-06-08", "2026-06-08").then((events) => { + const lehreinheitId = course.unr; + expect(lehreinheitId, "lehreinheit id for test event creation").to + .exist; + + const startDateTime = `2026-06-08 18:35`; + const endDateTime = `2026-06-08 19:20`; + + createKalenderEvent( + lehreinheitId, + startDateTime, + endDateTime, + ).then((response) => { + console.log(response.body.errors); + expect(response.status).to.eq(500); + expect(response.body).to.have.nested.property( + "meta.status", + "error", + ); + expect(response.body.errors).to.be.an("array"); + let hasStudentCollisionError = response.body.errors.some( + (error) => + error.message.toLowerCase().includes("verband kollision") || + error.message.toLowerCase().includes("student collision"), + ); + expect( + hasStudentCollisionError, + "response contains student collision error", + ).to.be.true; + }); + }); + }); + }, + ); + }); + }); + + it("prohibited event creation due to direct student collision", () => { + let settingsData = getSettingsData(); + settingsData.kollision_student = true; + + getStudyPlansTree().then((stgTree) => { + let studyPlan = stgTree.find( + (plan) => plan.name === "BMB (BMB) - Maschinenbau", + ); + expect(studyPlan, "study plan for test event creation").to.exist; + + getCoursesByStudyPlan(studyPlan.studiengang_kz, "SS2026").then( + (courses) => { + let course = courses.find( + (course) => + course.lehrfach === "DYN2" && + course.lektoren.some((lector) => lector.kurzbz === "Froeh N"), + ); + expect(course, "course for test event creation").to.exist; + + updateSettingsData(settingsData).then((response) => { + getPlannerEvents("2026-06-08", "2026-06-08").then((events) => { + const lehreinheitId = course.unr; + expect(lehreinheitId, "lehreinheit id for test event creation").to + .exist; + + const startDateTime = `2026-06-08 18:35`; + const endDateTime = `2026-06-08 19:20`; + + createKalenderEvent( + lehreinheitId, + startDateTime, + endDateTime, + ).then((response) => { + console.log(response.body.errors); + expect(response.status).to.eq(500); + expect(response.body).to.have.nested.property( + "meta.status", + "error", + ); + expect(response.body.errors).to.be.an("array"); + let hasStudentCollisionError = response.body.errors.some( + (error) => + error.message + .toLowerCase() + .includes("studierende kollision") || + error.message.toLowerCase().includes("student collision"), + ); + expect( + hasStudentCollisionError, + "response contains student collision error", + ).to.be.true; + }); + }); + }); + }, + ); + }); + }); + + it("prohibited event creation due to lector collision", () => { + getStudyPlansTree().then((stgTree) => { + let studyPlan = stgTree.find( + (plan) => plan.name === "BMR (BMR) - Mechatronik/Robotik", + ); + expect(studyPlan, "study plan for test event creation").to.exist; + + getCoursesByStudyPlan(studyPlan.studiengang_kz, "SS2026").then( + (courses) => { + let course = courses.find( + (course) => + course.lehrfach === "IROBO" && + course.lektoren.some((lector) => lector.kurzbz === "StujaKe"), + ); + expect(course, "course for test event creation").to.exist; + + updateSettingsData(getSettingsData()).then((response) => { + getPlannerEvents("2026-06-08", "2026-06-08").then((events) => { + const lehreinheitId = course.unr; + expect(lehreinheitId, "lehreinheit id for test event creation").to + .exist; + + const startDateTime = `2026-06-08 18:35`; + const endDateTime = `2026-06-08 19:20`; + + createKalenderEvent( + lehreinheitId, + startDateTime, + endDateTime, + ).then((response) => { + console.log(response.body.errors); + expect(response.status).to.eq(500); + expect(response.body).to.have.nested.property( + "meta.status", + "error", + ); + expect(response.body.errors).to.be.an("array"); + let hasStudentCollisionError = response.body.errors.some( + (error) => + error.message.toLowerCase().includes("verband kollision") || + error.message.toLowerCase().includes("student collision"), + ); + expect( + hasStudentCollisionError, + "response contains student collision error", + ).to.be.true; + }); + }); + }); + }, + ); + }); + }); + it("event update works for non collision case", () => { updateSettingsData(getSettingsData()).then((response) => { - getPlannerEvents("2026-06-02", "2026-06-02").then((events) => { + getPlannerEvents("2026-06-09", "2026-06-09").then((events) => { const sourceEvent = events.find( (event) => event.type === "lehreinheit" && @@ -85,7 +397,7 @@ describe("Tempus Kalender API", () => { it("prohibited event update due to room collision", () => { updateSettingsData(getSettingsData()).then((response) => { - getPlannerEvents("2026-06-01", "2026-06-01").then((events) => { + getPlannerEvents("2026-06-08", "2026-06-08").then((events) => { const sourceEvent = events.find( (event) => event.type === "lehreinheit" && @@ -124,12 +436,53 @@ describe("Tempus Kalender API", () => { }); }); + it("prohibited event update due to student collision", () => { + updateSettingsData(getSettingsData()).then((response) => { + getPlannerEvents("2026-06-08", "2026-06-08").then((events) => { + const sourceEvent = events.find( + (event) => + event.type === "lehreinheit" && + event.beginn === "19:30:00" && + event.ende === "20:15:00" && + event.organisationseinheit === "kfMathematik", + ); + expect( + sourceEvent, + "source event with fixed time and room for collision test", + ).to.exist; + + const startDateTime = `${sourceEvent.datum} 20:15`; + const endDateTime = `${sourceEvent.datum} 21:00`; + + updateKalenderEvent( + sourceEvent.kalender_id, + startDateTime, + endDateTime, + ).then((response) => { + expect(response.status).to.eq(500); + expect(response.body).to.have.nested.property("meta.status", "error"); + expect(response.body.errors).to.be.an("array"); + console.log(response.body.errors); + let hasStudentCollisionError = response.body.errors.some( + (error) => + error.message.toLowerCase().includes("verband kollision") || + error.message.toLowerCase().includes("student collision"), + ); + expect( + hasStudentCollisionError, + "response contains student collision error", + ).to.be.true; + }); + }); + }); + }); + it("prohibited event update due to student collision", () => { let settingsData = getSettingsData(); settingsData.kollision_student = true; updateSettingsData(settingsData).then((response) => { - getPlannerEvents("2026-06-01", "2026-06-01").then((events) => { + getPlannerEvents("2026-06-08", "2026-06-08").then((events) => { const sourceEvent = events.find( (event) => event.type === "lehreinheit" && @@ -173,7 +526,7 @@ describe("Tempus Kalender API", () => { settingsData.kollision_student = false; updateSettingsData(settingsData).then((response) => { - getPlannerEvents("2026-06-02", "2026-06-02").then((events) => { + getPlannerEvents("2026-06-09", "2026-06-09").then((events) => { console.log(events); const sourceEvent = events.find( (event) => @@ -218,7 +571,7 @@ describe("Tempus Kalender API", () => { settingsData.kollision_student = false; updateSettingsData(settingsData).then((response) => { - getPlannerEvents("2026-06-01", "2026-06-01").then((events) => { + getPlannerEvents("2026-06-08", "2026-06-08").then((events) => { const sourceEvent = events.find( (event) => event.type === "lehreinheit" && @@ -262,7 +615,7 @@ describe("Tempus Kalender API", () => { settingsData.kollision_student = false; updateSettingsData(settingsData).then((response) => { - getPlannerEvents("2026-06-01", "2026-06-01").then((events) => { + getPlannerEvents("2026-06-08", "2026-06-08").then((events) => { const sourceEvent = events.find( (event) => event.type === "lehreinheit" && @@ -306,7 +659,7 @@ describe("Tempus Kalender API", () => { settingsData.kollision_student = false; updateSettingsData(settingsData).then((response) => { - getPlannerEvents("2026-06-01", "2026-06-01").then((events) => { + getPlannerEvents("2026-06-08", "2026-06-08").then((events) => { const sourceEvent = events.find( (event) => event.type === "reservierung" &&