Skip to content

Commit

Permalink
Add Charging Module create transaction service (#140)
Browse files Browse the repository at this point in the history
https://eaflood.atlassian.net/browse/WATER-3911

The transactions we generate in the WRLS service as part of the SROC supplementary bill run need to be added to the Charging Module’s bill run. We already created the bill run using `app/services/charging-module/create-bill-run.service.js`. So, following that pattern, we add `app/services/charging-module/create-transaction.service.js` in this change.

---

**Housekeeping**

It is a personal preference that has become a convention in our tests. Executing the thing under test should be done within the test rather than a `before()` block.

It's our opinion when this isn't done you lose sight of what a test is testing as you add more and more unit tests. It does mean you get some duplication. But we think it makes for more readable code.

Because we based on unit tests on those in `test/services/charging-module/create-bill-run.service.test.js` we spotted this deviation and corrected it as part of this change.
  • Loading branch information
Jozzey authored Mar 4, 2023
1 parent 906c9e1 commit c46cb74
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 7 deletions.
19 changes: 19 additions & 0 deletions app/services/charging-module/create-transaction.service.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
'use strict'

/**
* Connects with the Charging Module to create a new transaction
* @module ChargingModuleCreateTransactionService
*/

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

async function go (billingBatchId, transactionData) {
const path = `v3/wrls/bill-runs/${billingBatchId}/transactions`
const result = await ChargingModuleRequestLib.post(path, transactionData)

return result
}

module.exports = {
go
}
12 changes: 5 additions & 7 deletions test/services/charging-module/create-bill-run.service.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ describe('Charge module create bill run service', () => {
})

describe('when the service can create a bill run', () => {
let result

beforeEach(async () => {
Sinon.stub(ChargingModuleRequestLib, 'post').resolves({
succeeded: true,
Expand All @@ -50,19 +48,19 @@ describe('Charge module create bill run service', () => {
}
}
})

result = await ChargingModuleCreateBillRunService.go(testRegion.regionId, 'sroc')
})

it('returns a `true` success status', async () => {
const result = await ChargingModuleCreateBillRunService.go(testRegion.regionId, 'sroc')

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

it('returns the bill run id and number in the `response`', async () => {
const { response } = result
const result = await ChargingModuleCreateBillRunService.go(testRegion.regionId, 'sroc')

expect(response.body.billRun.id).to.equal('2bbbe459-966e-4026-b5d2-2f10867bdddd')
expect(response.body.billRun.billRunNumber).to.equal(10004)
expect(result.response.body.billRun.id).to.equal('2bbbe459-966e-4026-b5d2-2f10867bdddd')
expect(result.response.body.billRun.billRunNumber).to.equal(10004)
})
})

Expand Down
118 changes: 118 additions & 0 deletions test/services/charging-module/create-transaction.service.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
'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 ChargingModuleRequestLib = require('../../../app/lib/charging-module-request.lib.js')

// Thing under test
const ChargingModuleCreateTransactionService = require('../../../app/services/charging-module/create-transaction.service.js')

describe('Charge module create transaction service', () => {
const billingBatchId = '2bbbe459-966e-4026-b5d2-2f10867bdddd'
const transactionData = { billingTransactionId: '2395429b-e703-43bc-8522-ce3f67507ffa' }

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

describe('when the service can create a transaction', () => {
beforeEach(async () => {
Sinon.stub(ChargingModuleRequestLib, 'post').resolves({
succeeded: true,
response: {
info: {
gitCommit: '273604040a47e0977b0579a0fef0f09726d95e39',
dockerTag: 'ghcr.io/defra/sroc-charging-module-api:v0.19.0'
},
statusCode: 200,
body: {
transaction: {
id: 'fd88e6c5-8da8-4e4f-b22f-c66554cd5bf3',
clientId: transactionData.billingTransactionId
}
}
}
})
})

it('returns a `true` success status', async () => {
const result = await ChargingModuleCreateTransactionService.go(billingBatchId, transactionData)

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

it('returns the CM transaction ID and our ID in the `response`', async () => {
const result = await ChargingModuleCreateTransactionService.go(billingBatchId, transactionData)

expect(result.response.body.transaction.id).to.equal('fd88e6c5-8da8-4e4f-b22f-c66554cd5bf3')
expect(result.response.body.transaction.clientId).to.equal(transactionData.billingTransactionId)
})
})

describe('when the service cannot create a transaction', () => {
describe('because the request did not return a 2xx/3xx response', () => {
beforeEach(async () => {
Sinon.stub(ChargingModuleRequestLib, '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 ChargingModuleCreateTransactionService.go(billingBatchId, transactionData)

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

it('returns the error in the `response`', async () => {
const result = await ChargingModuleCreateTransactionService.go(billingBatchId, 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(ChargingModuleRequestLib, 'post').resolves({
succeeded: false,
response: new Error("Timeout awaiting 'request' for 5000ms")
})
})

it('returns a `false` success status', async () => {
const result = await ChargingModuleCreateTransactionService.go(billingBatchId, transactionData)

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

it('returns the error in the `response`', async () => {
const result = await ChargingModuleCreateTransactionService.go(billingBatchId, 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")
})
})
})
})

0 comments on commit c46cb74

Please sign in to comment.