Compare commits

...

12 Commits

Author SHA1 Message Date
nolash
fab9b0c520 Add long timeout to first account create in contract migration part 2 2021-06-04 22:00:06 +02:00
9566f8c8e2 Merge branch 'philip/qfix-vbumps' into 'master'
Bumps cic-eth and cic-base versions.

See merge request grassrootseconomics/cic-internal-integration!179
2021-06-04 08:34:14 +00:00
007d7a5121 Bumps cic-eth and cic-base versions. 2021-06-04 11:12:04 +03:00
fc20849aff Merge branch 'bvander/contract-migration-requirements' into 'master'
pull the req out of the container and bump em

See merge request grassrootseconomics/cic-internal-integration!178
2021-06-03 18:54:19 +00:00
1605e53216 pull the req out of the container and bump em 2021-06-03 11:43:13 -07:00
200fdf0e3c Merge branch 'no-host-mount-startup' into 'master'
no local file mounts for config files

See merge request grassrootseconomics/cic-internal-integration!177
2021-06-03 17:22:49 +00:00
022db04198 no local file mounts for config files 2021-06-03 17:22:47 +00:00
1c17048981 Update README.md 2021-06-03 17:19:55 +00:00
Louis Holbrook
04c0963f33 Merge branch 'lash/tmp-check-chaintool' into 'master'
Update queue/syncer module structure

See merge request grassrootseconomics/cic-internal-integration!176
2021-06-03 13:51:55 +00:00
Louis Holbrook
096ed9bc27 Update queue/syncer module structure 2021-06-03 13:51:55 +00:00
1a931eced4 Merge branch 'philip/management-integration-tests' into 'master'
Philip/management integration tests

See merge request grassrootseconomics/cic-internal-integration!159
2021-06-03 13:40:51 +00:00
ed9e032890 Philip/management integration tests 2021-06-03 13:40:51 +00:00
60 changed files with 3504 additions and 195 deletions

View File

@@ -31,7 +31,7 @@ from chainqueue.db.enum import (
status_str, status_str,
) )
from chainqueue.error import TxStateChangeError from chainqueue.error import TxStateChangeError
from chainqueue.query import get_tx from chainqueue.sql.query import get_tx
from eth_erc20 import ERC20 from eth_erc20 import ERC20
# local imports # local imports

View File

@@ -19,7 +19,7 @@ from cic_eth_registry import CICRegistry
from cic_eth_registry.erc20 import ERC20Token from cic_eth_registry.erc20 import ERC20Token
from chainqueue.db.models.otx import Otx from chainqueue.db.models.otx import Otx
from chainqueue.db.enum import StatusEnum from chainqueue.db.enum import StatusEnum
from chainqueue.query import get_tx_cache from chainqueue.sql.query import get_tx_cache
from eth_erc20 import ERC20 from eth_erc20 import ERC20
# local imports # local imports

View File

