Compare commits
55 Commits
lash/rehab
...
philip/man
| Author | SHA1 | Date | |
|---|---|---|---|
|
e04d090b06
|
|||
|
122e012329
|
|||
|
f7bfea6563
|
|||
|
ac09875258
|
|||
|
0017247363
|
|||
|
d82d9979a5
|
|||
|
40b1e8272b
|
|||
|
25e4aaf9f6
|
|||
|
c90f1c59ec
|
|||
|
0dbd8d63b2
|
|||
|
9da3b7a099
|
|||
|
fbf736ba98
|
|||
|
8de6e9876e
|
|||
|
b2ab1465d7
|
|||
|
23015f8b98
|
|||
|
ea614e07af
|
|||
|
f35e7010ba
|
|||
|
23ed64836e
|
|||
|
866eb7397b
|
|||
|
a05df2280b
|
|||
|
9e4ad4c650
|
|||
|
5b89c151f9
|
|||
|
5bfe9fcd4a
|
|||
|
2608535200
|
|||
|
f39468d41f
|
|||
| 1676addbeb | |||
| 1efc25ac15 | |||
|
|
db2ec0dcfa | ||
| 5148e6428b | |||
|
|
0c186ed968 | ||
|
|
c44439bd90 | ||
| eee895ea71 | |||
|
2be23b9390
|
|||
|
e93851af76
|
|||
|
1e89f01d5f
|
|||
|
6c1c05335e
|
|||
|
5929a6c0bb
|
|||
|
f72313aea9
|
|||
|
43fd7465e5
|
|||
|
30eb9f517b
|
|||
|
f3e06dcd92
|
|||
|
c0f578db75
|
|||
|
5d2e5013f3
|
|||
| e8512ebbae | |||
|
06d9612c6c
|
|||
|
07fef8df40
|
|||
|
1bd281f2a2
|
|||
|
7ab278d098
|
|||
|
15d44c859e
|
|||
|
6d541d38bc
|
|||
|
08567436f2
|
|||
|
091b1e9f16
|
|||
|
85837e1fec
|
|||
|
a17da7b91b
|
|||
|
c8adfb7f19
|
@@ -1,2 +0,0 @@
|
||||
[syncer]
|
||||
loop_interval = 1
|
||||
@@ -72,7 +72,9 @@ class CallbackFilter(SyncFilter):
|
||||
#transfer_data['token_address'] = tx.inputs[0]
|
||||
faucet_contract = tx.inputs[0]
|
||||
|
||||
o = Faucet.token(faucet_contract, sender_address=self.caller_address)
|
||||
c = Faucet(self.chain_spec)
|
||||
|
||||
o = c.token(faucet_contract, sender_address=self.caller_address)
|
||||
r = conn.do(o)
|
||||
transfer_data['token_address'] = add_0x(c.parse_token(r))
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ version = (
|
||||
0,
|
||||
11,
|
||||
0,
|
||||
'beta.14',
|
||||
'beta.13',
|
||||
)
|
||||
|
||||
version_object = semver.VersionInfo(
|
||||
|
||||
@@ -4,7 +4,7 @@ import sys
|
||||
import logging
|
||||
|
||||
# external imports
|
||||
from chainlib.eth.erc20 import ERC20
|
||||
from eth_erc20 import ERC20
|
||||
|
||||
# local imports
|
||||
from cic_eth.api import Api
|
||||
|
||||
@@ -14,9 +14,9 @@ from chainlib.eth.tx import (
|
||||
Tx,
|
||||
)
|
||||
from chainlib.eth.block import Block
|
||||
from chainlib.eth.erc20 import ERC20
|
||||
from eth_erc20 import ERC20
|
||||
from sarafu_faucet import MinterFaucet
|
||||
from eth_accounts_index import AccountRegistry
|
||||
from eth_accounts_index.registry import AccountRegistry
|
||||
from potaahto.symbols import snake_and_camel
|
||||
from hexathon import add_0x
|
||||
|
||||
@@ -26,7 +26,6 @@ from cic_eth.runnable.daemons.filters.callback import CallbackFilter
|
||||
logg = logging.getLogger()
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_transfer_tx(
|
||||
default_chain_spec,
|
||||
init_database,
|
||||
@@ -66,7 +65,6 @@ def test_transfer_tx(
|
||||
assert transfer_type == 'transfer'
|
||||
|
||||
|
||||
@pytest.mark.skip()
|
||||
def test_transfer_from_tx(
|
||||
default_chain_spec,
|
||||
init_database,
|
||||
|
||||
@@ -4,7 +4,7 @@ import logging
|
||||
# external imports
|
||||
import pytest
|
||||
from chainlib.eth.nonce import RPCNonceOracle
|
||||
from chainlib.eth.erc20 import ERC20
|
||||
from eth_erc20 import ERC20
|
||||
from chainlib.eth.tx import receipt
|
||||
|
||||
# local imports
|
||||
|
||||
@@ -9,7 +9,7 @@ import celery
|
||||
from chainlib.connection import RPCConnection
|
||||
from chainlib.eth.nonce import RPCNonceOracle
|
||||
from chainlib.eth.tx import receipt
|
||||
from eth_accounts_index import AccountRegistry
|
||||
from eth_accounts_index.registry import AccountRegistry
|
||||
from hexathon import strip_0x
|
||||
from chainqueue.db.enum import StatusEnum
|
||||
from chainqueue.db.models.otx import Otx
|
||||
|
||||
@@ -4,7 +4,7 @@ import logging
|
||||
# external imports
|
||||
import pytest
|
||||
import celery
|
||||
from chainlib.eth.erc20 import ERC20
|
||||
from eth_erc20 import ERC20
|
||||
from chainlib.eth.nonce import RPCNonceOracle
|
||||
from chainlib.eth.tx import (
|
||||
receipt,
|
||||
|
||||
@@ -3,7 +3,7 @@ from chainlib.eth.nonce import RPCNonceOracle
|
||||
from chainlib.eth.tx import (
|
||||
receipt,
|
||||
)
|
||||
from eth_address_declarator import AddressDeclarator
|
||||
from eth_address_declarator import Declarator
|
||||
from hexathon import add_0x
|
||||
|
||||
# local imports
|
||||
@@ -23,7 +23,7 @@ def test_translate(
|
||||
|
||||
nonce_oracle = RPCNonceOracle(contract_roles['CONTRACT_DEPLOYER'], eth_rpc)
|
||||
|
||||
c = AddressDeclarator(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle)
|
||||
c = Declarator(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle)
|
||||
|
||||
description = 'alice'.encode('utf-8').ljust(32, b'\x00').hex()
|
||||
(tx_hash_hex, o) = c.add_declaration(address_declarator, contract_roles['CONTRACT_DEPLOYER'], agent_roles['ALICE'], add_0x(description))
|
||||
|
||||
@@ -8,7 +8,7 @@ from chainlib.eth.tx import (
|
||||
count,
|
||||
receipt,
|
||||
)
|
||||
from chainlib.eth.erc20 import ERC20
|
||||
from eth_erc20 import ERC20
|
||||
from chainlib.eth.nonce import RPCNonceOracle
|
||||
|
||||
# local imports
|
||||
|
||||
@@ -31,7 +31,7 @@ function handleNoMergeGet(db, digest, keystore) {
|
||||
doh(e);
|
||||
});
|
||||
}).catch((e) => {
|
||||
console.error('mesage', e);
|
||||
console.error('message', e);
|
||||
doh(e);
|
||||
});
|
||||
})
|
||||
@@ -46,7 +46,7 @@ function handleServerMergePost(data, db, digest, keystore, signer) {
|
||||
let e = undefined;
|
||||
let s = undefined;
|
||||
if (v === undefined) {
|
||||
s = new Syncable(digest, data);
|
||||
s = new Syncable(digest, o);
|
||||
s.onwrap = (e) => {
|
||||
whohoo(e.toJSON());
|
||||
};
|
||||
|
||||
@@ -9,3 +9,7 @@ class AlreadyInitializedError(Exception):
|
||||
class PleaseCommitFirstError(Exception):
|
||||
"""Raised when there exists uncommitted changes in the code while trying to build out the package."""
|
||||
pass
|
||||
|
||||
|
||||
class NotificationSendError(Exception):
|
||||
"""Raised when a notification failed to due to some error as per the service responsible for dispatching the notification."""
|
||||
|
||||
19
apps/cic-notify/cic_notify/ext/enums.py
Normal file
19
apps/cic-notify/cic_notify/ext/enums.py
Normal file
@@ -0,0 +1,19 @@
|
||||
# standard imports
|
||||
from enum import IntEnum
|
||||
|
||||
|
||||
class AfricasTalkingStatusCodes(IntEnum):
|
||||
PROCESSED = 100
|
||||
SENT = 101
|
||||
QUEUED = 102
|
||||
RISK_HOLD = 401
|
||||
INVALID_SENDER_ID = 402
|
||||
INVALID_PHONE_NUMBER = 403
|
||||
UNSUPPORTED_NUMBER_TYPE = 404
|
||||
INSUFFICIENT_BALANCE = 405
|
||||
USER_IN_BLACKLIST = 406
|
||||
COULD_NOT_ROUTE = 407
|
||||
INTERNAL_SERVER_ERROR = 500
|
||||
GATEWAY_ERROR = 501
|
||||
REJECTED_BY_GATEWAY = 502
|
||||
|
||||
@@ -6,7 +6,8 @@ import celery
|
||||
import africastalking
|
||||
|
||||
# local imports
|
||||
from cic_notify.error import NotInitializedError, AlreadyInitializedError
|
||||
from cic_notify.error import NotInitializedError, AlreadyInitializedError, NotificationSendError
|
||||
from cic_notify.ext.enums import AfricasTalkingStatusCodes
|
||||
|
||||
logg = logging.getLogger()
|
||||
celery_app = celery.current_app
|
||||
@@ -50,10 +51,27 @@ class AfricasTalkingNotifier:
|
||||
if self.sender_id:
|
||||
response = self.api_client.send(message=message, recipients=[recipient], sender_id=self.sender_id)
|
||||
logg.debug(f'Africastalking response sender-id {response}')
|
||||
|
||||
else:
|
||||
response = self.api_client.send(message=message, recipients=[recipient])
|
||||
logg.debug(f'africastalking response no-sender-id {response}')
|
||||
|
||||
recipients = response.get('SMSMessageData').get('Recipients')
|
||||
|
||||
if len(recipients) != 1:
|
||||
status = response.get('SMSMessageData').get('Message')
|
||||
raise NotificationSendError(f'Unexpected number of recipients: {len(recipients)}. Status: {status}')
|
||||
|
||||
status_code = recipients[0].get('statusCode')
|
||||
status = recipients[0].get('status')
|
||||
|
||||
if status_code not in [
|
||||
AfricasTalkingStatusCodes.PROCESSED.value,
|
||||
AfricasTalkingStatusCodes.SENT.value,
|
||||
AfricasTalkingStatusCodes.QUEUED.value
|
||||
]:
|
||||
raise NotificationSendError(f'Sending notification failed due to: {status}')
|
||||
|
||||
|
||||
@celery_app.task
|
||||
def send(message, recipient):
|
||||
|
||||
@@ -9,7 +9,7 @@ import semver
|
||||
|
||||
logg = logging.getLogger()
|
||||
|
||||
version = (0, 4, 0, 'alpha.4')
|
||||
version = (0, 4, 0, 'alpha.5')
|
||||
|
||||
version_object = semver.VersionInfo(
|
||||
major=version[0],
|
||||
|
||||
@@ -28,6 +28,7 @@ packages =
|
||||
cic_notify
|
||||
cic_notify.db
|
||||
cic_notify.db.models
|
||||
cic_notify.ext
|
||||
cic_notify.tasks.sms
|
||||
cic_notify.runnable
|
||||
scripts =
|
||||
|
||||
4
apps/cic-ussd/.config/test/integration.ini
Normal file
4
apps/cic-ussd/.config/test/integration.ini
Normal file
@@ -0,0 +1,4 @@
|
||||
[test]
|
||||
gift_value = 50.00
|
||||
server_url = http://localhost:63315/
|
||||
token_symbol = GFT
|
||||
@@ -238,13 +238,43 @@
|
||||
"description": "Menu to display a user's entire profile",
|
||||
"display_key": "ussd.kenya.display_user_metadata",
|
||||
"name": "display_user_metadata",
|
||||
"parent": "account_management"
|
||||
"parent": "metadata_management"
|
||||
},
|
||||
"41": {
|
||||
"description": "The recipient is not in the system",
|
||||
"display_key": "ussd.kenya.exit_invalid_recipient",
|
||||
"name": "exit_invalid_recipient",
|
||||
"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"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -78,31 +78,30 @@ class MetadataRequestsHandler(Metadata):
|
||||
:param data: The data to be stored in the metadata server.
|
||||
: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)
|
||||
metadata_http_error_handler(result=result)
|
||||
metadata = result.content
|
||||
metadata = result.json()
|
||||
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.
|
||||
:param data: The data to be edited in the metadata server.
|
||||
:type data: bytes
|
||||
:type data: dict
|
||||
"""
|
||||
cic_meta_signer = Signer()
|
||||
signature = cic_meta_signer.sign_digest(data=data)
|
||||
algorithm = cic_meta_signer.get_operational_key().get('algo')
|
||||
decoded_data = data.decode('utf-8')
|
||||
formatted_data = {
|
||||
'm': data.decode('utf-8'),
|
||||
'm': json.dumps(data),
|
||||
's': {
|
||||
'engine': self.engine,
|
||||
'algo': algorithm,
|
||||
'data': signature,
|
||||
'digest': json.loads(data).get('digest'),
|
||||
'digest': data.get('digest'),
|
||||
}
|
||||
}
|
||||
formatted_data = json.dumps(formatted_data).encode('utf-8')
|
||||
formatted_data = json.dumps(formatted_data)
|
||||
result = make_request(method='PUT', url=self.url, data=formatted_data, headers=self.headers)
|
||||
logg.info(f'signed metadata submission status: {result.status_code}.')
|
||||
metadata_http_error_handler(result=result)
|
||||
@@ -110,17 +109,32 @@ class MetadataRequestsHandler(Metadata):
|
||||
decoded_identifier = self.identifier.decode("utf-8")
|
||||
except UnicodeDecodeError:
|
||||
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):
|
||||
"""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)
|
||||
metadata_http_error_handler(result=result)
|
||||
response_data = result.content
|
||||
data = json.loads(response_data.decode('utf-8'))
|
||||
|
||||
# json serialize retrieved data
|
||||
result_data = result.json()
|
||||
|
||||
# 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':
|
||||
# validate person metadata
|
||||
person = Person()
|
||||
deserialized_person = person.deserialize(person_data=data)
|
||||
data = json.dumps(deserialized_person.serialize())
|
||||
cache_data(self.metadata_pointer, data=data)
|
||||
person_data = person.deserialize(person_data=result_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}')
|
||||
|
||||
@@ -47,14 +47,13 @@ class Signer:
|
||||
logg.debug(f'using signing key: {key_id}, algorithm: {key_algorithm}')
|
||||
return gpg_keys[0]
|
||||
|
||||
def sign_digest(self, data: bytes):
|
||||
def sign_digest(self, data: dict):
|
||||
"""
|
||||
:param data:
|
||||
:type data:
|
||||
:return:
|
||||
:rtype:
|
||||
"""
|
||||
data = json.loads(data)
|
||||
digest = data['digest']
|
||||
key_id = self.get_operational_key().get('keyid')
|
||||
signature = self.gpg.sign(digest, passphrase=self.gpg_passphrase, keyid=key_id)
|
||||
|
||||
@@ -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),
|
||||
cic_type=':cic.person'
|
||||
)
|
||||
user_metadata = get_cached_data(key)
|
||||
if user_metadata:
|
||||
user_metadata = json.loads(user_metadata)
|
||||
cached_metadata = get_cached_data(key)
|
||||
if cached_metadata:
|
||||
user_metadata = json.loads(cached_metadata)
|
||||
contact_data = get_contact_data_from_vcard(vcard=user_metadata.get('vcard'))
|
||||
logg.debug(f'{contact_data}')
|
||||
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_new_pin',
|
||||
'exit_pin_mismatch',
|
||||
'exit_invalid_request'
|
||||
'exit_invalid_request',
|
||||
'exit_successful_transaction'
|
||||
] and person_metadata is not None:
|
||||
return UssdMenu.find_by_name(name='start')
|
||||
else:
|
||||
|
||||
@@ -13,7 +13,7 @@ import bcrypt
|
||||
|
||||
# local imports
|
||||
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.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
|
||||
initial_pin = create_password_hash(user_input)
|
||||
session_data = {
|
||||
'initial_pin': initial_pin
|
||||
}
|
||||
if ussd_session.get('session_data'):
|
||||
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_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
|
||||
initial_pin = ussd_session.get('session_data').get('initial_pin')
|
||||
fernet = PasswordEncoder(PasswordEncoder.key)
|
||||
initial_pin = fernet.decrypt(initial_pin.encode())
|
||||
return bcrypt.checkpw(user_input.encode(), initial_pin)
|
||||
logg.debug(f'USSD SESSION: {ussd_session}')
|
||||
return check_password_hash(user_input, initial_pin)
|
||||
|
||||
|
||||
def complete_pin_change(state_machine_data: Tuple[str, dict, Account]):
|
||||
|
||||
@@ -64,13 +64,17 @@ def process_gender_user_input(user: Account, user_input: str):
|
||||
if user.preferred_language == 'en':
|
||||
if user_input == '1':
|
||||
gender = 'Male'
|
||||
else:
|
||||
elif user_input == '2':
|
||||
gender = 'Female'
|
||||
elif user_input == '3':
|
||||
gender = 'Other'
|
||||
else:
|
||||
if user_input == '1':
|
||||
gender = 'Mwanaume'
|
||||
else:
|
||||
elif user_input == '2':
|
||||
gender = 'Mwanamke'
|
||||
elif user_input == '3':
|
||||
gender = 'Nyingine'
|
||||
return gender
|
||||
|
||||
|
||||
@@ -88,14 +92,18 @@ def save_metadata_attribute_to_session_data(state_machine_data: Tuple[str, dict,
|
||||
key = ''
|
||||
if 'given_name' in current_state:
|
||||
key = 'given_name'
|
||||
elif 'family_name' in current_state:
|
||||
|
||||
if 'family_name' in current_state:
|
||||
key = 'family_name'
|
||||
elif 'gender' in current_state:
|
||||
|
||||
if 'gender' in current_state:
|
||||
key = 'gender'
|
||||
user_input = process_gender_user_input(user=user, user_input=user_input)
|
||||
elif 'location' in current_state:
|
||||
|
||||
if 'location' in current_state:
|
||||
key = 'location'
|
||||
elif 'products' in current_state:
|
||||
|
||||
if 'products' in current_state:
|
||||
key = 'products'
|
||||
|
||||
# check if there is existing session data
|
||||
@@ -121,12 +129,20 @@ def format_user_metadata(metadata: dict, user: Account):
|
||||
gender = metadata.get('gender')
|
||||
given_name = metadata.get('given_name')
|
||||
family_name = metadata.get('family_name')
|
||||
location = {
|
||||
"area_name": metadata.get('location')
|
||||
}
|
||||
products = []
|
||||
if metadata.get('products'):
|
||||
|
||||
# check whether there's existing location data
|
||||
if isinstance(metadata.get('location'), dict):
|
||||
location = metadata.get('location')
|
||||
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(',')
|
||||
|
||||
phone_number = user.phone_number
|
||||
date_registered = int(user.created.replace().timestamp())
|
||||
blockchain_address = user.blockchain_address
|
||||
@@ -192,28 +208,27 @@ def edit_user_metadata_attribute(state_machine_data: Tuple[str, dict, Account]):
|
||||
# validate user metadata
|
||||
person = Person()
|
||||
user_metadata = json.loads(user_metadata)
|
||||
deserialized_person = person.deserialize(person_data=user_metadata)
|
||||
|
||||
# edit specific metadata attribute
|
||||
if given_name:
|
||||
deserialized_person.given_name = given_name
|
||||
elif family_name:
|
||||
deserialized_person.family_name = family_name
|
||||
elif gender:
|
||||
deserialized_person.gender = gender
|
||||
elif location:
|
||||
user_metadata['given_name'] = given_name
|
||||
if family_name:
|
||||
user_metadata['family_name'] = family_name
|
||||
if gender:
|
||||
user_metadata['gender'] = gender
|
||||
if location:
|
||||
# get existing location metadata:
|
||||
location_data = user_metadata.get('location')
|
||||
location_data['area_name'] = location
|
||||
deserialized_person.location = location_data
|
||||
elif products:
|
||||
deserialized_person.products = products
|
||||
user_metadata['location'] = location_data
|
||||
if 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(
|
||||
'cic_ussd.tasks.metadata.edit_person_metadata',
|
||||
[blockchain_address, edited_metadata]
|
||||
'cic_ussd.tasks.metadata.create_person_metadata',
|
||||
[blockchain_address, user_metadata]
|
||||
)
|
||||
s_edit_person_metadata.apply_async(queue='cic-ussd')
|
||||
|
||||
|
||||
@@ -19,4 +19,6 @@ def translation_for(key: str, preferred_language: Optional[str] = None, **kwargs
|
||||
"""
|
||||
if preferred_language:
|
||||
i18n.set('locale', preferred_language)
|
||||
else:
|
||||
i18n.set('locale', i18n.config.get('fallback'))
|
||||
return i18n.t(key, **kwargs)
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
cic_base[full_graph]~=0.1.2b2
|
||||
cic-eth~=0.11.0b9
|
||||
cic-notify~=0.4.0a4
|
||||
cic-notify~=0.4.0a5
|
||||
cic-types~=0.1.0a10
|
||||
|
||||
@@ -6,7 +6,10 @@
|
||||
"enter_new_pin",
|
||||
"new_pin_confirmation",
|
||||
"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_statement_pin_authorization",
|
||||
"account_balances"
|
||||
|
||||
@@ -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-celery==0.0.0a1
|
||||
pytest-cov==2.10.1
|
||||
pytest-mock==3.3.1
|
||||
pytest-ordering==0.6
|
||||
pytest-redis==2.0.0
|
||||
requests-mock==1.8.0
|
||||
requests-mock==1.8.0
|
||||
tavern==1.14.2
|
||||
@@ -6,6 +6,7 @@ from cic_types.pytest import *
|
||||
from tests.fixtures.config import *
|
||||
from tests.fixtures.db import *
|
||||
from tests.fixtures.celery import *
|
||||
from tests.fixtures.integration import *
|
||||
from tests.fixtures.user import *
|
||||
from tests.fixtures.ussd_session import *
|
||||
from tests.fixtures.redis import *
|
||||
|
||||
249
apps/cic-ussd/tests/fixtures/integration.py
vendored
Normal file
249
apps/cic-ussd/tests/fixtures/integration.py
vendored
Normal 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')
|
||||
26
apps/cic-ussd/tests/helpers/accounts.py
Normal file
26
apps/cic-ussd/tests/helpers/accounts.py
Normal 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)
|
||||
11
apps/cic-ussd/tests/integration/ext/validator.py
Normal file
11
apps/cic-ussd/tests/integration/ext/validator.py
Normal 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
|
||||
2
apps/cic-ussd/tests/integration/run.sh
Normal file
2
apps/cic-ussd/tests/integration/run.sh
Normal file
@@ -0,0 +1,2 @@
|
||||
#!/bin/bash
|
||||
PYTHONPATH=. py.test --debug -vv --log-level debug -s --log-cli-level debug
|
||||
@@ -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
|
||||
@@ -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"
|
||||
1573
apps/cic-ussd/tests/integration/test_profile_management.tavern.yaml
Normal file
1573
apps/cic-ussd/tests/integration/test_profile_management.tavern.yaml
Normal file
File diff suppressed because it is too large
Load Diff
282
apps/cic-ussd/tests/integration/test_transactions.tavern.yaml
Normal file
282
apps/cic-ussd/tests/integration/test_transactions.tavern.yaml
Normal 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"
|
||||
@@ -4,12 +4,13 @@
|
||||
"source": "enter_gender",
|
||||
"dest": "enter_location",
|
||||
"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",
|
||||
"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",
|
||||
"conditions": [
|
||||
"cic_ussd.state_machine.logic.validator.has_cached_user_metadata",
|
||||
@@ -18,15 +19,14 @@
|
||||
},
|
||||
{
|
||||
"trigger": "scan_data",
|
||||
"source": "standard_pin_authorization",
|
||||
"source": "gender_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",
|
||||
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
||||
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
|
||||
},
|
||||
{
|
||||
"trigger": "scan_data",
|
||||
"source": "standard_pin_authorization",
|
||||
"source": "gender_edit_pin_authorization",
|
||||
"dest": "exit_pin_blocked",
|
||||
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
|
||||
},
|
||||
|
||||
@@ -3,26 +3,26 @@
|
||||
"trigger": "scan_data",
|
||||
"source": "enter_location",
|
||||
"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",
|
||||
"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",
|
||||
"conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
||||
},
|
||||
{
|
||||
"trigger": "scan_data",
|
||||
"source": "standard_pin_authorization",
|
||||
"source": "location_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",
|
||||
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
||||
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
|
||||
},
|
||||
{
|
||||
"trigger": "scan_data",
|
||||
"source": "standard_pin_authorization",
|
||||
"source": "location_edit_pin_authorization",
|
||||
"dest": "exit_pin_blocked",
|
||||
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
|
||||
}
|
||||
|
||||
@@ -7,49 +7,28 @@
|
||||
},
|
||||
{
|
||||
"trigger": "scan_data",
|
||||
"source": "enter_given_name",
|
||||
"dest": "standard_pin_authorization",
|
||||
"source": "enter_family_name",
|
||||
"dest": "name_edit_pin_authorization",
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"trigger": "scan_data",
|
||||
"source": "standard_pin_authorization",
|
||||
"dest": "exit_pin_blocked",
|
||||
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
|
||||
},
|
||||
{
|
||||
"trigger": "scan_data",
|
||||
"source": "enter_family_name",
|
||||
"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",
|
||||
"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",
|
||||
"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",
|
||||
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@
|
||||
"trigger": "scan_data",
|
||||
"source": "enter_current_pin",
|
||||
"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",
|
||||
"source": "enter_new_pin",
|
||||
"dest": "new_pin_confirmation",
|
||||
"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",
|
||||
@@ -28,7 +28,7 @@
|
||||
"source": "new_pin_confirmation",
|
||||
"dest": "complete",
|
||||
"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",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
{
|
||||
"trigger": "scan_data",
|
||||
"source": "enter_products",
|
||||
"dest": "standard_pin_authorization",
|
||||
"dest": "products_edit_pin_authorization",
|
||||
"conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata",
|
||||
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data"
|
||||
},
|
||||
@@ -13,18 +13,19 @@
|
||||
"after": [
|
||||
"cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
||||
"cic_ussd.state_machine.logic.user.save_complete_user_metadata"
|
||||
]
|
||||
],
|
||||
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
||||
},
|
||||
{
|
||||
"trigger": "scan_data",
|
||||
"source": "standard_pin_authorization",
|
||||
"source": "products_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": "standard_pin_authorization",
|
||||
"source": "products_edit_pin_authorization",
|
||||
"dest": "exit_pin_blocked",
|
||||
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
{
|
||||
"trigger": "scan_data",
|
||||
"source": "metadata_management",
|
||||
"dest": "enter_age",
|
||||
"dest": "enter_gender",
|
||||
"conditions": "cic_ussd.state_machine.logic.menu.menu_two_selected"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -6,7 +6,7 @@ en:
|
||||
2. Kiswahili
|
||||
3. Help
|
||||
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
|
||||
initial_pin_confirmation: |-
|
||||
CON Enter your four number PIN again
|
||||
@@ -76,7 +76,10 @@ en:
|
||||
CON Enter current PIN. You have %{remaining_attempts} attempts remaining.
|
||||
0. Back
|
||||
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
|
||||
transaction_pin_authorization:
|
||||
first: |-
|
||||
@@ -107,6 +110,34 @@ en:
|
||||
retry: |-
|
||||
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
|
||||
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: |-
|
||||
CON Your balances are as follows:
|
||||
balance: %{operational_balance} %{token_symbol}
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
sw:
|
||||
kenya:
|
||||
initial_language_selection: |-
|
||||
CON Welcome to Sarafu
|
||||
CON Karibu Sarafu Network
|
||||
1. English
|
||||
2. Kiswahili
|
||||
3. Help
|
||||
initial_pin_entry: |-
|
||||
CON Tafadhali weka PIN ili kudhibiti akaunti yako.
|
||||
CON Tafadhali weka pin mpya yenye nambari nne kwa akaunti yako
|
||||
0. Nyuma
|
||||
initial_pin_confirmation: |-
|
||||
CON Weka PIN yako tena
|
||||
@@ -21,12 +21,13 @@ sw:
|
||||
CON Weka jinsia yako
|
||||
1. Mwanaume
|
||||
2. Mwanamke
|
||||
3. Nyngine
|
||||
0. Nyuma
|
||||
enter_location: |-
|
||||
CON Weka eneo lako
|
||||
0. Nyuma
|
||||
enter_products: |-
|
||||
CON Tafadhali weka bidhaa ama huduma unauza
|
||||
CON Weka bidhaa ama huduma unauza
|
||||
0. Nyuma
|
||||
start: |-
|
||||
CON Salio %{account_balance} %{account_token_name}
|
||||
@@ -60,7 +61,7 @@ sw:
|
||||
Jina: %{full_name}
|
||||
Jinsia: %{gender}
|
||||
Eneo: %{location}
|
||||
Unauza: %{user_bio}
|
||||
Unauza: %{products}
|
||||
0. Nyuma
|
||||
select_preferred_language: |-
|
||||
CON Chagua lugha
|
||||
@@ -77,6 +78,9 @@ sw:
|
||||
enter_new_pin: |-
|
||||
CON Weka nambari ya siri mpya
|
||||
0. Nyuma
|
||||
new_pin_confirmation: |-
|
||||
CON Weka PIN yako tena
|
||||
0. Nyuma
|
||||
transaction_pin_authorization:
|
||||
first: |-
|
||||
CON %{recipient_information} atapokea %{transaction_amount} %{token_symbol} kutoka kwa %{sender_information}.
|
||||
@@ -85,9 +89,9 @@ sw:
|
||||
retry: |-
|
||||
CON Weka nambari ya siri. Una majaribio %{remaining_attempts} yaliyobaki.
|
||||
0. Nyuma
|
||||
standard_pin_authorization:
|
||||
display_metadata_pin_authorization:
|
||||
first: |-
|
||||
CON Tafadhali weka PIN yako.
|
||||
CON Tafadhali weka PIN yako
|
||||
0. Nyuma
|
||||
retry: |-
|
||||
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
|
||||
@@ -106,12 +110,40 @@ sw:
|
||||
retry: |-
|
||||
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
|
||||
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: |-
|
||||
CON Salio zako ni zifuatazo:
|
||||
salio: %{operational_balance}
|
||||
ushuru: %{tax}
|
||||
tuzo: %{bonus}
|
||||
0. Back
|
||||
salio: %{operational_balance} %{token_symbol}
|
||||
ushuru: %{tax} %{token_symbol}
|
||||
tuzo: %{bonus} %{token_symbol}
|
||||
0. Nyuma
|
||||
first_transaction_set: |-
|
||||
CON %{first_transaction_set}
|
||||
1. Mbele
|
||||
@@ -155,7 +187,7 @@ sw:
|
||||
99. Ondoka
|
||||
exit_insufficient_balance: |-
|
||||
CON Malipo ya %{amount} %{token_symbol} kwa %{recipient_information} halijakamilika kwa sababu salio lako haitoshi.
|
||||
Akaunti yako ya Sarafu-Network ina salio ifuatayo: %{token_balance}
|
||||
Akaunti yako ya Sarafu ina salio ifuatayo: %{token_balance}
|
||||
00. Nyuma
|
||||
99. Ondoka
|
||||
invalid_service_code: |-
|
||||
@@ -169,4 +201,4 @@ sw:
|
||||
00. Nyuma
|
||||
99. Ondoka
|
||||
account_creation_prompt: |-
|
||||
Akaunti yako ya Sarafu inatayarishwa. Utapokea ujumbe wa SMS akaunti yako ikiwa tayari.
|
||||
Akaunti yako ya Sarafu inatayarishwa. Utapokea ujumbe wa SMS akaunti yako ikiwa tayari.
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
# external imports
|
||||
from chainlib.jsonrpc import JSONRPCException
|
||||
from eth_erc20 import ERC20
|
||||
from eth_accounts_index import AccountsIndex
|
||||
from eth_token_index import TokenUniqueSymbolIndex
|
||||
|
||||
class ERC20Token:
|
||||
|
||||
def __init__(self, chain_spec, address, conn):
|
||||
self.__address = address
|
||||
|
||||
c = ERC20(chain_spec)
|
||||
o = c.symbol(address)
|
||||
r = conn.do(o)
|
||||
self.__symbol = c.parse_symbol(r)
|
||||
|
||||
o = c.decimals(address)
|
||||
r = conn.do(o)
|
||||
self.__decimals = c.parse_decimals(r)
|
||||
|
||||
|
||||
def symbol(self):
|
||||
return self.__symbol
|
||||
|
||||
|
||||
def decimals(self):
|
||||
return self.__decimals
|
||||
|
||||
|
||||
class IndexCache:
|
||||
|
||||
def __init__(self, chain_spec, address):
|
||||
self.address = address
|
||||
self.chain_spec = chain_spec
|
||||
|
||||
|
||||
def parse(self, r):
|
||||
return r
|
||||
|
||||
|
||||
def get(self, conn):
|
||||
entries = []
|
||||
i = 0
|
||||
while True:
|
||||
o = self.o.entry(self.address, i)
|
||||
try:
|
||||
r = conn.do(o)
|
||||
entries.append(self.parse(r, conn))
|
||||
except JSONRPCException:
|
||||
return entries
|
||||
i += 1
|
||||
|
||||
|
||||
class AccountRegistryCache(IndexCache):
|
||||
|
||||
def __init__(self, chain_spec, address):
|
||||
super(AccountRegistryCache, self).__init__(chain_spec, address)
|
||||
self.o = AccountsIndex(chain_spec)
|
||||
self.get_accounts = self.get
|
||||
|
||||
|
||||
def parse(self, r, conn):
|
||||
return self.o.parse_account(r)
|
||||
|
||||
|
||||
class TokenRegistryCache(IndexCache):
|
||||
|
||||
def __init__(self, chain_spec, address):
|
||||
super(TokenRegistryCache, self).__init__(chain_spec, address)
|
||||
self.o = TokenUniqueSymbolIndex(chain_spec)
|
||||
self.get_tokens = self.get
|
||||
|
||||
|
||||
def parse(self, r, conn):
|
||||
token_address = self.o.parse_entry(r)
|
||||
return ERC20Token(self.chain_spec, token_address, conn)
|
||||
@@ -163,9 +163,9 @@ class TrafficProvisioner:
|
||||
"""Aux parameter template to be passed to the traffic generator module"""
|
||||
|
||||
|
||||
def __init__(self, conn):
|
||||
self.tokens = self.oracles['token'].get_tokens(conn)
|
||||
self.accounts = self.oracles['account'].get_accounts(conn)
|
||||
def __init__(self):
|
||||
self.tokens = self.oracles['token'].get_tokens()
|
||||
self.accounts = self.oracles['account'].get_accounts()
|
||||
self.aux = copy.copy(self.default_aux)
|
||||
self.__balances = {}
|
||||
for a in self.accounts:
|
||||
@@ -277,14 +277,13 @@ class TrafficSyncHandler:
|
||||
:type traffic_router: TrafficRouter
|
||||
:raises Exception: Any Exception redis may raise on connection attempt.
|
||||
"""
|
||||
def __init__(self, config, traffic_router, conn):
|
||||
def __init__(self, config, traffic_router):
|
||||
self.traffic_router = traffic_router
|
||||
self.redis_channel = str(uuid.uuid4())
|
||||
self.pubsub = self.__connect_redis(self.redis_channel, config)
|
||||
self.traffic_items = {}
|
||||
self.config = config
|
||||
self.init = False
|
||||
self.conn = conn
|
||||
|
||||
|
||||
# connects to redis
|
||||
@@ -308,7 +307,7 @@ class TrafficSyncHandler:
|
||||
:param tx_index: Syncer block transaction index at time of call.
|
||||
:type tx_index: number
|
||||
"""
|
||||
traffic_provisioner = TrafficProvisioner(self.conn)
|
||||
traffic_provisioner = TrafficProvisioner()
|
||||
traffic_provisioner.add_aux('redis_channel', self.redis_channel)
|
||||
|
||||
refresh_accounts = None
|
||||
@@ -344,7 +343,7 @@ class TrafficSyncHandler:
|
||||
sender = traffic_provisioner.accounts[sender_index]
|
||||
#balance_full = balances[sender][token_pair[0].symbol()]
|
||||
if len(sender_indices) == 1:
|
||||
sender_indices[sender_index] = sender_indices[len(sender_indices)-1]
|
||||
sender_indices[m] = sender_sender_indices[len(senders)-1]
|
||||
sender_indices = sender_indices[:len(sender_indices)-1]
|
||||
|
||||
balance_full = traffic_provisioner.balance(sender, token_pair[0])
|
||||
@@ -352,14 +351,7 @@ class TrafficSyncHandler:
|
||||
recipient_index = random.randint(0, len(traffic_provisioner.accounts)-1)
|
||||
recipient = traffic_provisioner.accounts[recipient_index]
|
||||
|
||||
logg.debug('trigger item {} tokens {} sender {} recipient {} balance {}'.format(
|
||||
traffic_item,
|
||||
token_pair,
|
||||
sender,
|
||||
recipient,
|
||||
balance_full,
|
||||
)
|
||||
)
|
||||
logg.debug('trigger item {} tokens {} sender {} recipient {} balance {}')
|
||||
(e, t, balance_result,) = traffic_item.method(
|
||||
token_pair,
|
||||
sender,
|
||||
@@ -367,6 +359,7 @@ class TrafficSyncHandler:
|
||||
balance_full,
|
||||
traffic_provisioner.aux,
|
||||
block_number,
|
||||
tx_index,
|
||||
)
|
||||
traffic_provisioner.update_balance(sender, token_pair[0], balance_result)
|
||||
sender_indices.append(recipient_index)
|
||||
|
||||
@@ -3,7 +3,7 @@ import logging
|
||||
import copy
|
||||
|
||||
# external imports
|
||||
from cic_registry.registry import Registry
|
||||
from cic_registry import CICRegistry
|
||||
from eth_token_index import TokenUniqueSymbolIndex
|
||||
from eth_accounts_index import AccountRegistry
|
||||
from chainlib.chain import ChainSpec
|
||||
|
||||
@@ -3,7 +3,7 @@ import logging
|
||||
|
||||
# external imports
|
||||
from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer
|
||||
from crypto_dev_signer.keystore.dict import DictKeystore
|
||||
from crypto_dev_signer.keystore import DictKeystore
|
||||
|
||||
logg = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ queue = 'cic-eth'
|
||||
name = 'account'
|
||||
|
||||
|
||||
def do(token_pair, sender, recipient, sender_balance, aux, block_number):
|
||||
def do(token_pair, sender, recipient, sender_balance, aux, block_number, tx_index):
|
||||
"""Triggers creation and registration of new account through the custodial cic-eth component.
|
||||
|
||||
It expects the following aux parameters to exist:
|
||||
|
||||
@@ -5,7 +5,7 @@ logging.basicConfig(level=logging.WARNING)
|
||||
logg = logging.getLogger()
|
||||
|
||||
|
||||
def do(token_pair, sender, recipient, sender_balance, aux, block_number):
|
||||
def do(token_pair, sender, recipient, sender_balance, aux, block_number, tx_index):
|
||||
"""Defines the function signature for a traffic generator. The method itself only logs the input parameters.
|
||||
|
||||
If the error position in the return tuple is not None, the calling code should consider the generation as failed, and not count it towards the limit of simultaneous traffic items that can be simultaneously in flight.
|
||||
@@ -26,10 +26,12 @@ def do(token_pair, sender, recipient, sender_balance, aux, block_number):
|
||||
:type aux: dict
|
||||
:param block_number: Syncer block number position at time of method call
|
||||
:type block_number: number
|
||||
:param tx_index: Syncer block transaction index position at time of method call
|
||||
:type tx_index: number
|
||||
:raises KeyError: Missing required aux element
|
||||
:returns: Exception|None, task_id|None and adjusted_sender_balance respectively
|
||||
:rtype: tuple
|
||||
"""
|
||||
logg.debug('running {} {} {} {} {} {} {}'.format(__name__, token_pair, sender, recipient, sender_balance, aux, block_number))
|
||||
logg.debug('running {} {} {} {} {} {} {} {}'.format(__name__, token_pair, sender, recipient, sender_balance, aux, block_number, tx_index))
|
||||
|
||||
return (None, None, sender_balance, )
|
||||
|
||||
@@ -12,7 +12,7 @@ queue = 'cic-eth'
|
||||
name = 'erc20_transfer'
|
||||
|
||||
|
||||
def do(token_pair, sender, recipient, sender_balance, aux, block_number):
|
||||
def do(token_pair, sender, recipient, sender_balance, aux, block_number, tx_index):
|
||||
"""Triggers an ERC20 token transfer through the custodial cic-eth component, with a randomly chosen amount in integer resolution.
|
||||
|
||||
It expects the following aux parameters to exist:
|
||||
@@ -33,7 +33,7 @@ def do(token_pair, sender, recipient, sender_balance, aux, block_number):
|
||||
balance_units = int(sender_balance_value / decimals)
|
||||
|
||||
if balance_units <= 0:
|
||||
return (AttributeError('sender {} has zero balance ({} / {})'.format(sender, sender_balance_value, decimals)), None, 0,)
|
||||
return (AttributeError('sender {} has zero balance'), None, 0,)
|
||||
|
||||
spend_units = random.randint(1, balance_units)
|
||||
spend_value = spend_units * decimals
|
||||
|
||||
@@ -8,25 +8,16 @@ import json
|
||||
# external imports
|
||||
import redis
|
||||
import celery
|
||||
from cic_eth_registry.registry import CICRegistry
|
||||
from chainsyncer.backend.memory import MemBackend
|
||||
from chainsyncer.backend import MemBackend
|
||||
from chainsyncer.driver import HeadSyncer
|
||||
from chainlib.eth.connection import EthHTTPConnection
|
||||
from chainlib.chain import ChainSpec
|
||||
from chainlib.eth.gas import RPCGasOracle
|
||||
from chainlib.eth.nonce import RPCNonceOracle
|
||||
from chainlib.eth.connection import HTTPConnection
|
||||
from chainlib.eth.gas import DefaultGasOracle
|
||||
from chainlib.eth.nonce import DefaultNonceOracle
|
||||
from chainlib.eth.block import block_latest
|
||||
from hexathon import strip_0x
|
||||
from cic_base import (
|
||||
argparse,
|
||||
config,
|
||||
log,
|
||||
rpc,
|
||||
signer as signer_funcs,
|
||||
)
|
||||
|
||||
# local imports
|
||||
#import common
|
||||
import common
|
||||
from cmd.traffic import (
|
||||
TrafficItem,
|
||||
TrafficRouter,
|
||||
@@ -34,19 +25,15 @@ from cmd.traffic import (
|
||||
TrafficSyncHandler,
|
||||
)
|
||||
from cmd.traffic import add_args as add_traffic_args
|
||||
from cmd.cache import (
|
||||
AccountRegistryCache,
|
||||
TokenRegistryCache,
|
||||
)
|
||||
|
||||
|
||||
# common basics
|
||||
script_dir = os.path.realpath(os.path.dirname(__file__))
|
||||
logg = log.create()
|
||||
argparser = argparse.create(script_dir, argparse.full_template)
|
||||
argparser = argparse.add(argparser, add_traffic_args, 'traffic')
|
||||
args = argparse.parse(argparser, logg)
|
||||
config = config.create(args.c, args, args.env_prefix)
|
||||
logg = common.log.create()
|
||||
argparser = common.argparse.create(script_dir, common.argparse.full_template)
|
||||
argparser = common.argparse.add(argparser, add_traffic_args, 'traffic')
|
||||
args = common.argparse.parse(argparser, logg)
|
||||
config = common.config.create(args.c, args, args.env_prefix)
|
||||
|
||||
# map custom args to local config entries
|
||||
batchsize = args.batch_size
|
||||
@@ -62,32 +49,29 @@ config.add(args.y, '_KEYSTORE_FILE', True)
|
||||
|
||||
config.add(args.q, '_CELERY_QUEUE', True)
|
||||
|
||||
logg.debug(config)
|
||||
common.config.log(config)
|
||||
|
||||
chain_spec = ChainSpec.from_chain_str(config.get('CIC_CHAIN_SPEC'))
|
||||
|
||||
def main():
|
||||
# create signer (not currently in use, but needs to be accessible for custom traffic item generators)
|
||||
(signer_address, signer) = signer_funcs.from_keystore(config.get('_KEYSTORE_FILE'))
|
||||
(signer_address, signer) = common.signer.from_keystore(config.get('_KEYSTORE_FILE'))
|
||||
|
||||
# connect to celery
|
||||
celery.Celery(broker=config.get('CELERY_BROKER_URL'), backend=config.get('CELERY_RESULT_URL'))
|
||||
|
||||
# set up registry
|
||||
rpc.setup(config.get('CIC_CHAIN_SPEC'), config.get('ETH_PROVIDER')) # replace with HTTPConnection when registry has been so refactored
|
||||
conn = EthHTTPConnection(config.get('ETH_PROVIDER'))
|
||||
#registry = registry.init_legacy(config, w3)
|
||||
CICRegistry.address = config.get('CIC_REGISTRY_ADDRESS')
|
||||
registry = CICRegistry(chain_spec, conn)
|
||||
w3 = common.rpc.create(config.get('ETH_PROVIDER')) # replace with HTTPConnection when registry has been so refactored
|
||||
registry = common.registry.init_legacy(config, w3)
|
||||
|
||||
# Connect to blockchain with chainlib
|
||||
gas_oracle = RPCGasOracle(conn)
|
||||
nonce_oracle = RPCNonceOracle(signer_address, conn)
|
||||
conn = HTTPConnection(config.get('ETH_PROVIDER'))
|
||||
gas_oracle = DefaultGasOracle(conn)
|
||||
nonce_oracle = DefaultNonceOracle(signer_address, conn)
|
||||
|
||||
# Set up magic traffic handler
|
||||
traffic_router = TrafficRouter()
|
||||
traffic_router.apply_import_dict(config.all(), config)
|
||||
handler = TrafficSyncHandler(config, traffic_router, conn)
|
||||
handler = TrafficSyncHandler(config, traffic_router)
|
||||
|
||||
# Set up syncer
|
||||
syncer_backend = MemBackend(config.get('CIC_CHAIN_SPEC'), 0)
|
||||
@@ -96,21 +80,9 @@ def main():
|
||||
block_offset = int(strip_0x(r), 16) + 1
|
||||
syncer_backend.set(block_offset, 0)
|
||||
|
||||
# get relevant registry entries
|
||||
token_registry = registry.lookup('TokenRegistry')
|
||||
logg.info('using token registry {}'.format(token_registry))
|
||||
token_cache = TokenRegistryCache(chain_spec, token_registry)
|
||||
|
||||
account_registry = registry.lookup('AccountRegistry')
|
||||
logg.info('using account registry {}'.format(account_registry))
|
||||
account_cache = AccountRegistryCache(chain_spec, account_registry)
|
||||
|
||||
# Set up provisioner for common task input data
|
||||
#TrafficProvisioner.oracles['token']= common.registry.TokenOracle(w3, config.get('CIC_CHAIN_SPEC'), registry)
|
||||
#TrafficProvisioner.oracles['account'] = common.registry.AccountsOracle(w3, config.get('CIC_CHAIN_SPEC'), registry)
|
||||
TrafficProvisioner.oracles['token'] = token_cache
|
||||
TrafficProvisioner.oracles['account'] = account_cache
|
||||
|
||||
TrafficProvisioner.oracles['token']= common.registry.TokenOracle(w3, config.get('CIC_CHAIN_SPEC'), registry)
|
||||
TrafficProvisioner.oracles['account'] = common.registry.AccountsOracle(w3, config.get('CIC_CHAIN_SPEC'), registry)
|
||||
TrafficProvisioner.default_aux = {
|
||||
'chain_spec': config.get('CIC_CHAIN_SPEC'),
|
||||
'registry': registry,
|
||||
@@ -120,7 +92,7 @@ def main():
|
||||
'api_queue': config.get('_CELERY_QUEUE'),
|
||||
}
|
||||
|
||||
syncer = HeadSyncer(syncer_backend, block_callback=handler.refresh)
|
||||
syncer = HeadSyncer(syncer_backend, loop_callback=handler.refresh)
|
||||
syncer.add_filter(handler)
|
||||
syncer.loop(1, conn)
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
[traffic]
|
||||
#local.noop_traffic = 2
|
||||
#local.account = 2
|
||||
local.account = 2
|
||||
local.transfer = 2
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
cic-base[full_graph]==0.1.2b11
|
||||
cic-base[full_graph]==0.1.2b9
|
||||
sarafu-faucet==0.0.3a3
|
||||
cic-eth==0.11.0b14
|
||||
cic-eth==0.11.0b13
|
||||
cic-types==0.1.0a11
|
||||
crypto-dev-signer==0.4.14b3
|
||||
|
||||
@@ -72,7 +72,6 @@ argparser.add_argument('--ussd-provider', type=str, dest='ussd_provider', defaul
|
||||
argparser.add_argument('--skip-custodial', dest='skip_custodial', action='store_true', help='skip all custodial verifications')
|
||||
argparser.add_argument('--exclude', action='append', type=str, default=[], help='skip specified verification')
|
||||
argparser.add_argument('--include', action='append', type=str, help='include specified verification')
|
||||
argparser.add_argument('--token-symbol', default='SRF', type=str, dest='token_symbol', help='Token symbol to use for trnsactions')
|
||||
argparser.add_argument('-r', '--registry-address', type=str, dest='r', help='CIC Registry address')
|
||||
argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration')
|
||||
argparser.add_argument('-x', '--exit-on-error', dest='x', action='store_true', help='Halt exection on error')
|
||||
@@ -102,8 +101,6 @@ config.censor('PASSWORD', 'SSL')
|
||||
config.add(args.meta_provider, '_META_PROVIDER', True)
|
||||
config.add(args.ussd_provider, '_USSD_PROVIDER', True)
|
||||
|
||||
token_symbol = args.token_symbol
|
||||
|
||||
logg.debug('config loaded from {}:\n{}'.format(config_dir, config))
|
||||
|
||||
celery_app = celery.Celery(backend=config.get('CELERY_RESULT_URL'), broker=config.get('CELERY_BROKER_URL'))
|
||||
@@ -276,10 +273,7 @@ class Verifier:
|
||||
def verify_balance(self, address, balance):
|
||||
o = self.erc20_tx_factory.balance(self.token_address, address)
|
||||
r = self.conn.do(o)
|
||||
try:
|
||||
actual_balance = int(strip_0x(r), 16)
|
||||
except ValueError:
|
||||
actual_balance = int(r)
|
||||
actual_balance = int(strip_0x(r), 16)
|
||||
balance = int(balance / 1000000) * 1000000
|
||||
logg.debug('balance for {}: {}'.format(address, balance))
|
||||
if balance != actual_balance:
|
||||
@@ -467,7 +461,7 @@ def main():
|
||||
tx = txf.template(ZERO_ADDRESS, token_index_address)
|
||||
data = add_0x(registry_addressof_method)
|
||||
h = hashlib.new('sha256')
|
||||
h.update(token_symbol.encode('utf-8'))
|
||||
h.update(b'SRF')
|
||||
z = h.digest()
|
||||
data += eth_abi.encode_single('bytes32', z).hex()
|
||||
txf.set_code(tx, data)
|
||||
|
||||
@@ -446,9 +446,9 @@ services:
|
||||
PGPASSWORD: ${DATABASE_PASSWORD:-tralala}
|
||||
CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://redis}
|
||||
CELERY_RESULT_URL: ${CELERY_BROKER_URL:-redis://redis}
|
||||
TASKS_AFRICASTALKING: $TASKS_AFRICASTALKING
|
||||
TASKS_SMS_DB: $TASKS_SMS_DB
|
||||
TASKS_LOG: $TASKS_LOG
|
||||
AFRICASTALKING_API_USERNAME: $AFRICASTALKING_API_USERNAME
|
||||
AFRICASTALKING_API_KEY: $AFRICASTALKING_API_KEY
|
||||
AFRICASTALKING_API_SENDER_ID: $AFRICASTALKING_API_SENDER_ID
|
||||
depends_on:
|
||||
- postgres
|
||||
- redis
|
||||
|
||||
Reference in New Issue
Block a user