UNPKG

futoin-xferengine

Version:

Neutral clustered multi-currency transaction engine with limits

1,195 lines (1,070 loc) 150 kB
'use strict'; const expect = require( 'chai' ).expect; const moment = require( 'moment' ); const Executor = require( 'futoin-executor/Executor' ); const SpecTools = require( 'futoin-invoker/SpecTools' ); const $as = require( 'futoin-asyncsteps' ); module.exports = function( describe, it, vars ) { let as; let ccm; let executor; beforeEach( 'common', function() { ccm = vars.ccm; as = vars.as; executor = vars.executor; } ); describe( 'XferTools', function() { beforeEach( 'xfertools', function() { as.add( ( as ) => { ccm.unRegister( 'xfer.evtgen' ); executor = new Executor( ccm ); ccm.registerServices( as, executor ); }, ( as, err ) => { console.log( err ); console.log( as.state.error_info ); console.log( as.state.last_exception ); } ); } ); const XferTools = require( '../XferTools' ); it( 'process amount limits', function( done ) { as.add( ( as ) => { const xferlim = ccm.iface( 'xfer.limits' ); xferlim.addLimitGroup( as, 'XferTools' ); xferlim.setLimits( as, 'XferTools', 'Retail', 'I:EUR', { retail_daily_amt : "1.00", retail_daily_cnt : 20, retail_weekly_amt : "3.00", retail_weekly_cnt : 40, retail_monthly_amt : "5.00", retail_monthly_cnt : 60, retail_min_amt : "0.10", preauth_daily_amt : "1.00", preauth_daily_cnt : 20, preauth_weekly_amt : "3.00", preauth_weekly_cnt : 40, preauth_monthly_amt : "5.00", preauth_monthly_cnt : 60, preauth_min_amt : "0.10", }, { retail_daily_amt : "0.50", retail_daily_cnt : 10, retail_weekly_amt : "2.50", retail_weekly_cnt : 20, retail_monthly_amt : "4.50", retail_monthly_cnt : 30, retail_min_amt : "0.11", preauth_daily_amt : "0.50", preauth_daily_cnt : 10, preauth_weekly_amt : "2.50", preauth_weekly_cnt : 20, preauth_monthly_amt : "4.50", preauth_monthly_cnt : 30, preauth_min_amt : "0.11", }, { retail_daily_amt : "0.70", retail_daily_cnt : 10, retail_weekly_amt : "2.70", retail_weekly_cnt : 20, retail_monthly_amt : "4.70", retail_monthly_cnt : 30, retail_min_amt : "0.12", preauth_daily_amt : "0.70", preauth_daily_cnt : 10, preauth_weekly_amt : "2.70", preauth_weekly_cnt : 20, preauth_monthly_amt : "4.70", preauth_monthly_cnt : 30, preauth_min_amt : "0.12", } ); const xferacct = ccm.iface( 'xfer.accounts' ); xferacct.addAccountHolder( as, 'XferTools', 'XferTools', true, true, {}, {} ); }, ( as, err ) => { console.log( err ); console.log( as.state.error_info ); done( as.state.last_exception || 'Fail' ); } ); as.add( ( as, holder ) => { const db = ccm.db( 'xfer' ); const xt = new XferTools( ccm, 'Retail' ); //--- const xfer1 = db.newXfer(); xt.addLimitProcessing( as, xfer1, 'Retail', holder, 'I:EUR', '0.21', 'retail' ); as.add( ( as, { do_risk, do_check } ) => { as.state.test_name = "1"; expect( do_risk ).to.equal( false ); expect( do_check ).to.equal( false ); } ); as.add( ( as ) => xfer1.execute( as ) ); //--- const xfer2 = db.newXfer(); xt.addLimitProcessing( as, xfer2, 'Retail', holder, 'I:EUR', '0.30', 'retail' ); as.add( ( as, { do_risk, do_check } ) => { as.state.test_name = "2"; expect( do_risk ).to.equal( false ); expect( do_check ).to.equal( true ); } ); as.add( ( as ) => xfer2.execute( as ) ); //--- const xfer3 = db.newXfer(); xt.addLimitProcessing( as, xfer3, 'Retail', holder, 'I:EUR', '0.20', 'retail' ); as.add( ( as, { do_risk, do_check } ) => { as.state.test_name = "3"; expect( do_risk ).to.equal( true ); expect( do_check ).to.equal( true ); } ); as.add( ( as ) => xfer3.execute( as ) ); //--- const xfer4 = db.newXfer(); xt.addLimitProcessing( as, xfer4, 'Retail', holder, 'I:EUR', '0.10', 'retail' ); as.add( ( as, { do_risk, do_check } ) => { as.state.test_name = "4"; expect( do_risk ).to.equal( true ); expect( do_check ).to.equal( true ); } ); as.add( ( as ) => xfer4.execute( as ) ); }, ( as, err ) => { console.log( as.state.test_name ); console.log( err ); console.log( as.state.error_info ); done( as.state.last_exception || 'Fail' ); } ); as.add( ( as ) => done() ); as.execute(); const xt = new XferTools( ccm, 'Retail' ); } ); it( 'process count limits', function( done ) { as.add( ( as ) => { const xferlim = ccm.iface( 'xfer.limits' ); xferlim.setLimits( as, 'XferTools', 'Deposits', 'I:EUR', { deposit_daily_amt : "100.00", deposit_daily_cnt : 10, withdrawal_daily_amt : "100.00", withdrawal_daily_cnt : 10, deposit_weekly_amt : "100.00", deposit_weekly_cnt : 20, withdrawal_weekly_amt : "100.00", withdrawal_weekly_cnt : 20, deposit_monthly_amt : "100.00", deposit_monthly_cnt : 30, withdrawal_monthly_amt : "100.00", withdrawal_monthly_cnt : 30, deposit_min_amt : "0.10", withdrawal_min_amt : "100.00", }, { deposit_daily_amt : "100.00", deposit_daily_cnt : 1, withdrawal_daily_amt : "100.00", withdrawal_daily_cnt : 0, deposit_weekly_amt : "100.00", deposit_weekly_cnt : 4, withdrawal_weekly_amt : "100.00", withdrawal_weekly_cnt : 4, deposit_monthly_amt : "100.00", deposit_monthly_cnt : 4, withdrawal_monthly_amt : "100.00", withdrawal_monthly_cnt : 4, deposit_min_amt : "0.10", withdrawal_min_amt : "100.00", }, { deposit_daily_amt : "100.00", deposit_daily_cnt : 2, withdrawal_daily_amt : "100.00", withdrawal_daily_cnt : 10, deposit_weekly_amt : "100.00", deposit_weekly_cnt : 20, withdrawal_weekly_amt : "100.00", withdrawal_weekly_cnt : 20, deposit_monthly_amt : "100.00", deposit_monthly_cnt : 30, withdrawal_monthly_amt : "100.00", withdrawal_monthly_cnt : 30, deposit_min_amt : "0.10", withdrawal_min_amt : "100.00", } ); const xferacct = ccm.iface( 'xfer.accounts' ); xferacct.addAccountHolder( as, 'XferTools2', 'XferTools', true, true, {}, {} ); }, ( as, err ) => { console.log( err ); console.log( as.state.error_info ); done( as.state.last_exception || 'Fail' ); } ); as.add( ( as, holder ) => { const db = ccm.db( 'xfer' ); const xt = new XferTools( ccm, 'Deposits' ); //--- const xfer1 = db.newXfer(); xt.addLimitProcessing( as, xfer1, 'Deposits', holder, 'I:EUR', '0.21', 'deposit' ); as.add( ( as, { do_risk, do_check } ) => { as.state.test_name = "1"; expect( do_risk ).to.equal( false ); expect( do_check ).to.equal( false ); } ); as.add( ( as ) => xfer1.execute( as ) ); //--- const xfer2 = db.newXfer(); xt.addLimitProcessing( as, xfer2, 'Deposits', holder, 'I:EUR', '0.30', 'deposit' ); as.add( ( as, { do_risk, do_check } ) => { as.state.test_name = "2"; expect( do_risk ).to.equal( false ); expect( do_check ).to.equal( true ); } ); as.add( ( as ) => xfer2.execute( as ) ); //--- const xfer3 = db.newXfer(); xt.addLimitProcessing( as, xfer3, 'Deposits', holder, 'I:EUR', '0.20', 'deposit' ); as.add( ( as, { do_risk, do_check } ) => { as.state.test_name = "3"; expect( do_risk ).to.equal( true ); expect( do_check ).to.equal( true ); } ); as.add( ( as ) => xfer3.execute( as ) ); }, ( as, err ) => { console.log( as.state.test_name ); console.log( err ); console.log( as.state.error_info ); done( as.state.last_exception || 'Fail' ); } ); as.add( ( as ) => done() ); as.execute(); const xt = new XferTools( ccm, 'Retail' ); } ); it( 'process limits/xfer/stats currency mismatch', function( done ) { as.add( ( as ) => { const currmgr = ccm.iface( 'currency.manage' ); currmgr.setExRate( as, 'I:EUR', 'I:USD', '1.01', '0.01' ); currmgr.setExRate( as, 'I:EUR', 'I:USD', '0.99099099099', '0.01' ); const xferlim = ccm.iface( 'xfer.limits' ); xferlim.setLimits( as, 'XferTools', 'Payments', 'I:USD', { outbound_daily_amt : "1.02", outbound_daily_cnt : 2, inbound_daily_amt : "1.02", inbound_daily_cnt : 2, outbound_weekly_amt : "10.0", outbound_weekly_cnt : 2, inbound_weekly_amt : "10.0", inbound_weekly_cnt : 2, outbound_monthly_amt : "10.0", outbound_monthly_cnt : 2, inbound_monthly_amt : "10.0", inbound_monthly_cnt : 2, outbound_min_amt : "0", }, false, false ); xferlim.setLimits( as, 'XferTools', 'Misc', 'I:USD', { message_daily_cnt : 1000, failure_daily_cnt : 1000, limithit_daily_cnt : 1000, message_weekly_cnt : 1000, failure_weekly_cnt : 1000, limithit_weekly_cnt : 1000, message_monthly_cnt : 1000, failure_monthly_cnt : 1000, limithit_monthly_cnt : 1000, }, false, false ); const xferacct = ccm.iface( 'xfer.accounts' ); xferacct.addAccountHolder( as, 'XferToolsP', 'XferTools', true, true, {}, {} ); }, ( as, err ) => { console.log( err ); console.log( as.state.error_info ); done( as.state.last_exception || 'Fail' ); } ); as.add( ( as, holder ) => { const db = ccm.db( 'xfer' ); const xt = new XferTools( ccm, 'Payments' ); //--- const xfer1 = db.newXfer(); xt.addLimitProcessing( as, xfer1, 'Payments', holder, 'I:EUR', '1.00', 'outbound' ); as.add( ( as, { do_risk, do_check } ) => { as.state.test_name = "1"; expect( do_risk ).to.equal( false ); expect( do_check ).to.equal( false ); } ); as.add( ( as ) => xfer1.execute( as ) ); //--- as.add( ( as ) => { const xfer2 = db.newXfer(); xt.addLimitProcessing( as, xfer2, 'Payments', holder, 'I:USD', '0.01', 'outbound' ); as.add( ( as ) => as.error( 'Fail' ) ); }, ( as, err ) => { if ( err === 'LimitReject' ) { as.success(); } } ); //--- as.add( ( as ) => { const xfer3 = db.newXfer(); xt.addLimitProcessing( as, xfer3, 'Payments', holder, 'I:EUR', '1.01', 'inbound' ); as.add( ( as ) => as.error( 'Fail' ) ); }, ( as, err ) => { if ( err === 'LimitReject' ) { as.success(); } } ); const xferlim = ccm.iface( 'xfer.limits' ); xferlim.setLimits( as, 'XferTools', 'Payments', 'I:EUR', { outbound_daily_amt : "1.02", outbound_daily_cnt : 3, inbound_daily_amt : "1.02", inbound_daily_cnt : 3, outbound_weekly_amt : "10.0", outbound_weekly_cnt : 3, inbound_weekly_amt : "10.0", inbound_weekly_cnt : 3, outbound_monthly_amt : "10.0", outbound_monthly_cnt : 3, inbound_monthly_amt : "10.0", inbound_monthly_cnt : 3, outbound_min_amt : "0", }, false, false ); // try over limit //--- as.add( ( as ) => { const xfer3 = db.newXfer(); xt.addLimitProcessing( as, xfer3, 'Payments', holder, 'I:EUR', '1.01', 'inbound' ); as.add( ( as ) => as.error( 'Fail' ) ); }, ( as, err ) => { if ( err === 'LimitReject' ) { as.success(); } } ); // try limit //--- const xfer4 = db.newXfer(); xt.addLimitProcessing( as, xfer4, 'Payments', holder, 'I:EUR', '1.00', 'inbound' ); as.add( ( as, { do_risk, do_check } ) => { expect( do_risk ).to.equal( false ); expect( do_check ).to.equal( false ); } ); as.add( ( as ) => xfer4.execute( as ) ); // try over limit //--- as.add( ( as ) => { const xfer3 = db.newXfer(); xt.addLimitProcessing( as, xfer3, 'Payments', holder, 'I:EUR', '0.01', 'inbound' ); as.add( ( as ) => as.error( 'Fail' ) ); }, ( as, err ) => { if ( err === 'LimitReject' ) { as.success(); } } ); // cancel stats //--- const xfer5 = db.newXfer(); xt.addStatsCancel( as, xfer5, 'Payments', holder, moment.utc().format(), 'I:EUR', '1.00', 'inbound' ); as.add( ( as ) => xfer5.execute( as ) ); // try limit again //--- const xfer6 = db.newXfer(); xt.addLimitProcessing( as, xfer6, 'Payments', holder, 'I:EUR', '1.00', 'inbound' ); as.add( ( as, { do_risk, do_check } ) => { expect( do_risk ).to.equal( false ); expect( do_check ).to.equal( false ); } ); as.add( ( as ) => xfer6.execute( as ) ); // Check cnt statistics //--- db.select( 'limit_payments_stats' ).where( { holder } ).executeAssoc( as ); as.add( ( as, rows ) => { // xfer + cancel + xfer expect( rows[0].inbound_daily_cnt ).to.eql( 3 ); } ); // cancel stats //--- { const xfer = db.newXfer(); xt.addStatsCancel( as, xfer, 'Payments', holder, moment.utc().startOf( 'month' ).subtract( 1, 'day' ).format(), 'I:EUR', '1.00', 'inbound' ); xt.addStatsCancel( as, xfer, 'Payments', holder, moment.utc().startOf( 'week' ).subtract( 1, 'day' ).format(), 'I:EUR', '1.00', 'inbound' ); xt.addStatsCancel( as, xfer, 'Payments', holder, moment.utc().subtract( 1, 'day' ).format(), 'I:EUR', '1.00', 'inbound' ); } }, ( as, err ) => { console.log( err ); console.log( as.state.error_info ); done( as.state.last_exception || 'Fail' ); } ); as.add( ( as ) => done() ); as.execute(); const xt = new XferTools( ccm, 'Retail' ); } ); it ( 'should disable holder on limits hit limit', function( done ) { as.add( ( as ) => { const xt = new XferTools( ccm, 'Payments' ); const xferlim = ccm.iface( 'xfer.limits' ); //-- xferlim.addLimitGroup( as, 'AutoDisable' ); xferlim.setLimits( as, 'AutoDisable', 'Misc', 'I:EUR', { message_daily_cnt : 1, failure_daily_cnt : 1, limithit_daily_cnt : 1, message_weekly_cnt : 1, failure_weekly_cnt : 1, limithit_weekly_cnt : 1, message_monthly_cnt : 1, failure_monthly_cnt : 1, limithit_monthly_cnt : 1, }, false, false ); const xferacct = ccm.iface( 'xfer.accounts' ); xferacct.addAccountHolder( as, 'AutoDisable', 'AutoDisable', true, true, {}, {} ); as.add( ( as, holder ) => { const call_limits = ( as ) => { const dbxfer = ccm.db( 'xfer' ).newXfer(); xt._processLimits( as, dbxfer, 'Misc', holder, null, { message_daily_cnt: 1, message_weekly_cnt: 1, message_monthly_cnt: 1, } ); as.add( ( as ) => dbxfer.execute( as ) ); }; // First no limit call_limits( as ); //-- // Second just limit // Third - limit + limithit limit -> auto-disable for ( let i = 0; i < 2; ++i ) { as.add( ( as ) => { call_limits( as ); as.add( ( as ) => as.error( 'Fail' ) ); }, ( as, err ) => { if ( err === 'LimitReject' ) { as.success(); } } ); xferacct.getAccountHolder( as, holder ); as.add( ( as, info ) => expect( info.enabled ).to.be.equal( i === 0 ) ); } } ); }, ( as, err ) => { console.log( err ); console.log( as.state.error_info ); done( as.state.last_exception || 'Fail' ); } ); as.add( ( as ) => done() ); as.execute(); } ); let system_account; let first_account; let second_account; let foreign_account; let external_account; let first_transit; let second_transit; let disabled_account; let fee_account; const check_balance = ( as, account, req ) => { ccm.db( 'xfer' ).select( 'accounts' ) .where( 'uuidb64', account ) .executeAssoc( as ); as.add( ( as, rows ) => expect( `${rows[0].balance}` ).to.eql( req ) ); }; beforeEach( 'xferaccounts', function() { as.add( ( as ) => { // once only, but DB connection is required if ( system_account ) { return; } const xferlim = ccm.iface( 'xfer.limits' ); xferlim.addLimitGroup( as, 'ExternalXfer' ); xferlim.setLimits( as, 'ExternalXfer', 'Payments', 'I:EUR', { outbound_daily_amt : "1000.00", outbound_daily_cnt : 1000, inbound_daily_amt : "1000.00", inbound_daily_cnt : 1000, outbound_weekly_amt : "1000.00", outbound_weekly_cnt : 1000, inbound_weekly_amt : "1000.00", inbound_weekly_cnt : 1000, outbound_monthly_amt : "1000.00", outbound_monthly_cnt : 1000, inbound_monthly_amt : "1000.00", inbound_monthly_cnt : 1000, outbound_min_amt : "0", }, false, false ); xferlim.addLimitGroup( as, 'SimpleXfer' ); xferlim.setLimits( as, 'SimpleXfer', 'Gaming', 'I:EUR', { bet_daily_amt : "100", bet_daily_cnt : 100, win_daily_amt : "100", win_daily_cnt : 100, profit_daily_amt : "100", bet_weekly_amt : "100", bet_weekly_cnt : 100, win_weekly_amt : "100", win_weekly_cnt : 100, profit_weekly_amt : "100", bet_monthly_amt : "100", bet_monthly_cnt : 100, win_monthly_amt : "100", win_monthly_cnt : 100, profit_monthly_amt : "100", bet_min_amt : "0.01", }, { bet_daily_amt : "100", bet_daily_cnt : 100, win_daily_amt : "100", win_daily_cnt : 100, profit_daily_amt : "100", bet_weekly_amt : "100", bet_weekly_cnt : 100, win_weekly_amt : "100", win_weekly_cnt : 100, profit_weekly_amt : "100", bet_monthly_amt : "100", bet_monthly_cnt : 100, win_monthly_amt : "100", win_monthly_cnt : 100, profit_monthly_amt : "100", bet_min_amt : "10", }, false ); xferlim.setLimits( as, 'SimpleXfer', 'Deposits', 'I:EUR', { deposit_daily_amt : "100.00", deposit_daily_cnt : 10, withdrawal_daily_amt : "100.00", withdrawal_daily_cnt : 10, deposit_weekly_amt : "100.00", deposit_weekly_cnt : 20, withdrawal_weekly_amt : "100.00", withdrawal_weekly_cnt : 20, deposit_monthly_amt : "100.00", deposit_monthly_cnt : 30, withdrawal_monthly_amt : "100.00", withdrawal_monthly_cnt : 30, deposit_min_amt : "0.10", withdrawal_min_amt : "0.10", }, false, false ); xferlim.setLimits( as, 'SimpleXfer', 'Payments', 'I:EUR', { outbound_daily_amt : "1000.00", outbound_daily_cnt : 1000, inbound_daily_amt : "1000.00", inbound_daily_cnt : 1000, outbound_weekly_amt : "1000.00", outbound_weekly_cnt : 1000, inbound_weekly_amt : "1000.00", inbound_weekly_cnt : 1000, outbound_monthly_amt : "1000.00", outbound_monthly_cnt : 1000, inbound_monthly_amt : "1000.00", inbound_monthly_cnt : 1000, outbound_min_amt : "0", }, false, false ); const currmgr = ccm.iface( 'currency.manage' ); currmgr.setCurrency( as, 'L:XFRT', 3, 'Xfer Test Currency', 'XFT', true ); currmgr.setExRate( as, 'I:EUR', 'L:XFRT', '1.500', '0.05' ); const xferacct = ccm.iface( 'xfer.accounts' ); xferacct.addAccountHolder( as, 'ExternalXfer', 'ExternalXfer', true, true, {}, {} ); as.add( ( as, holder ) => { xferacct.addAccount( as, holder, 'External', 'I:EUR', 'Ext' ); as.add( ( as, id ) => external_account = id ); } ); xferacct.addAccountHolder( as, 'SimpleXfer', 'SimpleXfer', true, true, {}, {} ); as.add( ( as, holder ) => { xferacct.addAccount( as, holder, 'System', 'I:EUR', 'Source' ); as.add( ( as, id ) => system_account = id ); xferacct.addAccount( as, holder, 'System', 'I:EUR', 'Fee' ); as.add( ( as, id ) => fee_account = id ); xferacct.addAccount( as, holder, 'Regular', 'I:EUR', 'First' ); as.add( ( as, id ) => first_account = id ); xferacct.addAccount( as, holder, 'Regular', 'I:EUR', 'Second' ); as.add( ( as, id ) => second_account = id ); xferacct.addAccount( as, holder, 'Regular', 'L:XFRT', 'Foreign' ); as.add( ( as, id ) => foreign_account = id ); xferacct.addAccount( as, holder, 'Regular', 'I:EUR', 'Disabled', false ); as.add( ( as, id ) => disabled_account = id ); xferacct.addAccount( as, holder, 'Transit', 'I:EUR', 'Transit First', true, `transit1`, external_account ); as.add( ( as, id ) => first_transit = id ); xferacct.addAccount( as, holder, 'Transit', 'I:EUR', 'Transit Second', true, `transit2`, external_account ); as.add( ( as, id ) => second_transit = id ); } ); }, ( as, err ) => { console.log( err ); console.log( as.state.error_info ); } ); } ); it( 'should process simple xfer', function( done ) { const dxt = new class extends XferTools { constructor() { super( ccm, 'Deposits' ); } }; const pxt = new class extends XferTools { constructor() { super( ccm, 'Payments' ); } }; as.add( ( as ) => { const db = ccm.db( 'xfer' ); dxt.processXfer( as, { src_account: system_account, dst_account: first_account, currency: 'I:EUR', amount: '4.10', type: 'Deposit', src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, first_account, '410' ); dxt.processXfer( as, { src_account: system_account, dst_account: first_account, currency: 'I:EUR', amount: '6', type: 'Deposit', src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, first_account, '1010' ); //--- pxt.processXfer( as, { src_account: first_account, dst_account: second_account, currency: 'I:EUR', amount: '10.10', type: 'Generic', src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, first_account, '0' ); check_balance( as, second_account, '1010' ); //--- dxt.processXfer( as, { src_account: second_account, dst_account: system_account, currency: 'I:EUR', amount: '10.10', type: 'Withdrawal', src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, second_account, '0' ); }, ( as, err ) => { console.log( as.state.test_name ); console.log( err ); console.log( as.state.error_info ); done( as.state.last_exception || 'Fail' ); } ); as.add( ( as ) => done() ); as.execute(); } ); it( 'should process simple xfer with exrate', function( done ) { const dxt = new class extends XferTools { constructor() { super( ccm, 'Deposits' ); } }; const pxt = new class extends XferTools { constructor() { super( ccm, 'Payments' ); } }; as.add( ( as ) => { const db = ccm.db( 'xfer' ); dxt.processXfer( as, { src_account: system_account, dst_account: first_account, currency: 'L:XFRT', amount: '10.10', type: 'Deposit', src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, first_account, '650' ); //--- pxt.processXfer( as, { src_account: first_account, dst_account: second_account, currency: 'I:EUR', amount: '6.50', type: 'Generic', src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, first_account, '0' ); check_balance( as, second_account, '650' ); //--- dxt.processXfer( as, { src_account: second_account, dst_account: system_account, currency: 'L:XFRT', amount: '9.43', type: 'Withdrawal', src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, second_account, '0' ); }, ( as, err ) => { console.log( as.state.test_name ); console.log( err ); console.log( as.state.error_info ); done( as.state.last_exception || 'Fail' ); } ); as.add( ( as ) => done() ); as.execute(); } ); it( 'should process transit xfers', function( done ) { const pxt = new class extends XferTools { constructor() { super( ccm, 'Payments' ); } _domainExtIn( as, _in_xfer ) { as.add( ( as ) => {} ); } _domainExtOut( as, _out_xfer ) { as.add( ( as ) => {} ); } }; as.add( ( as ) => { const db = ccm.db( 'xfer' ); pxt.processXfer( as, { src_account: system_account, dst_account: external_account, currency: 'I:EUR', amount: '10.00', type: 'Generic', src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, external_account, '1000' ); //-- as.add( ( as ) => as.state.test_name = 'Transit In' ); pxt.processXfer( as, { src_account: first_transit, dst_account: first_account, currency: 'I:EUR', amount: '1.00', type: 'Generic', src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, external_account, '900' ); check_balance( as, first_transit, '0' ); check_balance( as, first_account, '100' ); //--- as.add( ( as ) => as.state.test_name = 'Transit Out' ); pxt.processXfer( as, { src_account: first_account, dst_account: second_transit, currency: 'I:EUR', amount: '1.00', type: 'Generic', src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, first_account, '0' ); check_balance( as, second_transit, '0' ); check_balance( as, external_account, '1000' ); //--- as.add( ( as ) => as.state.test_name = 'Transit In-Out' ); pxt.processXfer( as, { src_account: first_transit, dst_account: second_transit, currency: 'I:EUR', amount: '1.00', type: 'Generic', src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, first_transit, '0' ); check_balance( as, second_transit, '0' ); check_balance( as, external_account, '1000' ); //--- pxt.processXfer( as, { src_account: external_account, dst_account: system_account, currency: 'I:EUR', amount: '10.00', type: 'Generic', src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, external_account, '0' ); //--- as.add( ( as ) => as.state.test_name = 'Ensure all xfers Done' ); db.select( 'xfers' ).where( 'xfer_status !=', 'Done' ).execute( as ); as.add( ( as, { rows } ) => expect( rows.length ).to.equal( 0 ) ); }, ( as, err ) => { console.log( as.state.test_name ); console.log( err ); console.log( as.state.error_info ); done( as.state.last_exception || 'Fail' ); } ); as.add( ( as ) => done() ); as.execute(); } ); it( 'should process ext_id', function( done ) { const dxt = new class extends XferTools { constructor() { super( ccm, 'Deposits' ); } }; as.add( ( as ) => { const db = ccm.db( 'xfer' ); // as.add( ( as ) => as.state.test_name = 'setup' ); dxt.processXfer( as, { src_account: system_account, dst_account: external_account, currency: 'I:EUR', amount: '10.00', type: 'Generic', src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, external_account, '1000' ); // as.add( ( as ) => as.state.test_name = 'initial' ); dxt.processXfer( as, { src_account: external_account, dst_account: first_account, currency: 'I:EUR', amount: '4.10', type: 'Deposit', orig_ts: moment.utc().format(), ext_id: dxt.makeExtId( external_account, 'R1' ), src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, external_account, '590' ); check_balance( as, first_account, '410' ); // as.add( ( as ) => as.state.test_name = 'repeat first #1' ); dxt.processXfer( as, { src_account: external_account, dst_account: first_account, currency: 'I:EUR', amount: '4.10', type: 'Deposit', ext_id: dxt.makeExtId( external_account, 'R1' ), orig_ts: moment.utc().format(), src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, external_account, '590' ); check_balance( as, first_account, '410' ); // as.add( ( as ) => as.state.test_name = 'second' ); dxt.processXfer( as, { src_account: external_account, dst_account: first_account, currency: 'I:EUR', amount: '5.90', type: 'Deposit', orig_ts: moment.utc().format(), ext_id: dxt.makeExtId( external_account, 'R2' ), src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, external_account, '0' ); check_balance( as, first_account, '1000' ); // as.add( ( as ) => as.state.test_name = 'repeat first #2' ); dxt.processXfer( as, { src_account: external_account, dst_account: first_account, currency: 'I:EUR', amount: '4.10', type: 'Deposit', ext_id: dxt.makeExtId( external_account, 'R1' ), orig_ts: moment.utc().format(), src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, external_account, '0' ); check_balance( as, first_account, '1000' ); // as.add( ( as ) => as.state.test_name = 'repeat second #1' ); dxt.processXfer( as, { src_account: external_account, dst_account: first_account, currency: 'I:EUR', amount: '5.90', type: 'Deposit', orig_ts: moment.utc().format(), ext_id: dxt.makeExtId( external_account, 'R2' ), src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, external_account, '0' ); check_balance( as, first_account, '1000' ); // as.add( ( as ) => as.state.test_name = 'third' ); dxt.processXfer( as, { src_account: first_account, dst_account: external_account, currency: 'I:EUR', amount: '10.00', type: 'Withdrawal', orig_ts: moment.utc().format(), ext_id: dxt.makeExtId( external_account, 'R3' ), src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, external_account, '1000' ); check_balance( as, first_account, '0' ); // as.add( ( as ) => as.state.test_name = 'repeat second #2' ); dxt.processXfer( as, { src_account: external_account, dst_account: first_account, currency: 'I:EUR', amount: '5.90', type: 'Deposit', orig_ts: moment.utc().format(), ext_id: dxt.makeExtId( external_account, 'R2' ), src_limit_prefix: false, dst_limit_prefix: false, } ); // as.add( ( as ) => as.state.test_name = 'repeat third' ); dxt.processXfer( as, { src_account: first_account, dst_account: external_account, currency: 'I:EUR', amount: '10.00', type: 'Withdrawal', orig_ts: moment.utc().format(), ext_id: dxt.makeExtId( external_account, 'R3' ), src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, external_account, '1000' ); check_balance( as, first_account, '0' ); // as.add( ( as ) => as.state.test_name = 'cleanup' ); dxt.processXfer( as, { src_account: external_account, dst_account: system_account, currency: 'I:EUR', amount: '10.00', type: 'Generic', src_limit_prefix: false, dst_limit_prefix: false, } ); check_balance( as, external_account, '0' ); }, ( as, err ) => { console.log( as.state.test_name ); console.log( err ); console.log( as.state.error_info