@@ -5,7 +5,7 @@ import datetime
import celery import celery
from chainlib.chain import ChainSpec from chainlib.chain import ChainSpec
from chainlib.eth.tx import unpack from chainlib.eth.tx import unpack
import chainqueue.query import chainqueue.sql.query
from chainqueue.db.enum import ( from chainqueue.db.enum import (
StatusEnum, StatusEnum,
is_alive, is_alive,
@@ -28,7 +28,7 @@ celery_app = celery.current_app
def get_tx_cache(chain_spec_dict, tx_hash): def get_tx_cache(chain_spec_dict, tx_hash):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.query.get_tx_cache(chain_spec, tx_hash, session=session) r = chainqueue.sql.query.get_tx_cache(chain_spec, tx_hash, session=session)
session.close() session.close()
return r return r
@@ -37,7 +37,7 @@ def get_tx_cache(chain_spec_dict, tx_hash):
def get_tx(chain_spec_dict, tx_hash): def get_tx(chain_spec_dict, tx_hash):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.query.get_tx(chain_spec, tx_hash, session=session) r = chainqueue.sql.query.get_tx(chain_spec, tx_hash, session=session)
session.close() session.close()
return r return r
@@ -46,7 +46,7 @@ def get_tx(chain_spec_dict, tx_hash):
def get_account_tx(chain_spec_dict, address, as_sender=True, as_recipient=True, counterpart=None): def get_account_tx(chain_spec_dict, address, as_sender=True, as_recipient=True, counterpart=None):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.query.get_account_tx(chain_spec, address, as_sender=True, as_recipient=True, counterpart=None, session=session) r = chainqueue.sql.query.get_account_tx(chain_spec, address, as_sender=True, as_recipient=True, counterpart=None, session=session)
session.close() session.close()
return r return r
@@ -55,17 +55,17 @@ def get_account_tx(chain_spec_dict, address, as_sender=True, as_recipient=True,
def get_upcoming_tx_nolock(chain_spec_dict, status=StatusEnum.READYSEND, not_status=None, recipient=None, before=None, limit=0, session=None): def get_upcoming_tx_nolock(chain_spec_dict, status=StatusEnum.READYSEND, not_status=None, recipient=None, before=None, limit=0, session=None):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.query.get_upcoming_tx(chain_spec, status, not_status=not_status, recipient=recipient, before=before, limit=limit, session=session, decoder=unpack) r = chainqueue.sql.query.get_upcoming_tx(chain_spec, status, not_status=not_status, recipient=recipient, before=before, limit=limit, session=session, decoder=unpack)
session.close() session.close()
return r return r
def get_status_tx(chain_spec, status, not_status=None, before=None, exact=False, limit=0, session=None): def get_status_tx(chain_spec, status, not_status=None, before=None, exact=False, limit=0, session=None):
return chainqueue.query.get_status_tx_cache(chain_spec, status, not_status=not_status, before=before, exact=exact, limit=limit, session=session, decoder=unpack) return chainqueue.sql.query.get_status_tx_cache(chain_spec, status, not_status=not_status, before=before, exact=exact, limit=limit, session=session, decoder=unpack)
def get_paused_tx(chain_spec, status=None, sender=None, session=None, decoder=None): def get_paused_tx(chain_spec, status=None, sender=None, session=None, decoder=None):
return chainqueue.query.get_paused_tx_cache(chain_spec, status=status, sender=sender, session=session, decoder=unpack) return chainqueue.sql.query.get_paused_tx_cache(chain_spec, status=status, sender=sender, session=session, decoder=unpack)
def get_nonce_tx(chain_spec, nonce, sender): def get_nonce_tx(chain_spec, nonce, sender):

View File

@@ -1,6 +1,6 @@
# external imports # external imports
from chainlib.chain import ChainSpec from chainlib.chain import ChainSpec
import chainqueue.state import chainqueue.sql.state
# local imports # local imports
import celery import celery
@@ -14,7 +14,7 @@ celery_app = celery.current_app
def set_sent(chain_spec_dict, tx_hash, fail=False): def set_sent(chain_spec_dict, tx_hash, fail=False):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.state.set_sent(chain_spec, tx_hash, fail, session=session) r = chainqueue.sql.state.set_sent(chain_spec, tx_hash, fail, session=session)
session.close() session.close()
return r return r
@@ -23,7 +23,7 @@ def set_sent(chain_spec_dict, tx_hash, fail=False):
def set_final(chain_spec_dict, tx_hash, block=None, tx_index=None, fail=False): def set_final(chain_spec_dict, tx_hash, block=None, tx_index=None, fail=False):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.state.set_final(chain_spec, tx_hash, block=block, tx_index=tx_index, fail=fail, session=session) r = chainqueue.sql.state.set_final(chain_spec, tx_hash, block=block, tx_index=tx_index, fail=fail, session=session)
session.close() session.close()
return r return r
@@ -32,7 +32,7 @@ def set_final(chain_spec_dict, tx_hash, block=None, tx_index=None, fail=False):
def set_cancel(chain_spec_dict, tx_hash, manual=False): def set_cancel(chain_spec_dict, tx_hash, manual=False):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.state.set_cancel(chain_spec, tx_hash, manual, session=session) r = chainqueue.sql.state.set_cancel(chain_spec, tx_hash, manual, session=session)
session.close() session.close()
return r return r
@@ -41,7 +41,7 @@ def set_cancel(chain_spec_dict, tx_hash, manual=False):
def set_rejected(chain_spec_dict, tx_hash): def set_rejected(chain_spec_dict, tx_hash):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.state.set_rejected(chain_spec, tx_hash, session=session) r = chainqueue.sql.state.set_rejected(chain_spec, tx_hash, session=session)
session.close() session.close()
return r return r
@@ -50,7 +50,7 @@ def set_rejected(chain_spec_dict, tx_hash):
def set_fubar(chain_spec_dict, tx_hash): def set_fubar(chain_spec_dict, tx_hash):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.state.set_fubar(chain_spec, tx_hash, session=session) r = chainqueue.sql.state.set_fubar(chain_spec, tx_hash, session=session)
session.close() session.close()
return r return r
@@ -59,7 +59,7 @@ def set_fubar(chain_spec_dict, tx_hash):
def set_manual(chain_spec_dict, tx_hash): def set_manual(chain_spec_dict, tx_hash):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.state.set_manual(chain_spec, tx_hash, session=session) r = chainqueue.sql.state.set_manual(chain_spec, tx_hash, session=session)
session.close() session.close()
return r return r
@@ -68,7 +68,7 @@ def set_manual(chain_spec_dict, tx_hash):
def set_ready(chain_spec_dict, tx_hash): def set_ready(chain_spec_dict, tx_hash):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.state.set_ready(chain_spec, tx_hash, session=session) r = chainqueue.sql.state.set_ready(chain_spec, tx_hash, session=session)
session.close() session.close()
return r return r
@@ -77,7 +77,7 @@ def set_ready(chain_spec_dict, tx_hash):
def set_reserved(chain_spec_dict, tx_hash): def set_reserved(chain_spec_dict, tx_hash):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.state.set_reserved(chain_spec, tx_hash, session=session) r = chainqueue.sql.state.set_reserved(chain_spec, tx_hash, session=session)
session.close() session.close()
return r return r
@@ -86,7 +86,7 @@ def set_reserved(chain_spec_dict, tx_hash):
def set_waitforgas(chain_spec_dict, tx_hash): def set_waitforgas(chain_spec_dict, tx_hash):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.state.set_waitforgas(chain_spec, tx_hash, session=session) r = chainqueue.sql.state.set_waitforgas(chain_spec, tx_hash, session=session)
session.close() session.close()
return r return r
@@ -95,7 +95,7 @@ def set_waitforgas(chain_spec_dict, tx_hash):
def get_state_log(chain_spec_dict, tx_hash): def get_state_log(chain_spec_dict, tx_hash):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.state.get_state_log(chain_spec, tx_hash, session=session) r = chainqueue.sql.state.get_state_log(chain_spec, tx_hash, session=session)
session.close() session.close()
return r return r
@@ -104,6 +104,6 @@ def get_state_log(chain_spec_dict, tx_hash):
def obsolete(chain_spec_dict, tx_hash, final): def obsolete(chain_spec_dict, tx_hash, final):
chain_spec = ChainSpec.from_dict(chain_spec_dict) chain_spec = ChainSpec.from_dict(chain_spec_dict)
session = SessionBase.create_session() session = SessionBase.create_session()
r = chainqueue.state.obsolete_by_cache(chain_spec, tx_hash, final, session=session) r = chainqueue.sql.state.obsolete_by_cache(chain_spec, tx_hash, final, session=session)
session.close() session.close()
return r return r

View File

@@ -15,14 +15,14 @@ from sqlalchemy import tuple_
from sqlalchemy import func from sqlalchemy import func
from chainlib.chain import ChainSpec from chainlib.chain import ChainSpec
from chainlib.eth.tx import unpack from chainlib.eth.tx import unpack
import chainqueue.state import chainqueue.sql.state
from chainqueue.db.enum import ( from chainqueue.db.enum import (
StatusEnum, StatusEnum,
StatusBits, StatusBits,
is_alive, is_alive,
dead, dead,
) )
from chainqueue.tx import create from chainqueue.sql.tx import create
from chainqueue.error import NotLocalTxError from chainqueue.error import NotLocalTxError
from chainqueue.db.enum import status_str from chainqueue.db.enum import status_str

View File

@@ -21,7 +21,7 @@ from chainqueue.db.enum import (
StatusBits, StatusBits,
) )
from chainqueue.error import NotLocalTxError from chainqueue.error import NotLocalTxError
from chainqueue.state import set_reserved from chainqueue.sql.state import set_reserved
# local imports # local imports
import cic_eth import cic_eth

View File

@@ -10,7 +10,7 @@ from chainlib.eth.tx import unpack
from chainqueue.db.enum import StatusBits from chainqueue.db.enum import StatusBits
from chainqueue.db.models.tx import TxCache from chainqueue.db.models.tx import TxCache
from chainqueue.db.models.otx import Otx from chainqueue.db.models.otx import Otx
from chainqueue.query import get_paused_tx_cache as get_paused_tx from chainqueue.sql.query import get_paused_tx_cache as get_paused_tx
# local imports # local imports
from cic_eth.db.models.base import SessionBase from cic_eth.db.models.base import SessionBase

View File

@@ -3,7 +3,7 @@ import logging
# external imports # external imports
import celery import celery
from chainqueue.state import obsolete_by_cache from chainqueue.sql.state import obsolete_by_cache
logg = logging.getLogger() logg = logging.getLogger()

View File

@@ -10,7 +10,7 @@ version = (
0, 0,
11, 11,
0, 0,
'beta.15', 'beta.16',
) )
version_object = semver.VersionInfo( version_object = semver.VersionInfo(

View File

@@ -1,4 +1,4 @@
cic-base~=0.1.2b14 cic-base~=0.1.2b15
celery==4.4.7 celery==4.4.7
crypto-dev-signer~=0.4.14b3 crypto-dev-signer~=0.4.14b3
confini~=0.3.6rc3 confini~=0.3.6rc3
@@ -16,8 +16,8 @@ moolb~=0.1.1b2
eth-address-index~=0.1.1a11 eth-address-index~=0.1.1a11
chainlib~=0.0.3rc2 chainlib~=0.0.3rc2
hexathon~=0.0.1a7 hexathon~=0.0.1a7
chainsyncer[sql]~=0.0.2a4 chainsyncer[sql]~=0.0.2a5
chainqueue~=0.0.2b1 chainqueue~=0.0.2b3
sarafu-faucet==0.0.3a3 sarafu-faucet==0.0.3a3
erc20-faucet==0.2.1a4 erc20-faucet==0.2.1a4
coincurve==15.0.0 coincurve==15.0.0

View File

@@ -1,7 +1,7 @@
# external imports # external imports
from chainlib.connection import RPCConnection from chainlib.connection import RPCConnection
from chainlib.eth.nonce import OverrideNonceOracle from chainlib.eth.nonce import OverrideNonceOracle
from chainqueue.tx import create as queue_create from chainqueue.sql.tx import create as queue_create
from chainlib.eth.tx import ( from chainlib.eth.tx import (
TxFormat, TxFormat,
unpack, unpack,
@@ -16,7 +16,7 @@ from chainlib.eth.block import (
block_by_number, block_by_number,
Block, Block,
) )
from chainqueue.state import ( from chainqueue.sql.state import (
set_waitforgas, set_waitforgas,
) )
from hexathon import strip_0x from hexathon import strip_0x

View File

@@ -15,7 +15,7 @@ from chainlib.eth.block import (
) )
from erc20_faucet import Faucet from erc20_faucet import Faucet
from hexathon import strip_0x from hexathon import strip_0x
from chainqueue.query import get_account_tx from chainqueue.sql.query import get_account_tx
# local imports # local imports
from cic_eth.runnable.daemons.filters.register import RegistrationFilter from cic_eth.runnable.daemons.filters.register import RegistrationFilter

View File

@@ -17,8 +17,8 @@ from chainlib.eth.block import (
) )
from chainqueue.db.models.otx import Otx from chainqueue.db.models.otx import Otx
from chainqueue.db.enum import StatusBits from chainqueue.db.enum import StatusBits
from chainqueue.tx import create as queue_create from chainqueue.sql.tx import create as queue_create
from chainqueue.state import ( from chainqueue.sql.state import (
set_reserved, set_reserved,
set_ready, set_ready,
set_sent, set_sent,

View File

@@ -15,7 +15,7 @@ from chainlib.eth.block import (
Block, Block,
) )
from hexathon import strip_0x from hexathon import strip_0x
from chainqueue.query import get_account_tx from chainqueue.sql.query import get_account_tx
# local imports # local imports
from cic_eth.runnable.daemons.filters.transferauth import TransferAuthFilter from cic_eth.runnable.daemons.filters.transferauth import TransferAuthFilter

View File

@@ -17,8 +17,8 @@ from chainlib.eth.block import (
) )
from chainqueue.db.models.otx import Otx from chainqueue.db.models.otx import Otx
from chainqueue.db.enum import StatusBits from chainqueue.db.enum import StatusBits
from chainqueue.tx import create as queue_create from chainqueue.sql.tx import create as queue_create
from chainqueue.state import ( from chainqueue.sql.state import (
set_reserved, set_reserved,
set_ready, set_ready,
set_sent, set_sent,

View File

@@ -29,12 +29,12 @@ from chainqueue.db.enum import (
StatusBits, StatusBits,
status_str, status_str,
) )
from chainqueue.state import ( from chainqueue.sql.state import (
set_fubar, set_fubar,
set_ready, set_ready,
set_reserved, set_reserved,
) )
from chainqueue.query import ( from chainqueue.sql.query import (
get_tx, get_tx,
get_nonce_tx_cache, get_nonce_tx_cache,
) )

View File

@@ -11,7 +11,7 @@ from chainlib.eth.nonce import (
OverrideNonceOracle, OverrideNonceOracle,
RPCNonceOracle, RPCNonceOracle,
) )
from chainqueue.tx import create as queue_create from chainqueue.sql.tx import create as queue_create
from chainlib.eth.tx import ( from chainlib.eth.tx import (
raw, raw,
receipt, receipt,
@@ -23,14 +23,14 @@ from chainlib.eth.gas import (
Gas, Gas,
OverrideGasOracle, OverrideGasOracle,
) )
from chainqueue.state import ( from chainqueue.sql.state import (
set_reserved, set_reserved,
set_sent, set_sent,
set_ready, set_ready,
) )
from chainqueue.db.models.otx import Otx from chainqueue.db.models.otx import Otx
from chainqueue.db.enum import StatusBits from chainqueue.db.enum import StatusBits
from chainqueue.query import get_nonce_tx_cache from chainqueue.sql.query import get_nonce_tx_cache
from eth_erc20 import ERC20 from eth_erc20 import ERC20
from cic_eth_registry import CICRegistry from cic_eth_registry import CICRegistry

View File

@@ -12,7 +12,7 @@ from eth_accounts_index import AccountsIndex
from chainlib.eth.tx import ( from chainlib.eth.tx import (
transaction, transaction,
) )
from chainqueue.state import ( from chainqueue.sql.state import (
set_reserved, set_reserved,
) )

View File

@@ -5,7 +5,7 @@ import logging
import celery import celery
from chainlib.connection import RPCConnection from chainlib.connection import RPCConnection
from chainlib.eth.nonce import OverrideNonceOracle from chainlib.eth.nonce import OverrideNonceOracle
from chainqueue.tx import ( from chainqueue.sql.tx import (
create as queue_create, create as queue_create,
) )
from chainlib.eth.gas import ( from chainlib.eth.gas import (
@@ -13,7 +13,7 @@ from chainlib.eth.gas import (
OverrideGasOracle, OverrideGasOracle,
) )
from chainlib.eth.tx import TxFormat from chainlib.eth.tx import TxFormat
from chainqueue.query import get_nonce_tx_cache from chainqueue.sql.query import get_nonce_tx_cache
from chainqueue.db.models.otx import Otx from chainqueue.db.models.otx import Otx
from chainqueue.db.enum import StatusBits from chainqueue.db.enum import StatusBits
from hexathon import add_0x from hexathon import add_0x

View File

@@ -21,10 +21,10 @@ from chainlib.eth.constant import (
MINIMUM_FEE_UNITS, MINIMUM_FEE_UNITS,
MINIMUM_FEE_PRICE, MINIMUM_FEE_PRICE,
) )
from chainqueue.tx import create as queue_create from chainqueue.sql.tx import create as queue_create
from chainqueue.query import get_tx from chainqueue.sql.query import get_tx
from chainqueue.db.enum import StatusBits from chainqueue.db.enum import StatusBits
from chainqueue.state import ( from chainqueue.sql.state import (
set_ready, set_ready,
set_reserved, set_reserved,
set_sent, set_sent,

View File

@@ -18,8 +18,8 @@ from chainlib.eth.tx import (
) )
from hexathon import strip_0x from hexathon import strip_0x
from chainqueue.db.models.otx import Otx from chainqueue.db.models.otx import Otx
from chainqueue.tx import create as queue_create from chainqueue.sql.tx import create as queue_create
from chainqueue.state import ( from chainqueue.sql.state import (
set_reserved, set_reserved,
set_ready, set_ready,
set_sent, set_sent,

View File

@@ -5,7 +5,7 @@ import logging
# external imports # external imports
import pytest import pytest
import celery import celery
from chainqueue.tx import create as queue_create from chainqueue.sql.tx import create as queue_create
from chainlib.eth.nonce import ( from chainlib.eth.nonce import (
RPCNonceOracle, RPCNonceOracle,
OverrideNonceOracle, OverrideNonceOracle,
@@ -23,7 +23,7 @@ from hexathon import (
add_0x, add_0x,
strip_0x, strip_0x,
) )
from chainqueue.state import ( from chainqueue.sql.state import (
set_reserved, set_reserved,
set_ready, set_ready,
) )

View File

@@ -31,7 +31,7 @@ function handleNoMergeGet(db, digest, keystore) {
doh(e); doh(e);
}); });
}).catch((e) => { }).catch((e) => {
console.error('mesage', e); console.error('message', e);
doh(e); doh(e);
}); });
}) })
@@ -46,7 +46,7 @@ function handleServerMergePost(data, db, digest, keystore, signer) {
let e = undefined; let e = undefined;
let s = undefined; let s = undefined;
if (v === undefined) { if (v === undefined) {
s = new Syncable(digest, data); s = new Syncable(digest, o);
s.onwrap = (e) => { s.onwrap = (e) => {
whohoo(e.toJSON()); whohoo(e.toJSON());
}; };

View File

@@ -56,7 +56,7 @@ class AfricasTalkingNotifier:
response = self.api_client.send(message=message, recipients=[recipient]) response = self.api_client.send(message=message, recipients=[recipient])
logg.debug(f'africastalking response no-sender-id {response}') logg.debug(f'africastalking response no-sender-id {response}')
recipients = response.get('Recipients') recipients = response.get('SMSMessageData').get('Recipients')
if len(recipients) != 1: if len(recipients) != 1:
status = response.get('SMSMessageData').get('Message') status = response.get('SMSMessageData').get('Message')

View File

@@ -28,6 +28,7 @@ packages =
cic_notify cic_notify
cic_notify.db cic_notify.db
cic_notify.db.models cic_notify.db.models
cic_notify.ext
cic_notify.tasks.sms cic_notify.tasks.sms
cic_notify.runnable cic_notify.runnable
scripts = scripts =

View File

@@ -0,0 +1,4 @@
[test]
gift_value = 50.00
server_url = http://localhost:63315/
token_symbol = GFT

View File

@@ -238,13 +238,43 @@
"description": "Menu to display a user's entire profile", "description": "Menu to display a user's entire profile",
"display_key": "ussd.kenya.display_user_metadata", "display_key": "ussd.kenya.display_user_metadata",
"name": "display_user_metadata", "name": "display_user_metadata",
"parent": "account_management" "parent": "metadata_management"
}, },
"41": { "41": {
"description": "The recipient is not in the system", "description": "The recipient is not in the system",
"display_key": "ussd.kenya.exit_invalid_recipient", "display_key": "ussd.kenya.exit_invalid_recipient",
"name": "exit_invalid_recipient", "name": "exit_invalid_recipient",
"parent": null "parent": null
},
"42": {
"description": "Pin entry menu for changing name data.",
"display_key": "ussd.kenya.name_edit_pin_authorization",
"name": "name_edit_pin_authorization",
"parent": "metadata_management"
},
"43": {
"description": "Pin entry menu for changing gender data.",
"display_key": "ussd.kenya.gender_edit_pin_authorization",
"name": "gender_edit_pin_authorization",
"parent": "metadata_management"
},
"44": {
"description": "Pin entry menu for changing location data.",
"display_key": "ussd.kenya.location_edit_pin_authorization",
"name": "location_edit_pin_authorization",
"parent": "metadata_management"
},
"45": {
"description": "Pin entry menu for changing products data.",
"display_key": "ussd.kenya.products_edit_pin_authorization",
"name": "products_edit_pin_authorization",
"parent": "metadata_management"
},
"46": {
"description": "Pin confirmation for pin change.",
"display_key": "ussd.kenya.new_pin_confirmation",
"name": "new_pin_confirmation",
"parent": "metadata_management"
} }
} }

