Compare commits

..

6 Commits

Author SHA1 Message Date
nolash
dd9305a0f2 Change data endpoint to block range 2021-05-18 18:16:02 +02:00
nolash
f035bd3e9f Translate decimal type to int in tx lists 2021-05-18 17:39:07 +02:00
nolash
f1f5253865 handle string datetime format in tx list 2021-05-18 17:32:58 +02:00
nolash
8eb4e9631b Catch data header first 2021-05-18 17:04:11 +02:00
nolash
0169ce1930 Make daemon query include absolute path 2021-05-18 14:04:47 +02:00
nolash
b3adee69e7 Add data api 2021-05-18 13:20:02 +02:00
52 changed files with 163 additions and 3537 deletions

View File

@@ -16,6 +16,4 @@ def default_token(self):
return {
'symbol': self.default_token_symbol,
'address': self.default_token_address,
'name': self.default_token_name,
'decimals': self.default_token_decimals,
}

View File

@@ -72,9 +72,7 @@ class CallbackFilter(SyncFilter):
#transfer_data['token_address'] = tx.inputs[0]
faucet_contract = tx.inputs[0]
c = Faucet(self.chain_spec)
o = c.token(faucet_contract, sender_address=self.caller_address)
o = Faucet.token(faucet_contract, sender_address=self.caller_address)
r = conn.do(o)
transfer_data['token_address'] = add_0x(c.parse_token(r))

View File

