Skip to content

Commit

Permalink
Merge pull request #233 from ministryofjustice/locations/unavailable-…
Browse files Browse the repository at this point in the history
…location

[P4-650] Ensure a user can only see locations they have access to
  • Loading branch information
teneightfive authored Sep 10, 2019
2 parents c135174 + ad30cbc commit 43e8339
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 47 deletions.
24 changes: 3 additions & 21 deletions app/moves/controllers/list.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,12 @@
const { format, addDays, subDays } = require('date-fns')
const { get } = require('lodash')

const { getQueryString } = require('../../../common/lib/request')
const permissions = require('../../../common/middleware/permissions')
const presenters = require('../../../common/presenters')

module.exports = function list(req, res) {
const { moveDate, cancelledMovesByDate, requestedMovesByDate } = res.locals
const today = format(new Date(), 'YYYY-MM-DD')
const previousDay = format(subDays(moveDate, 1), 'YYYY-MM-DD')
const nextDay = format(addDays(moveDate, 1), 'YYYY-MM-DD')
const canViewMove = permissions.check(
'move:view',
get(req.session, 'user.permissions')
)
const { cancelledMovesByDate, requestedMovesByDate } = res.locals
const userPermissions = get(req.session, 'user.permissions')
const canViewMove = permissions.check('move:view', userPermissions)
const template = canViewMove ? 'moves/views/list' : 'moves/views/download'
const locals = {
pageTitle: 'moves::dashboard.upcoming_moves',
Expand All @@ -24,17 +17,6 @@ module.exports = function list(req, res) {
showTags: false,
})
),
pagination: {
todayUrl: getQueryString(req.query, {
'move-date': today,
}),
nextUrl: getQueryString(req.query, {
'move-date': nextDay,
}),
prevUrl: getQueryString(req.query, {
'move-date': previousDay,
}),
},
}

