REST Service for POPCORN - ILIAS
alex
6 hours ago 6138ffe99d016cc311f250bc1555b5403b8b1216
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
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 () {
 
   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")
   })
 
})
 
/////////////////////////////////////////////////////////////////////////