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 () { let conn = null let original = null let testValues = null beforeEach(async function () { 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 () { // 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, 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") }) }) /////////////////////////////////////////////////////////////////////////