SDK Support for Bulk Transfers - Tests

Test Strategy

The quality of the delivered solution is as good a the quality of the tests and testing strategy adopbted. The distributed nature of this event sourcing solution affected the testing strategy chosen. Multiple types of test were created, each supporting the others and designed to pick bugs as quickly as possible.

The Command event handler and the domain event handler have both unit tests and narrow integration tests as the base testing. The FSPIOP API and backend API components have only unit tests. Great emphasis was put on the functional tests which then tested the four components working together in both happy and unhappy path scenarios.

Narrow integration tests

These tests are written in jest and assert for example the updated state store and produced events based on a command event generated.

Command Handler Integration Test Harness

The functional test testharness

The functional test makes use of the TTK which simulates both the Payer and the Payee DFSP backends.

:::tip Note This test harness tests both the Payer SDK and the Payee SDK. :::

:::tip Note These test can be run on the local checked out monorepo, and are run in the CI pipeline, and are included in the helm as helm tests used to confirm deployment. :::

Payer DFSP Integration Test Matrix

Test CasesC1C2C3C4C5C6C7C8C9C10C11C12

INT D-1

x

INT D-2

x

INT D-3

x

INT D-4

x

INT D-5

x

INT D-6

x

INT A-1

x

INT A-2

x

INT T-1

x

INT T-2

x

INT T-3

x

INT T-4

x

INT T-5

x

INT T-6

x

Payer DFSP Functional Test Matrix

Test CasesB1B2B3B4B5F1F2F3F4F5F6F7F8F9D1D2D3D4D5D6D7D8D9D10D11D12D13D14D15D16D17D18D19D20C1C2C3C4C5C6C7C8C9C10C11C12

FUNC 1

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

FUNC 2

x

x

x

x

x

x

x

x

x

x

x

x

FUNC 3

x

x

x

x

x

x

x

x

x

x

x

x

FUNC 4

x

x

x

x

x

x

x

x

x

x

x

x

FUNC 5

x

x

x

x

x

x

x

x

x

x

x

x

FUNC 6

x

x

x

x

x

x

x

x

x

x

x

x

TC-BQ1

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BQ2

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BQ3

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BQ4

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BQ5

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BQ6

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BQ7

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BQ8

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BQ9

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BQ10

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BQ11

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BQ13

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BT1

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BT2

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BT3

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BT4

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BT5

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BT6

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BT7

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

TC-BT8

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

x

Payer DFSP Features reference

#Outbound FeaturesDetail

B1

Backend API

POST /bulkTransactions SDKBulkRequest

B2

Backend API

Event SDKOutboundBulkAcceptPartyInfoRequested

B3

Backend API

PUT /bulkTransactions/{bulkTransactionId} Accept Party

B4

Backend API

PUT /bulkTransactions/{bulkTransactionId} Accept Quote

B5

Backend API

PUT /bulkTransactions/{bulkTransactionId} Results

F1

FSPIOP API

GET /parties

F2

FSPIOP API

PUT /parties/{Type}/{ID}

F3

FSPIOP API

PUT /parties/{Type}/{ID}/error

F4

FSPIOP API

POST /bulkQuotes

F5

FSPIOP API

PUT /bulkQuotes/{ID}

F6

FSPIOP API

PUT /bulkQuotes/{ID}/error

F7

FSPIOP API

POST /bulkTransfers

F8

FSPIOP API

PUT /bulkTransfers/{ID}

F9

FSPIOP API

PUT /bulkTransfers/{ID}/error

D1

Domain Event Handler

SDKOutboundBulkRequestReceived

D2

Domain Event Handler

SDKOutboundBulkPartyInfoRequested

D3

Domain Event Handler

PartyInfoCallbackReceived

D4

Domain Event Handler

PartyInfoCallbackProcessed

D5

Domain Event Handler

SDKOutboundBulkPartyInfoRequestProcessed

D6

Domain Event Handler

SDKOutboundBulkAcceptPartyInfoReceived

D7

Domain Event Handler

SDKOutboundBulkAutoAcceptPartyInfoRequested

D8

Domain Event Handler

SDKOutboundBulkAcceptPartyInfoProcessed

D9

Domain Event Handler

BulkQuotesCallbackReceived

D10

Domain Event Handler

BulkQuotesCallbackProcessed

D11

Domain Event Handler

SDKOutboundBulkQuotesRequestProcessed

D12

Domain Event Handler

SDKOutboundBulkAcceptQuoteReceived

D13

Domain Event Handler

SDKOutboundBulkAcceptQuoteProcessed

D14

Domain Event Handler

SDKOutboundBulkAutoAcceptQuoteRequested

D15

Domain Event Handler

