From a02e9ff52f9c8e410a76f0b76af97640805d5f72 Mon Sep 17 00:00:00 2001 From: Joe Haig Date: Thu, 4 Jan 2024 16:56:08 +0000 Subject: [PATCH] Remove illegal characters before calculation --- .../javascripts/modules/determination.mjs | 20 +- .../modules/determination_spec.mjs | 194 ++++++++++++------ 2 files changed, 142 insertions(+), 72 deletions(-) diff --git a/app/webpack/javascripts/modules/determination.mjs b/app/webpack/javascripts/modules/determination.mjs index 59ed028b79..eedefe2c7a 100644 --- a/app/webpack/javascripts/modules/determination.mjs +++ b/app/webpack/javascripts/modules/determination.mjs @@ -55,16 +55,18 @@ export class Determination { ] this.fields = fieldIds.map(id => document.querySelector(`#claim_assessment_attributes_${id}`)).filter(field => field) - this.fields.forEach(element => element.addEventListener('change', () => { - this.calculateTotalRows() - return true - })) + this.fields.forEach(element => { + element.addEventListener('change', (event) => { + this.cleanNumber(event.target) + this.calculateTotalRows() + }) + }) this.vatField = document.querySelector('#claim_assessment_attributes_vat_amount') if (this.vatField) { - this.vatField.addEventListener('change', () => { + this.vatField.addEventListener('change', (event) => { + this.cleanNumber(event.target) this.calculateTotalRows() - return true }) } } @@ -81,7 +83,7 @@ export class Determination { async applyVat (netAmount) { const params = new URLSearchParams({ scheme: this.scheme, - lgfs_vat_amount: this.$LgfsVat?.value, + lgfs_vat_amount: parseFloat(this.$LgfsVat?.value), date: this.vatDate, apply_vat: this.ajaxVat, net_amount: parseFloat(netAmount) @@ -91,7 +93,7 @@ export class Determination { return await response.json() } - numberFromField (n) { - return parseFloat(n) + cleanNumber (element) { + element.value = element.value.replaceAll(/[^\d.]/g, '').replace(/^(\d*\.\d\d).*$/, '$1') } } diff --git a/app/webpack/javascripts/modules/determination_spec.mjs b/app/webpack/javascripts/modules/determination_spec.mjs index 06455e14e6..f9baaf1d10 100644 --- a/app/webpack/javascripts/modules/determination_spec.mjs +++ b/app/webpack/javascripts/modules/determination_spec.mjs @@ -16,33 +16,33 @@ describe('Determination', () => { return testArea } - describe('calculateTotalRows', () => { - const createTable = ({ scheme, body }) => { - const table = document.createElement('table') - table.id = 'determinations' - table.setAttribute('data-module', 'govuk-determination') - table.setAttribute('data-apply-vat', 'true') - table.setAttribute('data-vat-url', '/vat.json') - table.setAttribute('data-submitted-date', '2023-07-18') - table.setAttribute('data-scheme', scheme) - table.appendChild(body) - - return table - } + const createTable = ({ scheme, body }) => { + const table = document.createElement('table') + table.id = 'determinations' + table.setAttribute('data-module', 'govuk-determination') + table.setAttribute('data-apply-vat', 'true') + table.setAttribute('data-vat-url', '/vat.json') + table.setAttribute('data-submitted-date', '2023-07-18') + table.setAttribute('data-scheme', scheme) + table.appendChild(body) + + return table + } - const inputRow = (id, klass) => { - const row = document.createElement('tr') - const cell = document.createElement('td') - row.append(cell) - const input = document.createElement('input') - input.type = 'text' - input.value = 0.0 - input.id = id - if (klass) { input.classList.add(klass) } - cell.append(input) - return row - } + const inputRow = (id, klass) => { + const row = document.createElement('tr') + const cell = document.createElement('td') + row.append(cell) + const input = document.createElement('input') + input.type = 'text' + input.value = 0.0 + input.id = id + if (klass) { input.classList.add(klass) } + cell.append(input) + return row + } + describe('calculateTotalRows', () => { const attributeRow = (id) => { const row = document.createElement('tr') const cell = document.createElement('td') @@ -52,28 +52,6 @@ describe('Determination', () => { return row } - const itMakesARequestToTheAPI = (params) => { - document.querySelector('#claim_assessment_attributes_fees').value = params.fees - document.querySelector('#claim_assessment_attributes_expenses').value = params.expenses - let vatAmountParam - if (params.vat_amount) { - document.querySelector('#claim_assessment_attributes_vat_amount').value = params.vat_amount - vatAmountParam = `${params.vat_amount}` - } - const netAmountParam = `${params.fees + params.expenses}` - - return determination.calculateTotalRows().then(() => { - const searchParams = new URLSearchParams() - searchParams.set('scheme', params.scheme) - searchParams.set('lgfs_vat_amount', vatAmountParam) - searchParams.set('date', '2023-07-18') - searchParams.set('apply_vat', 'true') - searchParams.set('net_amount', netAmountParam) - - expect(fetchSpy).toHaveBeenCalledWith('/vat.json?' + searchParams) - }) - } - beforeEach(() => { document.body.classList.add('govuk-frontend-supported') @@ -107,7 +85,18 @@ describe('Determination', () => { }) it('makes a request to the API', () => { - itMakesARequestToTheAPI({ scheme: 'agfs', fees: 3.14, expenses: 2.72 }) + document.querySelector('#claim_assessment_attributes_fees').value = 3.14 + document.querySelector('#claim_assessment_attributes_expenses').value = 2.72 + return determination.calculateTotalRows().then(() => { + const searchParams = new URLSearchParams() + searchParams.set('scheme', 'agfs') + searchParams.set('lgfs_vat_amount', 'NaN') + searchParams.set('date', '2023-07-18') + searchParams.set('apply_vat', 'true') + searchParams.set('net_amount', 5.86) + + return expect(fetchSpy).toHaveBeenCalledWith('/vat.json?' + searchParams) + }) }) it('sets the net amount', () => { @@ -151,23 +140,19 @@ describe('Determination', () => { }) it('makes a request to the API', () => { - itMakesARequestToTheAPI({ scheme: 'lgfs', fees: 3.14, expenses: 2.72, vat_amount: 1.17 }) - }) + document.querySelector('#claim_assessment_attributes_fees').value = 3.14 + document.querySelector('#claim_assessment_attributes_expenses').value = 2.72 + document.querySelector('#claim_assessment_attributes_vat_amount').value = 1.17 - it('allows for comma in values in request to the API', () => { - document.querySelector('#claim_assessment_attributes_fees').value = '3,140' - document.querySelector('#claim_assessment_attributes_expenses').value = '2,720' - document.querySelector('#claim_assessment_attributes_vat_amount').value = '1,170' - - determination.calculateTotalRows().then(() => { + return determination.calculateTotalRows().then(() => { const searchParams = new URLSearchParams() searchParams.set('scheme', 'lgfs') - searchParams.set('lgfs_vat_amount', '1170') + searchParams.set('lgfs_vat_amount', 1.17) searchParams.set('date', '2023-07-18') searchParams.set('apply_vat', 'true') - searchParams.set('net_amount', '5860') + searchParams.set('net_amount', 5.86) - expect(fetchSpy).toHaveBeenCalledWith('/vat.json?' + searchParams) + return expect(fetchSpy).toHaveBeenCalledWith('/vat.json?' + searchParams) }) }) @@ -189,14 +174,97 @@ describe('Determination', () => { }) }) - describe('numberFromField', () => { + describe('clean up numbers', () => { + const itDoesNotChangeAValidNumber = (element) => { + element.value = '99.99' + determination.cleanNumber(element) + + return expect(element.value).toEqual('99.99') + } + + const itRemovesCommas = (element) => { + element.value = '12,345,678.00' + determination.cleanNumber(element) + + return expect(element.value).toEqual('12345678.00') + } + + const itRemovesExtraDigits = (element) => { + element.value = '1.1234' + determination.cleanNumber(element) + + return expect(element.value).toEqual('1.12') + } + + const itRemovesLetters = (element) => { + element.value = '10abc' + determination.cleanNumber(element) + + return expect(element.value).toEqual('10') + } + beforeEach(() => { document.body.classList.add('govuk-frontend-supported') - createTestArea({ content: '' }) + + const tableBody = document.createElement('tbody') + tableBody.appendChild(inputRow('claim_assessment_attributes_fees')) + tableBody.appendChild(inputRow('claim_assessment_attributes_expenses')) + tableBody.appendChild(inputRow('claim_assessment_attributes_disbursements')) + tableBody.appendChild(inputRow('claim_assessment_attributes_vat_amount', 'js-lgfs-vat-determination')) + + createTestArea({ content: createTable({ scheme: 'agfs', body: tableBody }) }) + + fetchSpy = spyOn(window, 'fetch').and.resolveTo( + new Response( + JSON.stringify({ + net_amount: '£196.50', + vat_amount: '£39.30', + total_inc_vat: '£235.80' + }), + { status: 200, statusText: 'OK' } + ) + ) }) - it('returns as a float', () => { - expect(determination.numberFromField('99.99)')).toEqual(99.99) + afterEach(() => { + document.body.classList.remove('govuk-frontend-supported') + document.querySelector('.test-area').remove() + }) + + it('fees field', () => { + const element = document.querySelector('#claim_assessment_attributes_fees') + + itDoesNotChangeAValidNumber(element) + itRemovesCommas(element) + itRemovesExtraDigits(element) + itRemovesLetters(element) + }) + + it('expenses field', () => { + const element = document.querySelector('#claim_assessment_attributes_expenses') + + itDoesNotChangeAValidNumber(element) + itRemovesCommas(element) + itRemovesExtraDigits(element) + itRemovesLetters(element) + }) + + it('disbursements field', () => { + const element = document.querySelector('#claim_assessment_attributes_disbursements') + + itDoesNotChangeAValidNumber(element) + itRemovesCommas(element) + itRemovesExtraDigits(element) + itRemovesLetters(element) + }) + + it('vat_amount field', () => { + const element = document.querySelector('#claim_assessment_attributes_vat_amount') + + itDoesNotChangeAValidNumber(element) + itRemovesCommas(element) + itRemovesExtraDigits(element) + itRemovesLetters(element) }) }) })