Skip to content

Commit

Permalink
Bugfix/714 Settlement Transfer Fulfilment Duplicate Check (#68)
Browse files Browse the repository at this point in the history
* Fixed transferFulfilment issue and settlement ABORT failure. Unit tests fail
* swagger.json update and unit tests fix
* Fix coverage
* Bump up version for next release
* Updated package-lock
* reset cache
* Fix ml-api-adapter start failure
  • Loading branch information
ggrg authored Apr 3, 2019
1 parent ee77cce commit ea4abde
Show file tree
Hide file tree
Showing 14 changed files with 147 additions and 44 deletions.
5 changes: 4 additions & 1 deletion .istanbul.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
instrumentation:
include-all-sources: true
excludes: ['**/test/**']
excludes: [
'**/test/**,
src/models/index.js'
]
check:
global:
statements: 90
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "central-settlement",
"description": "Central settlements hosted by a scheme to record and make settlements.",
"version": "5.3.0",
"description": "Central settlements hosted by a scheme to record and make settlements",
"version": "5.5.0",
"license": "Apache-2.0",
"private": true,
"author": "ModusBox",
Expand Down
3 changes: 2 additions & 1 deletion src/handlers/settlements/{id}.js
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,8 @@ module.exports = {
settlementStates: await request.server.methods.enums('settlementStates'),
settlementWindowStates: await request.server.methods.enums('settlementWindowStates'),
transferParticipantRoleTypes: await request.server.methods.enums('transferParticipantRoleTypes'),
transferStates: await request.server.methods.enums('transferStates')
transferStates: await request.server.methods.enums('transferStates'),
transferStateEnums: await request.server.methods.enums('transferStateEnums')
}
if (p.participants) {
return await Settlements.putById(settlementId, request.payload, Enums)
Expand Down
4 changes: 4 additions & 0 deletions src/interface/swagger.json
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,10 @@
"type": "string",
"enum": [
"PENDING_SETTLEMENT",
"PS_TRANSFERS_RECORDED",
"PS_TRANSFERS_RESERVED",
"PS_TRANSFERS_COMMITTED",
"SETTLING",
"SETTLED",
"ABORTED"
],
Expand Down
3 changes: 3 additions & 0 deletions src/models/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
their names indented and be marked with a '-'. Email address can be added
optionally within square brackets <email>.
* Gates Foundation
- Name Surname <name.surname@gatesfoundation.com>
* Georgi Georgiev <georgi.georgiev@modusbox.com>
* Valentin Genev <valentin.genev@modusbox.com>
* Deon Botha <deon.botha@modusbox.com>
Expand All @@ -24,5 +26,6 @@
--------------
******/
'use strict'

module.exports = require('@mojaloop/central-services-database').Db
17 changes: 17 additions & 0 deletions src/models/lib/enums.js
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,23 @@ module.exports = {
throw err
}
},
transferStateEnums: async function () {
try {
let transferStateEnum = {}
let transferStateEnumsList = await Db.transferState.find({})
if (transferStateEnumsList) {
for (let state of transferStateEnumsList) {
// apply distinct even though final result would contain distinct values
if (!transferStateEnum[`${state.enumeration}`]) {
transferStateEnum[`${state.enumeration}`] = state.enumeration
}
}
return transferStateEnum
}
} catch (err) {
throw err
}
},
ledgerAccountTypes: async function () {
try {
let ledgerAccountTypeEnum = {}
Expand Down
24 changes: 17 additions & 7 deletions src/models/settlement/facade.js
Original file line number Diff line number Diff line change
Expand Up @@ -389,13 +389,15 @@ const settlementTransfersAbort = async function (settlementId, transactionTimest
this.on('spcsc.settlementParticipantCurrencyId', 'spc.settlementParticipantCurrencyId')
.andOn('spcsc.settlementStateId', knex.raw('?', [enums.settlementStates.ABORTED]))
})
.leftJoin('transferStateChange AS tsc1', function () {
this.on('tsc1.transferId', 'spc.settlementTransferId')
.andOn('tsc1.transferStateId', knex.raw('?', [enums.transferStates.RESERVED]))
.leftJoin('transferStateChange AS tsc1', 'tsc1.transferId', 'spc.settlementTransferId')
.leftJoin('transferState AS ts1', function () {
this.on('ts1.transferStateId', 'tsc1.transferStateId')
.andOn('ts1.enumeration', knex.raw('?', [enums.transferStateEnums.RESERVED]))
})
.leftJoin('transferStateChange AS tsc2', function () {
this.on('tsc2.transferId', 'spc.settlementTransferId')
.andOn('tsc2.transferStateId', knex.raw('?', [enums.transferStates.ABORTED]))
.leftJoin('transferStateChange AS tsc2', 'tsc2.transferId', 'spc.settlementTransferId')
.leftJoin('transferState AS ts2', function () {
this.on('ts2.transferStateId', 'tsc2.transferStateId')
.andOn('ts2.enumeration', knex.raw('?', [enums.transferStateEnums.ABORTED]))
})
.join('transferParticipant AS tp1', function () {
this.on('tp1.transferId', 'spc.settlementTransferId')
Expand Down Expand Up @@ -575,9 +577,17 @@ const settlementTransfersCommit = async function (settlementId, transactionTimes
for (let { transferId, ledgerEntryTypeId, dfspAccountId, dfspAmount, hubAccountId, hubAmount,
dfspName, currencyId } of settlementTransferList) {
// Persist transfer fulfilment and transfer state change
const transferFulfilmentId = Uuid()
await knex('transferFulfilmentDuplicateCheck')
.insert({
transferFulfilmentId,
transferId
})
.transacting(trx)

await knex('transferFulfilment')
.insert({
transferFulfilmentId: Uuid(),
transferFulfilmentId,
transferId,
ilpFulfilment: 0,
completedDate: transactionTimestamp,
Expand Down
5 changes: 5 additions & 0 deletions test/integration-config-mlapiadapter.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
"expiresIn": 180000,
"generateTimeout": 30000
},
"ENDPOINT_SECURITY":{
"TLS": {
"rejectUnauthorized": true
}
},
"AMOUNT": {
"PRECISION": 10,
"SCALE": 2
Expand Down
1 change: 0 additions & 1 deletion test/integration/settlementTransfer.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
* Georgi Georgiev <georgi.georgiev@modusbox.com>
--------------
******/

'use strict'

const Test = require('tapes')(require('tape'))
Expand Down
2 changes: 2 additions & 0 deletions test/unit/handlers/settlements/{id}.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,7 @@ Test('/settlements/{id}', async (settlementTest) => {
sandbox.stub(Enums, 'settlementWindowStates').returns({})
sandbox.stub(Enums, 'transferParticipantRoleTypes').returns({})
sandbox.stub(Enums, 'transferStates').returns({})
sandbox.stub(Enums, 'transferStateEnums').returns({})
sandbox.stub(settlement, 'putById').returns({})
try {
const requests = new Promise((resolve, reject) => {
Expand Down Expand Up @@ -218,6 +219,7 @@ Test('/settlements/{id}', async (settlementTest) => {
sandbox.stub(Enums, 'settlementWindowStates').returns({})
sandbox.stub(Enums, 'transferParticipantRoleTypes').returns({})
sandbox.stub(Enums, 'transferStates').returns({})
sandbox.stub(Enums, 'transferStateEnums').returns({})
sandbox.stub(settlement, 'abortById').returns({})
try {
const requests = new Promise((resolve, reject) => {
Expand Down
1 change: 0 additions & 1 deletion test/unit/models/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@
* Georgi Georgiev <georgi.georgiev@modusbox.com>
--------------
******/

'use strict'

const Test = require('tapes')(require('tape'))
Expand Down
46 changes: 46 additions & 0 deletions test/unit/models/lib/enums.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,52 @@ Test('Enums', async (enumsTest) => {
}
})

await enumsTest.test('transferStateEnums should', async transferStateEnumsTest => {
try {
await transferStateEnumsTest.test('return', async test => {
try {
const states = [
{ enumeration: 'RECEIVED' },
{ enumeration: 'RESERVED' },
{ enumeration: 'COMMITTED' },
{ enumeration: 'ABORTED' },
{ enumeration: 'ABORTED' }
]
Db.transferState = { find: sandbox.stub().returns(states) }
let transferStateEnumsEnum = await Enums.transferStateEnums()
test.equal(Object.keys(transferStateEnumsEnum).length, states.length - 1, 'transfer states enum')

Db.transferState.find = sandbox.stub().returns(undefined)
transferStateEnumsEnum = await Enums.transferStateEnums()
test.notOk(transferStateEnumsEnum, 'undefined when no record is returned')
test.end()
} catch (err) {
Logger.error(`transferStateEnums failed with error - ${err}`)
test.fail()
test.end()
}
})

await transferStateEnumsTest.test('throw error if database is unavailable', async test => {
try {
Db.transferState = { find: sandbox.stub().throws(new Error('Database unavailable')) }
await Enums.transferStateEnums()
test.fail('Error not thrown!')
test.end()
} catch (err) {
Logger.error(`transferStateEnums failed with error - ${err}`)
test.pass('Error thrown')
test.end()
}
})
await transferStateEnumsTest.end()
} catch (err) {
Logger.error(`enumsTest failed with error - ${err}`)
transferStateEnumsTest.fail()
transferStateEnumsTest.end()
}
})

await enumsTest.test('ledgerAccountTypes should', async ledgerAccountTypesTest => {
try {
await ledgerAccountTypesTest.test('return', async test => {
Expand Down
74 changes: 44 additions & 30 deletions test/unit/models/settlement/facade.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,10 @@ Test('Settlement facade', async (settlementFacadeTest) => {
RESERVED: 'RESERVED',
COMMITTED: 'COMMITTED'
},
transferStateEnums: {
ABORTED: 'ABORTED',
RESERVED: 'RESERVED'
},
transferParticipantRoleTypes: {
PAYER_DFSP: 'PAYER_DFSP',
PAYEE_DFSP: 'PAYEE_DFSP',
Expand Down Expand Up @@ -1535,33 +1539,38 @@ Test('Settlement facade', async (settlementFacadeTest) => {
andOn: sandbox.stub()
})
let join1Stub = sandbox.stub().callsArgOn(1, context)
let join2Stub = sandbox.stub().callsArgOn(1, context)
let leftJoin1Stub = sandbox.stub().callsArgOn(1, context)
let leftJoin2Stub = sandbox.stub().callsArgOn(1, context)
let join2Stub = sandbox.stub().callsArgOn(1, context)
let join3Stub = sandbox.stub().callsArgOn(1, context)
let join4Stub = sandbox.stub().callsArgOn(1, context)
knexStub.returns({
join: join1Stub.returns({
leftJoin: join2Stub.returns({
leftJoin: sandbox.stub().returns({
leftJoin: leftJoin1Stub.returns({
join: join3Stub.returns({
join: sandbox.stub().returns({
join: sandbox.stub().returns({
join: join4Stub.returns({
select: sandbox.stub().returns({
where: sandbox.stub().returns({
whereNull: sandbox.stub().returns({
transacting: sandbox.stub().returns(
Promise.resolve(
stubData['settlementTransfersAbort'].settlementTransferList
)
)
leftJoin: sandbox.stub().returns({
leftJoin: leftJoin2Stub.returns({
join: join2Stub.returns({
join: sandbox.stub().returns({
join: sandbox.stub().returns({
join: join3Stub.returns({
select: sandbox.stub().returns({
where: sandbox.stub().returns({
whereNull: sandbox.stub().returns({
transacting: sandbox.stub().returns(
Promise.resolve(
stubData['settlementTransfersAbort'].settlementTransferList
)
)
})
})
})
})
})
})
})
})
})

})
})
}),
Expand Down Expand Up @@ -1768,33 +1777,38 @@ Test('Settlement facade', async (settlementFacadeTest) => {
andOn: sandbox.stub()
})
let join1Stub = sandbox.stub().callsArgOn(1, context)
let join2Stub = sandbox.stub().callsArgOn(1, context)
let leftJoin1Stub = sandbox.stub().callsArgOn(1, context)
let leftJoin2Stub = sandbox.stub().callsArgOn(1, context)
let join2Stub = sandbox.stub().callsArgOn(1, context)
let join3Stub = sandbox.stub().callsArgOn(1, context)
let join4Stub = sandbox.stub().callsArgOn(1, context)
knexStub.returns({
join: join1Stub.returns({
leftJoin: join2Stub.returns({
leftJoin: sandbox.stub().returns({
leftJoin: leftJoin1Stub.returns({
join: join3Stub.returns({
join: sandbox.stub().returns({
join: sandbox.stub().returns({
join: join4Stub.returns({
select: sandbox.stub().returns({
where: sandbox.stub().returns({
whereNull: sandbox.stub().returns({
transacting: sandbox.stub().returns(
Promise.resolve(
stubData['settlementTransfersAbort'].settlementTransferList
)
)
leftJoin: sandbox.stub().returns({
leftJoin: leftJoin2Stub.returns({
join: join2Stub.returns({
join: sandbox.stub().returns({
join: sandbox.stub().returns({
join: join3Stub.returns({
select: sandbox.stub().returns({
where: sandbox.stub().returns({
whereNull: sandbox.stub().returns({
transacting: sandbox.stub().returns(
Promise.resolve(
stubData['settlementTransfersAbort'].settlementTransferList
)
)
})
})
})
})
})
})
})
})
})

})
})
}),
Expand Down

0 comments on commit ea4abde

Please sign in to comment.