diff --git a/app/moves/controllers/list.js b/app/moves/controllers/list.js index dc7a391db..9653511d8 100644 --- a/app/moves/controllers/list.js +++ b/app/moves/controllers/list.js @@ -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', @@ -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) diff --git a/app/moves/controllers/list.test.js b/app/moves/controllers/list.test.js index 50a6ea4e4..2dd5bf99d 100644 --- a/app/moves/controllers/list.test.js +++ b/app/moves/controllers/list.test.js @@ -14,20 +14,17 @@ 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, }, @@ -35,10 +32,6 @@ describe('Moves controllers', function() { } }) - afterEach(function() { - this.clock.restore() - }) - describe('template params', function() { beforeEach(function() { controller(req, res) @@ -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 diff --git a/app/moves/index.js b/app/moves/index.js index d6638cde4..c42ef502d 100644 --- a/app/moves/index.js +++ b/app/moves/index.js @@ -9,6 +9,7 @@ const { storeQuery, setMoveDate, setFromLocation, + setPagination, setMovesByDate, } = require('./middleware') @@ -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( diff --git a/app/moves/middleware.js b/app/moves/middleware.js index b3c322f12..968d7c8c9 100644 --- a/app/moves/middleware.js +++ b/app/moves/middleware.js @@ -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') @@ -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 diff --git a/app/moves/middleware.test.js b/app/moves/middleware.test.js index 46f0e7191..15afb7360 100644 --- a/app/moves/middleware.test.js +++ b/app/moves/middleware.test.js @@ -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() + }) }) })