res.render(template, locals)
Expand Down
17 changes: 1 addition & 16 deletions app/moves/controllers/list.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,31 +14,24 @@ const mockCancelledMovesByDate = [

describe('Moves controllers', function() {
describe('#list()', function() {
const mockMoveDate = '2019-10-10'
let req, res, moveToCardComponentMapStub

beforeEach(function() {
moveToCardComponentMapStub = sinon.stub().returnsArg(0)
this.clock = sinon.useFakeTimers(new Date(mockMoveDate).getTime())
sinon.stub(presenters, 'movesByToLocation').returnsArg(0)
sinon
.stub(presenters, 'moveToCardComponent')
.callsFake(() => moveToCardComponentMapStub)
req = { query: {} }
req = {}
res = {
locals: {
moveDate: mockMoveDate,
requestedMovesByDate: mockRequestedMovesByDate,
cancelledMovesByDate: mockCancelledMovesByDate,
},
render: sinon.spy(),
}
})

afterEach(function() {
this.clock.restore()
})

describe('template params', function() {
beforeEach(function() {
controller(req, res)
Expand All @@ -48,14 +41,6 @@ describe('Moves controllers', function() {
expect(res.render.args[0][1]).to.have.property('pageTitle')
})

it('should contain pagination with correct links', function() {
const params = res.render.args[0][1]
expect(params).to.have.property('pagination')
expect(params.pagination.todayUrl).to.equal('?move-date=2019-10-10')
expect(params.pagination.nextUrl).to.equal('?move-date=2019-10-11')
expect(params.pagination.prevUrl).to.equal('?move-date=2019-10-09')
})

it('should call movesByToLocation presenter', function() {
expect(presenters.movesByToLocation).to.be.calledOnceWithExactly(
mockRequestedMovesByDate
Expand Down
3 changes: 3 additions & 0 deletions app/moves/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const {
storeQuery,
setMoveDate,
setFromLocation,
setPagination,
setMovesByDate,
} = require('./middleware')

Expand All @@ -26,12 +27,14 @@ router.get(
redirectUsers,
protectRoute('moves:view:all'),
setMovesByDate,
setPagination,
list
)
router.get(
`/:locationId(${uuidRegex})`,
protectRoute('moves:view:by_location'),
setMovesByDate,
setPagination,
list
)
router.get(
Expand Down
33 changes: 30 additions & 3 deletions app/moves/middleware.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
const queryString = require('query-string')
const { format } = require('date-fns')
const { get } = require('lodash')
const { format, addDays, subDays } = require('date-fns')
const { find, get } = require('lodash')

const { getQueryString } = require('../../common/lib/request')
const moveService = require('../../common/services/move')
const permissions = require('../../common/middleware/permissions')

const moveDateFormat = 'YYYY-MM-DD'

module.exports = {
redirectUsers: (req, res, next) => {
const userPermissions = get(req.session, 'user.permissions')
Expand Down Expand Up @@ -33,14 +36,38 @@ module.exports = {
},
setMoveDate: (req, res, next) => {
res.locals.moveDate =
req.query['move-date'] || format(new Date(), 'YYYY-MM-DD')
req.query['move-date'] || format(new Date(), moveDateFormat)

next()
},
setFromLocation: (req, res, next, locationId) => {
const userLocations = get(req.session, 'user.locations')
const location = find(userLocations, { id: locationId })

if (!location) {
const error = new Error('Location not found')
error.statusCode = 404

return next(error)
}

res.locals.fromLocationId = locationId
next()
},
setPagination: (req, res, next) => {
const { moveDate } = res.locals
const today = format(new Date(), moveDateFormat)
const previousDay = format(subDays(moveDate, 1), moveDateFormat)
const nextDay = format(addDays(moveDate, 1), moveDateFormat)

res.locals.pagination = {
todayUrl: getQueryString(req.query, { 'move-date': today }),
nextUrl: getQueryString(req.query, { 'move-date': nextDay }),
prevUrl: getQueryString(req.query, { 'move-date': previousDay }),
}

next()
},
setMovesByDate: async (req, res, next) => {
const { moveDate, fromLocationId } = res.locals

Expand Down
119 changes: 112 additions & 7 deletions app/moves/middleware.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -247,22 +247,127 @@ describe('Moves middleware', function() {

beforeEach(function() {
res = { locals: {} }
req = {
query: {},
session: {},
}
nextSpy = sinon.spy()
})

context('when location exists in users locations', function() {
beforeEach(function() {
req.session.user = {
locations: [
{
id: locationId,
},
],
}

middleware.setFromLocation(req, res, nextSpy, locationId)
})

it('should set from location to locals', function() {
expect(res.locals).to.have.property('fromLocationId')
expect(res.locals.fromLocationId).to.equal(locationId)
})

it('should call next', function() {
expect(nextSpy).to.be.calledOnceWithExactly()
})
})

context('when location does not exist in users locations', function() {
beforeEach(function() {
middleware.setFromLocation(req, res, nextSpy, locationId)
})

it('should not set from location to locals', function() {
expect(res.locals).not.to.have.property('fromLocationId')
})

it('should call next with 404 error', function() {
const error = nextSpy.args[0][0]

expect(nextSpy).to.be.calledOnce

expect(error).to.be.an('error')
expect(error.message).to.equal('Location not found')
expect(error.statusCode).to.equal(404)
})
})
})

describe('#setPagination()', function() {
const mockMoveDate = '2019-10-10'
let req, res, nextSpy

beforeEach(function() {
req = { query: {} }
this.clock = sinon.useFakeTimers(new Date(mockMoveDate).getTime())
res = {
locals: {
moveDate: mockMoveDate,
},
}
req = {
query: {},
}
nextSpy = sinon.spy()
})

middleware.setFromLocation(req, res, nextSpy, locationId)
afterEach(function() {
this.clock.restore()
})

it('should set from location to locals', function() {
expect(res.locals).to.have.property('fromLocationId')
expect(res.locals.fromLocationId).to.equal(locationId)
context('with empty query', function() {
beforeEach(function() {
middleware.setPagination(req, res, nextSpy)
})

it('should contain pagination on locals', function() {
expect(res.locals).to.have.property('pagination')
})

it('should contain correct pagination links', function() {
const pagination = res.locals.pagination
expect(pagination.todayUrl).to.equal('?move-date=2019-10-10')
expect(pagination.nextUrl).to.equal('?move-date=2019-10-11')
expect(pagination.prevUrl).to.equal('?move-date=2019-10-09')
})

it('should call next', function() {
expect(nextSpy).to.be.calledOnceWithExactly()
})
})

it('should call next', function() {
expect(nextSpy).to.be.calledOnceWithExactly()
context('with existing query', function() {
beforeEach(function() {
req.query = {
location: '12345',
}
middleware.setPagination(req, res, nextSpy)
})

it('should contain pagination on locals', function() {
expect(res.locals).to.have.property('pagination')
})

it('should contain correct pagination links', function() {
const pagination = res.locals.pagination
expect(pagination.todayUrl).to.equal(
'?location=12345&move-date=2019-10-10'
)
expect(pagination.nextUrl).to.equal(
'?location=12345&move-date=2019-10-11'
)
expect(pagination.prevUrl).to.equal(
'?location=12345&move-date=2019-10-09'
)
})

it('should call next', function() {
expect(nextSpy).to.be.calledOnceWithExactly()
})
})
})

Expand Down

0 comments on commit 43e8339

Please sign in to comment.