@@ -22,7 +22,6 @@ from chainlib.eth.connection import (
from chainlib.chain import ChainSpec
from chainqueue.db.models.otx import Otx
from cic_eth_registry.error import UnknownContractError
from cic_eth_registry.erc20 import ERC20Token
import liveness.linux
@@ -208,11 +207,6 @@ def main():
BaseTask.default_token_symbol = config.get('CIC_DEFAULT_TOKEN_SYMBOL')
BaseTask.default_token_address = registry.by_name(BaseTask.default_token_symbol)
default_token = ERC20Token(chain_spec, rpc, BaseTask.default_token_address)
default_token.load(rpc)
BaseTask.default_token_decimals = default_token.decimals
BaseTask.default_token_name = default_token.name
BaseTask.run_dir = config.get('CIC_RUN_DIR')
logg.info('default token set to {} {}'.format(BaseTask.default_token_symbol, BaseTask.default_token_address))

View File

@@ -67,8 +67,6 @@ def main():
token_info = t.get()
print('Default token symbol: {}'.format(token_info['symbol']))
print('Default token address: {}'.format(token_info['address']))
logg.debug('Default token name: {}'.format(token_info['name']))
logg.debug('Default token decimals: {}'.format(token_info['decimals']))
if __name__ == '__main__':

View File

@@ -33,8 +33,6 @@ class BaseTask(celery.Task):
create_gas_oracle = RPCGasOracle
default_token_address = None
default_token_symbol = None
default_token_name = None
default_token_decimals = None
run_dir = '/run'
def create_session(self):

View File

@@ -4,7 +4,7 @@ import sys
import logging
# external imports
from eth_erc20 import ERC20
from chainlib.eth.erc20 import ERC20
# local imports
from cic_eth.api import Api

View File

@@ -14,9 +14,9 @@ from chainlib.eth.tx import (
Tx,
)
from chainlib.eth.block import Block
from eth_erc20 import ERC20
from chainlib.eth.erc20 import ERC20
from sarafu_faucet import MinterFaucet
from eth_accounts_index.registry import AccountRegistry
from eth_accounts_index import AccountRegistry
from potaahto.symbols import snake_and_camel
from hexathon import add_0x
@@ -26,6 +26,7 @@ from cic_eth.runnable.daemons.filters.callback import CallbackFilter
logg = logging.getLogger()
@pytest.mark.skip()
def test_transfer_tx(
default_chain_spec,
init_database,
@@ -65,6 +66,7 @@ def test_transfer_tx(
assert transfer_type == 'transfer'
@pytest.mark.skip()
def test_transfer_from_tx(
default_chain_spec,
init_database,

View File

@@ -4,7 +4,7 @@ import logging
# external imports
import pytest
from chainlib.eth.nonce import RPCNonceOracle
from eth_erc20 import ERC20
from chainlib.eth.erc20 import ERC20
from chainlib.eth.tx import receipt
# local imports

View File

@@ -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.registry import AccountRegistry
from eth_accounts_index import AccountRegistry
from hexathon import strip_0x
from chainqueue.db.enum import StatusEnum
from chainqueue.db.models.otx import Otx

View File

@@ -4,7 +4,7 @@ import logging
# external imports
import pytest
import celery
from eth_erc20 import ERC20
from chainlib.eth.erc20 import ERC20
from chainlib.eth.nonce import RPCNonceOracle
from chainlib.eth.tx import (
receipt,

View File

@@ -3,7 +3,7 @@ from chainlib.eth.nonce import RPCNonceOracle
from chainlib.eth.tx import (
receipt,
)
from eth_address_declarator import Declarator
from eth_address_declarator import AddressDeclarator
from hexathon import add_0x
# local imports
@@ -23,7 +23,7 @@ def test_translate(
nonce_oracle = RPCNonceOracle(contract_roles['CONTRACT_DEPLOYER'], eth_rpc)
c = Declarator(default_chain_spec, signer=eth_signer, nonce_oracle=nonce_oracle)
c = AddressDeclarator(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))

View File

@@ -8,7 +8,7 @@ from chainlib.eth.tx import (
count,
receipt,
)
from eth_erc20 import ERC20
from chainlib.eth.erc20 import ERC20
from chainlib.eth.nonce import RPCNonceOracle
# local imports

View File

@@ -31,7 +31,7 @@ function handleNoMergeGet(db, digest, keystore) {
doh(e);
});
}).catch((e) => {
console.error('message', e);
console.error('mesage', 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, o);
s = new Syncable(digest, data);
s.onwrap = (e) => {
whohoo(e.toJSON());
};

View File

@@ -9,7 +9,3 @@ 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."""

View File

@@ -1,19 +0,0 @@
# 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

View File

@@ -6,8 +6,7 @@ import celery
import africastalking
# local imports
from cic_notify.error import NotInitializedError, AlreadyInitializedError, NotificationSendError
from cic_notify.ext.enums import AfricasTalkingStatusCodes
from cic_notify.error import NotInitializedError, AlreadyInitializedError
logg = logging.getLogger()
celery_app = celery.current_app
@@ -51,27 +50,10 @@ 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):

View File

@@ -9,7 +9,7 @@ import semver
logg = logging.getLogger()
version = (0, 4, 0, 'alpha.5')
version = (0, 4, 0, 'alpha.4')
version_object = semver.VersionInfo(
major=version[0],

View File

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

View File

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

View File

@@ -238,43 +238,13 @@
"description": "Menu to display a user's entire profile",
"display_key": "ussd.kenya.display_user_metadata",
"name": "display_user_metadata",
"parent": "metadata_management"
"parent": "account_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"
}
}

View File

@@ -78,30 +78,31 @@ class MetadataRequestsHandler(Metadata):
:param data: The data to be stored in the metadata server.
:type data: dict|str
"""
data = json.dumps(data)
data = json.dumps(data).encode('utf-8')
result = make_request(method='POST', url=self.url, data=data, headers=self.headers)
metadata_http_error_handler(result=result)
metadata = result.json()
metadata = result.content
self.edit(data=metadata)
def edit(self, data: Union[Dict, str]):
def edit(self, data: bytes):
""" 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: dict
:type data: bytes
"""
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': json.dumps(data),
'm': data.decode('utf-8'),
's': {
'engine': self.engine,
'algo': algorithm,
'data': signature,
'digest': data.get('digest'),
'digest': json.loads(data).get('digest'),
}
}
formatted_data = json.dumps(formatted_data)
formatted_data = json.dumps(formatted_data).encode('utf-8')
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)
@@ -109,32 +110,17 @@ 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: {data}.')
logg.info(f'identifier: {decoded_identifier}. metadata pointer: {self.metadata_pointer} set to: {decoded_data}.')
def query(self):
"""
:return:
:rtype:
"""
# retrieve the metadata
"""This function is responsible for querying the metadata server for data corresponding to a unique pointer."""
result = make_request(method='GET', url=self.url)
metadata_http_error_handler(result=result)
# 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}.')
response_data = result.content
data = json.loads(response_data.decode('utf-8'))
if result.status_code == 200 and self.cic_type == ':cic.person':
# validate person metadata
person = Person()
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)
deserialized_person = person.deserialize(person_data=data)
data = json.dumps(deserialized_person.serialize())
cache_data(self.metadata_pointer, data=data)
logg.debug(f'caching: {data} with key: {self.metadata_pointer}')

View File

@@ -47,13 +47,14 @@ class Signer:
logg.debug(f'using signing key: {key_id}, algorithm: {key_algorithm}')
return gpg_keys[0]
def sign_digest(self, data: dict):
def sign_digest(self, data: bytes):
"""
: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)

View File

@@ -251,9 +251,9 @@ def process_display_user_metadata(user: Account, display_key: str):
identifier=blockchain_address_to_metadata_pointer(blockchain_address=user.blockchain_address),
cic_type=':cic.person'
)
cached_metadata = get_cached_data(key)
if cached_metadata:
user_metadata = json.loads(cached_metadata)
user_metadata = get_cached_data(key)
if user_metadata:
user_metadata = json.loads(user_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,8 +433,7 @@ 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_successful_transaction'
'exit_invalid_request'
] and person_metadata is not None:
return UssdMenu.find_by_name(name='start')
else:

View File

@@ -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, check_password_hash
from cic_ussd.encoder import PasswordEncoder, create_password_hash
from cic_ussd.operations import persist_session_to_db_task, create_or_update_session
from cic_ussd.redis import InMemoryStore
@@ -78,13 +78,9 @@ 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)
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
}
session_data = {
'initial_pin': initial_pin
}
# create new in memory ussd session with current ussd session data
create_or_update_session(
@@ -107,8 +103,9 @@ 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')
logg.debug(f'USSD SESSION: {ussd_session}')
return check_password_hash(user_input, initial_pin)
fernet = PasswordEncoder(PasswordEncoder.key)
initial_pin = fernet.decrypt(initial_pin.encode())
return bcrypt.checkpw(user_input.encode(), initial_pin)
def complete_pin_change(state_machine_data: Tuple[str, dict, Account]):

View File

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

View File

@@ -19,6 +19,4 @@ 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)

View File

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

View File

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

View File

@@ -1,11 +1,7 @@
Faker==8.1.2
faker-e164==0.1.0
pytest==6.2.4
pytest==6.0.1
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
tavern==1.14.2
requests-mock==1.8.0

View File

@@ -6,7 +6,6 @@ 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 *

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1,587 +0,0 @@
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"

View File

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

View File

@@ -4,13 +4,12 @@
"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",
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
"conditions": "cic_ussd.state_machine.logic.validator.is_valid_gender_selection"
},
{
"trigger": "scan_data",
"source": "enter_gender",
"dest": "gender_edit_pin_authorization",
"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",
@@ -19,14 +18,15 @@
},
{
"trigger": "scan_data",
"source": "gender_edit_pin_authorization",
"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"
"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": "gender_edit_pin_authorization",
"source": "standard_pin_authorization",
"dest": "exit_pin_blocked",
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
},

View File

@@ -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",
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data"
},
{
"trigger": "scan_data",
"source": "enter_location",
"dest": "location_edit_pin_authorization",
"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": "location_edit_pin_authorization",
"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"
"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": "location_edit_pin_authorization",
"source": "standard_pin_authorization",
"dest": "exit_pin_blocked",
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
}

View File

@@ -7,28 +7,49 @@
},
{
"trigger": "scan_data",
"source": "enter_family_name",
"dest": "name_edit_pin_authorization",
"source": "enter_given_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": "enter_family_name",
"dest": "enter_gender",
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_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": "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"
"source": "standard_pin_authorization",
"dest": "exit_pin_blocked",
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
},
{
"trigger": "scan_data",
"source": "name_edit_pin_authorization",
"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",
"dest": "exit_pin_blocked",
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
}

View File

@@ -9,14 +9,14 @@
"trigger": "scan_data",
"source": "enter_current_pin",
"dest": "exit_pin_blocked",
"conditions": "cic_ussd.state_machine.logic.pin.is_blocked_pin"
"conditions": "cic_ussd.state_machine.logic.menu.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.pin.is_valid_new_pin"
"conditions": "cic_ussd.state_machine.logic.menu.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.pin.complete_pin_change"
"after": "cic_ussd.state_machine.logic.menu.complete_pin_change"
},
{
"trigger": "scan_data",

View File

@@ -2,7 +2,7 @@
{
"trigger": "scan_data",
"source": "enter_products",
"dest": "products_edit_pin_authorization",
"dest": "standard_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,19 +13,18 @@
"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": "products_edit_pin_authorization",
"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"
},
{
"trigger": "scan_data",
"source": "products_edit_pin_authorization",
"source": "standard_pin_authorization",
"dest": "exit_pin_blocked",
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
}

View File

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

View File

@@ -1,7 +1,7 @@
en:
account_successfully_created: |-
You have been registered on Sarafu Network! To use dial *384*96# on Safaricom and *483*96# on other networks. For help %{support_phone}.
Hello, you have been registered on Sarafu Network! Your balance is %{balance} %{token_symbol}. To use dial *483*46#. For help 0757628885.
received_tokens: |-
Successfully received %{amount} %{token_symbol} from %{tx_sender_information} %{timestamp}. New balance is %{balance} %{token_symbol}.
terms: |-
By using the service, you agree to the terms and conditions at http://grassecon.org/tos
By using the service, you agree to the terms and conditions at https://www.grassrootseconomics.org/terms-and-conditions.

View File

@@ -1,7 +1,7 @@
sw:
account_successfully_created: |-
Umesajiliwa kwa huduma ya Sarafu! Kutumia bonyeza *384*96# Safaricom ama *483*46# kwa utandao tofauti. Kwa Usaidizi %{support_phone}.
Habari, umesajiliwa kwa huduma ya sarafu! Salio lako ni %{token_symbol} %{balance}. Kutumia bonyeza *483*46#. Kwa Usaidizi 0757628885.
received_tokens: |-
Umepokea %{amount} %{token_symbol} kutoka kwa %{tx_sender_information} %{timestamp}. Salio la %{token_symbol} ni %{balance}.
terms: |-
Kwa kutumia hii huduma, umekubali sheria na masharti yafuatayo http://grassecon.org/tos
Kwa kutumia hii huduma, umekubali sheria na masharti yafuatayo https://www.grassrootseconomics.org/terms-and-conditions.

View File

@@ -1,30 +1,29 @@
en:
kenya:
initial_language_selection: |-
CON Welcome to Sarafu Network
CON Welcome to Sarafu
1. English
2. Kiswahili
3. Help
initial_pin_entry: |-
CON Please enter a new four number PIN for your account.
CON Please enter a PIN to manage your account.
0. Back
initial_pin_confirmation: |-
CON Enter your four number PIN again
CON Enter your PIN again
0. Back
enter_given_name: |-
CON Enter first name
0. Back
enter_family_name: |-
CON Enter family name
CON Enter last name
0. Back
enter_gender: |-
CON Enter gender
1. Male
2. Female
3. Other
0. Back
enter_location: |-
CON Enter your location
CON Enter location
0. Back
enter_products: |-
CON Please enter a product or service you offer
@@ -76,10 +75,7 @@ en:
CON Enter current PIN. You have %{remaining_attempts} attempts remaining.
0. Back
enter_new_pin: |-
CON Enter your new four number PIN
0. Back
new_pin_confirmation: |-
CON Enter your new four number PIN again
CON Enter new PIN again
0. Back
transaction_pin_authorization:
first: |-
@@ -87,62 +83,34 @@ en:
Please enter your PIN to confirm.
0. Back
retry: |-
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining.
0. Back
display_metadata_pin_authorization:
first: |-
CON Please enter your PIN
CON Please enter your PIN.
0. Back
retry: |-
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining.
0. Back
account_balances_pin_authorization:
first: |-
CON Please enter your PIN to view balances
CON Please enter your PIN to view balances.
0. Back
retry: |-
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining.
0. Back
account_statement_pin_authorization:
first: |-
CON Please enter your PIN to view statement
CON Please enter your PIN to view statement.
0. Back
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
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}
fees: %{tax} %{token_symbol}
rewards: %{bonus} %{token_symbol}
taxes: %{tax} %{token_symbol}
bonsuses: %{bonus} %{token_symbol}
0. Back
first_transaction_set: |-
CON %{first_transaction_set}
@@ -172,9 +140,9 @@ en:
exit_pin_blocked: |-
END Your PIN has been blocked. For help, please call %{support_phone}.
exit_invalid_pin: |-
END The PIN you have entered is invalid. PIN must consist of 4 digits. For help, call %{support_phone}.
END The PIN you have entered is Invalid. PIN must consist of 4 digits. For help, call %{support_phone}.
exit_invalid_new_pin: |-
END The PIN you have entered is invalid. PIN must be different from your current PIN. For help, call %{support_phone}.
END The PIN you have entered is Invalid. PIN must be different from your current PIN. For help, call %{support_phone}.
exit_pin_mismatch: |-
END The new PIN does not match the one you entered. Please try again. For help, call %{support_phone}.
exit_invalid_recipient: |-
@@ -201,4 +169,4 @@ en:
00. Back
99. Exit
account_creation_prompt: |-
Your account is being created. You will receive an SMS when your account is ready.
Your account is being created. You will receive an SMS when your account is ready.

View File

@@ -1,12 +1,12 @@
sw:
kenya:
initial_language_selection: |-
CON Karibu Sarafu Network
CON Welcome to Sarafu
1. English
2. Kiswahili
3. Help
initial_pin_entry: |-
CON Tafadhali weka pin mpya yenye nambari nne kwa akaunti yako
CON Tafadhali weka PIN ili kudhibiti akaunti yako.
0. Nyuma
initial_pin_confirmation: |-
CON Weka PIN yako tena
@@ -21,13 +21,12 @@ sw:
CON Weka jinsia yako
1. Mwanaume
2. Mwanamke
3. Nyngine
0. Nyuma
enter_location: |-
CON Weka eneo lako
0. Nyuma
enter_products: |-
CON Weka bidhaa ama huduma unauza
CON Tafadhali weka bidhaa ama huduma unauza
0. Nyuma
start: |-
CON Salio %{account_balance} %{account_token_name}
@@ -61,7 +60,7 @@ sw:
Jina: %{full_name}
Jinsia: %{gender}
Eneo: %{location}
Unauza: %{products}
Unauza: %{user_bio}
0. Nyuma
select_preferred_language: |-
CON Chagua lugha
@@ -78,9 +77,6 @@ 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}.
@@ -89,9 +85,9 @@ sw:
retry: |-
CON Weka nambari ya siri. Una majaribio %{remaining_attempts} yaliyobaki.
0. Nyuma
display_metadata_pin_authorization:
standard_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.
@@ -110,40 +106,12 @@ 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} %{token_symbol}
ushuru: %{tax} %{token_symbol}
tuzo: %{bonus} %{token_symbol}
0. Nyuma
salio: %{operational_balance}
ushuru: %{tax}
tuzo: %{bonus}
0. Back
first_transaction_set: |-
CON %{first_transaction_set}
1. Mbele
@@ -187,7 +155,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 ina salio ifuatayo: %{token_balance}
Akaunti yako ya Sarafu-Network ina salio ifuatayo: %{token_balance}
00. Nyuma
99. Ondoka
invalid_service_code: |-
@@ -201,4 +169,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.

View File

@@ -171,7 +171,6 @@ if __name__ == '__main__':
logg.error('load error for {}: {}'.format(y, e))
continue
f.close()
logg.debug('deserializing {} {}'.format(filepath, o))
u = Person.deserialize(o)
new_address = register_eth(i, u)

View File

@@ -105,7 +105,7 @@ def genId(addr, typ):
def genDate():
ts = random.randint(ts_then, ts_now)
return int(datetime.datetime.fromtimestamp(ts).timestamp())
return datetime.datetime.fromtimestamp(ts).timestamp()
def genPhone():
@@ -193,7 +193,6 @@ def prepareLocalFilePath(datadir, address):
if __name__ == '__main__':
base_dir = os.path.join(user_dir, 'old')
ussd_dir = os.path.join(user_dir, 'ussd')
os.makedirs(base_dir, exist_ok=True)
fa = open(os.path.join(user_dir, 'balances.csv'), 'w')
@@ -224,8 +223,6 @@ if __name__ == '__main__':
f = open('{}/{}'.format(d, uid + '.json'), 'w')
json.dump(o.serialize(), f)
f.close()
d = prepareLocalFilePath(ussd_dir, uid)
x = open('{}/{}'.format(d, uid + '_ussd_data.json'), 'w')
json.dump(ussd_data, x)
x.close()

View File

@@ -23,7 +23,7 @@ from chainlib.eth.connection import EthHTTPConnection
from chainlib.eth.gas import RPCGasOracle
from chainlib.eth.nonce import RPCNonceOracle
from cic_types.processor import generate_metadata_pointer
from eth_accounts_index.registry import AccountRegistry
from eth_accounts_index import AccountRegistry
from eth_contract_registry import Registry
from crypto_dev_signer.keystore.dict import DictKeystore
from crypto_dev_signer.eth.signer.defaultsigner import ReferenceSigner as EIP155Signer

View File

@@ -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}
AFRICASTALKING_API_USERNAME: $AFRICASTALKING_API_USERNAME
AFRICASTALKING_API_KEY: $AFRICASTALKING_API_KEY
AFRICASTALKING_API_SENDER_ID: $AFRICASTALKING_API_SENDER_ID
TASKS_AFRICASTALKING: $TASKS_AFRICASTALKING
TASKS_SMS_DB: $TASKS_SMS_DB
TASKS_LOG: $TASKS_LOG
depends_on:
- postgres
- redis