Skip to content

Commit 3197a8c

Browse files
authored
Merge pull request #230 from DFEAGILEDEVOPS/feature/pupils-not-taking-check-tests
Feature/pupils not taking check tests
2 parents 4ed74e7 + 0adf8db commit 3197a8c

12 files changed

+278
-57
lines changed

admin/controllers/school.js

+6-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@ const mongoose = require('mongoose')
55

66
const Pupil = require('../models/pupil')
77
const School = require('../models/school')
8-
const AttendanceCode = require('../models/attendance-code')
98
const randomGenerator = require('../lib/random-generator')
109
const ValidationError = require('../lib/validation-error')
1110
const errorConverter = require('../lib/error-converter')
@@ -22,7 +21,9 @@ const {
2221
formatPupilsWithReasons,
2322
sortPupilsByLastName,
2423
sortPupilsByReason } = require('../services/pupils-not-taking-check.service')
25-
const { fetchPupilsWithReasons } = require('../services/data-access/pupils-not-taking-check.data.service')
24+
const {
25+
fetchPupilsWithReasons,
26+
getAttendanceCodes } = require('../services/data-access/pupils-not-taking-check.data.service')
2627
const dateService = require('../services/date.service')
2728
const { sortRecords } = require('../utils')
2829

@@ -372,7 +373,7 @@ const getPupilNotTakingCheck = async (req, res, next) => {
372373

373374
// Get attendance code index
374375
try {
375-
attendanceCodes = await AttendanceCode.getAttendanceCodes().exec()
376+
attendanceCodes = await getAttendanceCodes()
376377
} catch (error) {
377378
return next(error)
378379
}
@@ -417,7 +418,7 @@ const getSelectPupilNotTakingCheck = async (req, res, next) => {
417418

418419
// Get attendance code index
419420
try {
420-
attendanceCodes = await AttendanceCode.getAttendanceCodes().exec()
421+
attendanceCodes = await getAttendanceCodes()
421422
} catch (error) {
422423
return next(error)
423424
}
@@ -496,7 +497,7 @@ const savePupilNotTakingCheck = async (req, res, next) => {
496497

497498
// Get attendance code index
498499
try {
499-
attendanceCodes = await AttendanceCode.getAttendanceCodes().exec()
500+
attendanceCodes = await getAttendanceCodes()
500501
} catch (error) {
501502
return next(error)
502503
}

admin/models/attendance-code.js

-10
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,4 @@ const AttendanceCode = new Schema({
1616
}
1717
}, {timestamps: true})
1818

19-
AttendanceCode.statics.getAttendanceCodes = function () {
20-
let attendanceCodes
21-
try {
22-
attendanceCodes = this.find()
23-
} catch (error) {
24-
console.log('ERROR getting attendance codes', error)
25-
}
26-
return attendanceCodes
27-
}
28-
2919
module.exports = mongoose.model('AttendanceCode', AttendanceCode)

admin/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@
4444
"gulp-sass": "^3.1.0",
4545
"gulp-standard": "^10.1.1",
4646
"gulp-uglify": "^3.0.0",
47-
"helmet": "^3.8.2",
47+
"helmet": "^3.9.0",
4848
"iconv-lite": "^0.4.19",
4949
"jsonwebtoken": "^7.4.3",
5050
"migrate-mongo": "^2.2.1",

admin/services/data-access/pupils-not-taking-check.data.service.js

+9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'use strict'
22

33
const Pupil = require('../../models/pupil')
4+
const AttendanceCode = require('../../models/attendance-code')
45
const pupilsNotTakingCheckDataService = {}
56

67
/**
@@ -16,4 +17,12 @@ pupilsNotTakingCheckDataService.fetchPupilsWithReasons = async (schoolId) => {
1617
return pupilsWithReasons
1718
}
1819

20+
pupilsNotTakingCheckDataService.getAttendanceCodes = async () => {
21+
let attendanceCodes
22+
attendanceCodes = await AttendanceCode
23+
.find()
24+
.sort('order')
25+
return attendanceCodes
26+
}
27+
1928
module.exports = pupilsNotTakingCheckDataService

admin/spec/controllers/school.spec.js

+136-4
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,147 @@
33

44
const mongoose = require('mongoose')
55
mongoose.Promomise = global.Promise
6+
67
const sinon = require('sinon')
78
require('sinon-mongoose')
8-
const proxyquire = require('proxyquire').noCallThru()
9+
10+
const proxyquire = require('proxyquire')
911
const httpMocks = require('node-mocks-http')
10-
const School = require('../../models/school')
12+
1113
const Pupil = require('../../models/pupil')
12-
const pupilValidator = require('../../lib/validator/pupil-validator')
13-
const ValidationError = require('../../lib/validation-error')
14+
15+
const pupilService = require('../../services/pupil.service')
16+
const pupilsNotTakingCheckService = require('../../services/pupils-not-taking-check.service')
17+
const pupilsNotTakingCheckDataService = require('../../services/data-access/pupils-not-taking-check.data.service')
18+
19+
const pupilMock = require('../mocks/pupil-with-reason')
20+
const attendanceCodesMock = require('../mocks/attendance-codes')
21+
const pupilsWithReasonsMock = require('../mocks/pupils-with-reason-2')
22+
const pupilsWithReasonsFormattedMock = require('../mocks/pupils-with-reason-formatted')
1423

1524
describe('school controller:', () => {
25+
function getRes () {
26+
const res = httpMocks.createResponse()
27+
res.locals = {}
28+
return res
29+
}
30+
31+
function getReq (params) {
32+
const req = httpMocks.createRequest(params)
33+
req.user = { School: 9991001 }
34+
req.breadcrumbs = jasmine.createSpy('breadcrumbs')
35+
req.flash = jasmine.createSpy('flash')
36+
return req
37+
}
38+
39+
describe('Check routes', () => {
40+
let controller
41+
let sandbox
42+
let next
43+
let goodReqParams = {
44+
method: 'GET',
45+
url: '/school/pupils-not-taking-check'
46+
}
47+
48+
beforeEach(() => {
49+
sandbox = sinon.sandbox.create()
50+
next = jasmine.createSpy('next')
51+
})
52+
53+
afterEach(() => {
54+
sandbox.restore()
55+
})
56+
57+
describe('When there are pupils for the active school', () => {
58+
beforeEach(() => {
59+
spyOn(pupilsNotTakingCheckDataService, 'getAttendanceCodes').and.returnValue(Promise.resolve(attendanceCodesMock))
60+
spyOn(pupilsNotTakingCheckDataService, 'fetchPupilsWithReasons').and.returnValue(Promise.resolve(pupilsWithReasonsMock))
61+
spyOn(pupilsNotTakingCheckService, 'formatPupilsWithReasons').and.returnValue(Promise.resolve(pupilsWithReasonsFormattedMock))
62+
controller = proxyquire('../../controllers/school', {}).getPupilNotTakingCheck
63+
})
64+
65+
it('should display \'pupils not taking the check\' initial page', async (done) => {
66+
const res = getRes()
67+
const req = getReq(goodReqParams)
68+
await controller(req, res, next)
69+
expect(res.statusCode).toBe(200)
70+
expect(res.locals.pageTitle).toBe('Pupils not taking the check')
71+
expect(next).not.toHaveBeenCalled()
72+
done()
73+
})
74+
})
75+
76+
describe('Select reason for pupils', () => {
77+
beforeEach(() => {
78+
spyOn(pupilsNotTakingCheckDataService, 'getAttendanceCodes').and.returnValue(Promise.resolve(attendanceCodesMock))
79+
spyOn(pupilService, 'fetchSortedPupilsData').and.returnValue(Promise.resolve(pupilsWithReasonsMock))
80+
spyOn(pupilsNotTakingCheckService, 'formatPupilsWithReasons').and.returnValue(Promise.resolve(pupilsWithReasonsFormattedMock))
81+
spyOn(pupilsNotTakingCheckService, 'sortPupilsByReason').and.returnValue(Promise.resolve(pupilsWithReasonsFormattedMock))
82+
controller = proxyquire('../../controllers/school', {}).getSelectPupilNotTakingCheck
83+
})
84+
85+
it('should display reasons and pupils', async (done) => {
86+
const res = getRes()
87+
const req = getReq(goodReqParams)
88+
await controller(req, res, next)
89+
expect(res.statusCode).toBe(200)
90+
expect(res.locals.pageTitle).toBe('Select pupils not taking the check')
91+
expect(next).not.toHaveBeenCalled()
92+
done()
93+
})
94+
})
95+
96+
describe('Save reason for pupil', () => {
97+
beforeEach(() => {
98+
spyOn(pupilService, 'fetchMultiplePupils').and.returnValue(Promise.resolve(pupilsWithReasonsMock))
99+
spyOn(Pupil, 'create').and.returnValue(Promise.resolve(pupilMock))
100+
spyOn(pupilsNotTakingCheckDataService, 'getAttendanceCodes').and.returnValue(Promise.resolve(attendanceCodesMock))
101+
spyOn(pupilsNotTakingCheckDataService, 'fetchPupilsWithReasons').and.returnValue(Promise.resolve(pupilsWithReasonsMock))
102+
controller = proxyquire('../../controllers/school', {}).savePupilNotTakingCheck
103+
})
104+
105+
it('should save and display reasons and pupils', async (done) => {
106+
const res = getRes()
107+
const req = getReq(
108+
{
109+
method: 'POST',
110+
url: '/school/pupils-not-taking-check/save-pupils',
111+
body: {
112+
attendanceCode: '59df7e1c283960b43172ac6c',
113+
pupil: {
114+
_id: ['595cd5416e5ca13e48ed2518']
115+
}
116+
}
117+
}
118+
)
119+
await controller(req, res, next)
120+
expect(res.statusCode).toBe(200)
121+
expect(res.locals.pageTitle).toBe('Save pupils not taking the check')
122+
expect(next).not.toHaveBeenCalled()
123+
done()
124+
})
125+
})
16126

127+
describe('Remove reason for pupil', () => {
128+
beforeEach(() => {
129+
spyOn(pupilService, 'fetchOnePupil').and.returnValue(Promise.resolve(pupilsWithReasonsMock))
130+
spyOn(Pupil, 'create').and.returnValue(Promise.resolve(pupilMock))
131+
controller = proxyquire('../../controllers/school', {}).removePupilNotTakingCheck
132+
})
133+
it('should delete reason from pupils document and redirect', async (done) => {
134+
const res = getRes()
135+
const req = getReq(
136+
{
137+
method: 'GET',
138+
url: '/school/pupils-not-taking-check/remove',
139+
params: '59d02ab09b865f35a3f51940'
140+
}
141+
)
142+
await controller(req, res, next)
143+
expect(res.statusCode).toBe(302)
144+
expect(next).not.toHaveBeenCalled()
145+
done()
146+
})
147+
})
148+
})
17149
})

admin/spec/mocks/attendance-codes.js

+28-11
Original file line numberDiff line numberDiff line change
@@ -3,31 +3,48 @@ const moment = require('moment')
33

44
module.exports = [
55
{
6-
'_id': ObjectId('59c39fe72186e6748a58bbc4'),
6+
'_id': ObjectId('59df7e1c283960b43172ac6b'),
77
'updatedAt': moment('2017-09-21 12:17:59').toDate(),
88
'createdAt': moment('2017-09-21 12:17:59').toDate(),
9-
'reason': 'Left school',
10-
'code': 1
9+
'reason': 'Incorrect registration',
10+
'code': 1,
11+
'order': 0
1112
},
1213
{
13-
'_id': ObjectId('59c39fe72186e6748a58bbc5'),
14+
'_id': ObjectId('59df7e1c283960b43172ac6c'),
1415
'updatedAt': moment('2017-09-21 12:18:32').toDate(),
1516
'createdAt': moment('2017-09-21 12:18:32').toDate(),
16-
'reason': 'Withdrawn',
17-
'code': 2
17+
'reason': 'Absent',
18+
'code': 2,
19+
'order': 1
1820
},
1921
{
20-
'_id': ObjectId('59c39fe72186e6748a58bbc6'),
22+
'_id': ObjectId('59df7e1c283960b43172ac6d'),
2123
'updatedAt': moment('2017-09-21 12:19:04').toDate(),
2224
'createdAt': moment('2017-09-21 12:19:04').toDate(),
23-
'reason': 'Incorrect registration',
24-
'code': 3
25+
'reason': 'Left school',
26+
'code': 3,
27+
'order': 2
2528
},
2629
{
27-
'_id': ObjectId('59c39fe72186e6748a58bbc7'),
30+
'_id': ObjectId('59df7e1c283960b43172ac6e'),
2831
'updatedAt': moment('2017-09-21 12:21:32').toDate(),
2932
'createdAt': moment('2017-09-21 12:21:32').toDate(),
30-
'reason': 'Absent',
33+
'reason': 'Unable to access',
3134
'code': 4
35+
},
36+
{
37+
'_id': ObjectId('59df7e1c283960b43172ac6f'),
38+
'updatedAt': moment('2017-09-23 12:21:32').toDate(),
39+
'createdAt': moment('2017-09-23 12:21:32').toDate(),
40+
'reason': 'Working below the overall standard of the check',
41+
'code': 5
42+
},
43+
{
44+
'_id': ObjectId('59df7e1c283960b43172ac70'),
45+
'updatedAt': moment('2017-09-25 12:21:32').toDate(),
46+
'createdAt': moment('2017-09-25 12:21:32').toDate(),
47+
'reason': 'Just arrived',
48+
'code': 6
3249
}
3350
]

admin/spec/mocks/pupil-with-reason.js

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
const moment = require('moment')
2+
3+
module.exports = {
4+
_id: '59d02ab09b865f35a3f51940',
5+
school: 9991001,
6+
foreName: 'Pupil',
7+
lastName: 'One',
8+
pin: 'd55sg',
9+
dob: '2000-12-31 00:00:00',
10+
attendanceCode: {
11+
byUserEmail: 'teacher1',
12+
byUserName: 'teacher1',
13+
dateRecorded: moment('2017-10-09 15:24:05').toDate(),
14+
_id: '59df7e1c283960b43172ac6c'
15+
}
16+
}
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
const moment = require('moment')
2+
3+
module.exports = [
4+
{
5+
_id: '595cd5416e5ca13e48ed2518',
6+
school: 9991001,
7+
foreName: 'John',
8+
lastName: 'Smith',
9+
pin: 'd55sg',
10+
attendanceCode: {
11+
byUserEmail: 'teacher1',
12+
byUserName: 'teacher1',
13+
dateRecorded: moment('2017-10-09 15:24:05').toDate(),
14+
_id: '59df7e1c283960b43172ac6b'
15+
}
16+
},
17+
{
18+
_id: '595cd5416e5cv88e69ed2632',
19+
school: 9991001,
20+
foreName: 'Tom',
21+
lastName: 'Miller',
22+
pin: '437bu',
23+
attendanceCode: {
24+
byUserEmail: 'teacher2',
25+
byUserName: 'teacher2',
26+
dateRecorded: moment('2017-10-09 15:29:55').toDate(),
27+
_id: '59df7e1c283960b43172ac6c'
28+
}
29+
},
30+
{
31+
_id: '595cd5416e5cv88e48ed2512',
32+
school: 9991001,
33+
foreName: 'Sarah',
34+
lastName: 'Connor',
35+
pin: 's34sy',
36+
attendanceCode: {
37+
byUserEmail: 'teacher2',
38+
byUserName: 'teacher2',
39+
dateRecorded: moment('2017-10-09 15:28:15').toDate(),
40+
_id: '59df7e1c283960b43172ac6d'
41+
}
42+
},
43+
{
44+
_id: '595cd5416e5cv88e48edc451',
45+
school: 9991001,
46+
foreName: 'Bronislaw',
47+
lastName: 'Malinowsky',
48+
pin: 'a67lp'
49+
}
50+
]

0 commit comments

Comments
 (0)