SDKOutboundBulkAutoAcceptQuoteProcessed

D16

Domain Event Handler

BulkTransfersCallbackReceived

D17

Domain Event Handler

BulkTransfersCallbackProcessed

D18

Domain Event Handler

SDKOutboundBulkTransfersRequestProcessed

D19

Domain Event Handler

SDKOutboundBulkResponseSent

D20

Domain Event Handler

SDKOutboundBulkResponseSentProcessed

C1

Command Event Handler

ProcessSDKOutboundBulkRequest

C2

Command Event Handler

ProcessSDKOutboundBulkPartyInfoRequest

C3

Command Event Handler

ProcessPartyInfoCallback

C4

Command Event Handler

ProcessSDKOutboundBulkAcceptPartyInfo

C5

Command Event Handler

ProcessSDKOutboundBulkQuotesRequest

C6

Command Event Handler

ProcessBulkQuotesCallback

C7

Command Event Handler

ProcessSDKOutboundBulkAcceptQuote

C8

Command Event Handler

ProcessSDKOutboundBulkAutoAcceptQuote

C9

Command Event Handler

ProcessSDKOutboundBulkTransfersRequest

C10

Command Event Handler

ProcessBulkTransfersCallback

C11

Command Event Handler

PrepareSDKOutboundBulkResponse

C12

Command Event Handler

ProcessSDKOutboundBulkResponseSent

Test Cases reference

Group# test caseTest TypeStatusDetail

Discovery - Comand Handler Integration Tests

(process_bulk_accept_party_info.test.ts)

INT D-1

Integration

Pass

Given inbound command event ProcessSDKOutboundBulkAcceptPartyInfo is received Then the logic should loop through individual transfer in the bulk request And update the individual transfer state to DISCOVERY_ACCEPTED or DISCOVERY_REJECTED based on the value in the incoming event And update the overall global state to DISCOVERY_ACCEPTANCE_COMPLETED And outbound event SDKOutboundBulkAcceptPartyInfoProcessed should be published

(process_bulk_party_info_request.test.ts)

INT D-2

Integration

Pass

Given Party info does not already exist for none of the individual transfers. And Party Lookup is not skipped When inbound command event ProcessSDKOutboundBulkPartyInfoRequest is received Then the global state should be updated to DISCOVERY_PROCESSING And PartyInfoRequested kafka event should be published for each individual transfer. And State for individual transfer should be updated to DISCOVERY_PROCESSING

(process_bulk_party_info_request.test.ts)

INT D-3

Integration

Pass

Given Party info exists for individual transfers. And Party Lookup is not skipped When inbound command event ProcessSDKOutboundBulkPartyInfoRequest is received Then the global state should be updated to DISCOVERY_PROCESSING. And PartyInfoRequested outbound event should not be published for each individual transfer. And State for individual transfer should be updated to RECEIVED.

(process_bulk_request.test.ts)

INT D-4

Integration

Pass

When inbound command event ProcessSDKOutboundBulkRequest is received Then outbound event SDKOutboundBulkPartyInfoRequested should be published And Global state should be updated to RECEIVED.

(process_party_info_callback.test.ts)

INT D-5

Integration

Pass

Given receiving party info does not exist And receiving party lookup was successful When inbound command event ProcessPartyInfoCallback is received Then the state for individual successful party lookups should be updated to DISCOVERY_SUCCESS And the data in redis for individual transfer should be updated with received party info And outbound event PartyInfoCallbackProcessed event should be published And if all lookups are incomplete, outbound event ProcessSDKOutboundBulkPartyInfoRequestProcessed should not be published And neither outbound event SDKOutboundBulkAutoAcceptPartyInfoRequested/SDKOutboundBulkAutoAcceptPartyInfoRequested should be published

(process_party_info_callback.test.ts)

INT D-6

Integration

Pass

Given receiving party info does not exist And receiving party lookup was successful When inbound command event ProcessPartyInfoCallback is received Then the state for individual successful party lookups should be updated to DISCOVERY_SUCCESS And the data in redis for individual transfer should be updated with received party info And outbound event PartyInfoCallbackProcessed event should be published And if all lookups are complete, outbound event ProcessSDKOutboundBulkPartyInfoRequestProcessed should be published And if auto accept party is false, outbound event SDKOutboundBulkAcceptPartyInfoRequested should be published.

Agreement - Comand Handler Integration Tests

(process_bulk_quotes_callback.test.ts)

INT A-1

Integration

Pass

