Skip to content

Commit c3c1739

Browse files
committed
refactor: improve currency formatting and add tests
1 parent c71b5fc commit c3c1739

8 files changed

Lines changed: 30 additions & 31 deletions

File tree

src/server/plugins/engine/components/PaymentField.test.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ describe('PaymentField', () => {
196196
label: { text: def.title },
197197
name: 'myComponent',
198198
id: 'myComponent',
199-
amount: '100.00',
199+
amount: '£100.00',
200200
attributes: {},
201201
description: 'Test payment description'
202202
})
@@ -220,7 +220,7 @@ describe('PaymentField', () => {
220220
label: { text: def.title },
221221
name: 'myComponent',
222222
id: 'myComponent',
223-
amount: '100.00',
223+
amount: '£100.00',
224224
attributes: {},
225225
description: 'Test payment description'
226226
})

src/server/plugins/engine/components/PaymentField.ts

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ import {
3131
} from '~/src/server/plugins/engine/types.js'
3232
import {
3333
createPaymentService,
34-
formatPaymentAmount
34+
formatCurrency
3535
} from '~/src/server/plugins/payment/helper.js'
3636

3737
export class PaymentField extends FormComponent {
@@ -94,7 +94,7 @@ export class PaymentField extends FormComponent {
9494
return ''
9595
}
9696

97-
return `${formatPaymentAmount(value.amount)} - ${value.description}`
97+
return `${formatCurrency(value.amount)} - ${value.description}`
9898
}
9999

