Skip to content

Commit

Permalink
Calculate and display expected charge during 2PT review (#1036)
Browse files Browse the repository at this point in the history
https://eaflood.atlassian.net/browse/WATER-4441

Add functionality to the Review Charge Reference page to allow the user to preview the charge for the Charge Reference.

The preview of the charge will be triggered by a button on the Review Charge Reference details page and will display the result in a banner at the top of the screen.

This is the first of two PRs. In this PR a new Charging Module "request" is being added to enable a request to be sent to the Charging Module to calculate a charge. The next PR will cover adding the functionality to the screens to enable a charge to be calculated for a charge reference.
  • Loading branch information
Jozzey authored May 23, 2024
1 parent ac09f0d commit e51889f
Show file tree
Hide file tree
Showing 2 changed files with 186 additions and 0 deletions.
28 changes: 28 additions & 0 deletions app/requests/charging-module/calculate-charge.request.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
'use strict'

/**
* Connects with the Charging Module to calculate a standalone charge
* @module CalculateChargeRequest
*/

const ChargingModuleRequest = require('../charging-module.request.js')

/**
* Sends a request to the Charging Module to calculate a standalone charge and returns the result.
*
* See {@link https://defra.github.io/sroc-charging-module-api-docs/#/calculate/CalculateCharge | API docs} for
* more details
*
* @param {Object} transactionData - The transaction details to be sent in the body of the request
*
* @returns {Promise<Object>} The result of the request; whether it succeeded and the response or error returned
*/
async function send (transactionData) {
const path = 'v3/wrls/calculate-charge'

return ChargingModuleRequest.post(path, transactionData)
}

module.exports = {
send
}
158 changes: 158 additions & 0 deletions test/requests/charging-module/calculate-charge.request.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
'use strict'

// Test framework dependencies
const Lab = require('@hapi/lab')
const Code = require('@hapi/code')
const Sinon = require('sinon')

const { describe, it, beforeEach, afterEach } = exports.lab = Lab.script()
const { expect } = Code

// Things we need to stub
const ChargingModuleRequest = require('../../../app/requests/charging-module.request.js')

// Thing under test
const CalculateChargeRequest = require('../../../app/requests/charging-module/calculate-charge.request.js')

describe('Charging Module Calculate Charge request', () => {
const transactionData = _transactionData()

afterEach(() => {
Sinon.restore()
})

describe('when the charge can be calculated', () => {
beforeEach(async () => {
Sinon.stub(ChargingModuleRequest, 'post').resolves({
succeeded: true,
response: {
info: {
gitCommit: '273604040a47e0977b0579a0fef0f09726d95e39',
dockerTag: 'ghcr.io/defra/sroc-charging-module-api:v0.19.0'
},
statusCode: 200,
body: {
calculation: {
chargeValue: 7000,
baseCharge: 9700,
waterCompanyChargeValue: 800,
supportedSourceValue: 3500,
winterOnlyFactor: null,
section130Factor: null,
section127Factor: 0.5,
compensationChargePercent: null
}
}
}
})
})

it('returns a "true" success status', async () => {
const result = await CalculateChargeRequest.send(transactionData)

expect(result.succeeded).to.be.true()
})

it('returns the results of the calculation in the "response"', async () => {
const result = await CalculateChargeRequest.send(transactionData)

expect(result.response.body.calculation.chargeValue).to.equal(7000)
expect(result.response.body.calculation.baseCharge).to.equal(9700)
expect(result.response.body.calculation.waterCompanyChargeValue).to.equal(800)
expect(result.response.body.calculation.supportedSourceValue).to.equal(3500)
expect(result.response.body.calculation.winterOnlyFactor).to.be.null()
expect(result.response.body.calculation.section130Factor).to.be.null()
expect(result.response.body.calculation.section127Factor).to.equal(0.5)
expect(result.response.body.calculation.compensationChargePercent).to.be.null()
})
})

describe('when the request cannot calculate a charge', () => {
describe('because the request did not return a 2xx/3xx response', () => {
beforeEach(async () => {
Sinon.stub(ChargingModuleRequest, 'post').resolves({
succeeded: false,
response: {
info: {
gitCommit: '273604040a47e0977b0579a0fef0f09726d95e39',
dockerTag: 'ghcr.io/defra/sroc-charging-module-api:v0.19.0'
},
statusCode: 401,
body: {
statusCode: 401,
error: 'Unauthorized',
message: 'Invalid JWT: Token format not valid',
attributes: { error: 'Invalid JWT: Token format not valid' }
}
}
})
})

it('returns a "false" success status', async () => {
const result = await CalculateChargeRequest.send(transactionData)

expect(result.succeeded).to.be.false()
})

it('returns the error in the "response"', async () => {
const result = await CalculateChargeRequest.send(transactionData)

expect(result.response.body.statusCode).to.equal(401)
expect(result.response.body.error).to.equal('Unauthorized')
expect(result.response.body.message).to.equal('Invalid JWT: Token format not valid')
})
})

describe('because the request attempt returned an error, for example, TimeoutError', () => {
beforeEach(async () => {
Sinon.stub(ChargingModuleRequest, 'post').resolves({
succeeded: false,
response: new Error("Timeout awaiting 'request' for 5000ms")
})
})

it('returns a "false" success status', async () => {
const result = await CalculateChargeRequest.send(transactionData)

expect(result.succeeded).to.be.false()
})

it('returns the error in the "response"', async () => {
const result = await CalculateChargeRequest.send(transactionData)

expect(result.response.statusCode).not.to.exist()
expect(result.response.body).not.to.exist()
expect(result.response.message).to.equal("Timeout awaiting 'request' for 5000ms")
})
})
})
})

function _transactionData () {
return {
abatementFactor: 1.0,
actualVolume: 1.0,
adjustmentFactor: 1.0,
aggregateProportion: 1.0,
authorisedDays: 21,
authorisedVolume: 1.0,
billableDays: 2,
chargeCategoryCode: '4.1.1',
compensationCharge: false,
credit: false,
loss: 'Low',
periodStart: '01-APR-2022',
periodEnd: '31-MAR-2023',
ruleset: 'sroc',
section127Agreement: true,
section130Agreement: false,
supportedSource: true,
// If `supportedSource` is `true` then `supportedSourceName` must be present
supportedSourceName: 'Candover',
// If `twoPartTariff` is `true` then `section127Agreement` must also be `true`
twoPartTariff: true,
waterCompanyCharge: true,
waterUndertaker: false,
winterOnly: false
}
}

0 comments on commit e51889f

Please sign in to comment.