View File

@@ -78,28 +78,27 @@ class MetadataRequestsHandler(Metadata):
:param data: The data to be stored in the metadata server. :param data: The data to be stored in the metadata server.
:type data: dict|str :type data: dict|str
""" """
data = json.dumps(data).encode('utf-8') data = json.dumps(data)
result = make_request(method='POST', url=self.url, data=data, headers=self.headers) result = make_request(method='POST', url=self.url, data=data, headers=self.headers)
metadata_http_error_handler(result=result) metadata_http_error_handler(result=result)
metadata = result.content metadata = result.json()
self.edit(data=metadata) self.edit(data=metadata)
def edit(self, data: bytes): def edit(self, data: Union[Dict, str]):
""" This function is responsible for editing data in the metadata server corresponding to a unique pointer. """ This function is responsible for editing data in the metadata server corresponding to a unique pointer.
:param data: The data to be edited in the metadata server. :param data: The data to be edited in the metadata server.
:type data: bytes :type data: dict
""" """
cic_meta_signer = Signer() cic_meta_signer = Signer()
signature = cic_meta_signer.sign_digest(data=data) signature = cic_meta_signer.sign_digest(data=data)
algorithm = cic_meta_signer.get_operational_key().get('algo') algorithm = cic_meta_signer.get_operational_key().get('algo')
decoded_data = data.decode('utf-8')
formatted_data = { formatted_data = {
'm': data.decode('utf-8'), 'm': json.dumps(data),
's': { 's': {
'engine': self.engine, 'engine': self.engine,
'algo': algorithm, 'algo': algorithm,
'data': signature, 'data': signature,
'digest': json.loads(data).get('digest'), 'digest': data.get('digest'),
} }
} }
formatted_data = json.dumps(formatted_data) formatted_data = json.dumps(formatted_data)
@@ -110,19 +109,32 @@ class MetadataRequestsHandler(Metadata):
decoded_identifier = self.identifier.decode("utf-8") decoded_identifier = self.identifier.decode("utf-8")
except UnicodeDecodeError: except UnicodeDecodeError:
decoded_identifier = self.identifier.hex() decoded_identifier = self.identifier.hex()
logg.info(f'identifier: {decoded_identifier}. metadata pointer: {self.metadata_pointer} set to: {decoded_data}.') logg.info(f'identifier: {decoded_identifier}. metadata pointer: {self.metadata_pointer} set to: {data}.')
def query(self): def query(self):
"""This function is responsible for querying the metadata server for data corresponding to a unique pointer.""" """
:return:
:rtype:
"""
# retrieve the metadata
result = make_request(method='GET', url=self.url) result = make_request(method='GET', url=self.url)
metadata_http_error_handler(result=result) metadata_http_error_handler(result=result)
response_data = result.json()
data = json.loads(response_data) # json serialize retrieved data
if not isinstance(data, dict): result_data = result.json()
raise ValueError(f'Invalid data object: {data}.')
# validate result data format
if not isinstance(result_data, dict):
raise ValueError(f'Invalid result data object: {result_data}.')
if result.status_code == 200 and self.cic_type == ':cic.person': if result.status_code == 200 and self.cic_type == ':cic.person':
# validate person metadata
person = Person() person = Person()
deserialized_person = person.deserialize(person_data=data) person_data = person.deserialize(person_data=result_data)
data = json.dumps(deserialized_person.serialize())
cache_data(self.metadata_pointer, data=data) # format new person data for caching
data = json.dumps(person_data.serialize())
# cache metadata
cache_data(key=self.metadata_pointer, data=data)
logg.debug(f'caching: {data} with key: {self.metadata_pointer}') logg.debug(f'caching: {data} with key: {self.metadata_pointer}')

