Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PP-13377 show test payment notification on card payment screens #3945

Merged
merged 1 commit into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions app/middleware/retrieve-charge.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ module.exports = (req, res, next) => {
Charge(req.headers[CORRELATION_HEADER]).find(chargeId, getLoggingFields(req))
.then(data => {
req.chargeData = data
res.locals.isTestPayment = data.gateway_account.type === 'test'
setLoggingField(req, GATEWAY_ACCOUNT_ID, data.gateway_account.gateway_account_id)
setLoggingField(req, GATEWAY_ACCOUNT_TYPE, data.gateway_account.type)
setLoggingField(req, PROVIDER, data.payment_provider)
Expand Down
3 changes: 2 additions & 1 deletion app/views/charge.njk
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,8 @@
<div class="govuk-width-container govuk-main-wrapper">
<div class="govuk-grid-row govuk-!-margin-bottom-9">
<main class="charge-new govuk-grid-column-two-thirds" id="main-content" role="main">
<div class="charge-new__content">
{% include "includes/test-payment-notification-banner.njk" %}
<div class="charge-new__content">
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you've added a div here but you haven't added a closing tag - is that deliberate?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this div is just moved, not removed?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ha, yes clearly it is.

<div id="error-summary" data-cy="error-summary" class="govuk-error-summary {% if not hasError %}hidden{% endif %}" aria-labelledby="error-summary-title" role="alert" tabindex="-1" data-module="error-summary">
<h2 class="govuk-error-summary__title" id="error-summary-title">
{{ __p("fieldErrors.summary") }}
Expand Down
3 changes: 2 additions & 1 deletion app/views/confirm.njk
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<div class="govuk-width-container govuk-main-wrapper">
<div class="govuk-grid-row govuk-!-margin-bottom-9">
<main class="govuk-grid-column-two-thirds confirm-page" id="main-content" role="main">
{% include "includes/test-payment-notification-banner.njk" %}
<div class="confirm-page__content">
<h1 class="govuk-heading-xl govuk-!-margin-bottom-6">{{ __p("confirmDetails.title") }}</h1>

Expand Down Expand Up @@ -91,7 +92,7 @@
] %}
{% endif %}

{% if (charge.gatewayAccount.emailCollectionMode === 'MANDATORY')
{% if (charge.gatewayAccount.emailCollectionMode === 'MANDATORY')
or(charge.gatewayAccount.emailCollectionMode === 'OPTIONAL' and charge.email) %}
{% set emailArray = [
[
Expand Down
14 changes: 14 additions & 0 deletions app/views/includes/test-payment-notification-banner.njk
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{% from "govuk/components/notification-banner/macro.njk" import govukNotificationBanner %}
{% if isTestPayment === true %}
{% set html %}
<p class="govuk-notification-banner__heading">
This is a test page. No money will be taken.
</p>
<p class="govuk-body">
Contact the service you’re trying to pay for if you are trying to make a payment.
</p>
{% endset %}
{{ govukNotificationBanner({
html: html
}) }}
{% endif %}
21 changes: 16 additions & 5 deletions app/views/layout.njk
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
{% extends "govuk/template.njk" %}
{% from "govuk/components/phase-banner/macro.njk" import govukPhaseBanner %}

{% set htmlLang = language %}

{% block head %}
{% if service and service.customBranding and service.customBranding.cssUrl %}
<link href="{{ service.customBranding.cssUrl }}" media="all" rel="stylesheet" />
{% if service and service.customBranding and service.customBranding.cssUrl %}
<link href="{{ service.customBranding.cssUrl }}" media="all" rel="stylesheet"/>
{% else %}
<link href="{{ css_path }}" media="all" rel="stylesheet" />
<link href="{{ css_path }}" media="all" rel="stylesheet"/>
{% endif %}

{% include "includes/analytics.njk" %}
Expand Down Expand Up @@ -48,12 +49,22 @@
</div>
<div class="govuk-header__content">
<span class="govuk-header__service-name">
{{serviceName}}
{{ serviceName }}
</span>
</div>
</div>
</header>
{% endif %}
{% if isTestPayment %}
<div class="govuk-width-container">
{{ govukPhaseBanner({
tag: {
text: "Test service"
},
html: 'This is a test payment service.'
}) }}
</div>
{% endif %}
{% endblock %}

{% block bodyEnd %}
Expand Down Expand Up @@ -84,7 +95,7 @@
<ul class="govuk-footer__inline-list merchant-details">
<li class="govuk-footer__inline-list-item merchant-details-line-1">Service provided by {{ service.merchantDetails.name }}</li>
{% if service.hasCompleteMerchantDetailsAddress %}
<li class="govuk-footer__inline-list-item merchant-details-line-2">{{ service.merchantDetails.addressLine1 }}, {% if service.merchantDetails.addressLine2 -%} {{ service.merchantDetails.addressLine2 }}, {% endif -%} {{ service.merchantDetails.city }} {{ service.merchantDetails.postcode }} {{ service.merchantDetails.countryName }}</li>
<li class="govuk-footer__inline-list-item merchant-details-line-2">{{ service.merchantDetails.addressLine1 }}, {% if service.merchantDetails.addressLine2 -%} {{ service.merchantDetails.addressLine2 }}, {% endif -%} {{ service.merchantDetails.city }} {{ service.merchantDetails.postcode }} {{ service.merchantDetails.countryName }}</li>
{% endif %}
</ul>
{% endif %}
Expand Down
157 changes: 157 additions & 0 deletions test/cypress/integration/card/test-payment-notification.test.cy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
const cardPaymentStubs = require('../../utils/card-payment-stubs')
const { adminUsersGetService } = require('../../utils/stub-builders/service-stubs')
const {
connectorMultipleSubsequentChargeDetails,
connectorValidPatchConfirmedChargeDetails
} = require('../../utils/stub-builders/charge-stubs')
const { cardIdValidCardDetails } = require('../../utils/stub-builders/card-id-stubs')

const tokenId = 'be88a908-3b99-4254-9807-c855d53f6b2b'
const chargeId = 'ub8de8r5mh4pb49rgm1ismaqfv'
const validPayment = {
cardNumber: '4444333322221111',
expiryMonth: '01',
expiryYear: '30',
name: 'S. McDuck',
securityCode: '012',
addressLine1: 'McDuck Manor',
city: 'Duckburg',
postcode: 'SW1A 1AA',
email: '[email protected]'
}
const createPaymentChargeStubsEnglish = (isLive) => {
return cardPaymentStubs.buildCreatePaymentChargeStubs(tokenId, chargeId, 'en', 42, {}, {}, {
gatewayAccountType: isLive ? 'live' : 'test'
})
}
const checkCardDetailsStubs = (isLive) => {
return cardPaymentStubs.checkCardDetailsStubs(chargeId, 42, {
gatewayAccountType: isLive ? 'live' : 'test'
})
}
const confirmPaymentDetailsStubs = (isLive) => {
const gatewayAccountType = isLive ? 'live' : 'test'
return [
adminUsersGetService(),
connectorMultipleSubsequentChargeDetails([
{
chargeId,
status: 'AUTHORISATION READY',
state: { finished: false, status: 'started' },
gatewayAccountType
},
{
chargeId,
paymentDetails: validPayment,
status: 'AUTHORISATION READY',
state: { finished: false, status: 'submitted' },
gatewayAccountType
},
{
chargeId,
paymentDetails: validPayment,
status: 'AUTHORISATION SUCCESS',
state: { finished: false, status: 'submitted' },
gatewayAccountType
},
{
chargeId,
paymentDetails: validPayment,
status: 'AUTHORISATION SUCCESS',
state: { finished: false, status: 'submitted' },
gatewayAccountType
}
]),
cardIdValidCardDetails(),
connectorValidPatchConfirmedChargeDetails(chargeId)
]
}



describe('Card payment page', () => {
describe('A test payment', () => {
it('should show phase and notification banners', () => {
cy.task('setupStubs', createPaymentChargeStubsEnglish(false))
cy.visit(`/secure/${tokenId}`)
cy.location('pathname').should('eq', `/card_details/${chargeId}`)
shouldCheckPhaseBanner()
shouldCheckNotificationBanner()
cy.task('clearStubs')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it would be easier to follow if there was a line break each time the stubs are cleared, but that may be a personal thing so I wouldn't hold it back for that reason

cy.task('setupStubs', checkCardDetailsStubs(false))
shouldEnterCardDetails()
cy.task('clearStubs')
cy.task('setupStubs', confirmPaymentDetailsStubs(false))
cy.get('#card-details').submit()
cy.location('pathname').should('eq', `/card_details/${chargeId}/auth_waiting`)
shouldCheckPhaseBanner()
cy.get('p.lede').should('exist')
cy.location('pathname').should('eq', `/card_details/${chargeId}/confirm`)
shouldCheckPhaseBanner()
shouldCheckNotificationBanner()
cy.get('#expiry-date').should(($td) => expect($td).to.contain(`${validPayment.expiryMonth}/${validPayment.expiryYear}`))
cy.get('#cardholder-name').should(($td) => expect($td).to.contain(validPayment.name))
})
})
describe('A live payment', () => {
it('should not show phase and notification banners', () => {
cy.task('setupStubs', createPaymentChargeStubsEnglish(true))
cy.visit(`/secure/${tokenId}`)
cy.location('pathname').should('eq', `/card_details/${chargeId}`)
cy.get('.govuk-phase-banner')
.should('not.exist')
cy.get('.govuk-notification-banner')
.should('not.exist')
cy.task('clearStubs')
cy.task('setupStubs', checkCardDetailsStubs(true))
shouldEnterCardDetails()
cy.task('clearStubs')
cy.task('setupStubs', confirmPaymentDetailsStubs(true))
cy.get('#card-details').submit()
cy.location('pathname').should('eq', `/card_details/${chargeId}/auth_waiting`)
cy.get('.govuk-phase-banner')
.should('not.exist')
cy.get('p.lede').should('exist')
cy.location('pathname').should('eq', `/card_details/${chargeId}/confirm`)
cy.get('.govuk-phase-banner')
.should('not.exist')
cy.get('.govuk-notification-banner')
.should('not.exist')
cy.get('#expiry-date').should(($td) => expect($td).to.contain(`${validPayment.expiryMonth}/${validPayment.expiryYear}`))
cy.get('#cardholder-name').should(($td) => expect($td).to.contain(validPayment.name))
})
})
})

function shouldCheckPhaseBanner () {
cy.get('.govuk-phase-banner')
.should('exist')
.should('contain.text', 'Test service')
.should('contain.text', 'This is a test payment service.')
}

function shouldCheckNotificationBanner () {
cy.get('.govuk-notification-banner')
.should('exist')
.find('p.govuk-notification-banner__heading')
.should('contain.text', 'This is a test page. No money will be taken.')
.parent()
.find('p.govuk-body')
.should('contain.text', 'Contact the service you’re trying to pay for if you are trying to make a payment.')
}

function shouldEnterCardDetails () {
cy.intercept('POST', `/check_card/${chargeId}`).as('checkCard')
cy.log('Should enter card details')
cy.get('#card-no').type(validPayment.cardNumber)
cy.get('#card-no').blur()
cy.wait('@checkCard')
cy.get('#expiry-month').type(validPayment.expiryMonth)
cy.get('#expiry-year').type(validPayment.expiryYear)
cy.get('#cardholder-name').type(validPayment.name)
cy.get('#cvc').type(validPayment.securityCode)
cy.get('#address-line-1').type(validPayment.addressLine1)
cy.get('#address-city').type(validPayment.city)
cy.get('#address-postcode').type(validPayment.postcode)
cy.get('#email').type(validPayment.email)
}
3 changes: 2 additions & 1 deletion test/cypress/utils/card-payment-stubs.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,8 @@ function buildCreatePaymentChargeStubs (tokenId, chargeId, language = 'en', gate
emailCollectionMode: gatewayAccountOpts.emailCollectionMode || 'MANDATORY',
allowMoto: gatewayAccountOpts.allowMoto,
motoMaskCardNumberInput: gatewayAccountOpts.motoMaskCardNumberInput,
motoMaskCardSecurityCodeInput: gatewayAccountOpts.motoMaskCardSecurityCodeInput
motoMaskCardSecurityCodeInput: gatewayAccountOpts.motoMaskCardSecurityCodeInput,
gatewayAccountType: gatewayAccountOpts.gatewayAccountType || 'test'
}),
cardIdValidCardDetails(),
chargeStubs.connectorUpdateChargeStatus(chargeId),
Expand Down
3 changes: 1 addition & 2 deletions test/cypress/utils/stub-builders/charge-stubs.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ function connectorMultipleSubsequentChargeDetails (...chargesArr) {
})
})

const stub = {
return {
predicates: [{
equals: {
method: 'GET',
Expand All @@ -39,7 +39,6 @@ function connectorMultipleSubsequentChargeDetails (...chargesArr) {
}],
responses: responseArray
}
return stub
}

function connectorValidPatchConfirmedChargeDetails (chargeId) {
Expand Down
Loading