100100
getViewModel(payload: FormPayload, errors?: FormSubmissionError[]) {
@@ -108,14 +108,9 @@ export class PaymentField extends FormComponent {
108108
// When user initially visits the payment page, there is no payment state yet so the amount is read form the form definition.
109109
const amount = paymentState?.amount ?? this.options.amount
110110

111-
const formattedAmount = new Intl.NumberFormat('en-GB', {
112-
minimumFractionDigits: 2,
113-
maximumFractionDigits: 2
114-
}).format(amount)
115-
116111
return {
117112
...viewModel,
118-
amount: formattedAmount,
113+
amount: formatCurrency(amount),
119114
description: this.options.description,
120115
paymentState
121116
}
@@ -159,7 +154,7 @@ export class PaymentField extends FormComponent {
159154

160155
getContextValueFromState(state: FormSubmissionState) {
161156
return this.isPaymentState(state)
162-
? `Reference: ${state.reference}\nAmount: ${formatPaymentAmount(state.amount)}`
157+
? `Reference: ${state.reference}\nAmount: ${formatCurrency(state.amount)}`
163158
: ''
164159
}
165160

src/server/plugins/engine/outputFormatters/human/v1.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ import {
1616
} from '~/src/server/plugins/engine/models/types.js'
1717
import { type FormContext } from '~/src/server/plugins/engine/types.js'
1818
import {
19-
formatPaymentAmount,
19+
formatCurrency,
2020
formatPaymentDate
2121
} from '~/src/server/plugins/payment/helper.js'
2222

@@ -115,7 +115,7 @@ function appendPaymentSection(paymentItems: DetailItem[], lines: string[]) {
115115
return
116116
}
117117

118-
const formattedAmount = formatPaymentAmount(paymentState.amount)
118+
const formattedAmount = formatCurrency(paymentState.amount)
119119
const dateOfPayment = paymentState.preAuth?.createdAt
120120
? formatPaymentDate(paymentState.preAuth.createdAt)
121121
: ''

src/server/plugins/engine/pageControllers/SummaryPageController.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ import {
4646
} from '~/src/server/plugins/engine/types.js'
4747
import {
4848
DEFAULT_PAYMENT_HELP_URL,
49-
formatPaymentAmount,
49+
formatCurrency,
5050
formatPaymentDate
5151
} from '~/src/server/plugins/payment/helper.js'
5252
import {
@@ -125,7 +125,7 @@ export class SummaryPageController extends QuestionPageController {
125125
},
126126
{
127127
key: { text: 'Total amount' },
128-
value: { text: formatPaymentAmount(paymentState.amount) }
128+
value: { text: formatCurrency(paymentState.amount) }
129129
},
130130
{
131131
key: { text: 'Reference' },

src/server/plugins/engine/pageControllers/helpers/submission.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import {
77
type DetailItemField
88
} from '~/src/server/plugins/engine/models/types.js'
99
import {
10-
formatPaymentAmount,
10+
formatCurrency,
1111
formatPaymentDate
1212
} from '~/src/server/plugins/payment/helper.js'
1313

@@ -71,7 +71,7 @@ export function buildPaymentRecords(item: DetailItemField): SubmitRecord[] {
7171
{
7272
name: `${item.name}_paymentAmount`,
7373
title: 'Payment amount',
74-
value: formatPaymentAmount(paymentState.amount)
74+
value: formatCurrency(paymentState.amount)
7575
},
7676
{
7777
name: `${item.name}_paymentReference`,

src/server/plugins/engine/views/components/paymentfield.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ <h2 class="govuk-heading-m">{{ model.label.text if model.label and model.label.t
2828
<p class="govuk-body">You can submit the form after you have added your payment details.</p>
2929

3030
<p class="govuk-body govuk-!-margin-bottom-1">Total amount:</p>
31-
<p class="govuk-heading-l govuk-!-margin-bottom-4 govuk-!-padding-top-0">£{{ amount }}</p>
31+
<p class="govuk-heading-l govuk-!-margin-bottom-4 govuk-!-padding-top-0">{{ amount }}</p>
3232

3333
{{ govukButton({
3434
text: "Add payment details",

src/server/plugins/payment/helper.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,17 @@ export function formatPaymentDate(isoString) {
4747
}
4848

4949
/**
50-
* Formats a payment amount with thousand separators and two decimal places
50+
* Formats a currency amount with thousand separators and two decimal places
5151
* @param {number} amount - amount in pounds
52+
* @param {'en-GB'} [locale] - locale for formatting
53+
* @param {'GBP'} [currency] - currency code
5254
* @returns {string} Formatted amount (e.g., "£1,234.56")
5355
*/
54-
export function formatPaymentAmount(amount) {
55-
return new Intl.NumberFormat('en-GB', {
56+
export function formatCurrency(amount, locale = 'en-GB', currency = 'GBP') {
57+
const formatter = new Intl.NumberFormat(locale, {
5658
style: 'currency',
57-
currency: 'GBP'
58-
}).format(amount)
59+
currency
60+
})
61+
62+
return formatter.format(amount)
5963
}

src/server/plugins/payment/helper.test.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { config } from '~/src/config/index.js'
22
import {
3-
formatPaymentAmount,
3+
formatCurrency,
44
formatPaymentDate,
55
getPaymentApiKey
66
} from '~/src/server/plugins/payment/helper.js'
@@ -41,20 +41,20 @@ describe('formatPaymentDate', () => {
4141
})
4242
})
4343

44-
describe('formatPaymentAmount', () => {
45-
it('should format whole number with two decimal places', () => {
46-
expect(formatPaymentAmount(10)).toBe('£10.00')
44+
describe('formatCurrency', () => {
45+
it('should format whole number with currency symbol', () => {
46+
expect(formatCurrency(10)).toBe('£10.00')
4747
})
4848

49-
it('should format decimal amount', () => {
50-
expect(formatPaymentAmount(99.5)).toBe('£99.50')
49+
it('should format decimal amount with currency symbol', () => {
50+
expect(formatCurrency(99.5)).toBe('£99.50')
5151
})
5252

5353
it('should format large amounts with thousand separators', () => {
54-
expect(formatPaymentAmount(1234.56)).toBe('£1,234.56')
54+
expect(formatCurrency(1234.56)).toBe('£1,234.56')
5555
})
5656

5757
it('should format very large amounts with thousand separators', () => {
58-
expect(formatPaymentAmount(20000)).toBe('£20,000.00')
58+
expect(formatCurrency(20000)).toBe('£20,000.00')
5959
})
6060
})

0 commit comments

Comments
 (0)