View File

@@ -47,14 +47,13 @@ class Signer:
logg.debug(f'using signing key: {key_id}, algorithm: {key_algorithm}') logg.debug(f'using signing key: {key_id}, algorithm: {key_algorithm}')
return gpg_keys[0] return gpg_keys[0]
def sign_digest(self, data: bytes): def sign_digest(self, data: dict):
""" """
:param data: :param data:
:type data: :type data:
:return: :return:
:rtype: :rtype:
""" """
data = json.loads(data)
digest = data['digest'] digest = data['digest']
key_id = self.get_operational_key().get('keyid') key_id = self.get_operational_key().get('keyid')
signature = self.gpg.sign(digest, passphrase=self.gpg_passphrase, keyid=key_id) signature = self.gpg.sign(digest, passphrase=self.gpg_passphrase, keyid=key_id)

View File

@@ -251,9 +251,9 @@ def process_display_user_metadata(user: Account, display_key: str):
identifier=blockchain_address_to_metadata_pointer(blockchain_address=user.blockchain_address), identifier=blockchain_address_to_metadata_pointer(blockchain_address=user.blockchain_address),
cic_type=':cic.person' cic_type=':cic.person'
) )
user_metadata = get_cached_data(key) cached_metadata = get_cached_data(key)
if user_metadata: if cached_metadata:
user_metadata = json.loads(user_metadata) user_metadata = json.loads(cached_metadata)
contact_data = get_contact_data_from_vcard(vcard=user_metadata.get('vcard')) contact_data = get_contact_data_from_vcard(vcard=user_metadata.get('vcard'))
logg.debug(f'{contact_data}') logg.debug(f'{contact_data}')
full_name = f'{contact_data.get("given")} {contact_data.get("family")}' full_name = f'{contact_data.get("given")} {contact_data.get("family")}'
@@ -433,7 +433,8 @@ def process_request(user_input: str, user: Account, ussd_session: Optional[dict]
'exit_invalid_pin', 'exit_invalid_pin',
'exit_invalid_new_pin', 'exit_invalid_new_pin',
'exit_pin_mismatch', 'exit_pin_mismatch',
'exit_invalid_request' 'exit_invalid_request',
'exit_successful_transaction'
] and person_metadata is not None: ] and person_metadata is not None:
return UssdMenu.find_by_name(name='start') return UssdMenu.find_by_name(name='start')
else: else:

View File