Given the BulkTransaction with Options { synchronous: false, onlyValidateParty: true, skipPartyLookup: false, autoAcceptParty: false, autoAcceptQuote: false } And callback for quote batch is successful And the callback has a combination of success and failed responses for individual quotes When Inbound command event ProcessBulkQuotesCallback is received Then the logic should update the individual batch state to AGREEMENT_COMPLETED or AGREEMENT_FAILED, And for each individual transfers in the batch, the state could be AGREEMENT_SUCCESS or AGREEMENT_FAILED accordingly And the individual quote data in redis should be updated with the response And the global BulkTransaction state should be AGREEMENT_ACCEPTANCE_PENDING And domain event BulkQuotesCallbackProcessed should be published And domain event SDKOutboundBulkQuotesRequestProcessed should be published

(process_bulk_quotes_callback.test.ts)

INT A-2

Integration

Pass

When Inbound command event ProcessSDKOutboundBulkQuotesRequest is received Then the logic should update the global state to AGREEMENT_PROCESSING, And create batches based on FSP that has DISCOVERY_ACCEPTED state And also has config maxEntryConfigPerBatch And publish BulkQuotesRequested per each batch And update the state of each batch to AGREEMENT_PROCESSING.

Transfers - Comand Handler Integration Tests

(prepare_sdk_outbound_bulk_response.test.ts)

INT T-1

Integration

Pass

Given the BulkTransaction with Options { synchronous: false, onlyValidateParty: true, skipPartyLookup: false, autoAcceptParty: false, autoAcceptQuote: false } When inbound command event PrepareSDKOutboundBulkResponseCmdEvt is received And SDKOutboundBulkResponsePreparedDmEvt should be published for each transfer batch And the Bulk Transaction global state should be updated to RESPONSE_PROCESSING

(process_bulk_transfers_callback.test.ts )

INT T-2

Integration

Pass

Given the BulkTransaction with Options { synchronous: false, onlyValidateParty: true, skipPartyLookup: false, autoAcceptParty: false, autoAcceptQuote: false } When inbound command event ProcessBulkTransfersCallbackCmdEvt is received Then the transfer batch state should be updated to TRANSFERS_COMPLETED States of failed quotes should remain AGREEMENT_FAILED And the logic should loop through individual transfers in the batch and update the state to TRANSFER_SUCCESS or TRANSFER_FAILED And BulkTransferProcessedDmEvt should be published for each transfer batch And domain event BulkQuotesCallbackProcessed should be published And domain event SDKOutboundBulkQuotesRequestProcessed should be published And domain event SDKOutboundBulkAutoAcceptQuoteProcessedDmEvt should be published And domain event BulkTransfersRequestedDmEvt should be published And domain event BulkTransfersCallbackProcessed should be published And domain event SDKOutboundBulkTransfersRequestProcessed should be published

(process_bulk_transfers_request.test.ts)

INT T-3

Integration

Pass

Given the BulkTransaction with Options { synchronous: false, onlyValidateParty: true, skipPartyLookup: false, autoAcceptParty: false, autoAcceptQuote: false } And callback for quote batch is successful And the callback has a combination of success and failed responses for individual quotes When Inbound command event ProcessSDKOutboundBulkTransfersRequestCmdEvt is received Then the global Bulk Transaction State should be updated to TRANSFERS_PROCESSING And the individual batch state should be equal to either TRANSFERS_PROCESSING or TRANSFERS_FAILED, And for each individual transfers in the batch, the state AGREEMENT_ACCEPTED or AGREEMENT_REJECTED depending on the acceptQuotes = TRUE/FALSE, And for each individual transfers in an AGREEMENT_FAILED state should not be altered, And the individual quote data in redis should be updated with the response And domain event BulkQuotesCallbackProcessed should be published And domain event SDKOutboundBulkQuotesRequestProcessed should be published And domain event SDKOutboundBulkAutoAcceptQuoteProcessedDmEvt should be published And domain event BulkTransfersRequestedDmEvt should be published

(process_prepare_bulk_response.test.ts)

INT T-4

Integration

Pass

When inbound command event PrepareSDKOutboundBulkResponseCmdEvt is received Then SDKOutboundBulkResponsePreparedDmEvnt should be published

(process_sdk_outbound_bulk_accept_quote.test.ts)

INT T-5

Integration

Pass

Given the BulkTransaction with Options { synchronous: false, onlyValidateParty: true, skipPartyLookup: false, autoAcceptParty: false, autoAcceptQuote: false } And callback for quote batch is successful And the callback has a combination of success and failed responses for individual quotes When Inbound command event ProcessSDKOutboundBulkAcceptQuote is received Then the global Bulk Transaction State should be updated to AGREEMENT_ACCEPTANCE_COMPLETED And the individual batch state should be equal to either AGREEMENT_COMPLETED or AGREEMENT_FAILED, And for each individual transfers in the batch, the state AGREEMENT_ACCEPTED or AGREEMENT_REJECTED depending on the acceptQuotes = TRUE/FALSE, And the individual quote data in redis should be updated with the response And domain event BulkQuotesCallbackProcessed should be published And domain event SDKOutboundBulkQuotesRequestProcessed should be published And domain event SDKOutboundBulkAutoAcceptQuoteProcessedDmEvt should be published And domain event BulkTransfersRequestedDmEvt should be published

(process_sdk_outbound_bulk_response_sent.test.ts)#

INT T-6

Integration

Pass

Given the BulkTransaction with Options { synchronous: false, onlyValidateParty: true, skipPartyLookup: false, autoAcceptParty: false, autoAcceptQuote: false } When inbound command event ProcessSDKOutboundBulkResponseSentCmdEvt is received And SDKOutboundBulkResponseSentProcessedDmEvt should be published for each transfer batch And the Bulk Transaction global state should be updated to RESPONSE_SENT

Happy Path: (bulk-happy-path.json)

- 1 transfer with acceptParty and acceptQuote set to true

TC-BHP1

Functional

Pass

4 transfers to 2 dfsps, with acceptParty and acceptQuote set to true

TC-BHP2

Validation

Pass

Bulk transaction having a format error

Parties Errors: (bulk-parties-error-cases.json)

- 1 transfer in the request

TC-BP1

Functional

Pass

Receiver sends error for in parties response

TC-BP2

Functional

Pass

Receiver timesout

TC-BP3

Functional

Pass

skipPartyLookup is false and receiver ifo exists in the request.

- 2 transfers in the request

TC-BP4

Functional

Pass

Receiver sends an error response for one of the transfers

TC-BP5

Functional

Pass

Receiver times out sending response for one of the transfers

TC-BP6

Functional

Pass

Do not get any response from the receiver for both the transfers

Quotes Errors: (bulk-quotes-error-cases.json)

- 2 transfers having the same receiver fsp id

- acceptParty for all transfers

TC-BQ1

Functional

Pass

Receiver fsp fails the entire batch

TC-BQ2

Functional

Pass

Receiver fsp times out the entire batch

TC-BQ3

Functional

Pass

Receiver fsp sends only one response and skips the other

TC-BQ4

Functional

Out of scope for MVP

Receiver fsp sends one success response and one failure response (Not Implemented - Issue 3015)

- acceptParty varying

TC-BQ5

Functional

Pass

One true, one false

TC-BQ6

Functional

Out of scope for MVP

Accept party false for all responses - Then only party details and no quote respone, final state to be COMPLETED (Not Implemented - Issue 3015)

TC-BQ7

Functional

Out of scope for MVP

True is sent only for one quote in PUT /bulkTxn acceptParty, ignoring second one (Not Implemented - Issue 3015)

TC-BQ8

Functional

Out of scope for MVP

false is sent only for one quote in PUT /bulkTxn acceptParty, ignoring second one - (Not Implemented - Issue 3015)

- 2 transfers having different receiver fsp ids - acceptParty for all transfers

TC-BQ9

Functional

Pass

One batch sends an error

TC-BQ10

Functional

Pass

Both batches sends error

TC-BQ11

Functional

Pass

One batch times out

- 3 transfers with 2 transfers having 1 receiver fsp id and the other having a different one

TC-BQ12

Functional

Out of scope for MVP

- The batch with 2 transfers sends only 1 transfer response and the other batch sends the success response (Not implemented - issue 3015)

TC-BQ13

Functional

Out of scope for MVP

Error in switch for unsupported currency - (issue -

Transfers Errors: (bulk-transfer-errors.json)

- One bulkTransfer with 2 transfers

- acceptQuote for all transfers

TC-BT1

Functional

Pass

Receiver fails the entire batch

TC-BT2

Functional

Pass

Receiver times out for the entire batch

TC-BT3

Functional

Out of scope for MVP

Receiver fsp sends only one response and skips the other (Not Implemented - Issue 3015)

TC-BT4

Functional

Intermittent Failures

Receiver fsp sends one success response and one failure - ( Issue: 3019 )

- acceptQuote varying

TC-BT5

Functional

Out of scope for MVP

One true one false - TC2 - Bug 2958

TC-BT6

Functional

Out of scope for MVP

Accept quote - All false (Not Implemented - Issue 3015)

TC-BT7

Functional

Out of scope for MVP

True is sent only for one transfer in PUT /bulkTxn acceptParty, ignoring second one - (Not Implemented - Issue 3015)

TC-BT8

Functional

Out of scope for MVP

false is sent only for one transfer in PUT /bulkTxn acceptParty, ignoring second one - (Not Implemented - Issue 3015)

Last updated