From c913abe1fdf25c926f7a5a2b3406e6038b93d4f0 Mon Sep 17 00:00:00 2001 From: Stephen Daly Date: Tue, 19 Jan 2021 14:54:40 +0000 Subject: [PATCH] PP-7583 Update credentials routes Move credentials routes to use the new account URL structure. Remove some duplicate paths/routes that had the same URLs as other paths, so were redundant. Remove functional and UI tests for the credentials settings pages, as the coverage is duplicated by Cypress tests. --- .secrets.baseline | 4 +- app/controllers/credentials.controller.js | 2 +- app/paths.js | 37 +- app/routes.js | 24 +- app/utils/nav-builder.js | 4 +- app/views/credentials/epdq.njk | 2 +- app/views/credentials/smartpay.njk | 4 +- app/views/credentials/worldpay.njk | 2 +- app/views/your-psp/_epdq.njk | 10 +- app/views/your-psp/_smartpay.njk | 10 +- app/views/your-psp/_worldpay.njk | 6 +- .../integration/settings/your-psp.cy.test.js | 2 +- test/integration/credentials.ft.test.js | 623 ------------------ test/ui/credentials.ui.test.js | 152 ----- 14 files changed, 48 insertions(+), 834 deletions(-) delete mode 100644 test/integration/credentials.ft.test.js delete mode 100644 test/ui/credentials.ui.test.js diff --git a/.secrets.baseline b/.secrets.baseline index 6e33eb9a23..1a6d084bcb 100644 --- a/.secrets.baseline +++ b/.secrets.baseline @@ -3,7 +3,7 @@ "files": "package-lock.json", "lines": null }, - "generated_at": "2021-01-19T16:07:47Z", + "generated_at": "2021-01-19T17:38:25Z", "plugins_used": [ { "name": "AWSKeyDetector" @@ -72,7 +72,7 @@ "hashed_secret": "ece65afda87c1c6120602c9a3b66890308d7e53c", "is_secret": false, "is_verified": false, - "line_number": 127, + "line_number": 138, "type": "Secret Keyword" } ], diff --git a/app/controllers/credentials.controller.js b/app/controllers/credentials.controller.js index d5ab40efde..1c25941d9d 100644 --- a/app/controllers/credentials.controller.js +++ b/app/controllers/credentials.controller.js @@ -97,7 +97,7 @@ module.exports = { if (_.get(req, 'session.flash.genericError.length')) { _.set(req, 'session.pageData.editNotificationCredentials', { username, password }) - return res.redirect(paths.notificationCredentials.edit) + return res.redirect(formatAccountPathsFor(paths.account.notificationCredentials.edit, req.account && req.account.external_id)) } const correlationId = req.headers[CORRELATION_HEADER] || '' diff --git a/app/paths.js b/app/paths.js index 982a573110..14ebbcb794 100644 --- a/app/paths.js +++ b/app/paths.js @@ -19,6 +19,10 @@ module.exports = { revoke: '/api-keys/revoke', update: '/api-keys/update' }, + credentials: { + index: '/credentials', + edit: '/credentials/edit' + }, digitalWallet: { applePay: '/digital-wallet/apple-pay', googlePay: '/digital-wallet/google-pay' @@ -35,6 +39,10 @@ module.exports = { confirmation: '/email-settings-confirmation', refund: '/email-settings-refund' }, + notificationCredentials: { + edit: '/notification-credentials/edit', + update: '/notification-credentials' + }, paymentLinks: { start: '/create-payment-link', information: '/create-payment-link/information', @@ -79,6 +87,15 @@ module.exports = { }, settings: { index: '/settings' + }, + stripe: { + addPspAccountDetails: '/stripe/add-psp-account-details' + }, + stripeSetup: { + bankDetails: '/bank-details', + responsiblePerson: '/responsible-person', + vatNumber: '/vat-number', + companyNumber: '/company-number' }, toggle3ds: { index: '/3ds' @@ -94,15 +111,6 @@ module.exports = { index: '/your-psp', flex: '/your-psp/flex', worldpay3dsFlex: '/your-psp/worldpay-3ds-flex' - }, - stripeSetup: { - bankDetails: '/bank-details', - responsiblePerson: '/responsible-person', - vatNumber: '/vat-number', - companyNumber: '/company-number' - }, - stripe: { - addPspAccountDetails: '/stripe/add-psp-account-details' } }, redirects: { @@ -119,16 +127,7 @@ module.exports = { index: '/all-service-transactions', download: '/all-service-transactions/download' }, - credentials: { - index: '/credentials', - edit: '/credentials/edit', - create: '/credentials' - }, - notificationCredentials: { - index: '/credentials', - edit: '/notification-credentials/edit', - update: '/notification-credentials' - }, + user: { logIn: '/login', otpLogIn: '/otp-login', diff --git a/app/routes.js b/app/routes.js index b39efe4d4e..d6628a924a 100644 --- a/app/routes.js +++ b/app/routes.js @@ -86,26 +86,27 @@ const stripeSetupDashboardRedirectController = require('./controllers/stripe-set // Assignments const { - healthcheck, registerUser, user, dashboard, selfCreateService, transactions, credentials, - serviceSwitcher, teamMembers, staticPaths, inviteValidation, editServiceName, merchantDetails, - notificationCredentials, + healthcheck, registerUser, user, dashboard, selfCreateService, transactions, + serviceSwitcher,teamMembers, staticPaths, inviteValidation, editServiceName, merchantDetails, requestToGoLive, policyPages, allServiceTransactions, payouts, redirects } = paths const { apiKeys, + credentials, digitalWallet, emailNotifications, + notificationCredentials, paymentLinks, paymentTypes, prototyping, settings, + stripe, + stripeSetup, toggle3ds, toggleBillingAddress, toggleMotoMaskCardNumberAndSecurityCode, - yourPsp, - stripeSetup, - stripe + yourPsp } = paths.account // Exports @@ -183,13 +184,10 @@ module.exports.bind = function (app) { const authenticatedPaths = [ ...lodash.values(transactions), ...lodash.values(allServiceTransactions), - ...lodash.values(credentials), - ...lodash.values(notificationCredentials), ...lodash.values(editServiceName), ...lodash.values(serviceSwitcher), ...lodash.values(teamMembers), ...lodash.values(merchantDetails), - ...lodash.values(paymentLinks), ...lodash.values(user.profile), ...lodash.values(requestToGoLive), ...lodash.values(policyPages), @@ -291,17 +289,9 @@ module.exports.bind = function (app) { account.post(yourPsp.flex, permission('gateway-credentials:update'), paymentMethodIsCard, yourPspController.postFlex) // Credentials - app.get(credentials.index, permission('gateway-credentials:read'), getAccount, paymentMethodIsCard, credentialsController.index) - app.get(credentials.edit, permission('gateway-credentials:update'), getAccount, paymentMethodIsCard, credentialsController.editCredentials) - app.post(credentials.index, permission('gateway-credentials:update'), getAccount, paymentMethodIsCard, credentialsController.update) - app.get(notificationCredentials.index, permission('gateway-credentials:read'), getAccount, paymentMethodIsCard, credentialsController.index) - app.get(notificationCredentials.edit, permission('gateway-credentials:update'), getAccount, paymentMethodIsCard, credentialsController.editNotificationCredentials) - app.post(notificationCredentials.update, permission('gateway-credentials:update'), getAccount, paymentMethodIsCard, credentialsController.updateNotificationCredentials) - account.get(credentials.index, permission('gateway-credentials:read'), paymentMethodIsCard, credentialsController.index) account.get(credentials.edit, permission('gateway-credentials:update'), paymentMethodIsCard, credentialsController.editCredentials) account.post(credentials.index, permission('gateway-credentials:update'), paymentMethodIsCard, credentialsController.update) - account.get(notificationCredentials.index, permission('gateway-credentials:read'), paymentMethodIsCard, credentialsController.index) account.get(notificationCredentials.edit, permission('gateway-credentials:update'), paymentMethodIsCard, credentialsController.editNotificationCredentials) account.post(notificationCredentials.update, permission('gateway-credentials:update'), paymentMethodIsCard, credentialsController.updateNotificationCredentials) diff --git a/app/utils/nav-builder.js b/app/utils/nav-builder.js index 85ca327500..6ab35cc713 100644 --- a/app/utils/nav-builder.js +++ b/app/utils/nav-builder.js @@ -17,8 +17,8 @@ const mainSettingsPaths = [ const yourPspPaths = [ paths.account.yourPsp, - paths.credentials, - paths.notificationCredentials + paths.account.credentials, + paths.account.notificationCredentials ] const serviceNavigationItems = (currentPath, permissions, type, account = {}) => { diff --git a/app/views/credentials/epdq.njk b/app/views/credentials/epdq.njk index daad52f1ae..fe1291e8fd 100644 --- a/app/views/credentials/epdq.njk +++ b/app/views/credentials/epdq.njk @@ -3,7 +3,7 @@ {% block provider_content %} {% if permissions.gateway_credentials_update %} -
+ {{ govukInput({ diff --git a/app/views/credentials/smartpay.njk b/app/views/credentials/smartpay.njk index 7a42e8247c..d7c535740e 100644 --- a/app/views/credentials/smartpay.njk +++ b/app/views/credentials/smartpay.njk @@ -2,7 +2,7 @@ {% block provider_content %} {% if editNotificationCredentialsMode %} - + {% set username %}{{lastNotificationsData.username or currentGatewayAccount.notificationCredentials.userName}}{% endset %} @@ -47,7 +47,7 @@
{% else %} {% if permissions.gateway_credentials_update %} -
+ {{ govukInput({ diff --git a/app/views/credentials/worldpay.njk b/app/views/credentials/worldpay.njk index ff7b825a29..5f99f23f29 100644 --- a/app/views/credentials/worldpay.njk +++ b/app/views/credentials/worldpay.njk @@ -2,7 +2,7 @@ {% block provider_content %} {% if permissions.gateway_credentials_update %} - + {% if change === 'merchantId' %} diff --git a/app/views/your-psp/_epdq.njk b/app/views/your-psp/_epdq.njk index ea0b8d046d..d738cab40e 100644 --- a/app/views/your-psp/_epdq.njk +++ b/app/views/your-psp/_epdq.njk @@ -18,7 +18,7 @@ actions: { items: [ { - href: routes.credentials.edit + "?change=merchantId", + href: formatAccountPathsFor(routes.account.credentials.edit, currentGatewayAccount.external_id) + "?change=merchantId", text: "Change", visuallyHiddenText: "account credentials", attributes: { @@ -39,7 +39,7 @@ actions: { items: [ { - href: routes.credentials.edit + "?change=username", + href: formatAccountPathsFor(routes.account.credentials.edit, currentGatewayAccount.external_id) + "?change=username", text: "Change", visuallyHiddenText: "account credentials" } @@ -57,7 +57,7 @@ actions: { items: [ { - href: routes.credentials.edit + "?change=password", + href: formatAccountPathsFor(routes.account.credentials.edit, currentGatewayAccount.external_id) + "?change=password", text: "Change", visuallyHiddenText: "account credentials" } @@ -75,7 +75,7 @@ actions: { items: [ { - href: routes.credentials.edit + "?change=password", + href: formatAccountPathsFor(routes.account.credentials.edit, currentGatewayAccount.external_id) + "?change=password", text: "Change", visuallyHiddenText: "account credentials" } @@ -93,7 +93,7 @@ actions: { items: [ { - href: routes.credentials.edit + "?change=password", + href: formatAccountPathsFor(routes.account.credentials.edit, currentGatewayAccount.external_id) + "?change=password", text: "Change", visuallyHiddenText: "account credentials" } diff --git a/app/views/your-psp/_smartpay.njk b/app/views/your-psp/_smartpay.njk index 654113a90d..1c1236c4ff 100644 --- a/app/views/your-psp/_smartpay.njk +++ b/app/views/your-psp/_smartpay.njk @@ -17,7 +17,7 @@ actions: { items: [ { - href: routes.credentials.edit + "?change=merchantId", + href: formatAccountPathsFor(routes.account.credentials.edit, currentGatewayAccount.external_id) + "?change=merchantId", text: "Change", visuallyHiddenText: "account credentials", attributes: { @@ -38,7 +38,7 @@ actions: { items: [ { - href: routes.credentials.edit + "?change=username", + href: formatAccountPathsFor(routes.account.credentials.edit, currentGatewayAccount.external_id) + "?change=username", text: "Change", visuallyHiddenText: "account credentials" } @@ -56,7 +56,7 @@ actions: { items: [ { - href: routes.credentials.edit + "?change=password", + href: formatAccountPathsFor(routes.account.credentials.edit, currentGatewayAccount.external_id) + "?change=password", text: "Change", visuallyHiddenText: "account credentials" } @@ -94,7 +94,7 @@ actions: { items: [ { - href: routes.notificationCredentials.edit + "?change=username", + href: formatAccountPathsFor(routes.account.notificationCredentials.edit, currentGatewayAccount.external_id) + "?change=username", text: "Change", visuallyHiddenText: "account credentials", attributes: { @@ -115,7 +115,7 @@ actions: { items: [ { - href: routes.notificationCredentials.edit + "?change=password", + href: formatAccountPathsFor(routes.account.notificationCredentials.edit, currentGatewayAccount.external_id) + "?change=password", text: "Change", visuallyHiddenText: "account credentials" } diff --git a/app/views/your-psp/_worldpay.njk b/app/views/your-psp/_worldpay.njk index 30e8bd3cff..433cc2fc44 100644 --- a/app/views/your-psp/_worldpay.njk +++ b/app/views/your-psp/_worldpay.njk @@ -17,7 +17,7 @@ actions: { items: [ { - href: routes.credentials.edit + "?change=merchantId", + href: formatAccountPathsFor(routes.account.credentials.edit, currentGatewayAccount.external_id) + "?change=merchantId", text: "Change", visuallyHiddenText: "account credentials", attributes: { @@ -38,7 +38,7 @@ actions: { items: [ { - href: routes.credentials.edit + "?change=username", + href: formatAccountPathsFor(routes.account.credentials.edit, currentGatewayAccount.external_id) + "?change=username", text: "Change", visuallyHiddenText: "account credentials" } @@ -56,7 +56,7 @@ actions: { items: [ { - href: routes.credentials.edit + "?change=password", + href: formatAccountPathsFor(routes.account.credentials.edit, currentGatewayAccount.external_id) + "?change=password", text: "Change", visuallyHiddenText: "account credentials" } diff --git a/test/cypress/integration/settings/your-psp.cy.test.js b/test/cypress/integration/settings/your-psp.cy.test.js index d9ac04d098..a4df82085b 100644 --- a/test/cypress/integration/settings/your-psp.cy.test.js +++ b/test/cypress/integration/settings/your-psp.cy.test.js @@ -9,7 +9,7 @@ describe('Your PSP settings page', () => { const gatewayAccountExternalId = 'a-valid-external-id' const serviceName = 'Purchase a positron projection permit' const yourPspPath = `/account/${gatewayAccountExternalId}/your-psp` - + const testCredentials = { merchant_id: 'positron-permit-people', username: 'jonheslop', diff --git a/test/integration/credentials.ft.test.js b/test/integration/credentials.ft.test.js deleted file mode 100644 index 7883499a54..0000000000 --- a/test/integration/credentials.ft.test.js +++ /dev/null @@ -1,623 +0,0 @@ -'use strict' - -const request = require('supertest') -const nock = require('nock') -const csrf = require('csrf') -const { expect } = require('chai') - -const userCreator = require('../test-helpers/user-creator.js') -require('../test-helpers/serialize-mock.js') -const getApp = require('../../server.js').getApp -const paths = require('../../app/paths.js') -const mockSession = require('../test-helpers/mock-session.js') -const gatewayAccountFixtures = require('../fixtures/gateway-account.fixtures') - -const ACCOUNT_ID = '182364' -const ACCOUNT_EXTERNAL_ID = 'an-account-external-id' -const CONNECTOR_ACCOUNT_PATH = '/v1/frontend/accounts/' + ACCOUNT_ID -// const CONNECTOR_ACCOUNT_BY_EXTERNAL_ID_PATH = '/v1/api/accounts/external-id/' + ACCOUNT_ID -const CONNECTOR_ACCOUNT_CREDENTIALS_PATH = CONNECTOR_ACCOUNT_PATH + '/credentials' -const CONNECTOR_ACCOUNT_NOTIFICATION_CREDENTIALS_PATH = '/v1/api/accounts/' + ACCOUNT_ID + '/notification-credentials' - -const requestId = 'some-unique-id' -const defaultCorrelationHeader = { - reqheaders: { 'x-request-id': requestId } -} -const yourPspPath = `/account/${ACCOUNT_EXTERNAL_ID}/your-psp` - -const connectorMock = nock(process.env.CONNECTOR_URL, defaultCorrelationHeader) - -let app - -describe('Credentials endpoints', () => { - describe('The ' + paths.credentials.index + ' endpoint', function () { - afterEach(function () { - nock.cleanAll() - app = null - }) - - beforeEach(function (done) { - const permissions = 'gateway-credentials:read' - const user = mockSession.getUser({ - gateway_account_ids: [ACCOUNT_ID], permissions: [{ name: permissions }] - }) - app = mockSession.getAppWithLoggedInUser(getApp(), user) - - userCreator.mockUserResponse(user.toJson(), done) - }) - - it('should display empty credential values when no gateway credentials are set', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(200, { - payment_provider: 'sandbox', - gateway_account_id: '1', - credentials: {} - }) - - buildGetRequest(paths.credentials.index, app) - .expect(200) - .expect(response => { - expect(response.body.currentGatewayAccount.credentials).to.be.empty // eslint-disable-line - }) - .end(done) - }) - - it('should display received credentials from connector', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(200, { - payment_provider: 'sandbox', - gateway_account_id: '1', - external_id: ACCOUNT_EXTERNAL_ID, - credentials: { username: 'a-username' } - }) - - buildGetRequest(paths.credentials.index, app) - .expect(200) - .expect(response => { - expect(response.body.currentGatewayAccount.credentials).to.deep.equal({ username: 'a-username' }) - }) - .end(done) - }) - - it('should return the account', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(200, { - payment_provider: 'sandbox', - gateway_account_id: '1', - external_id: ACCOUNT_EXTERNAL_ID, - credentials: { username: 'a-username', merchant_id: 'a-merchant-id' } - }) - - buildGetRequest(paths.credentials.index, app) - .expect(200) - .expect(response => { - expect(response.body.currentGatewayAccount.gateway_account_id).to.equal('1') - }) - .end(done) - }) - - it('should display an error if the account does not exist', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(404, { - message: "The gateway account id '" + ACCOUNT_ID + "' does not exist" - }) - - buildGetRequest(paths.credentials.index, app) - .expect(500, { message: 'There is a problem with the payments platform' }) - .end(done) - }) - - it('should display an error if connector returns any other error', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(999, { - message: 'Some error in Connector' - }) - - buildGetRequest(paths.credentials.index, app) - .expect(500, { message: 'There is a problem with the payments platform' }) - .end(done) - }) - - it('should display an error if the connection to connector fails', function (done) { - // No connectorMock defined on purpose to mock a network failure - - buildGetRequest(paths.credentials.index, app) - .expect(500, { message: 'There is a problem with the payments platform' }) - .end(done) - }) - }) - - describe('The ' + paths.credentials.edit + ' endpoint', function () { - afterEach(function () { - nock.cleanAll() - app = null - }) - - beforeEach(function (done) { - const permissions = 'gateway-credentials:update' - const user = mockSession.getUser({ - gateway_account_ids: [ACCOUNT_ID], permissions: [{ name: permissions }] - }) - app = mockSession.getAppWithLoggedInUser(getApp(), user) - - userCreator.mockUserResponse(user.toJson(), done) - }) - - it('should display payment provider name', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(200, { - payment_provider: 'sandbox', - gateway_account_id: '1', - external_id: ACCOUNT_EXTERNAL_ID, - credentials: {} - }) - - buildGetRequest(paths.credentials.edit, app) - .expect(200) - .expect(response => { - expect(response.body.currentGatewayAccount.payment_provider).to.equal('sandbox') - }) - .end(done) - }) - - it('should display empty credential values when no gateway credentials are set', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(200, { - payment_provider: 'sandbox', - gateway_account_id: '1', - external_id: ACCOUNT_EXTERNAL_ID, - credentials: {} - }) - - buildGetRequest(paths.credentials.edit, app) - .expect(200) - .expect(response => { - expect(response.body.currentGatewayAccount.credentials).to.be.empty // eslint-disable-line - }) - .end(done) - }) - - it('should display received credentials from connector', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(200, { - payment_provider: 'sandbox', - gateway_account_id: '1', - external_id: ACCOUNT_EXTERNAL_ID, - credentials: { username: 'a-username' } - }) - - buildGetRequest(paths.credentials.edit, app) - .expect(200) - .expect(response => { - expect(response.body.currentGatewayAccount.credentials).to.deep.equal({ username: 'a-username' }) - }) - .end(done) - }) - - it('should return the account', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(200, { - payment_provider: 'sandbox', - gateway_account_id: '1', - external_id: ACCOUNT_EXTERNAL_ID, - credentials: { username: 'a-username' } - }) - - buildGetRequest(paths.credentials.edit, app) - .expect(200) - .expect(response => { - expect(response.body.currentGatewayAccount.gateway_account_id).to.equal('1') - }) - .end(done) - }) - - it('should display an error if the account does not exist', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(404, { - message: "The gateway account id '" + ACCOUNT_ID + "' does not exist" - }) - - buildGetRequest(paths.credentials.edit, app) - .expect(500, { message: 'There is a problem with the payments platform' }) - .end(done) - }) - - it('should display an error if connector returns any other error', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(999, { - message: 'Some error in Connector' - }) - - buildGetRequest(paths.credentials.edit, app) - .expect(500, { message: 'There is a problem with the payments platform' }) - .end(done) - }) - - it('should display an error if the connection to connector fails', function (done) { - // No connectorMock defined on purpose to mock a network failure - - buildGetRequest(paths.credentials.edit, app) - .expect(500, { message: 'There is a problem with the payments platform' }) - .end(done) - }) - }) - - describe('The ' + paths.notificationCredentials.edit + ' endpoint', function () { - afterEach(function () { - nock.cleanAll() - app = null - }) - - beforeEach(function (done) { - const permissions = 'gateway-credentials:update' - const user = mockSession.getUser({ - gateway_account_ids: [ACCOUNT_ID], permissions: [{ name: permissions }] - }) - app = mockSession.getAppWithLoggedInUser(getApp(), user) - - userCreator.mockUserResponse(user.toJson(), done) - }) - - it('should display payment provider name', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(200, { - payment_provider: 'sandbox', - gateway_account_id: '1', - external_id: ACCOUNT_EXTERNAL_ID, - credentials: {} - }) - - buildGetRequest(paths.notificationCredentials.edit, app) - .expect(200) - .expect(response => { - expect(response.body.currentGatewayAccount.payment_provider).to.equal('sandbox') - }) - .end(done) - }) - - it('should display empty credential values when no gateway credentials are set', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(200, { - payment_provider: 'sandbox', - gateway_account_id: '1', - external_id: ACCOUNT_EXTERNAL_ID, - credentials: {} - }) - - buildGetRequest(paths.notificationCredentials.edit, app) - .expect(200) - .expect(response => { - expect(response.body.currentGatewayAccount.credentials).to.be.empty // eslint-disable-line - }) - .end(done) - }) - - it('should display received credentials from connector', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(200, { - payment_provider: 'sandbox', - gateway_account_id: '1', - external_id: ACCOUNT_EXTERNAL_ID, - credentials: { username: 'a-username' } - }) - - buildGetRequest(paths.notificationCredentials.edit, app) - .expect(200) - .expect(response => { - expect(response.body.currentGatewayAccount.credentials).to.be.deep.equal({ username: 'a-username' }) - }) - .end(done) - }) - - it('should return the account', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(200, { - payment_provider: 'sandbox', - gateway_account_id: '1', - credentials: { username: 'a-username', merchant_id: 'a-merchant-id' } - }) - - buildGetRequest(paths.notificationCredentials.edit, app) - .expect(200) - .expect(response => { - expect(response.body.currentGatewayAccount.gateway_account_id).to.equal('1') - }) - .end(done) - }) - - it('should display an error if the account does not exist', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(404, { - message: "The gateway account id '" + ACCOUNT_ID + "' does not exist" - }) - - buildGetRequest(paths.notificationCredentials.edit, app) - .expect(500, { message: 'There is a problem with the payments platform' }) - .end(done) - }) - - it('should display an error if connector returns any other error', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(999, { - message: 'Some error in Connector' - }) - - buildGetRequest(paths.notificationCredentials.edit, app) - .expect(500, { message: 'There is a problem with the payments platform' }) - .end(done) - }) - - it('should display an error if the connection to connector fails', function (done) { - // No connectorMock defined on purpose to mock a network failure - - buildGetRequest(paths.notificationCredentials.edit, app) - .expect(500, { message: 'There is a problem with the payments platform' }) - .end(done) - }) - }) - - describe('The notification credentials', function () { - afterEach(function () { - nock.cleanAll() - app = null - }) - - beforeEach(function (done) { - const permissions = 'gateway-credentials:read' - const user = mockSession.getUser({ - gateway_account_ids: [ACCOUNT_ID], permissions: [{ name: permissions }] - }) - app = mockSession.getAppWithLoggedInUser(getApp(), user) - - userCreator.mockUserResponse(user.toJson(), done) - }) - - it('should pass through the notification credentials', function (done) { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(200, { - payment_provider: 'smartpay', - gateway_account_id: '1', - external_id: ACCOUNT_EXTERNAL_ID, - credentials: { - username: 'a-username', - merchant_id: 'a-merchant-id' - }, - 'notificationCredentials': { username: 'a-notification-username' } - }) - - buildGetRequest(paths.notificationCredentials.index, app) - .expect(200) - .expect(response => { - expect(response.body.currentGatewayAccount.notificationCredentials).to.deep.equal({ username: 'a-notification-username' }) - }) - .end(done) - }) - }) - - describe('The provider update credentials endpoint', function () { - afterEach(function () { - nock.cleanAll() - app = null - }) - - beforeEach(function (done) { - const permissions = 'gateway-credentials:update' - const user = mockSession.getUser({ - gateway_account_ids: [ACCOUNT_ID], permissions: [{ name: permissions }] - }) - app = mockSession.getAppWithLoggedInUser(getApp(), user) - - userCreator.mockUserResponse(user.toJson(), done) - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(200, - gatewayAccountFixtures.validGatewayAccountResponse({ - gateway_account_id: ACCOUNT_ID, - external_id: ACCOUNT_EXTERNAL_ID - })) - }) - - it('should send new username, password and merchant_id credentials to connector', function (done) { - connectorMock.patch(CONNECTOR_ACCOUNT_CREDENTIALS_PATH, { - credentials: { - username: 'a-username', - password: 'a-password', - merchant_id: 'a-merchant-id' - } - }).reply(200, {}) - - const sendData = { username: 'a-username', password: 'a-password', merchantId: 'a-merchant-id' } - const path = paths.credentials.index - buildFormPostRequest(path, sendData, true, app) - .expect(303, {}) - .expect('Location', yourPspPath) - .end(done) - }) - - it('should send new username, password, merchant_id, sha_in_passphrase and sha_out_passphrase credentials to connector', function (done) { - connectorMock.patch(CONNECTOR_ACCOUNT_CREDENTIALS_PATH, { - credentials: { - username: 'a-username', - password: 'a-password', - merchant_id: 'a-psp-id', - sha_in_passphrase: 'a-sha-in-passphrase', - sha_out_passphrase: 'a-sha-out-passphrase' - - } - }).reply(200, {}) - - const sendData = { - username: 'a-username', - password: 'a-password', - merchantId: 'a-psp-id', - shaInPassphrase: 'a-sha-in-passphrase', - shaOutPassphrase: 'a-sha-out-passphrase' - } - const path = paths.credentials.index - buildFormPostRequest(path, sendData, true, app) - .expect(303, {}) - .expect('Location', yourPspPath) - .end(done) - }) - - it('should send any arbitrary credentials together with username and password to connector', function (done) { - connectorMock.patch(CONNECTOR_ACCOUNT_CREDENTIALS_PATH, { - credentials: { - username: 'a-username', - password: 'a-password' - } - }) - .reply(200, {}) - - const sendData = { username: 'a-username', password: 'a-password' } - const path = paths.credentials.index - buildFormPostRequest(path, sendData, true, app) - .expect(303, {}) - .expect('Location', yourPspPath) - .end(done) - }) - - it('should display an error if connector returns failure', function (done) { - connectorMock.patch(CONNECTOR_ACCOUNT_PATH, { - username: 'a-username', - password: 'a-password' - }) - .reply(999, { - message: 'Error message' - }) - - const sendData = { username: 'a-username', password: 'a-password' } - const expectedData = { message: 'There is a problem with the payments platform' } - const path = paths.credentials.index - buildFormPostRequest(path, sendData, true, app) - .expect(500, expectedData) - .end(done) - }) - - it('should display an error if the connection to connector fails', function (done) { - // No connectorMock defined on purpose to mock a network failure - - const sendData = { username: 'a-username', password: 'a-password' } - const expectedData = { message: 'There is a problem with the payments platform' } - const path = paths.credentials.index - buildFormPostRequest(path, sendData, true, app) - .expect(500, expectedData) - .end(done) - }) - - it('should fail if there is no csrf', done => { - connectorMock.patch(CONNECTOR_ACCOUNT_CREDENTIALS_PATH, { - username: 'a-username', - password: 'a-password' - }).reply(200, {}) - - const sendData = { username: 'a-username', password: 'a-password' } - const path = paths.credentials.index - buildFormPostRequest(path, sendData, false, app) - .expect(400, { message: 'There is a problem with the payments platform' }) - .end(done) - }) - }) - - describe('The provider update notification credentials endpoint', function () { - let session - afterEach(function () { - nock.cleanAll() - app = null - }) - - beforeEach(function (done) { - const permissions = 'gateway-credentials:update' - const user = mockSession.getUser({ - gateway_account_ids: [ACCOUNT_ID], permissions: [{ name: permissions }] - }) - session = mockSession.getMockSession(user) - app = mockSession.createAppWithSession(getApp(), session) - - userCreator.mockUserResponse(user.toJson(), done) - mockConnectorGetAccount() - }) - - it('should send new username and password notification credentials to connector', function (done) { - connectorMock.post(CONNECTOR_ACCOUNT_NOTIFICATION_CREDENTIALS_PATH, { - username: 'a-notification-username', - password: 'a-notification-password' - }) - .reply(200, {}) - - const sendData = { username: 'a-notification-username', password: 'a-notification-password' } - const path = paths.notificationCredentials.update - buildFormPostRequest(path, sendData, true, app) - .expect(303, {}) - .expect('Location', yourPspPath) - .end(done) - }) - - it('should should flash a relevant error if no password is sent', function (done) { - const sendData = { password: 'a-notification-password' } - const path = paths.notificationCredentials.update - buildFormPostRequest(path, sendData, true, app) - .expect(res => { - expect(res.statusCode).to.equal(302) - expect(res.headers.location).to.equal(paths.notificationCredentials.edit) - expect(session.flash.genericError).to.have.property('length').to.equal(1) - expect(session.flash.genericError[0]).to.equal('Enter a username') - }) - .end(done) - }) - it('should should flash a relevant error if no password is sent', function (done) { - const sendData = { username: 'a-notification-username' } - const path = paths.notificationCredentials.update - buildFormPostRequest(path, sendData, true, app) - .expect(res => { - expect(res.statusCode).to.equal(302) - expect(res.headers.location).to.equal(paths.notificationCredentials.edit) - expect(session.flash.genericError).to.have.property('length').to.equal(1) - expect(session.flash.genericError[0]).to.equal('Enter a password') - }) - .end(done) - }) - - it('should should flash a relevant error if too short a password is sent', function (done) { - const sendData = { username: 'a-notification-username', password: '123456789' } - const path = paths.notificationCredentials.update - buildFormPostRequest(path, sendData, true, app) - .expect(res => { - expect(res.statusCode).to.equal(302) - expect(res.headers.location).to.equal(paths.notificationCredentials.edit) - expect(session.flash.genericError).to.have.property('length').to.equal(1) - expect(session.flash.genericError[0]).to.equal('Password must be 10 characters or more') - }) - .end(done) - }) - }) -}) - -function mockConnectorGetAccount () { - connectorMock.get(CONNECTOR_ACCOUNT_PATH) - .reply(200, - gatewayAccountFixtures.validGatewayAccountResponse({ - gateway_account_id: ACCOUNT_ID, - external_id: ACCOUNT_EXTERNAL_ID - })) -} - -function buildGetRequest (path, app) { - return request(app) - .get(path) - .set('Accept', 'application/json') - .set('x-request-id', requestId) -} - -function buildFormPostRequest (path, sendData, sendCSRF, app) { - sendCSRF = (sendCSRF === undefined) ? true : sendCSRF - if (sendCSRF) { - sendData.csrfToken = csrf().create('123') - } - - return request(app) - .post(path) - .set('Accept', 'application/json') - .set('Content-Type', 'application/x-www-form-urlencoded') - .set('x-request-id', requestId) - .send(sendData) -} diff --git a/test/ui/credentials.ui.test.js b/test/ui/credentials.ui.test.js deleted file mode 100644 index 138f8394f7..0000000000 --- a/test/ui/credentials.ui.test.js +++ /dev/null @@ -1,152 +0,0 @@ -'use strict' - -const path = require('path') - -const renderTemplate = require(path.join(__dirname, '/../test-helpers/html-assertions.js')).render -const paths = require(path.join(__dirname, '/../../app/paths.js')) - -describe('The credentials view in edit mode', function () { - it('should display credentials view for a worldpay account', function () { - const templateData = { - currentGatewayAccount: { - 'payment_provider': 'worldpay', - 'credentials': { - 'username': 'a-username', - 'merchant_id': 'a-merchant-id' - } - }, - 'editMode': 'true', - permissions: { - gateway_credentials_update: true - } - } - - const body = renderTemplate('credentials/worldpay', templateData) - - body.should.containSelector('#view-title').withExactText('Your Worldpay credentials') - - body.should.containSelector('form#credentials-form') - .withAttribute('method', 'post') - .withAttribute('action', paths.credentials.create) - - body.should.not.containSelector('a#edit-credentials-link') - - body.should.containInputField('merchantId', 'text') - .withAttribute('value', 'a-merchant-id') - .withLabel('Merchant code') - - body.should.containInputField('username', 'text') - .withAttribute('value', 'a-username') - .withLabel('Username') - - body.should.containInputField('password', 'password') - .withLabel('Password') - - body.should.containSelector('#submitCredentials') - }) - - it('should display credentials view for a smartpay account', function () { - const templateData = { - currentGatewayAccount: { - 'payment_provider': 'smartpay', - 'credentials': { - 'username': 'a-username', - 'merchant_id': 'a-merchant-id' - } - }, - 'editMode': 'true', - permissions: { - gateway_credentials_update: true - } - } - - const body = renderTemplate('credentials/smartpay', templateData) - - body.should.containSelector('#view-title').withExactText('Your Smartpay credentials') - - body.should.containSelector('form#credentials-form') - .withAttribute('method', 'post') - .withAttribute('action', paths.credentials.create) - - body.should.not.containSelector('a#edit-credentials-link') - - body.should.containInputField('merchantId', 'text') - .withAttribute('value', 'a-merchant-id') - .withLabel('Merchant account code') - - body.should.containInputField('username', 'text') - .withAttribute('value', 'a-username') - .withLabel('Username') - - body.should.containInputField('password', 'password') - .withLabel('Password') - - body.should.containSelector('#submitCredentials') - }) - - it('should display credentials view for a ePDQ account', function () { - const templateData = { - currentGatewayAccount: { - 'payment_provider': 'epdq', - 'credentials': { - 'username': 'a-username', - 'merchant_id': 'a-psp-id' - } - }, - 'editMode': 'true', - permissions: { - gateway_credentials_update: true - } - } - - let body = renderTemplate('credentials/epdq', templateData) - - body.should.containSelector('#view-title').withExactText('Your ePDQ credentials') - - body.should.containSelector('form#credentials-form') - .withAttribute('method', 'post') - .withAttribute('action', paths.credentials.create) - - body.should.not.containSelector('a#edit-credentials-link') - - body.should.containInputField('merchantId', 'text') - .withAttribute('value', 'a-psp-id') - .withLabel('PSP ID') - - body.should.containInputField('username', 'text') - .withAttribute('value', 'a-username') - .withLabel('Username') - - body.should.containInputField('password', 'password') - .withLabel('Password') - - body.should.containInputField('shaInPassphrase', 'password') - .withLabel('SHA-IN passphrase') - - body.should.containInputField('shaOutPassphrase', 'password') - .withLabel('SHA-OUT passphrase') - - body.should.containSelector('#submitCredentials') - }) - - it('should display error page for `stripe`', function () { - const templateData = { - currentGatewayAccount: { - 'payment_provider': 'stripe', - 'credentials': {} - }, - 'editMode': 'true', - permissions: { - gateway_credentials_update: true - } - } - - const body = renderTemplate('404', templateData) - - body.should.containSelector('h1:first-of-type').withExactText('Page not found') - - body.should.not.containSelector('form#credentials-form') - body.should.not.containSelector('a#edit-credentials-link') - body.should.not.containSelector('input#submitCredentials') - }) -})