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")
|
})
|
|
})
|
|
/////////////////////////////////////////////////////////////////////////
|