Skip to content

Commit

Permalink
[squash] controller/middleware tests
Browse files Browse the repository at this point in the history
  • Loading branch information
nlsteers committed Oct 11, 2024
1 parent 77881d8 commit c85e838
Show file tree
Hide file tree
Showing 7 changed files with 320 additions and 12 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
// TODO
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
const { expect } = require('chai')
const { LIVE, NOT_STARTED } = require('../../../models/go-live-stage')
const proxyquire = require('proxyquire')
const sinon = require('sinon')
const paths = require('../../../paths')
const formatSimplifiedAccountPathsFor = require('../../../utils/simplified-account/format/format-simplified-account-paths-for')

const LIVE_ACCOUNT_TYPE = 'live'
const TEST_ACCOUNT_TYPE = 'test'
const SERVICE_ID = 'service-id-123abc'

let req, res, indexController

const getController = () => {
return proxyquire('./index.controller', {})
}

describe('Controller: settings/index', () => {
describe('get', () => {
beforeEach(() => {
indexController = getController()
res = {
redirect: sinon.spy()
}
req = {
account: {
service_id: SERVICE_ID,
type: TEST_ACCOUNT_TYPE
},
service: {
currentGoLiveStage: NOT_STARTED
}
}
})

it('should redirect to service name index for test account on service with no live account', () => {
indexController.get(req, res)
expect(res.redirect.calledWith(formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.serviceName.index, SERVICE_ID, TEST_ACCOUNT_TYPE))).to.be.true // eslint-disable-line
})

it('should redirect to service name index for live account', () => {
req.account.type = 'live'
indexController.get(req, res)
expect(res.redirect.calledWith(formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.serviceName.index, SERVICE_ID, LIVE_ACCOUNT_TYPE))).to.be.true // eslint-disable-line
})

it('should redirect to email notifications index for test account on service with live account', () => {
req.service.currentGoLiveStage = LIVE
indexController.get(req, res)
expect(res.redirect.calledWith(formatSimplifiedAccountPathsFor(paths.simplifiedAccount.settings.emailNotifications.index, SERVICE_ID, TEST_ACCOUNT_TYPE))).to.be.true // eslint-disable-line
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ describe('Controller: settings/service-name', () => {
before(() => setupTest('get'))

it('should call the response method', () => {
expect(responseStub.called).to.equal(true)
expect(responseStub.called).to.be.true // eslint-disable-line
})

it('should pass req, res and template path to the response method', () => {
Expand All @@ -79,7 +79,7 @@ describe('Controller: settings/service-name', () => {
before(() => setupTest('getEditServiceName', { query: queryParams }))

it('should call the response method', () => {
expect(responseStub.called).to.equal(true)
expect(responseStub.called).to.be.true // eslint-disable-line
})

it('should pass req, res and template path to the response method', () => {
Expand Down Expand Up @@ -131,14 +131,14 @@ describe('Controller: settings/service-name', () => {
before(() => {
setupTest('postEditServiceName', {
body: {
'service-name-input': 'New Welsh Name',
'service-name-input': 'Enw Cymraeg newydd',
cy: 'true'
}
})
})

it('should update the service name', () => {
expect(updateServiceNameStub.calledWith(SERVICE_ID, EN_SERVICE_NAME, 'New Welsh Name')).to.be.true // eslint-disable-line
expect(updateServiceNameStub.calledWith(SERVICE_ID, EN_SERVICE_NAME, 'Enw Cymraeg newydd')).to.be.true // eslint-disable-line
})

it('should redirect to the service name index page', () => {
Expand Down Expand Up @@ -171,7 +171,7 @@ describe('Controller: settings/service-name', () => {

it('should render the edit page with errors', () => {
expect(responseStub.calledOnce).to.be.true // eslint-disable-line
const [ , , template, context] = responseStub.args[0]
const [, , template, context] = responseStub.args[0]
expect(template).to.equal('simplified-account/settings/service-name/edit-service-name')
expect(context.errors).to.deep.equal({
summary: ['Error summary'],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { InvalidConfigurationError } = require('../../errors')

module.exports = function checkDegatewayParameters (req, res, next) {
module.exports = (req, res, next) => {
const user = req.user
if (user.isDegatewayed()) {
return next()
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
const { expect } = require('chai')
const sinon = require('sinon')
const proxyquire = require('proxyquire')

describe('Middleware: isOptedInToSimplifiedAccounts', () => {
let isOptedInToSimplifiedAccounts, req, res, next, invalidConfigurationError

beforeEach(() => {
invalidConfigurationError = sinon.stub()
isOptedInToSimplifiedAccounts = proxyquire('./simplified-account-opt-in.middleware', {
'../../errors': { InvalidConfigurationError: invalidConfigurationError }
})

req = {
user: {
externalId: 'user-123',
isDegatewayed: sinon.stub()
}
}
res = {}
next = sinon.stub()
})

it('should call next() when user is opted in', () => {
req.user.isDegatewayed.returns(true)

isOptedInToSimplifiedAccounts(req, res, next)

expect(next.calledOnce).to.be.true // eslint-disable-line
expect(next.args[0]).to.be.empty // eslint-disable-line
})

it('should call next() with error when user is not opted in', () => {
req.user.isDegatewayed.returns(false)

isOptedInToSimplifiedAccounts(req, res, next)

expect(next.calledOnce).to.be.true // eslint-disable-line
expect(invalidConfigurationError.calledOnce).to.be.true // eslint-disable-line
expect(invalidConfigurationError.args[0][0]).to.equal(
'User with id user-123 not opted in to account simplification or feature is disabled in this environment.'
)
})
})
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
'use strict'
const _ = require('lodash')
const { keys } = require('@govuk-pay/pay-js-commons').logging
const { addField } = require('../../services/clients/base/request-context')
const Connector = require('../../services/clients/connector.client.js').ConnectorClient
const { getSwitchingCredentialIfExists } = require('../../utils/credentials')
const { SERVICE_EXTERNAL_ID, ACCOUNT_TYPE, ENVIRONMENT_ID } = require('../../paths').keys
const { SERVICE_EXTERNAL_ID, ACCOUNT_TYPE } = require('../../paths').keys
const _ = require('lodash')
const logger = require('../../utils/logger')(__filename)
const Connector = require('../../services/clients/connector.client.js').ConnectorClient
const connectorClient = new Connector(process.env.CONNECTOR_URL)

function getService (user, serviceExternalId, gatewayAccountId) {
Expand Down Expand Up @@ -76,9 +76,8 @@ module.exports = async function getSimplifiedAccount (req, res, next) {
req.account = gatewayAccount
addField(keys.GATEWAY_ACCOUNT_ID, gatewayAccount.gateway_account_id)
addField(keys.GATEWAY_ACCOUNT_TYPE, gatewayAccount.type)
req.gateway_account = {
currentGatewayAccountExternalId: gatewayAccount.external_id
}
} else {
throw new Error('getGatewayAccountByServiceIdAndAccountType failed for provided parameters')
}
const service = getService(req.user, serviceExternalId, gatewayAccount.gateway_account_id)
if (service) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,211 @@
'use strict'

const { expect } = require('chai')
const path = require('path')
const proxyquire = require('proxyquire')
const sinon = require('sinon')
const User = require('../../models/User.class')
const userFixtures = require('../../../test/fixtures/user.fixtures')
const stripeAccountSetupFixture = require('../../../test/fixtures/stripe-account-setup.fixtures')

const A_GATEWAY_EXTERNAL_ID = 'a-gateway-external-id'
const A_SERVICE_EXTERNAL_ID = 'a-service-external-id'

let req, res, next

const buildUser = (serviceExternalId, gatewayAccountIds) => {
return new User(userFixtures.validUserResponse({
service_roles: [{
service: {
external_id: serviceExternalId,
gateway_account_ids: gatewayAccountIds
}
}]
}))
}

const setupSimplifiedAccountStrategyTest = function (options) {
const {
gatewayAccountID,
gatewayAccountExternalId,
paymentProvider,
serviceExternalId,
accountType,
errorCode
} = options

req = {
params: { serviceExternalId, accountType },
user: buildUser(serviceExternalId, [`${gatewayAccountID}`])
}
next = sinon.spy()

let connectorGetAccountMock
if (errorCode) {
connectorGetAccountMock = sinon.stub().rejects({ errorCode })
} else {
connectorGetAccountMock = sinon.stub().resolves({
gateway_account_id: gatewayAccountID,
external_id: gatewayAccountExternalId,
payment_provider: paymentProvider
})
}

const connectorMock = {
ConnectorClient: function () {
return {
getAccountByServiceIdAndAccountType: connectorGetAccountMock,
getStripeAccountSetup: paymentProvider === 'stripe'
? sinon.stub().resolves(stripeAccountSetupFixture.buildGetStripeAccountSetupResponse())
: undefined
}
}
}

const simplifiedAccountStrategy = proxyquire(
path.join(__dirname, './simplified-account-strategy.middleware'),
{ '../../services/clients/connector.client.js': connectorMock }
)

return {
simplifiedAccountStrategy,
connectorGetAccountMock
}
}

describe('middleware: getSimplifiedAccount', () => {
it('should set gateway account and service on request object', async () => {
const { simplifiedAccountStrategy, connectorGetAccountMock } = setupSimplifiedAccountStrategyTest({
gatewayAccountID: '1',
gatewayAccountExternalId: A_GATEWAY_EXTERNAL_ID,
paymentProvider: 'worldpay',
serviceExternalId: A_SERVICE_EXTERNAL_ID,
accountType: 'test'
})
await simplifiedAccountStrategy(req, res, next)

sinon.assert.calledOnce(next)
expect(connectorGetAccountMock.called).to.equal(true)
expect(connectorGetAccountMock.calledWith({
serviceId: A_SERVICE_EXTERNAL_ID,
accountType: 'test'
})).to.equal(true)

expect(req.account.external_id).to.equal(A_GATEWAY_EXTERNAL_ID)
expect(req.service.externalId).to.equal(A_SERVICE_EXTERNAL_ID)
})
it('should error if service external ID or gateway account type cannot be resolved from request parameters', async () => {
const { simplifiedAccountStrategy } = setupSimplifiedAccountStrategyTest({
gatewayAccountID: '1',
gatewayAccountExternalId: A_GATEWAY_EXTERNAL_ID,
paymentProvider: 'worldpay',
serviceExternalId: A_SERVICE_EXTERNAL_ID,
accountType: 'test'
})
req.params['serviceExternalId'] = undefined
req.params['accountType'] = undefined

await simplifiedAccountStrategy(req, res, next)

const expectedError = sinon.match.instanceOf(Error)
.and(sinon.match.has('message', 'Could not resolve service external ID or gateway account type from request params'))
sinon.assert.calledWith(next, expectedError)
})
it('should error if gateway account lookup fails for account type', async () => {
const { simplifiedAccountStrategy } = setupSimplifiedAccountStrategyTest({
gatewayAccountID: '1',
serviceExternalId: A_SERVICE_EXTERNAL_ID,
accountType: 'test',
errorCode: '404'
})
await simplifiedAccountStrategy(req, res, next)

const expectedError = sinon.match.instanceOf(Error)
.and(sinon.match.has('message', 'getGatewayAccountByServiceIdAndAccountType failed for provided parameters'))
sinon.assert.calledWith(next, expectedError)
})
describe('extend gateway account data with disableToggle3ds field', () => {
['worldpay', 'smartpay', 'epdq'].forEach(function (paymentProvider) {
it('should extend the account data with disableToggle3ds set to false if payment provider is ' + paymentProvider, async () => {
const { simplifiedAccountStrategy } = setupSimplifiedAccountStrategyTest({
gatewayAccountID: '1',
gatewayAccountExternalId: A_GATEWAY_EXTERNAL_ID,
paymentProvider,
serviceExternalId: A_SERVICE_EXTERNAL_ID,
accountType: 'test'
})
await simplifiedAccountStrategy(req, res, next)
expect(req.account.disableToggle3ds).to.equal(false)
expect(req.account.external_id).to.equal(A_GATEWAY_EXTERNAL_ID)
})
})
it('should extend the account data with disableToggle3ds set to true if payment provider is stripe', async () => {
const { simplifiedAccountStrategy } = setupSimplifiedAccountStrategyTest({
gatewayAccountID: '1',
gatewayAccountExternalId: A_GATEWAY_EXTERNAL_ID,
paymentProvider: 'stripe',
serviceExternalId: A_SERVICE_EXTERNAL_ID,
accountType: 'test'
})
await simplifiedAccountStrategy(req, res, next)
expect(req.account.disableToggle3ds).to.equal(true)
expect(req.account.external_id).to.equal(A_GATEWAY_EXTERNAL_ID)
})
})
describe('extend gateway account data with supports3ds field', () => {
['worldpay', 'smartpay', 'epdq', 'stripe'].forEach(function (paymentProvider) {
it('should extend the account data with supports3ds set to true if payment provider is ' + paymentProvider, async () => {
const { simplifiedAccountStrategy } = setupSimplifiedAccountStrategyTest({
gatewayAccountID: '1',
gatewayAccountExternalId: A_GATEWAY_EXTERNAL_ID,
paymentProvider,
serviceExternalId: A_SERVICE_EXTERNAL_ID,
accountType: 'test'
})
await simplifiedAccountStrategy(req, res, next)
expect(req.account.supports3ds).to.equal(true)
expect(req.account.external_id).to.equal(A_GATEWAY_EXTERNAL_ID)
})
})
it('should extend the account data with supports3ds set to false if payment provider is sandbox', async () => {
const { simplifiedAccountStrategy } = setupSimplifiedAccountStrategyTest({
gatewayAccountID: '1',
gatewayAccountExternalId: A_GATEWAY_EXTERNAL_ID,
paymentProvider: 'sandbox',
serviceExternalId: A_SERVICE_EXTERNAL_ID,
accountType: 'test'
})
await simplifiedAccountStrategy(req, res, next)
expect(req.account.supports3ds).to.equal(false)
expect(req.account.external_id).to.equal(A_GATEWAY_EXTERNAL_ID)
})
})
describe('extend gateway account data stripe setup', () => {
['worldpay', 'smartpay', 'epdq', 'sandbox'].forEach(function (paymentProvider) {
it('should not extend the account data with stripe setup if payment provider is ' + paymentProvider, async () => {
const { simplifiedAccountStrategy } = setupSimplifiedAccountStrategyTest({
gatewayAccountID: '1',
gatewayAccountExternalId: A_GATEWAY_EXTERNAL_ID,
paymentProvider,
serviceExternalId: A_SERVICE_EXTERNAL_ID,
accountType: 'test'
})
await simplifiedAccountStrategy(req, res, next)
expect(req.account.external_id).to.equal(A_GATEWAY_EXTERNAL_ID)
expect(req.account).to.not.have.property('connectorGatewayAccountStripeProgress')
})
})
it('should extend the account data with supports3ds set to false if payment provider is stripe', async () => {
const { simplifiedAccountStrategy } = setupSimplifiedAccountStrategyTest({
gatewayAccountID: '1',
gatewayAccountExternalId: A_GATEWAY_EXTERNAL_ID,
paymentProvider: 'stripe',
serviceExternalId: A_SERVICE_EXTERNAL_ID,
accountType: 'test'
})
await simplifiedAccountStrategy(req, res, next)
expect(req.account.external_id).to.equal(A_GATEWAY_EXTERNAL_ID)
expect(req.account).to.have.property('connectorGatewayAccountStripeProgress')
})
})
})

0 comments on commit c85e838

Please sign in to comment.