From 6138ffe99d016cc311f250bc1555b5403b8b1216 Mon Sep 17 00:00:00 2001
From: alex <alex@alexloehr.net>
Date: Thu, 08 Oct 2026 17:18:04 +0000
Subject: [PATCH] GS-2555

---
 test/testSetStatus.js |  134 ++++++++++++++++++++++++++++++++++++++++----
 1 files changed, 121 insertions(+), 13 deletions(-)

diff --git a/test/testSetStatus.js b/test/testSetStatus.js
index dcd47da..1b4fb3e 100644
--- a/test/testSetStatus.js
+++ b/test/testSetStatus.js
@@ -1,34 +1,142 @@
 const expect = require("chai").expect
+const mysql = require("mysql2/promise")
 
 const db = require("../lib/db")
 const testData = require("./data")
+const {host, port, user: dbUser, database, password} = require("../settings").db
 
 /////////////////////////////////////////////////////////////////////////
 
+const {obj_id: courseId, usr_id: userId} = testData.setStatus
+
 describe("the function setStatus", function () {
 
-   const kurs = testData.kurs // TODO
-   const user = testData.user
-
-   // TODO make generic
-   let kursId = 32212
-   let userId = 31793
-   const status = 2
-   const passed = 1
+   let conn = null
+   let original = null
+   let testValues = null
 
    beforeEach(async function () {
-      // TODO add kurs, add User
+      conn = await mysql.createConnection({host, port, database, user: dbUser, password})
+
+      // snapshot the current values (source of truth)
+      const [lp] = await conn.query(
+         `SELECT status, status_changed FROM ${database}.ut_lp_marks WHERE usr_id = ? AND obj_id = ?`,
+         [userId, courseId]
+      )
+      const [om] = await conn.query(
+         `SELECT passed FROM ${database}.obj_members WHERE usr_id = ? AND obj_id = ?`,
+         [userId, courseId]
+      )
+      expect(lp, "ut_lp_marks row must exist").to.have.lengthOf(1)
+      expect(om, "obj_members row must exist").to.have.lengthOf(1)
+
+      original = {
+         status: lp[0].status,
+         status_changed: lp[0].status_changed,
+         passed: om[0].passed,
+      }
+
+      // pick values that are guaranteed to differ from the original ones
+      testValues = {
+         status: original.status === 2 ? 1 : 2,
+         passed: original.passed === 1 ? 0 : 1,
+      }
+
+      this.testStart = new Date()
    })
 
    afterEach(async function () {
-      // TODO delete kurs, delete user
+      // restore the exact original values, including status_changed
+      await conn.query(
+         `UPDATE ${database}.ut_lp_marks SET status = ?, status_changed = ? WHERE usr_id = ? AND obj_id = ?`,
+         [original.status, original.status_changed, userId, courseId]
+      )
+      await conn.query(
+         `UPDATE ${database}.obj_members SET passed = ? WHERE usr_id = ? AND obj_id = ?`,
+         [original.passed, userId, courseId]
+      )
+      await conn.end()
    })
 
-   it("should set status and passed for a kurs TN", async function () {
-      const res = await db.setStatus(kursId, userId, passed, status)
-      console.dir(res, {depth: null})
+   it("should set status, passed and status_changed for a kurs TN", async function () {
+      const {status, passed} = testValues
+      const res = await db.setStatus(courseId, userId, passed, status)
+      expect(res).to.have.property("status").and.to.equal("ok")
+
+      // read back directly from the DB
+      const [[lp]] = await conn.query(
+         `SELECT status, status_changed FROM ${database}.ut_lp_marks WHERE usr_id = ? AND obj_id = ?`,
+         [userId, courseId]
+      )
+      const [[om]] = await conn.query(
+         `SELECT passed FROM ${database}.obj_members WHERE usr_id = ? AND obj_id = ?`,
+         [userId, courseId]
+      )
+
+      expect(lp.status).to.equal(status)
+      expect(om.passed).to.equal(passed)
+
+      const changed = new Date(lp.status_changed)
+      expect(changed.getTime()).to.be.at.least(this.testStart.getTime() - 1000)
+      expect(changed.getTime()).to.be.above(new Date(original.status_changed).getTime())
+   })
+
+   it("should be idempotent when called twice with the same values", async function () {
+      const {status, passed} = testValues
+      const res1 = await db.setStatus(courseId, userId, passed, status)
+      const res2 = await db.setStatus(courseId, userId, passed, status)
+      expect(res1).to.have.property("status").and.to.equal("ok")
+      expect(res2).to.have.property("status").and.to.equal("ok")
+
+      const [[lp]] = await conn.query(
+         `SELECT status FROM ${database}.ut_lp_marks WHERE usr_id = ? AND obj_id = ?`,
+         [userId, courseId]
+      )
+      const [[om]] = await conn.query(
+         `SELECT passed FROM ${database}.obj_members WHERE usr_id = ? AND obj_id = ?`,
+         [userId, courseId]
+      )
+      expect(lp.status).to.equal(status)
+      expect(om.passed).to.equal(passed)
+   })
+
+   it("should reject for a non-existent (user, course) pair", async function () {
+      const missingUserId = 999999999
+      let err = null
+      try {
+         await db.setStatus(courseId, missingUserId, 1, 2)
+      } catch (ex) {
+         err = ex
+      }
+      expect(err, "expected setStatus to throw").to.not.equal(null)
+      expect(err).to.have.property("status").and.to.equal("error")
+      expect(err).to.have.nested.property("reason.affectedRows1").and.to.equal(0)
+      expect(err).to.have.nested.property("reason.affectedRows2").and.to.equal(0)
+   })
+
+   it("should reject for a non-existent course", async function () {
+      const missingCourseId = 999999999
+      let err = null
+      try {
+         await db.setStatus(missingCourseId, userId, 1, 2)
+      } catch (ex) {
+         err = ex
+      }
+      expect(err, "expected setStatus to throw").to.not.equal(null)
+      expect(err).to.have.property("status").and.to.equal("error")
+      expect(err).to.have.nested.property("reason.affectedRows1").and.to.equal(0)
+      expect(err).to.have.nested.property("reason.affectedRows2").and.to.equal(0)
+   })
+
+   it("should succeed even when passed keeps its current value", async function () {
+      // status is changed (status_changed always updates), passed stays the same;
+      // this DB counts matched rows, so the update still reports affectedRows = 1
+      const status = testValues.status
+      const passed = original.passed
+      const res = await db.setStatus(courseId, userId, passed, status)
       expect(res).to.have.property("status").and.to.equal("ok")
    })
 
 })
 
+/////////////////////////////////////////////////////////////////////////

--
Gitblit v1.8.0