@@ -13,7 +13,7 @@ import bcrypt
# local imports # local imports
from cic_ussd.db.models.account import AccountStatus, Account from cic_ussd.db.models.account import AccountStatus, Account
from cic_ussd.encoder import PasswordEncoder, create_password_hash from cic_ussd.encoder import PasswordEncoder, create_password_hash, check_password_hash
from cic_ussd.operations import persist_session_to_db_task, create_or_update_session from cic_ussd.operations import persist_session_to_db_task, create_or_update_session
from cic_ussd.redis import InMemoryStore from cic_ussd.redis import InMemoryStore
@@ -78,9 +78,13 @@ def save_initial_pin_to_session_data(state_machine_data: Tuple[str, dict, Accoun
# set initial pin data # set initial pin data
initial_pin = create_password_hash(user_input) initial_pin = create_password_hash(user_input)
session_data = { if ussd_session.get('session_data'):
'initial_pin': initial_pin session_data = ussd_session.get('session_data')
} session_data['initial_pin'] = initial_pin
else:
session_data = {
'initial_pin': initial_pin
}
# create new in memory ussd session with current ussd session data # create new in memory ussd session with current ussd session data
create_or_update_session( create_or_update_session(
@@ -103,9 +107,8 @@ def pins_match(state_machine_data: Tuple[str, dict, Account]) -> bool:
""" """
user_input, ussd_session, user = state_machine_data user_input, ussd_session, user = state_machine_data
initial_pin = ussd_session.get('session_data').get('initial_pin') initial_pin = ussd_session.get('session_data').get('initial_pin')
fernet = PasswordEncoder(PasswordEncoder.key) logg.debug(f'USSD SESSION: {ussd_session}')
initial_pin = fernet.decrypt(initial_pin.encode()) return check_password_hash(user_input, initial_pin)
return bcrypt.checkpw(user_input.encode(), initial_pin)
def complete_pin_change(state_machine_data: Tuple[str, dict, Account]): def complete_pin_change(state_machine_data: Tuple[str, dict, Account]):

View File

@@ -64,13 +64,17 @@ def process_gender_user_input(user: Account, user_input: str):
if user.preferred_language == 'en': if user.preferred_language == 'en':
if user_input == '1': if user_input == '1':
gender = 'Male' gender = 'Male'
else: elif user_input == '2':
gender = 'Female' gender = 'Female'
elif user_input == '3':
gender = 'Other'
else: else:
if user_input == '1': if user_input == '1':
gender = 'Mwanaume' gender = 'Mwanaume'
else: elif user_input == '2':
gender = 'Mwanamke' gender = 'Mwanamke'
elif user_input == '3':
gender = 'Nyingine'
return gender return gender
@@ -88,14 +92,18 @@ def save_metadata_attribute_to_session_data(state_machine_data: Tuple[str, dict,
key = '' key = ''
if 'given_name' in current_state: if 'given_name' in current_state:
key = 'given_name' key = 'given_name'
elif 'family_name' in current_state:
if 'family_name' in current_state:
key = 'family_name' key = 'family_name'
elif 'gender' in current_state:
if 'gender' in current_state:
key = 'gender' key = 'gender'
user_input = process_gender_user_input(user=user, user_input=user_input) user_input = process_gender_user_input(user=user, user_input=user_input)
elif 'location' in current_state:
if 'location' in current_state:
key = 'location' key = 'location'
elif 'products' in current_state:
if 'products' in current_state:
key = 'products' key = 'products'
# check if there is existing session data # check if there is existing session data
@@ -121,12 +129,20 @@ def format_user_metadata(metadata: dict, user: Account):
gender = metadata.get('gender') gender = metadata.get('gender')
given_name = metadata.get('given_name') given_name = metadata.get('given_name')
family_name = metadata.get('family_name') family_name = metadata.get('family_name')
location = {
"area_name": metadata.get('location') # check whether there's existing location data
} if isinstance(metadata.get('location'), dict):
products = [] location = metadata.get('location')
if metadata.get('products'): else:
location = {
"area_name": metadata.get('location')
}
# check whether it is a list
if isinstance(metadata.get('products'), list):
products = metadata.get('products')
else:
products = metadata.get('products').split(',') products = metadata.get('products').split(',')
phone_number = user.phone_number phone_number = user.phone_number
date_registered = int(user.created.replace().timestamp()) date_registered = int(user.created.replace().timestamp())
blockchain_address = user.blockchain_address blockchain_address = user.blockchain_address
@@ -192,28 +208,27 @@ def edit_user_metadata_attribute(state_machine_data: Tuple[str, dict, Account]):
# validate user metadata # validate user metadata
person = Person() person = Person()
user_metadata = json.loads(user_metadata) user_metadata = json.loads(user_metadata)
deserialized_person = person.deserialize(person_data=user_metadata)
# edit specific metadata attribute # edit specific metadata attribute
if given_name: if given_name:
deserialized_person.given_name = given_name user_metadata['given_name'] = given_name
elif family_name: if family_name:
deserialized_person.family_name = family_name user_metadata['family_name'] = family_name
elif gender: if gender:
deserialized_person.gender = gender user_metadata['gender'] = gender
elif location: if location:
# get existing location metadata: # get existing location metadata:
location_data = user_metadata.get('location') location_data = user_metadata.get('location')
location_data['area_name'] = location location_data['area_name'] = location
deserialized_person.location = location_data user_metadata['location'] = location_data
elif products: if products:
deserialized_person.products = products user_metadata['products'] = products
edited_metadata = deserialized_person.serialize() user_metadata = format_user_metadata(metadata=user_metadata, user=user)
s_edit_person_metadata = celery.signature( s_edit_person_metadata = celery.signature(
'cic_ussd.tasks.metadata.edit_person_metadata', 'cic_ussd.tasks.metadata.create_person_metadata',
[blockchain_address, edited_metadata] [blockchain_address, user_metadata]
) )
s_edit_person_metadata.apply_async(queue='cic-ussd') s_edit_person_metadata.apply_async(queue='cic-ussd')

View File

@@ -19,4 +19,6 @@ def translation_for(key: str, preferred_language: Optional[str] = None, **kwargs
""" """
if preferred_language: if preferred_language:
i18n.set('locale', preferred_language) i18n.set('locale', preferred_language)
else:
i18n.set('locale', i18n.config.get('fallback'))
return i18n.t(key, **kwargs) return i18n.t(key, **kwargs)

View File

@@ -1,4 +1,4 @@
cic_base[full_graph]~=0.1.2b2 cic_base[full_graph]~=0.1.2b15
cic-eth~=0.11.0b9 cic-eth~=0.11.0b16
cic-notify~=0.4.0a4 cic-notify~=0.4.0a5
cic-types~=0.1.0a10 cic-types~=0.1.0a10

View File

@@ -6,7 +6,10 @@
"enter_new_pin", "enter_new_pin",
"new_pin_confirmation", "new_pin_confirmation",
"display_user_metadata", "display_user_metadata",
"standard_pin_authorization", "name_edit_pin_authorization",
"gender_edit_pin_authorization",
"location_edit_pin_authorization",
"products_edit_pin_authorization",
"account_balances_pin_authorization", "account_balances_pin_authorization",
"account_statement_pin_authorization", "account_statement_pin_authorization",
"account_balances" "account_balances"

View File

@@ -1,7 +1,11 @@
pytest==6.0.1 Faker==8.1.2
faker-e164==0.1.0
pytest==6.2.4
pytest-alembic==0.2.5 pytest-alembic==0.2.5
pytest-celery==0.0.0a1 pytest-celery==0.0.0a1
pytest-cov==2.10.1 pytest-cov==2.10.1
pytest-mock==3.3.1 pytest-mock==3.3.1
pytest-ordering==0.6
pytest-redis==2.0.0 pytest-redis==2.0.0
requests-mock==1.8.0 requests-mock==1.8.0
tavern==1.14.2

View File

@@ -6,6 +6,7 @@ from cic_types.pytest import *
from tests.fixtures.config import * from tests.fixtures.config import *
from tests.fixtures.db import * from tests.fixtures.db import *
from tests.fixtures.celery import * from tests.fixtures.celery import *
from tests.fixtures.integration import *
from tests.fixtures.user import * from tests.fixtures.user import *
from tests.fixtures.ussd_session import * from tests.fixtures.ussd_session import *
from tests.fixtures.redis import * from tests.fixtures.redis import *

View File

@@ -0,0 +1,249 @@
# standard imports
# external imports
import pytest
from faker import Faker
# local imports
# test imports
from tests.helpers.accounts import phone_number, pin_number, session_id
fake = Faker()
@pytest.fixture(scope='function')
def generate_phone_number() -> str:
return phone_number()
@pytest.fixture(scope='function')
def generate_session_id() -> str:
return session_id()
@pytest.fixture(scope='session')
def first_account_phone_number() -> str:
return phone_number()
@pytest.fixture(scope='session')
def second_account_phone_number() -> str:
return phone_number()
@pytest.fixture(scope='session')
def first_account_pin_number() -> str:
return pin_number()
@pytest.fixture(scope='session')
def second_account_pin_number() -> str:
return pin_number()
@pytest.fixture(scope='session')
def first_metadata_entry_session_id() -> str:
return session_id()
@pytest.fixture(scope='session')
def second_metadata_entry_session_id() -> str:
return session_id()
@pytest.fixture(scope='session')
def first_transaction_session_id() -> str:
return session_id()
@pytest.fixture(scope='session')
def second_transaction_session_id() -> str:
return session_id()
@pytest.fixture(scope='session')
def first_account_given_name() -> str:
return fake.first_name()
@pytest.fixture(scope='session')
def second_account_given_name() -> str:
return fake.first_name()
@pytest.fixture(scope='session')
def first_account_family_name() -> str:
return fake.last_name()
@pytest.fixture(scope='session')
def second_account_family_name() -> str:
return fake.last_name()
@pytest.fixture(scope='session')
def first_account_location() -> str:
return fake.city()
@pytest.fixture(scope='session')
def second_account_location() -> str:
return fake.city()
@pytest.fixture(scope='session')
def first_account_product() -> str:
return fake.color_name()
@pytest.fixture(scope='session')
def second_account_product() -> str:
return fake.color_name()
@pytest.fixture(scope='session')
def first_account_verify_balance_session_id() -> str:
return session_id()
@pytest.fixture(scope='session')
def second_account_verify_balance_session_id() -> str:
return session_id()
@pytest.fixture(scope='session')
def first_profile_management_session_id() -> str:
return session_id()
@pytest.fixture(scope='session')
def second_profile_management_session_id() -> str:
return session_id()
@pytest.fixture(scope='session')
def first_account_change_given_name() -> str:
return fake.first_name()
@pytest.fixture(scope='session')
def second_account_change_given_name() -> str:
return fake.first_name()
@pytest.fixture(scope='session')
def first_account_change_family_name() -> str:
return fake.last_name()
@pytest.fixture(scope='session')
def second_account_change_family_name() -> str:
return fake.last_name()
@pytest.fixture(scope='session')
def first_account_change_location() -> str:
return fake.city()
@pytest.fixture(scope='session')
def second_account_change_location() -> str:
return fake.city()
@pytest.fixture(scope='session')
def first_account_change_product() -> str:
return fake.color_name()
@pytest.fixture(scope='session')
def second_account_change_product() -> str:
return fake.color_name()
@pytest.fixture(scope='session')
def first_profile_management_session_id_1() -> str:
return session_id()
@pytest.fixture(scope='session')
def second_profile_management_session_id_1() -> str:
return session_id()
@pytest.fixture(scope='session')
def first_profile_management_session_id_2() -> str:
return session_id()
@pytest.fixture(scope='session')
def second_profile_management_session_id_2() -> str:
return session_id()
@pytest.fixture(scope='session')
def first_profile_management_session_id_3() -> str:
return session_id()
@pytest.fixture(scope='session')
def second_profile_management_session_id_3() -> str:
return session_id()
@pytest.fixture(scope='session')
def first_profile_management_session_id_4() -> str:
return session_id()
@pytest.fixture(scope='session')
def second_profile_management_session_id_4() -> str:
return session_id()
@pytest.fixture(scope='session')
def first_account_management_session_id() -> str:
return session_id()
@pytest.fixture(scope='session')
def second_account_management_session_id() -> str:
return session_id()
@pytest.fixture(scope='session')
def first_account_management_session_id_1() -> str:
return session_id()
@pytest.fixture(scope='session')
def second_account_management_session_id_1() -> str:
return session_id()
@pytest.fixture(scope='session')
def first_account_new_pin_number() -> str:
return pin_number()
@pytest.fixture(scope='session')
def second_account_new_pin_number() -> str:
return pin_number()
@pytest.fixture(scope='session')
def gift_value(load_config):
return load_config.get('TEST_GIFT_VALUE')
@pytest.fixture(scope='session')
def server_url(load_config):
return load_config.get('TEST_SERVER_URL')
@pytest.fixture(scope='session')
def token_symbol(load_config):
return load_config.get('TEST_TOKEN_SYMBOL')

View File

@@ -0,0 +1,26 @@
# standard imports
import random
import uuid
# external imports
from faker import Faker
from faker_e164.providers import E164Provider
# local imports
# test imports
fake = Faker()
fake.add_provider(E164Provider)
def phone_number() -> str:
return fake.e164('KE')
def session_id() -> str:
return uuid.uuid4().hex
def pin_number() -> int:
return random.randint(1000, 9999)

View File

@@ -0,0 +1,11 @@
import logging
logg = logging.getLogger()
logg.setLevel(logging.DEBUG)
def validate_response(response, expected_response):
"""Makes sure that the response received matches the expected response"""
logg.debug(f'RESPONSE: {response.content.decode("utf-8")}')
assert response.content.decode('utf-8') == expected_response

View File

@@ -0,0 +1,2 @@
#!/bin/bash
PYTHONPATH=. py.test --debug -vv --log-level debug -s --log-cli-level debug

View File

@@ -0,0 +1,466 @@
test_name: Test the creation of accounts through the cic_user_ussd_server entrypoint.
marks:
- usefixtures:
- gift_value
- server_url
- token_symbol
- generate_session_id
- first_account_phone_number
- second_account_phone_number
- first_account_pin_number
- second_account_pin_number
- first_account_family_name
- second_account_family_name
- first_account_given_name
- second_account_given_name
- first_account_location
- second_account_location
- first_account_product
- second_account_product
- first_metadata_entry_session_id
- second_metadata_entry_session_id
- first
stages:
- name: Initiate account creation process [first account].
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{generate_session_id}"
phoneNumber: "{first_account_phone_number}"
text: ""
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '175'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "END Your account is being created. You will receive an SMS when your account is ready.\nAkaunti yako ya Sarafu inatayarishwa. Utapokea ujumbe wa SMS akaunti yako ikiwa tayari.\n"
- name: Initiate account creation process [second account].
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{generate_session_id}"
phoneNumber: "{second_account_phone_number}"
text: ""
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '175'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "END Your account is being created. You will receive an SMS when your account is ready.\nAkaunti yako ya Sarafu inatayarishwa. Utapokea ujumbe wa SMS akaunti yako ikiwa tayari.\n"
delay_after: 5
- name: Initaite account metadata entry [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_metadata_entry_session_id}"
phoneNumber: "{first_account_phone_number}"
text: ""
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '61'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Welcome to Sarafu Network\n1. English\n2. Kiswahili\n3. Help"
- name: Initaite account metadata entry [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_metadata_entry_session_id}"
phoneNumber: "{second_account_phone_number}"
text: ""
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '61'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Welcome to Sarafu Network\n1. English\n2. Kiswahili\n3. Help"
- name: Select preferred language [English]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_metadata_entry_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '64'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Please enter a new four number PIN for your account.\n0. Back"
- name: Select preferred language [Kiswahili]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_metadata_entry_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '71'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Tafadhali weka pin mpya yenye nambari nne kwa akaunti yako\n0. Nyuma"
- name: Enter pin number [{first_account_pin_number} - first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_metadata_entry_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{first_account_pin_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '44'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Enter your four number PIN again\n0. Back"
- name: Enter pin number [second_account_pin_number - second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_metadata_entry_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2*{second_account_pin_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '31'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka PIN yako tena\n0. Nyuma"
- name: Pin number confirmation [first_account_pin_number - first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_metadata_entry_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{first_account_pin_number}*{first_account_pin_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '28'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Enter first name\n0. Back"
- name: Pin number confirmation [{second_account_pin_number} - second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_metadata_entry_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2*{second_account_pin_number}*{second_account_pin_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '37'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka jina lako la kwanza\n0. Nyuma"
- name: Enter first name [first_account_given_name - first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_metadata_entry_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '29'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Enter family name\n0. Back"
- name: Enter first name [second_account_given_name - second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_metadata_entry_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '37'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka jina lako la mwisho\n0. Nyuma"
- name: Enter last name [first_account_family_name - first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_metadata_entry_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '51'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Enter gender\n1. Male\n2. Female\n3. Other\n0. Back"
- name: Enter last name [second_account_family_name - second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_metadata_entry_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '64'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka jinsia yako\n1. Mwanaume\n2. Mwanamke\n3. Nyngine\n0. Nyuma"
- name: Select gender [Male - first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_metadata_entry_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}*1"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '31'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Enter your location\n0. Back"
- name: Select gender [Female - second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_metadata_entry_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}*2"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '27'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka eneo lako\n0. Nyuma"
- name: Enter location [first_account_location - first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_metadata_entry_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}*1*{first_account_location}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '55'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Please enter a product or service you offer\n0. Back"
- name: Enter location [second_account_location - second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_metadata_entry_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}*2*{second_account_location}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '42'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka bidhaa ama huduma unauza\n0. Nyuma"
- name: Enter product [first_account_product - first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_metadata_entry_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}*1*{first_account_location}*{first_account_product}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '51'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Balance {gift_value} {token_symbol}\n1. Send\n2. My Account\n3. Help"
delay_before: 10
- name: Enter product [second_account_product - second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_metadata_entry_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}*2*{second_account_location}*{second_account_product}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '56'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Salio {gift_value} {token_symbol}\n1. Tuma\n2. Akaunti yangu\n3. Usaidizi"
delay_before: 10

View File

@@ -0,0 +1,587 @@
test_name: Test performing account management operations.
marks:
- usefixtures:
- server_url
- token_symbol
- first_account_pin_number
- second_account_pin_number
- first_account_phone_number
- second_account_phone_number
- first_account_management_session_id
- second_account_management_session_id
- first_account_management_session_id_1
- second_account_management_session_id_1
- first_account_new_pin_number
- second_account_new_pin_number
- fourth
stages:
- name: Account management start menu [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_account_management_session_id}"
phoneNumber: "{first_account_phone_number}"
text: ""
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '51'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Balance 58.00 {token_symbol}\n1. Send\n2. My Account\n3. Help"
- name: Account management start menu [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_account_management_session_id}"
phoneNumber: "{second_account_phone_number}"
text: ""
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '56'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Salio 42.00 {token_symbol}\n1. Tuma\n2. Akaunti yangu\n3. Usaidizi"
- name: Account management menu [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_account_management_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "2"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '105'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON My account\n1. My profile\n2. Change language\n3. Check balance\n4. Check statement\n5. Change PIN\n0. Back"
- name: Account management menu [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_account_management_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '148'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Akaunti yangu\n1. Wasifu wangu\n2. Chagua lugha utakayotumia\n3. Angalia salio\n4. Angalia taarifa ya matumizi\n5. Badilisha nambari ya siri\n0. Nyuma"
- name: Language change [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_account_management_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "2*2"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '51'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Choose language\n1. English\n2. Kiswahili\n0. Back"
- name: Language change [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_account_management_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2*2"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '51'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Chagua lugha\n1. Kingereza\n2. Kiswahili\n0. Nyuma"
- name: Select language [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_account_management_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "2*2*2"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '30'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "END Asante kwa kutumia huduma."
- name: Select language [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_account_management_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "2*2*1"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '36'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "END Thank you for using the service."
- name: Second account management start menu [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_account_management_session_id_1}"
phoneNumber: "{first_account_phone_number}"
text: ""
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '56'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Salio 58.00 {token_symbol}\n1. Tuma\n2. Akaunti yangu\n3. Usaidizi"
- name: Second account management start menu [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_account_management_session_id_1}"
phoneNumber: "{second_account_phone_number}"
text: ""
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '51'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Balance 42.00 {token_symbol}\n1. Send\n2. My Account\n3. Help"
- name: Second account management menu [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_account_management_session_id_1}"
phoneNumber: "{first_account_phone_number}"
text: "2"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '148'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Akaunti yangu\n1. Wasifu wangu\n2. Chagua lugha utakayotumia\n3. Angalia salio\n4. Angalia taarifa ya matumizi\n5. Badilisha nambari ya siri\n0. Nyuma"
- name: Second account management menu [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_account_management_session_id_1}"
phoneNumber: "{second_account_phone_number}"
text: "2"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '105'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON My account\n1. My profile\n2. Change language\n3. Check balance\n4. Check statement\n5. Change PIN\n0. Back"
- name: Check balance [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_account_management_session_id_1}"
phoneNumber: "{first_account_phone_number}"
text: "2*3"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '49'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Tafadhali weka PIN yako kuona salio.\n0. Nyuma"
- name: Check balance [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_account_management_session_id_1}"
phoneNumber: "{second_account_phone_number}"
text: "2*3"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '50'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Please enter your PIN to view balances\n0. Back"
- name: Display balances [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_account_management_session_id_1}"
phoneNumber: "{first_account_phone_number}"
text: "2*3*{first_account_pin_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Salio zako ni zifuatazo:\n salio: 58.00 {token_symbol}\n ushuru: {token_symbol}\n tuzo: {token_symbol}\n0. Nyuma"
- name: Display balances [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_account_management_session_id_1}"
phoneNumber: "{second_account_phone_number}"
text: "2*3*{second_account_pin_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Your balances are as follows:\n balance: 42.00 {token_symbol}\n fees: {token_symbol}\n rewards: {token_symbol}\n0. Back"
- name: Resume account management menu [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_account_management_session_id_1}"
phoneNumber: "{first_account_phone_number}"
text: "2*3*{first_account_pin_number}*0"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '148'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Akaunti yangu\n1. Wasifu wangu\n2. Chagua lugha utakayotumia\n3. Angalia salio\n4. Angalia taarifa ya matumizi\n5. Badilisha nambari ya siri\n0. Nyuma"
- name: Resume account management menu [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_account_management_session_id_1}"
phoneNumber: "{second_account_phone_number}"
text: "2*3*{second_account_pin_number}*0"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '105'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON My account\n1. My profile\n2. Change language\n3. Check balance\n4. Check statement\n5. Change PIN\n0. Back"
- name: Change pin number [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_account_management_session_id_1}"
phoneNumber: "{first_account_phone_number}"
text: "2*3*{first_account_pin_number}*0*5"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '34'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka nambari ya siri.\n0. Nyuma"
- name: Change pin number [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_account_management_session_id_1}"
phoneNumber: "{second_account_phone_number}"
text: "2*3*{second_account_pin_number}*0*5"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '30'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Enter current PIN.\n0. Back"
- name: Enter old pin [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_account_management_session_id_1}"
phoneNumber: "{first_account_phone_number}"
text: "2*3*{first_account_pin_number}*0*5*{first_account_pin_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '38'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka nambari ya siri mpya\n0. Nyuma"
- name: Enter old pin [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_account_management_session_id_1}"
phoneNumber: "{second_account_phone_number}"
text: "2*3*{second_account_pin_number}*0*5*{second_account_pin_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '42'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Enter your new four number PIN\n0. Back"
- name: Enter new pin [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_account_management_session_id_1}"
phoneNumber: "{first_account_phone_number}"
text: "2*3*{first_account_pin_number}*0*5*{first_account_pin_number}*{first_account_new_pin_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '31'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka PIN yako tena\n0. Nyuma"
- name: Enter new pin [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_account_management_session_id_1}"
phoneNumber: "{second_account_phone_number}"
text: "2*3*{second_account_pin_number}*0*5*{second_account_pin_number}*{second_account_new_pin_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '48'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Enter your new four number PIN again\n0. Back"
- name: Enter new pin confirmation [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_account_management_session_id_1}"
phoneNumber: "{first_account_phone_number}"
text: "2*3*{first_account_pin_number}*0*5*{first_account_pin_number}*{first_account_new_pin_number}*{first_account_new_pin_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '91'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Ombi lako limetumwa. Utapokea uthibitishaji wa SMS kwa muda mfupi.\n00. Nyuma\n99. Ondoka"
- name: Enter new pin confirmation [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_account_management_session_id_1}"
phoneNumber: "{second_account_phone_number}"
text: "2*3*{second_account_pin_number}*0*5*{second_account_pin_number}*{second_account_new_pin_number}*{second_account_new_pin_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '82'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Your request has been sent. You will receive an SMS shortly.\n00. Back\n99. Exit"

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,282 @@
test_name: Test that the two test accounts can trade with each other.
marks:
- usefixtures:
- gift_value
- server_url
- token_symbol
- first_account_family_name
- second_account_family_name
- first_account_given_name
- second_account_given_name
- first_account_phone_number
- second_account_phone_number
- first_account_pin_number
- second_account_pin_number
- first_transaction_session_id
- second_transaction_session_id
- first_account_verify_balance_session_id
- second_account_verify_balance_session_id
- second
stages:
- name: Transactions start menu [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_transaction_session_id}"
phoneNumber: "{first_account_phone_number}"
text: ""
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '51'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Balance {gift_value} {token_symbol}\n1. Send\n2. My Account\n3. Help"
- name: Transactions start menu [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_transaction_session_id}"
phoneNumber: "{second_account_phone_number}"
text: ""
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '56'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Salio {gift_value} {token_symbol}\n1. Tuma\n2. Akaunti yangu\n3. Usaidizi"
- name: Initate transcation attempt [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_transaction_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '30'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Enter phone number\n0. Back"
- name: Initate transcation attempt [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_transaction_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "1"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '33'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka nambari ya simu\n0. Nyuma"
- name: Enter phone number [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_transaction_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{second_account_phone_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '24'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Enter amount\n0. Back"
- name: Enter phone number [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_transaction_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "1*{first_account_phone_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '25'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Weka kiwango\n0. Nyuma"
- name: Enter transcation amount [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_transaction_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{second_account_phone_number}*17"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON {second_account_given_name} {second_account_family_name} {second_account_phone_number} will receive 17.00 {token_symbol} from {first_account_given_name} {first_account_family_name} {first_account_phone_number}.\nPlease enter your PIN to confirm.\n0. Back"
- name: Enter transcation amount [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_transaction_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "1*{first_account_phone_number}*25"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON {first_account_given_name} {first_account_family_name} {first_account_phone_number} atapokea 25.00 {token_symbol} kutoka kwa {second_account_given_name} {second_account_family_name} {second_account_phone_number}.\nTafadhali weka nambari yako ya siri kudhibitisha.\n0. Nyuma"
- name: Pin to authorize transaction [first account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_transaction_session_id}"
phoneNumber: "{first_account_phone_number}"
text: "1*{second_account_phone_number}*17*{first_account_pin_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Your request has been sent. {second_account_given_name} {second_account_family_name} {second_account_phone_number} will receive 17.00 {token_symbol} from {first_account_given_name} {first_account_family_name} {first_account_phone_number}.\n00. Back\n99. Exit"
- name: Pin to authorize transaction [second account]
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_transaction_session_id}"
phoneNumber: "{second_account_phone_number}"
text: "1*{first_account_phone_number}*25*{second_account_pin_number}"
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Ombi lako limetumwa. {first_account_given_name} {first_account_family_name} {first_account_phone_number} atapokea 25.00 {token_symbol} kutoka kwa {second_account_given_name} {second_account_family_name} {second_account_phone_number}.\n00. Nyuma\n99. Ondoka"
- name: Verify balance changes [first account]
delay_before: 10
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{first_account_verify_balance_session_id}"
phoneNumber: "{first_account_phone_number}"
text: ""
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '51'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Balance 58.00 {token_symbol}\n1. Send\n2. My Account\n3. Help"
- name: Verify balance changes [second account]
delay_before: 10
request:
url: "{server_url}"
data:
serviceCode: "*483*46#"
sessionId: "{second_account_verify_balance_session_id}"
phoneNumber: "{second_account_phone_number}"
text: ""
headers:
content-type: "application/x-www-form-urlencoded"
method: POST
response:
status_code:
- 200
headers:
Content-Length: '56'
Content-Type: "text/plain"
verify_response_with:
function: ext.validator:validate_response
extra_kwargs:
expected_response: "CON Salio 42.00 {token_symbol}\n1. Tuma\n2. Akaunti yangu\n3. Usaidizi"

View File

@@ -4,12 +4,13 @@
"source": "enter_gender", "source": "enter_gender",
"dest": "enter_location", "dest": "enter_location",
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data", "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
"conditions": "cic_ussd.state_machine.logic.validator.is_valid_gender_selection" "conditions": "cic_ussd.state_machine.logic.validator.is_valid_gender_selection",
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
}, },
{ {
"trigger": "scan_data", "trigger": "scan_data",
"source": "enter_gender", "source": "enter_gender",
"dest": "standard_pin_authorization", "dest": "gender_edit_pin_authorization",
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data", "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
"conditions": [ "conditions": [
"cic_ussd.state_machine.logic.validator.has_cached_user_metadata", "cic_ussd.state_machine.logic.validator.has_cached_user_metadata",
@@ -18,15 +19,14 @@
}, },
{ {
"trigger": "scan_data", "trigger": "scan_data",
"source": "standard_pin_authorization", "source": "gender_edit_pin_authorization",
"dest": "exit", "dest": "exit",
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin", "conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute", "after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
}, },
{ {
"trigger": "scan_data", "trigger": "scan_data",
"source": "standard_pin_authorization", "source": "gender_edit_pin_authorization",
"dest": "exit_pin_blocked", "dest": "exit_pin_blocked",
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account" "conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
}, },

View File

@@ -3,26 +3,26 @@
"trigger": "scan_data", "trigger": "scan_data",
"source": "enter_location", "source": "enter_location",
"dest": "enter_products", "dest": "enter_products",
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data" "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
}, },
{ {
"trigger": "scan_data", "trigger": "scan_data",
"source": "enter_location", "source": "enter_location",
"dest": "standard_pin_authorization", "dest": "location_edit_pin_authorization",
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data", "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
"conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata" "conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
}, },
{ {
"trigger": "scan_data", "trigger": "scan_data",
"source": "standard_pin_authorization", "source": "location_edit_pin_authorization",
"dest": "exit", "dest": "exit",
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin", "conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute", "after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
}, },
{ {
"trigger": "scan_data", "trigger": "scan_data",
"source": "standard_pin_authorization", "source": "location_edit_pin_authorization",
"dest": "exit_pin_blocked", "dest": "exit_pin_blocked",
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account" "conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
} }

View File

@@ -7,49 +7,28 @@
}, },
{ {
"trigger": "scan_data", "trigger": "scan_data",
"source": "enter_given_name", "source": "enter_family_name",
"dest": "standard_pin_authorization", "dest": "name_edit_pin_authorization",
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data", "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
"conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata" "conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
}, },
{
"trigger": "scan_data",
"source": "standard_pin_authorization",
"dest": "exit",
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute",
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
},
{
"trigger": "scan_data",
"source": "standard_pin_authorization",
"dest": "exit_pin_blocked",
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
},
{ {
"trigger": "scan_data", "trigger": "scan_data",
"source": "enter_family_name", "source": "enter_family_name",
"dest": "enter_gender", "dest": "enter_gender",
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data"
},
{
"trigger": "scan_data",
"source": "enter_family_name",
"dest": "standard_pin_authorization",
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data", "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
"conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
},
{
"trigger": "scan_data",
"source": "standard_pin_authorization",
"dest": "exit",
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute",
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata" "unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
}, },
{ {
"trigger": "scan_data", "trigger": "scan_data",
"source": "standard_pin_authorization", "source": "name_edit_pin_authorization",
"dest": "exit",
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
},
{
"trigger": "scan_data",
"source": "name_edit_pin_authorization",
"dest": "exit_pin_blocked", "dest": "exit_pin_blocked",
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account" "conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
} }

View File

@@ -9,14 +9,14 @@
"trigger": "scan_data", "trigger": "scan_data",
"source": "enter_current_pin", "source": "enter_current_pin",
"dest": "exit_pin_blocked", "dest": "exit_pin_blocked",
"conditions": "cic_ussd.state_machine.logic.menu.is_blocked_pin" "conditions": "cic_ussd.state_machine.logic.pin.is_blocked_pin"
}, },
{ {
"trigger": "scan_data", "trigger": "scan_data",
"source": "enter_new_pin", "source": "enter_new_pin",
"dest": "new_pin_confirmation", "dest": "new_pin_confirmation",
"after": "cic_ussd.state_machine.logic.pin.save_initial_pin_to_session_data", "after": "cic_ussd.state_machine.logic.pin.save_initial_pin_to_session_data",
"conditions": "cic_ussd.state_machine.logic.menu.is_valid_new_pin" "conditions": "cic_ussd.state_machine.logic.pin.is_valid_new_pin"
}, },
{ {
"trigger": "scan_data", "trigger": "scan_data",
@@ -28,7 +28,7 @@
"source": "new_pin_confirmation", "source": "new_pin_confirmation",
"dest": "complete", "dest": "complete",
"conditions": "cic_ussd.state_machine.logic.pin.pins_match", "conditions": "cic_ussd.state_machine.logic.pin.pins_match",
"after": "cic_ussd.state_machine.logic.menu.complete_pin_change" "after": "cic_ussd.state_machine.logic.pin.complete_pin_change"
}, },
{ {
"trigger": "scan_data", "trigger": "scan_data",

View File

@@ -2,7 +2,7 @@
{ {
"trigger": "scan_data", "trigger": "scan_data",
"source": "enter_products", "source": "enter_products",
"dest": "standard_pin_authorization", "dest": "products_edit_pin_authorization",
"conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata", "conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata",
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data" "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data"
}, },
@@ -13,18 +13,19 @@
"after": [ "after": [
"cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data", "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
"cic_ussd.state_machine.logic.user.save_complete_user_metadata" "cic_ussd.state_machine.logic.user.save_complete_user_metadata"
] ],
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
}, },
{ {
"trigger": "scan_data", "trigger": "scan_data",
"source": "standard_pin_authorization", "source": "products_edit_pin_authorization",
"dest": "exit", "dest": "exit",
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin", "conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute" "after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
}, },
{ {
"trigger": "scan_data", "trigger": "scan_data",
"source": "standard_pin_authorization", "source": "products_edit_pin_authorization",
"dest": "exit_pin_blocked", "dest": "exit_pin_blocked",
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account" "conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
} }

View File

@@ -8,7 +8,7 @@
{ {
"trigger": "scan_data", "trigger": "scan_data",
"source": "metadata_management", "source": "metadata_management",
"dest": "enter_age", "dest": "enter_gender",
"conditions": "cic_ussd.state_machine.logic.menu.menu_two_selected" "conditions": "cic_ussd.state_machine.logic.menu.menu_two_selected"
}, },
{ {

View File

@@ -6,7 +6,7 @@ en:
2. Kiswahili 2. Kiswahili
3. Help 3. Help
initial_pin_entry: |- initial_pin_entry: |-
CON Please enter a new four number PIN for your account. CON Please enter a new four number PIN for your account.
0. Back 0. Back
initial_pin_confirmation: |- initial_pin_confirmation: |-
CON Enter your four number PIN again CON Enter your four number PIN again
@@ -76,7 +76,10 @@ en:
CON Enter current PIN. You have %{remaining_attempts} attempts remaining. CON Enter current PIN. You have %{remaining_attempts} attempts remaining.
0. Back 0. Back
enter_new_pin: |- enter_new_pin: |-
CON Enter new PIN again CON Enter your new four number PIN
0. Back
new_pin_confirmation: |-
CON Enter your new four number PIN again
0. Back 0. Back
transaction_pin_authorization: transaction_pin_authorization:
first: |- first: |-
@@ -107,6 +110,34 @@ en:
retry: |- retry: |-
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
0. Back 0. Back
name_edit_pin_authorization:
first: |-
CON Please enter your PIN
0. Back
retry: |-
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
0. Back
gender_edit_pin_authorization:
first: |-
CON Please enter your PIN
0. Back
retry: |-
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
0. Back
location_edit_pin_authorization:
first: |-
CON Please enter your PIN
0. Back
retry: |-
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
0. Back
products_edit_pin_authorization:
first: |-
CON Please enter your PIN
0. Back
retry: |-
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
0. Back
account_balances: |- account_balances: |-
CON Your balances are as follows: CON Your balances are as follows:
balance: %{operational_balance} %{token_symbol} balance: %{operational_balance} %{token_symbol}

View File

@@ -21,7 +21,7 @@ sw:
CON Weka jinsia yako CON Weka jinsia yako
1. Mwanaume 1. Mwanaume
2. Mwanamke 2. Mwanamke
3. Nyngine 3. Nyngine
0. Nyuma 0. Nyuma
enter_location: |- enter_location: |-
CON Weka eneo lako CON Weka eneo lako
@@ -61,7 +61,7 @@ sw:
Jina: %{full_name} Jina: %{full_name}
Jinsia: %{gender} Jinsia: %{gender}
Eneo: %{location} Eneo: %{location}
Unauza: %{user_bio} Unauza: %{products}
0. Nyuma 0. Nyuma
select_preferred_language: |- select_preferred_language: |-
CON Chagua lugha CON Chagua lugha
@@ -78,6 +78,9 @@ sw:
enter_new_pin: |- enter_new_pin: |-
CON Weka nambari ya siri mpya CON Weka nambari ya siri mpya
0. Nyuma 0. Nyuma
new_pin_confirmation: |-
CON Weka PIN yako tena
0. Nyuma
transaction_pin_authorization: transaction_pin_authorization:
first: |- first: |-
CON %{recipient_information} atapokea %{transaction_amount} %{token_symbol} kutoka kwa %{sender_information}. CON %{recipient_information} atapokea %{transaction_amount} %{token_symbol} kutoka kwa %{sender_information}.
@@ -86,9 +89,9 @@ sw:
retry: |- retry: |-
CON Weka nambari ya siri. Una majaribio %{remaining_attempts} yaliyobaki. CON Weka nambari ya siri. Una majaribio %{remaining_attempts} yaliyobaki.
0. Nyuma 0. Nyuma
standard_pin_authorization: display_metadata_pin_authorization:
first: |- first: |-
CON Tafadhali weka PIN yako. CON Tafadhali weka PIN yako
0. Nyuma 0. Nyuma
retry: |- retry: |-
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki. CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
@@ -107,12 +110,40 @@ sw:
retry: |- retry: |-
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki. CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
0. Nyuma 0. Nyuma
name_edit_pin_authorization:
first: |-
CON Tafadhali weka PIN yako
0. Nyuma
retry: |-
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
0. Nyuma
gender_edit_pin_authorization:
first: |-
CON Tafadhali weka PIN yako
0. Nyuma
retry: |-
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
0. Nyuma
location_edit_pin_authorization:
first: |-
CON Tafadhali weka PIN yako
0. Nyuma
retry: |-
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
0. Nyuma
products_edit_pin_authorization:
first: |-
CON Tafadhali weka PIN yako
0. Nyuma
retry: |-
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
0. Nyuma
account_balances: |- account_balances: |-
CON Salio zako ni zifuatazo: CON Salio zako ni zifuatazo:
salio: %{operational_balance} salio: %{operational_balance} %{token_symbol}
ushuru: %{tax} ushuru: %{tax} %{token_symbol}
tuzo: %{bonus} tuzo: %{bonus} %{token_symbol}
0. Back 0. Nyuma
first_transaction_set: |- first_transaction_set: |-
CON %{first_transaction_set} CON %{first_transaction_set}
1. Mbele 1. Mbele

View File

@@ -51,19 +51,13 @@ ENV PATH $NVM_DIR/versions/node//v$NODE_VERSION/bin:$PATH
# WORKDIR /home/grassroots # WORKDIR /home/grassroots
# USER grassroots # USER grassroots
COPY contract-migration/requirements.txt .
ARG pip_extra_args="" ARG pip_extra_args=""
ARG pip_index_url=https://pypi.org/simple ARG pip_index_url=https://pypi.org/simple
ARG pip_extra_index_url=https://pip.grassrootseconomics.net:8433 ARG pip_extra_index_url=https://pip.grassrootseconomics.net:8433
ARG cic_base_version=0.1.2b11 RUN pip install --index-url https://pypi.org/simple \
ARG cic_eth_version=0.11.0b14 --extra-index-url $pip_extra_index_url -r requirements.txt
ARG sarafu_token_version=0.0.1a8
ARG sarafu_faucet_version=0.0.3a3
RUN pip install --index-url https://pypi.org/simple --extra-index-url $pip_extra_index_url \
cic-base[full_graph]==$cic_base_version \
cic-eth==$cic_eth_version \
sarafu-faucet==$sarafu_faucet_version \
sarafu-token==$sarafu_token_version \
cic-eth==$cic_eth_version
# -------------- begin runtime container ---------------- # -------------- begin runtime container ----------------
FROM python:3.8.6-slim-buster as runtime-image FROM python:3.8.6-slim-buster as runtime-image

View File

@@ -0,0 +1,4 @@
cic-base[full_graph]==0.1.2b15
sarafu-faucet==0.0.3a3
sarafu-token==0.0.1a8
cic-eth==0.11.0b16

View File

@@ -47,7 +47,7 @@ EOF
>&2 echo "create account for gas gifter" >&2 echo "create account for gas gifter"
old_gas_provider=$DEV_ETH_ACCOUNT_GAS_PROVIDER old_gas_provider=$DEV_ETH_ACCOUNT_GAS_PROVIDER
DEV_ETH_ACCOUNT_GAS_GIFTER=`cic-eth-create $debug --redis-host-callback=$REDIS_HOST --redis-port-callback=$REDIS_PORT --no-register` DEV_ETH_ACCOUNT_GAS_GIFTER=`cic-eth-create --timeout 120 $debug --redis-host-callback=$REDIS_HOST --redis-port-callback=$REDIS_PORT --no-register`
echo DEV_ETH_ACCOUNT_GAS_GIFTER=$DEV_ETH_ACCOUNT_GAS_GIFTER >> $env_out_file echo DEV_ETH_ACCOUNT_GAS_GIFTER=$DEV_ETH_ACCOUNT_GAS_GIFTER >> $env_out_file
cic-eth-tag -i $CIC_CHAIN_SPEC GAS_GIFTER $DEV_ETH_ACCOUNT_GAS_GIFTER cic-eth-tag -i $CIC_CHAIN_SPEC GAS_GIFTER $DEV_ETH_ACCOUNT_GAS_GIFTER

View File

@@ -259,4 +259,6 @@ Should exit with code 0 if all input data is found in the respective services.
- Running the balance script should be _optional_ in all cases, but is currently required in the case of `cic_ussd` because it is needed to generate the metadata. An improvement would be moving the task to `import_users.py`, for a different queue than the balance tx handler. - Running the balance script should be _optional_ in all cases, but is currently required in the case of `cic_ussd` because it is needed to generate the metadata. An improvement would be moving the task to `import_users.py`, for a different queue than the balance tx handler.
- MacOS BigSur issue when installing psycopg2: ld: library not found for -lssl -> https://github.com/psycopg/psycopg2/issues/1115#issuecomment-831498953
- `cic_ussd` imports is poorly implemented, and consumes a lot of resources. Therefore it takes a long time to complete. Reducing the amount of polls for the phone pointer would go a long way to improve it. - `cic_ussd` imports is poorly implemented, and consumes a lot of resources. Therefore it takes a long time to complete. Reducing the amount of polls for the phone pointer would go a long way to improve it.

View File

@@ -1,5 +1,5 @@
cic-base[full_graph]==0.1.2b11 cic-base[full_graph]==0.1.2b15
sarafu-faucet==0.0.3a3 sarafu-faucet==0.0.3a3
cic-eth==0.11.0b15 cic-eth==0.11.0b16
cic-types==0.1.0a11 cic-types==0.1.0a11
crypto-dev-signer==0.4.14b3 crypto-dev-signer==0.4.14b3

View File

@@ -6,11 +6,7 @@ volumes:
bee-data: {} bee-data: {}
signer-data: {} signer-data: {}
bloxberg-data: {} bloxberg-data: {}
contract-config: contract-config: {}
driver_opts:
type: local
o: bind
device: ./service-configs
networks: networks:
default: default: