Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: unit tests for zero position change #1081

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion audit-ci.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
"GHSA-c429-5p7v-vgjp", // https://github.com/advisories/GHSA-c429-5p7v-vgjp
"GHSA-g64q-3vg8-8f93", // https://github.com/advisories/GHSA-g64q-3vg8-8f93
"GHSA-mg85-8mv5-ffjr", // https://github.com/advisories/GHSA-mg85-8mv5-ffjr
"GHSA-8hc4-vh64-cxmj" // https://github.com/advisories/GHSA-8hc4-vh64-cxmj
"GHSA-8hc4-vh64-cxmj", // https://github.com/advisories/GHSA-8hc4-vh64-cxmj
"GHSA-952p-6rrq-rcjv" // https://github.com/advisories/GHSA-952p-6rrq-rcjv
]
}
10 changes: 5 additions & 5 deletions src/domain/position/abort.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ const Logger = require('@mojaloop/central-services-logger')
*
* @param {array} abortBins - an array containing abort / fx-abort action bins
* @param {object} options
* @param {number} accumulatedPositionValue - value of position accumulated so far from previous bin processing
* @param {number} accumulatedPositionReservedValue - value of position reserved accumulated so far, not used but kept for consistency
* @param {object} accumulatedTransferStates - object with transfer id keys and transfer state id values. Used to check if transfer is in correct state for processing. Clone and update states for output.
* @param {object} transferInfoList - object with transfer id keys and transfer info values. Used to pass transfer info to domain function.
* @param {boolean} changePositions - whether to change positions or not
* @param {number} accumulatedPositionValue - value of position accumulated so far from previous bin processing
* @param {number} accumulatedPositionReservedValue - value of position reserved accumulated so far, not used but kept for consistency
* @param {object} accumulatedTransferStates - object with transfer id keys and transfer state id values. Used to check if transfer is in correct state for processing. Clone and update states for output.
* @param {object} transferInfoList - object with transfer id keys and transfer info values. Used to pass transfer info to domain function.
* @param {boolean} changePositions - whether to change positions or not
* @returns {object} - Returns an object containing accumulatedPositionValue, accumulatedPositionReservedValue, accumulatedTransferStateChanges, accumulatedTransferStates, resultMessages, limitAlarms or throws an error if failed
*/
const processPositionAbortBin = async (
Expand Down
1 change: 0 additions & 1 deletion src/domain/position/binProcessor.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@

* INFITX
- Vijay Kumar Guthi <[email protected]>
- Steven Oderayi <[email protected]>

--------------
******/
Expand Down
15 changes: 8 additions & 7 deletions src/domain/position/fx-prepare.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,14 +11,14 @@ const Logger = require('@mojaloop/central-services-logger')
* @async
* @description This is the domain function to process a bin of position-prepare messages of a single participant account.
*
* @param {array} binItems - an array of objects that contain a position prepare message and its span. {message, span}
* @param {array} binItems - an array of objects that contain a position prepare message and its span. {message, decodedPayload, span}
* @param {object} options
* @param {number} accumulatedPositionValue - value of position accumulated so far from previous bin processing
* @param {number} accumulatedPositionReservedValue - value of position reserved accumulated so far, not used but kept for consistency
* @param {object} accumulatedFxTransferStates - object with fx commit request id keys and fx transfer state id values. Used to check if fx transfer is in correct state for processing. Clone and update states for output.
* @param {number} settlementParticipantPosition - position value of the participants settlement account
* @param {object} participantLimit - participant limit object for the currency
* @param {boolean} changePositions - whether to change positions or not
* @param {number} accumulatedPositionValue - value of position accumulated so far from previous bin processing
* @param {number} accumulatedPositionReservedValue - value of position reserved accumulated so far, not used but kept for consistency
* @param {object} accumulatedFxTransferStates - object with fx commit request id keys and fx transfer state id values. Used to check if fx transfer is in correct state for processing. Clone and update states for output.
* @param {number} settlementParticipantPosition - position value of the participants settlement account
* @param {object} participantLimit - participant limit object for the currency
* @param {boolean} changePositions - whether to change positions or not
* @returns {object} - Returns an object containing accumulatedPositionValue, accumulatedPositionReservedValue, accumulatedFxTransferStateChanges, accumulatedTransferStates, resultMessages, limitAlarms or throws an error if failed
*/
const processFxPositionPrepareBin = async (
Expand All @@ -42,6 +42,7 @@ const processFxPositionPrepareBin = async (
let liquidityCover = 0
let availablePositionBasedOnLiquidityCover = 0
let availablePositionBasedOnPayerLimit = 0

if (changePositions) {
const reservedPosition = new MLNumber(accumulatedPositionReservedValue)
const effectivePosition = new MLNumber(currentPosition.add(reservedPosition).toFixed(Config.AMOUNT.SCALE))
Expand Down
18 changes: 9 additions & 9 deletions src/domain/position/prepare.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,25 @@
const { Enum } = require('@mojaloop/central-services-shared')
const ErrorHandler = require('@mojaloop/central-services-error-handling')
const Config = require('../../lib/config')
const Utility = require('@mojaloop/central-services-shared').Util
const MLNumber = require('@mojaloop/ml-number')
const Logger = require('@mojaloop/central-services-logger')
const Config = require('../../lib/config')

/**
* @function processPositionPrepareBin
*
* @async
* @description This is the domain function to process a bin of position-prepare messages of a single participant account.
*
* @param {array} binItems - an array of objects that contain a position prepare message and its span. {message, span}
* @param {array} binItems - an array of objects that contain a position prepare message and its span. {message, decodedPayload, span}
* @param {object} options
* @param {number} accumulatedPositionValue - value of position accumulated so far from previous bin processing
* @param {number} accumulatedPositionReservedValue - value of position reserved accumulated so far, not used but kept for consistency
* @param {object} accumulatedTransferStates - object with transfer id keys and transfer state id values. Used to check if transfer is in correct state for processing. Clone and update states for output.
* @param {number} settlementParticipantPosition - position value of the participants settlement account
* @param {object} settlementModel - settlement model object for the currency
* @param {object} participantLimit - participant limit object for the currency
* @param {boolean} changePositions - whether to change positions or not
* @param {number} accumulatedPositionValue - value of position accumulated so far from previous bin processing
* @param {number} accumulatedPositionReservedValue - value of position reserved accumulated so far, not used but kept for consistency
* @param {object} accumulatedTransferStates - object with transfer id keys and transfer state id values. Used to check if transfer is in correct state for processing. Clone and update states for output.
* @param {number} settlementParticipantPosition - position value of the participants settlement account
* @param {object} settlementModel - settlement model object for the currency
* @param {object} participantLimit - participant limit object for the currency
* @param {boolean} changePositions - whether to change positions or not
* @returns {object} - Returns an object containing accumulatedPositionValue, accumulatedPositionReservedValue, accumulatedTransferStateChanges, accumulatedTransferStates, resultMessages, limitAlarms or throws an error if failed
*/
const processPositionPrepareBin = async (
Expand Down
1 change: 0 additions & 1 deletion src/models/misc/segment.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@

const Db = require('../../lib/db')
const ErrorHandler = require('@mojaloop/central-services-error-handling')
// const Logger = require('@mojaloop/central-services-logger')

const getByParams = async (params) => {
try {
Expand Down
28 changes: 28 additions & 0 deletions test/unit/domain/position/abort.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -530,6 +530,34 @@ Test('abort domain', positionIndexTest => {
test.end()
})

processPositionAbortBinTest.test('skip position changes if changePositions is false', async (test) => {
const binItems = getAbortBinItems()
try {
const processedResult = await processPositionAbortBin(
binItems,
{
accumulatedPositionValue: 0,
accumulatedPositionReservedValue: 0,
accumulatedTransferStates: {
'a0000001-0000-0000-0000-000000000000': Enum.Transfers.TransferInternalState.RECEIVED_ERROR,
'a0000002-0000-0000-0000-000000000000': Enum.Transfers.TransferInternalState.RECEIVED_ERROR
},
isFx: false,
changePositions: false
}
)
test.equal(processedResult.accumulatedPositionChanges.length, 0)
test.equal(processedResult.accumulatedPositionValue, 0)
test.equal(processedResult.accumulatedTransferStateChanges.length, 2)
processedResult.accumulatedTransferStateChanges.forEach(transferStateChange => test.equal(transferStateChange.transferStateId, Enum.Transfers.TransferInternalState.ABORTED_ERROR))
processedResult.accumulatedTransferStates[abortMessage1.value.id] = Enum.Transfers.TransferInternalState.ABORTED_ERROR
processedResult.accumulatedTransferStates[abortMessage2.value.id] = Enum.Transfers.TransferInternalState.ABORTED_ERROR
} catch (e) {
test.fail('Error thrown')
}
test.end()
})

processPositionAbortBinTest.end()
})

Expand Down
67 changes: 53 additions & 14 deletions test/unit/domain/position/binProcessor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ const fxTimeoutReservedTransfers = [

Test('BinProcessor', async (binProcessorTest) => {
let sandbox

binProcessorTest.beforeEach(async test => {
sandbox = Sinon.createSandbox()
sandbox.stub(BatchPositionModel)
Expand Down Expand Up @@ -439,8 +440,8 @@ Test('BinProcessor', async (binProcessorTest) => {
test.end()
})

binProcessorTest.test('binProcessor should', prepareActionTest => {
prepareActionTest.test('processBins should process a bin of positions and return the expected results', async (test) => {
binProcessorTest.test('binProcessor should', processBinsTest => {
processBinsTest.test('processBins should process a bin of positions and return the expected results', async (test) => {
const sampleParticipantLimitReturnValues = [
{
participantId: 2,
Expand Down Expand Up @@ -484,7 +485,7 @@ Test('BinProcessor', async (binProcessorTest) => {
test.end()
})

prepareActionTest.test('processBins should handle prepare messages', async (test) => {
processBinsTest.test('processBins should handle prepare messages', async (test) => {
const sampleParticipantLimitReturnValues = [
{
participantId: 2,
Expand Down Expand Up @@ -536,7 +537,7 @@ Test('BinProcessor', async (binProcessorTest) => {
test.end()
})

prepareActionTest.test('processBins should handle commit messages', async (test) => {
processBinsTest.test('processBins should handle commit messages', async (test) => {
const sampleParticipantLimitReturnValues = [
{
participantId: 2,
Expand Down Expand Up @@ -585,7 +586,7 @@ Test('BinProcessor', async (binProcessorTest) => {
test.end()
})

prepareActionTest.test('processBins should handle reserve messages', async (test) => {
processBinsTest.test('processBins should handle reserve messages', async (test) => {
const sampleParticipantLimitReturnValues = [
{
participantId: 2,
Expand Down Expand Up @@ -634,7 +635,7 @@ Test('BinProcessor', async (binProcessorTest) => {
test.end()
})

prepareActionTest.test('processBins should handle timeout-reserved messages', async (test) => {
processBinsTest.test('processBins should handle timeout-reserved messages', async (test) => {
const sampleParticipantLimitReturnValues = [
{
participantId: 2,
Expand Down Expand Up @@ -683,7 +684,7 @@ Test('BinProcessor', async (binProcessorTest) => {
test.end()
})

prepareActionTest.test('processBins should handle fx-timeout-reserved messages', async (test) => {
processBinsTest.test('processBins should handle fx-timeout-reserved messages', async (test) => {
const sampleParticipantLimitReturnValues = [
{
participantId: 2,
Expand Down Expand Up @@ -732,7 +733,7 @@ Test('BinProcessor', async (binProcessorTest) => {
test.end()
})

prepareActionTest.test('processBins should throw error if any accountId cannot be matched to atleast one participantCurrencyId', async (test) => {
processBinsTest.test('processBins should throw error if any accountId cannot be matched to atleast one participantCurrencyId', async (test) => {
const sampleParticipantLimitReturnValues = [
{
participantId: 2,
Expand Down Expand Up @@ -761,7 +762,7 @@ Test('BinProcessor', async (binProcessorTest) => {
test.end()
})

prepareActionTest.test('processBins should throw error if no settlement model is found', async (test) => {
processBinsTest.test('processBins should throw error if no settlement model is found', async (test) => {
SettlementModelCached.getAll.returns([])
const sampleParticipantLimitReturnValues = [
{
Expand All @@ -787,7 +788,7 @@ Test('BinProcessor', async (binProcessorTest) => {
test.end()
})

prepareActionTest.test('processBins should throw error if no default settlement model if currency model is missing', async (test) => {
processBinsTest.test('processBins should throw error if no default settlement model if currency model is missing', async (test) => {
SettlementModelCached.getAll.returns([
{
settlementModelId: 3,
Expand Down Expand Up @@ -828,7 +829,7 @@ Test('BinProcessor', async (binProcessorTest) => {
test.end()
})

prepareActionTest.test('processBins should use default settlement model if currency model is missing', async (test) => {
processBinsTest.test('processBins should use default settlement model if currency model is missing', async (test) => {
SettlementModelCached.getAll.returns([
{
settlementModelId: 2,
Expand Down Expand Up @@ -885,7 +886,7 @@ Test('BinProcessor', async (binProcessorTest) => {
test.end()
})

prepareActionTest.test('processBins should handle no binItems', async (test) => {
processBinsTest.test('processBins should handle no binItems', async (test) => {
const sampleParticipantLimitReturnValues = [
{
participantId: 2,
Expand Down Expand Up @@ -936,7 +937,7 @@ Test('BinProcessor', async (binProcessorTest) => {
test.end()
})

prepareActionTest.test('processBins should handle non supported bins', async (test) => {
processBinsTest.test('processBins should handle non supported bins', async (test) => {
const sampleParticipantLimitReturnValues = [
{
participantId: 2,
Expand Down Expand Up @@ -964,8 +965,45 @@ Test('BinProcessor', async (binProcessorTest) => {

test.end()
})
prepareActionTest.end()

processBinsTest.test('processBins should process bins with accountId 0 differently', async (test) => {
const sampleParticipantLimitReturnValues = [
{
participantId: 2,
currencyId: 'USD',
participantLimitTypeId: 1,
value: 1000000
},
{
participantId: 3,
currencyId: 'USD',
participantLimitTypeId: 1,
value: 1000000
}
]
participantFacade.getParticipantLimitByParticipantCurrencyLimit.returns(sampleParticipantLimitReturnValues.shift())
const binsWithZeroId = JSON.parse(JSON.stringify(sampleBins))
binsWithZeroId[0] = binsWithZeroId[15]
delete binsWithZeroId[15]
delete binsWithZeroId[7]

const result = await BinProcessor.processBins(binsWithZeroId, trx)

// Assert on result.notifyMessages
test.equal(result.notifyMessages.length, 6, 'processBins should return 6 messages')

// Assert on number of function calls for DB update on position value
test.equal(BatchPositionModel.updateParticipantPosition.callCount, 0, 'updateParticipantPosition should not be called')
test.ok(BatchPositionModel.bulkInsertTransferStateChanges.calledOnce, 'bulkInsertTrasferStateChanges should be called once')
test.ok(BatchPositionModel.bulkInsertFxTransferStateChanges.calledOnce, 'bulkInsertFxTrasferStateChanges should be called once')
test.equal(BatchPositionModel.bulkInsertParticipantPositionChanges.callCount, 0, 'bulkInsertParticipantPositionChanges should not be called')

test.end()
})

processBinsTest.end()
})

binProcessorTest.test('iterateThroughBins should', async (iterateThroughBinsTest) => {
iterateThroughBinsTest.test('iterateThroughBins should call callback function for each message in bins', async (test) => {
const spyCb = sandbox.spy()
Expand Down Expand Up @@ -995,5 +1033,6 @@ Test('BinProcessor', async (binProcessorTest) => {
})
iterateThroughBinsTest.end()
})

binProcessorTest.end()
})
40 changes: 40 additions & 0 deletions test/unit/domain/position/fulfil.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -502,6 +502,46 @@ Test('Fulfil domain', processPositionFulfilBinTest => {
test.end()
})

processPositionFulfilBinTest.test('should skip position changes if changePosition is false', async (test) => {
const accumulatedTransferStates = {
[transferTestData1.message.value.id]: Enum.Transfers.TransferInternalState.RECEIVED_FULFIL,
[transferTestData2.message.value.id]: Enum.Transfers.TransferInternalState.RECEIVED_FULFIL
}
const accumulatedFxTransferStates = {}
const transferInfoList = {
[transferTestData1.message.value.id]: transferTestData1.transferInfo,
[transferTestData2.message.value.id]: transferTestData2.transferInfo
}
// Call the function
const result = await processPositionFulfilBin(
[commitBinItems, []],
{
accumulatedPositionValue: 0,
accumulatedPositionReservedValue: 0,
accumulatedTransferStates,
accumulatedFxTransferStates,
transferInfoList,
reservedActionTransfers: [],
changePositions: false
}
)

// Assert the expected results
test.equal(result.notifyMessages.length, 2)
test.equal(result.accumulatedPositionValue, 0)
test.equal(result.accumulatedTransferStateChanges.length, 2)
test.equal(result.accumulatedPositionChanges.length, 0)

test.equal(result.accumulatedTransferStateChanges[0].transferId, transferTestData1.message.value.id)
test.equal(result.accumulatedTransferStateChanges[1].transferId, transferTestData2.message.value.id)
test.equal(result.accumulatedTransferStateChanges[0].transferStateId, Enum.Transfers.TransferState.COMMITTED)
test.equal(result.accumulatedTransferStateChanges[1].transferStateId, Enum.Transfers.TransferState.COMMITTED)
test.equal(result.accumulatedTransferStates[transferTestData1.message.value.id], Enum.Transfers.TransferState.COMMITTED)
test.equal(result.accumulatedTransferStates[transferTestData2.message.value.id], Enum.Transfers.TransferState.COMMITTED)

test.end()
})

// FX tests

processPositionFulfilBinTest.test('should process a bin of position-commit messages involved in fx transfers', async (test) => {
Expand Down
Loading