Compare commits
55 Commits
bvander/mo
...
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
|
@@ -6,7 +6,6 @@ include:
|
|||||||
- local: 'apps/cic-notify/.gitlab-ci.yml'
|
- local: 'apps/cic-notify/.gitlab-ci.yml'
|
||||||
- local: 'apps/cic-meta/.gitlab-ci.yml'
|
- local: 'apps/cic-meta/.gitlab-ci.yml'
|
||||||
- local: 'apps/cic-cache/.gitlab-ci.yml'
|
- local: 'apps/cic-cache/.gitlab-ci.yml'
|
||||||
- local: 'apps/data-seeding/.gitlab-ci.yml'
|
|
||||||
|
|
||||||
stages:
|
stages:
|
||||||
- build
|
- build
|
||||||
|
|||||||
@@ -72,7 +72,9 @@ class CallbackFilter(SyncFilter):
|
|||||||
#transfer_data['token_address'] = tx.inputs[0]
|
#transfer_data['token_address'] = tx.inputs[0]
|
||||||
faucet_contract = 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)
|
r = conn.do(o)
|
||||||
transfer_data['token_address'] = add_0x(c.parse_token(r))
|
transfer_data['token_address'] = add_0x(c.parse_token(r))
|
||||||
|
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import sys
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
# external imports
|
# external imports
|
||||||
from chainlib.eth.erc20 import ERC20
|
from eth_erc20 import ERC20
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_eth.api import Api
|
from cic_eth.api import Api
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ from chainlib.eth.tx import (
|
|||||||
Tx,
|
Tx,
|
||||||
)
|
)
|
||||||
from chainlib.eth.block import Block
|
from chainlib.eth.block import Block
|
||||||
from chainlib.eth.erc20 import ERC20
|
from eth_erc20 import ERC20
|
||||||
from sarafu_faucet import MinterFaucet
|
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 potaahto.symbols import snake_and_camel
|
||||||
from hexathon import add_0x
|
from hexathon import add_0x
|
||||||
|
|
||||||
@@ -26,7 +26,6 @@ from cic_eth.runnable.daemons.filters.callback import CallbackFilter
|
|||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip()
|
|
||||||
def test_transfer_tx(
|
def test_transfer_tx(
|
||||||
default_chain_spec,
|
default_chain_spec,
|
||||||
init_database,
|
init_database,
|
||||||
@@ -66,7 +65,6 @@ def test_transfer_tx(
|
|||||||
assert transfer_type == 'transfer'
|
assert transfer_type == 'transfer'
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.skip()
|
|
||||||
def test_transfer_from_tx(
|
def test_transfer_from_tx(
|
||||||
default_chain_spec,
|
default_chain_spec,
|
||||||
init_database,
|
init_database,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import logging
|
|||||||
# external imports
|
# external imports
|
||||||
import pytest
|
import pytest
|
||||||
from chainlib.eth.nonce import RPCNonceOracle
|
from chainlib.eth.nonce import RPCNonceOracle
|
||||||
from chainlib.eth.erc20 import ERC20
|
from eth_erc20 import ERC20
|
||||||
from chainlib.eth.tx import receipt
|
from chainlib.eth.tx import receipt
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import celery
|
|||||||
from chainlib.connection import RPCConnection
|
from chainlib.connection import RPCConnection
|
||||||
from chainlib.eth.nonce import RPCNonceOracle
|
from chainlib.eth.nonce import RPCNonceOracle
|
||||||
from chainlib.eth.tx import receipt
|
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 hexathon import strip_0x
|
||||||
from chainqueue.db.enum import StatusEnum
|
from chainqueue.db.enum import StatusEnum
|
||||||
from chainqueue.db.models.otx import Otx
|
from chainqueue.db.models.otx import Otx
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import logging
|
|||||||
# external imports
|
# external imports
|
||||||
import pytest
|
import pytest
|
||||||
import celery
|
import celery
|
||||||
from chainlib.eth.erc20 import ERC20
|
from eth_erc20 import ERC20
|
||||||
from chainlib.eth.nonce import RPCNonceOracle
|
from chainlib.eth.nonce import RPCNonceOracle
|
||||||
from chainlib.eth.tx import (
|
from chainlib.eth.tx import (
|
||||||
receipt,
|
receipt,
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from chainlib.eth.nonce import RPCNonceOracle
|
|||||||
from chainlib.eth.tx import (
|
from chainlib.eth.tx import (
|
||||||
receipt,
|
receipt,
|
||||||
)
|
)
|
||||||
from eth_address_declarator import AddressDeclarator
|
from eth_address_declarator import Declarator
|
||||||
from hexathon import add_0x
|
from hexathon import add_0x
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
@@ -23,7 +23,7 @@ def test_translate(
|
|||||||
|
|
||||||
nonce_oracle = RPCNonceOracle(contract_roles['CONTRACT_DEPLOYER'], eth_rpc)
|
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()
|
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))
|
(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,
|
count,
|
||||||
receipt,
|
receipt,
|
||||||
)
|
)
|
||||||
from chainlib.eth.erc20 import ERC20
|
from eth_erc20 import ERC20
|
||||||
from chainlib.eth.nonce import RPCNonceOracle
|
from chainlib.eth.nonce import RPCNonceOracle
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ function handleNoMergeGet(db, digest, keystore) {
|
|||||||
doh(e);
|
doh(e);
|
||||||
});
|
});
|
||||||
}).catch((e) => {
|
}).catch((e) => {
|
||||||
console.error('mesage', e);
|
console.error('message', e);
|
||||||
doh(e);
|
doh(e);
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
@@ -46,7 +46,7 @@ function handleServerMergePost(data, db, digest, keystore, signer) {
|
|||||||
let e = undefined;
|
let e = undefined;
|
||||||
let s = undefined;
|
let s = undefined;
|
||||||
if (v === undefined) {
|
if (v === undefined) {
|
||||||
s = new Syncable(digest, data);
|
s = new Syncable(digest, o);
|
||||||
s.onwrap = (e) => {
|
s.onwrap = (e) => {
|
||||||
whohoo(e.toJSON());
|
whohoo(e.toJSON());
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -9,3 +9,7 @@ class AlreadyInitializedError(Exception):
|
|||||||
class PleaseCommitFirstError(Exception):
|
class PleaseCommitFirstError(Exception):
|
||||||
"""Raised when there exists uncommitted changes in the code while trying to build out the package."""
|
"""Raised when there exists uncommitted changes in the code while trying to build out the package."""
|
||||||
pass
|
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
|
import africastalking
|
||||||
|
|
||||||
# local imports
|
# 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()
|
logg = logging.getLogger()
|
||||||
celery_app = celery.current_app
|
celery_app = celery.current_app
|
||||||
@@ -50,10 +51,27 @@ class AfricasTalkingNotifier:
|
|||||||
if self.sender_id:
|
if self.sender_id:
|
||||||
response = self.api_client.send(message=message, recipients=[recipient], sender_id=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}')
|
logg.debug(f'Africastalking response sender-id {response}')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
response = self.api_client.send(message=message, recipients=[recipient])
|
response = self.api_client.send(message=message, recipients=[recipient])
|
||||||
logg.debug(f'africastalking response no-sender-id {response}')
|
logg.debug(f'africastalking response no-sender-id {response}')
|
||||||
|
|
||||||
|
recipients = response.get('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
|
@celery_app.task
|
||||||
def send(message, recipient):
|
def send(message, recipient):
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import semver
|
|||||||
|
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
|
|
||||||
version = (0, 4, 0, 'alpha.4')
|
version = (0, 4, 0, 'alpha.5')
|
||||||
|
|
||||||
version_object = semver.VersionInfo(
|
version_object = semver.VersionInfo(
|
||||||
major=version[0],
|
major=version[0],
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ packages =
|
|||||||
cic_notify
|
cic_notify
|
||||||
cic_notify.db
|
cic_notify.db
|
||||||
cic_notify.db.models
|
cic_notify.db.models
|
||||||
|
cic_notify.ext
|
||||||
cic_notify.tasks.sms
|
cic_notify.tasks.sms
|
||||||
cic_notify.runnable
|
cic_notify.runnable
|
||||||
scripts =
|
scripts =
|
||||||
|
|||||||
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",
|
"description": "Menu to display a user's entire profile",
|
||||||
"display_key": "ussd.kenya.display_user_metadata",
|
"display_key": "ussd.kenya.display_user_metadata",
|
||||||
"name": "display_user_metadata",
|
"name": "display_user_metadata",
|
||||||
"parent": "account_management"
|
"parent": "metadata_management"
|
||||||
},
|
},
|
||||||
"41": {
|
"41": {
|
||||||
"description": "The recipient is not in the system",
|
"description": "The recipient is not in the system",
|
||||||
"display_key": "ussd.kenya.exit_invalid_recipient",
|
"display_key": "ussd.kenya.exit_invalid_recipient",
|
||||||
"name": "exit_invalid_recipient",
|
"name": "exit_invalid_recipient",
|
||||||
"parent": null
|
"parent": null
|
||||||
|
},
|
||||||
|
"42": {
|
||||||
|
"description": "Pin entry menu for changing name data.",
|
||||||
|
"display_key": "ussd.kenya.name_edit_pin_authorization",
|
||||||
|
"name": "name_edit_pin_authorization",
|
||||||
|
"parent": "metadata_management"
|
||||||
|
},
|
||||||
|
"43": {
|
||||||
|
"description": "Pin entry menu for changing gender data.",
|
||||||
|
"display_key": "ussd.kenya.gender_edit_pin_authorization",
|
||||||
|
"name": "gender_edit_pin_authorization",
|
||||||
|
"parent": "metadata_management"
|
||||||
|
},
|
||||||
|
"44": {
|
||||||
|
"description": "Pin entry menu for changing location data.",
|
||||||
|
"display_key": "ussd.kenya.location_edit_pin_authorization",
|
||||||
|
"name": "location_edit_pin_authorization",
|
||||||
|
"parent": "metadata_management"
|
||||||
|
},
|
||||||
|
"45": {
|
||||||
|
"description": "Pin entry menu for changing products data.",
|
||||||
|
"display_key": "ussd.kenya.products_edit_pin_authorization",
|
||||||
|
"name": "products_edit_pin_authorization",
|
||||||
|
"parent": "metadata_management"
|
||||||
|
},
|
||||||
|
"46": {
|
||||||
|
"description": "Pin confirmation for pin change.",
|
||||||
|
"display_key": "ussd.kenya.new_pin_confirmation",
|
||||||
|
"name": "new_pin_confirmation",
|
||||||
|
"parent": "metadata_management"
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -78,31 +78,30 @@ class MetadataRequestsHandler(Metadata):
|
|||||||
:param data: The data to be stored in the metadata server.
|
:param data: The data to be stored in the metadata server.
|
||||||
:type data: dict|str
|
:type data: dict|str
|
||||||
"""
|
"""
|
||||||
data = json.dumps(data).encode('utf-8')
|
data = json.dumps(data)
|
||||||
result = make_request(method='POST', url=self.url, data=data, headers=self.headers)
|
result = make_request(method='POST', url=self.url, data=data, headers=self.headers)
|
||||||
metadata_http_error_handler(result=result)
|
metadata_http_error_handler(result=result)
|
||||||
metadata = result.content
|
metadata = result.json()
|
||||||
self.edit(data=metadata)
|
self.edit(data=metadata)
|
||||||
|
|
||||||
def edit(self, data: bytes):
|
def edit(self, data: Union[Dict, str]):
|
||||||
""" This function is responsible for editing data in the metadata server corresponding to a unique pointer.
|
""" This function is responsible for editing data in the metadata server corresponding to a unique pointer.
|
||||||
:param data: The data to be edited in the metadata server.
|
:param data: The data to be edited in the metadata server.
|
||||||
:type data: bytes
|
:type data: dict
|
||||||
"""
|
"""
|
||||||
cic_meta_signer = Signer()
|
cic_meta_signer = Signer()
|
||||||
signature = cic_meta_signer.sign_digest(data=data)
|
signature = cic_meta_signer.sign_digest(data=data)
|
||||||
algorithm = cic_meta_signer.get_operational_key().get('algo')
|
algorithm = cic_meta_signer.get_operational_key().get('algo')
|
||||||
decoded_data = data.decode('utf-8')
|
|
||||||
formatted_data = {
|
formatted_data = {
|
||||||
'm': data.decode('utf-8'),
|
'm': json.dumps(data),
|
||||||
's': {
|
's': {
|
||||||
'engine': self.engine,
|
'engine': self.engine,
|
||||||
'algo': algorithm,
|
'algo': algorithm,
|
||||||
'data': signature,
|
'data': signature,
|
||||||
'digest': json.loads(data).get('digest'),
|
'digest': data.get('digest'),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
formatted_data = json.dumps(formatted_data).encode('utf-8')
|
formatted_data = json.dumps(formatted_data)
|
||||||
result = make_request(method='PUT', url=self.url, data=formatted_data, headers=self.headers)
|
result = make_request(method='PUT', url=self.url, data=formatted_data, headers=self.headers)
|
||||||
logg.info(f'signed metadata submission status: {result.status_code}.')
|
logg.info(f'signed metadata submission status: {result.status_code}.')
|
||||||
metadata_http_error_handler(result=result)
|
metadata_http_error_handler(result=result)
|
||||||
@@ -110,17 +109,32 @@ class MetadataRequestsHandler(Metadata):
|
|||||||
decoded_identifier = self.identifier.decode("utf-8")
|
decoded_identifier = self.identifier.decode("utf-8")
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
decoded_identifier = self.identifier.hex()
|
decoded_identifier = self.identifier.hex()
|
||||||
logg.info(f'identifier: {decoded_identifier}. metadata pointer: {self.metadata_pointer} set to: {decoded_data}.')
|
logg.info(f'identifier: {decoded_identifier}. metadata pointer: {self.metadata_pointer} set to: {data}.')
|
||||||
|
|
||||||
def query(self):
|
def query(self):
|
||||||
"""This function is responsible for querying the metadata server for data corresponding to a unique pointer."""
|
"""
|
||||||
|
:return:
|
||||||
|
:rtype:
|
||||||
|
"""
|
||||||
|
# retrieve the metadata
|
||||||
result = make_request(method='GET', url=self.url)
|
result = make_request(method='GET', url=self.url)
|
||||||
metadata_http_error_handler(result=result)
|
metadata_http_error_handler(result=result)
|
||||||
response_data = result.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':
|
if result.status_code == 200 and self.cic_type == ':cic.person':
|
||||||
|
# validate person metadata
|
||||||
person = Person()
|
person = Person()
|
||||||
deserialized_person = person.deserialize(person_data=data)
|
person_data = person.deserialize(person_data=result_data)
|
||||||
data = json.dumps(deserialized_person.serialize())
|
|
||||||
cache_data(self.metadata_pointer, data=data)
|
# format new person data for caching
|
||||||
|
data = json.dumps(person_data.serialize())
|
||||||
|
|
||||||
|
# cache metadata
|
||||||
|
cache_data(key=self.metadata_pointer, data=data)
|
||||||
logg.debug(f'caching: {data} with key: {self.metadata_pointer}')
|
logg.debug(f'caching: {data} with key: {self.metadata_pointer}')
|
||||||
|
|||||||
@@ -47,14 +47,13 @@ class Signer:
|
|||||||
logg.debug(f'using signing key: {key_id}, algorithm: {key_algorithm}')
|
logg.debug(f'using signing key: {key_id}, algorithm: {key_algorithm}')
|
||||||
return gpg_keys[0]
|
return gpg_keys[0]
|
||||||
|
|
||||||
def sign_digest(self, data: bytes):
|
def sign_digest(self, data: dict):
|
||||||
"""
|
"""
|
||||||
:param data:
|
:param data:
|
||||||
:type data:
|
:type data:
|
||||||
:return:
|
:return:
|
||||||
:rtype:
|
:rtype:
|
||||||
"""
|
"""
|
||||||
data = json.loads(data)
|
|
||||||
digest = data['digest']
|
digest = data['digest']
|
||||||
key_id = self.get_operational_key().get('keyid')
|
key_id = self.get_operational_key().get('keyid')
|
||||||
signature = self.gpg.sign(digest, passphrase=self.gpg_passphrase, keyid=key_id)
|
signature = self.gpg.sign(digest, passphrase=self.gpg_passphrase, keyid=key_id)
|
||||||
|
|||||||
@@ -251,9 +251,9 @@ def process_display_user_metadata(user: Account, display_key: str):
|
|||||||
identifier=blockchain_address_to_metadata_pointer(blockchain_address=user.blockchain_address),
|
identifier=blockchain_address_to_metadata_pointer(blockchain_address=user.blockchain_address),
|
||||||
cic_type=':cic.person'
|
cic_type=':cic.person'
|
||||||
)
|
)
|
||||||
user_metadata = get_cached_data(key)
|
cached_metadata = get_cached_data(key)
|
||||||
if user_metadata:
|
if cached_metadata:
|
||||||
user_metadata = json.loads(user_metadata)
|
user_metadata = json.loads(cached_metadata)
|
||||||
contact_data = get_contact_data_from_vcard(vcard=user_metadata.get('vcard'))
|
contact_data = get_contact_data_from_vcard(vcard=user_metadata.get('vcard'))
|
||||||
logg.debug(f'{contact_data}')
|
logg.debug(f'{contact_data}')
|
||||||
full_name = f'{contact_data.get("given")} {contact_data.get("family")}'
|
full_name = f'{contact_data.get("given")} {contact_data.get("family")}'
|
||||||
@@ -433,7 +433,8 @@ def process_request(user_input: str, user: Account, ussd_session: Optional[dict]
|
|||||||
'exit_invalid_pin',
|
'exit_invalid_pin',
|
||||||
'exit_invalid_new_pin',
|
'exit_invalid_new_pin',
|
||||||
'exit_pin_mismatch',
|
'exit_pin_mismatch',
|
||||||
'exit_invalid_request'
|
'exit_invalid_request',
|
||||||
|
'exit_successful_transaction'
|
||||||
] and person_metadata is not None:
|
] and person_metadata is not None:
|
||||||
return UssdMenu.find_by_name(name='start')
|
return UssdMenu.find_by_name(name='start')
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import bcrypt
|
|||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from cic_ussd.db.models.account import AccountStatus, Account
|
from cic_ussd.db.models.account import AccountStatus, Account
|
||||||
from cic_ussd.encoder import PasswordEncoder, create_password_hash
|
from cic_ussd.encoder import PasswordEncoder, create_password_hash, check_password_hash
|
||||||
from cic_ussd.operations import persist_session_to_db_task, create_or_update_session
|
from cic_ussd.operations import persist_session_to_db_task, create_or_update_session
|
||||||
from cic_ussd.redis import InMemoryStore
|
from cic_ussd.redis import InMemoryStore
|
||||||
|
|
||||||
@@ -78,6 +78,10 @@ def save_initial_pin_to_session_data(state_machine_data: Tuple[str, dict, Accoun
|
|||||||
|
|
||||||
# set initial pin data
|
# set initial pin data
|
||||||
initial_pin = create_password_hash(user_input)
|
initial_pin = create_password_hash(user_input)
|
||||||
|
if ussd_session.get('session_data'):
|
||||||
|
session_data = ussd_session.get('session_data')
|
||||||
|
session_data['initial_pin'] = initial_pin
|
||||||
|
else:
|
||||||
session_data = {
|
session_data = {
|
||||||
'initial_pin': initial_pin
|
'initial_pin': initial_pin
|
||||||
}
|
}
|
||||||
@@ -103,9 +107,8 @@ def pins_match(state_machine_data: Tuple[str, dict, Account]) -> bool:
|
|||||||
"""
|
"""
|
||||||
user_input, ussd_session, user = state_machine_data
|
user_input, ussd_session, user = state_machine_data
|
||||||
initial_pin = ussd_session.get('session_data').get('initial_pin')
|
initial_pin = ussd_session.get('session_data').get('initial_pin')
|
||||||
fernet = PasswordEncoder(PasswordEncoder.key)
|
logg.debug(f'USSD SESSION: {ussd_session}')
|
||||||
initial_pin = fernet.decrypt(initial_pin.encode())
|
return check_password_hash(user_input, initial_pin)
|
||||||
return bcrypt.checkpw(user_input.encode(), initial_pin)
|
|
||||||
|
|
||||||
|
|
||||||
def complete_pin_change(state_machine_data: Tuple[str, dict, Account]):
|
def complete_pin_change(state_machine_data: Tuple[str, dict, Account]):
|
||||||
|
|||||||
@@ -64,13 +64,17 @@ def process_gender_user_input(user: Account, user_input: str):
|
|||||||
if user.preferred_language == 'en':
|
if user.preferred_language == 'en':
|
||||||
if user_input == '1':
|
if user_input == '1':
|
||||||
gender = 'Male'
|
gender = 'Male'
|
||||||
else:
|
elif user_input == '2':
|
||||||
gender = 'Female'
|
gender = 'Female'
|
||||||
|
elif user_input == '3':
|
||||||
|
gender = 'Other'
|
||||||
else:
|
else:
|
||||||
if user_input == '1':
|
if user_input == '1':
|
||||||
gender = 'Mwanaume'
|
gender = 'Mwanaume'
|
||||||
else:
|
elif user_input == '2':
|
||||||
gender = 'Mwanamke'
|
gender = 'Mwanamke'
|
||||||
|
elif user_input == '3':
|
||||||
|
gender = 'Nyingine'
|
||||||
return gender
|
return gender
|
||||||
|
|
||||||
|
|
||||||
@@ -88,14 +92,18 @@ def save_metadata_attribute_to_session_data(state_machine_data: Tuple[str, dict,
|
|||||||
key = ''
|
key = ''
|
||||||
if 'given_name' in current_state:
|
if 'given_name' in current_state:
|
||||||
key = 'given_name'
|
key = 'given_name'
|
||||||
elif 'family_name' in current_state:
|
|
||||||
|
if 'family_name' in current_state:
|
||||||
key = 'family_name'
|
key = 'family_name'
|
||||||
elif 'gender' in current_state:
|
|
||||||
|
if 'gender' in current_state:
|
||||||
key = 'gender'
|
key = 'gender'
|
||||||
user_input = process_gender_user_input(user=user, user_input=user_input)
|
user_input = process_gender_user_input(user=user, user_input=user_input)
|
||||||
elif 'location' in current_state:
|
|
||||||
|
if 'location' in current_state:
|
||||||
key = 'location'
|
key = 'location'
|
||||||
elif 'products' in current_state:
|
|
||||||
|
if 'products' in current_state:
|
||||||
key = 'products'
|
key = 'products'
|
||||||
|
|
||||||
# check if there is existing session data
|
# check if there is existing session data
|
||||||
@@ -121,12 +129,20 @@ def format_user_metadata(metadata: dict, user: Account):
|
|||||||
gender = metadata.get('gender')
|
gender = metadata.get('gender')
|
||||||
given_name = metadata.get('given_name')
|
given_name = metadata.get('given_name')
|
||||||
family_name = metadata.get('family_name')
|
family_name = metadata.get('family_name')
|
||||||
|
|
||||||
|
# check whether there's existing location data
|
||||||
|
if isinstance(metadata.get('location'), dict):
|
||||||
|
location = metadata.get('location')
|
||||||
|
else:
|
||||||
location = {
|
location = {
|
||||||
"area_name": metadata.get('location')
|
"area_name": metadata.get('location')
|
||||||
}
|
}
|
||||||
products = []
|
# check whether it is a list
|
||||||
if metadata.get('products'):
|
if isinstance(metadata.get('products'), list):
|
||||||
|
products = metadata.get('products')
|
||||||
|
else:
|
||||||
products = metadata.get('products').split(',')
|
products = metadata.get('products').split(',')
|
||||||
|
|
||||||
phone_number = user.phone_number
|
phone_number = user.phone_number
|
||||||
date_registered = int(user.created.replace().timestamp())
|
date_registered = int(user.created.replace().timestamp())
|
||||||
blockchain_address = user.blockchain_address
|
blockchain_address = user.blockchain_address
|
||||||
@@ -192,28 +208,27 @@ def edit_user_metadata_attribute(state_machine_data: Tuple[str, dict, Account]):
|
|||||||
# validate user metadata
|
# validate user metadata
|
||||||
person = Person()
|
person = Person()
|
||||||
user_metadata = json.loads(user_metadata)
|
user_metadata = json.loads(user_metadata)
|
||||||
deserialized_person = person.deserialize(person_data=user_metadata)
|
|
||||||
|
|
||||||
# edit specific metadata attribute
|
# edit specific metadata attribute
|
||||||
if given_name:
|
if given_name:
|
||||||
deserialized_person.given_name = given_name
|
user_metadata['given_name'] = given_name
|
||||||
elif family_name:
|
if family_name:
|
||||||
deserialized_person.family_name = family_name
|
user_metadata['family_name'] = family_name
|
||||||
elif gender:
|
if gender:
|
||||||
deserialized_person.gender = gender
|
user_metadata['gender'] = gender
|
||||||
elif location:
|
if location:
|
||||||
# get existing location metadata:
|
# get existing location metadata:
|
||||||
location_data = user_metadata.get('location')
|
location_data = user_metadata.get('location')
|
||||||
location_data['area_name'] = location
|
location_data['area_name'] = location
|
||||||
deserialized_person.location = location_data
|
user_metadata['location'] = location_data
|
||||||
elif products:
|
if products:
|
||||||
deserialized_person.products = products
|
user_metadata['products'] = products
|
||||||
|
|
||||||
edited_metadata = deserialized_person.serialize()
|
user_metadata = format_user_metadata(metadata=user_metadata, user=user)
|
||||||
|
|
||||||
s_edit_person_metadata = celery.signature(
|
s_edit_person_metadata = celery.signature(
|
||||||
'cic_ussd.tasks.metadata.edit_person_metadata',
|
'cic_ussd.tasks.metadata.create_person_metadata',
|
||||||
[blockchain_address, edited_metadata]
|
[blockchain_address, user_metadata]
|
||||||
)
|
)
|
||||||
s_edit_person_metadata.apply_async(queue='cic-ussd')
|
s_edit_person_metadata.apply_async(queue='cic-ussd')
|
||||||
|
|
||||||
|
|||||||
@@ -19,4 +19,6 @@ def translation_for(key: str, preferred_language: Optional[str] = None, **kwargs
|
|||||||
"""
|
"""
|
||||||
if preferred_language:
|
if preferred_language:
|
||||||
i18n.set('locale', preferred_language)
|
i18n.set('locale', preferred_language)
|
||||||
|
else:
|
||||||
|
i18n.set('locale', i18n.config.get('fallback'))
|
||||||
return i18n.t(key, **kwargs)
|
return i18n.t(key, **kwargs)
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
cic_base[full_graph]~=0.1.2b2
|
cic_base[full_graph]~=0.1.2b2
|
||||||
cic-eth~=0.11.0b9
|
cic-eth~=0.11.0b9
|
||||||
cic-notify~=0.4.0a4
|
cic-notify~=0.4.0a5
|
||||||
cic-types~=0.1.0a10
|
cic-types~=0.1.0a10
|
||||||
|
|||||||
@@ -6,7 +6,10 @@
|
|||||||
"enter_new_pin",
|
"enter_new_pin",
|
||||||
"new_pin_confirmation",
|
"new_pin_confirmation",
|
||||||
"display_user_metadata",
|
"display_user_metadata",
|
||||||
"standard_pin_authorization",
|
"name_edit_pin_authorization",
|
||||||
|
"gender_edit_pin_authorization",
|
||||||
|
"location_edit_pin_authorization",
|
||||||
|
"products_edit_pin_authorization",
|
||||||
"account_balances_pin_authorization",
|
"account_balances_pin_authorization",
|
||||||
"account_statement_pin_authorization",
|
"account_statement_pin_authorization",
|
||||||
"account_balances"
|
"account_balances"
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
pytest==6.0.1
|
Faker==8.1.2
|
||||||
|
faker-e164==0.1.0
|
||||||
|
pytest==6.2.4
|
||||||
pytest-alembic==0.2.5
|
pytest-alembic==0.2.5
|
||||||
pytest-celery==0.0.0a1
|
pytest-celery==0.0.0a1
|
||||||
pytest-cov==2.10.1
|
pytest-cov==2.10.1
|
||||||
pytest-mock==3.3.1
|
pytest-mock==3.3.1
|
||||||
|
pytest-ordering==0.6
|
||||||
pytest-redis==2.0.0
|
pytest-redis==2.0.0
|
||||||
requests-mock==1.8.0
|
requests-mock==1.8.0
|
||||||
|
tavern==1.14.2
|
||||||
@@ -6,6 +6,7 @@ from cic_types.pytest import *
|
|||||||
from tests.fixtures.config import *
|
from tests.fixtures.config import *
|
||||||
from tests.fixtures.db import *
|
from tests.fixtures.db import *
|
||||||
from tests.fixtures.celery import *
|
from tests.fixtures.celery import *
|
||||||
|
from tests.fixtures.integration import *
|
||||||
from tests.fixtures.user import *
|
from tests.fixtures.user import *
|
||||||
from tests.fixtures.ussd_session import *
|
from tests.fixtures.ussd_session import *
|
||||||
from tests.fixtures.redis import *
|
from tests.fixtures.redis import *
|
||||||
|
|||||||
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",
|
"source": "enter_gender",
|
||||||
"dest": "enter_location",
|
"dest": "enter_location",
|
||||||
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
||||||
"conditions": "cic_ussd.state_machine.logic.validator.is_valid_gender_selection"
|
"conditions": "cic_ussd.state_machine.logic.validator.is_valid_gender_selection",
|
||||||
|
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "enter_gender",
|
"source": "enter_gender",
|
||||||
"dest": "standard_pin_authorization",
|
"dest": "gender_edit_pin_authorization",
|
||||||
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
||||||
"conditions": [
|
"conditions": [
|
||||||
"cic_ussd.state_machine.logic.validator.has_cached_user_metadata",
|
"cic_ussd.state_machine.logic.validator.has_cached_user_metadata",
|
||||||
@@ -18,15 +19,14 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "standard_pin_authorization",
|
"source": "gender_edit_pin_authorization",
|
||||||
"dest": "exit",
|
"dest": "exit",
|
||||||
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
|
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
|
||||||
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute",
|
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
|
||||||
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "standard_pin_authorization",
|
"source": "gender_edit_pin_authorization",
|
||||||
"dest": "exit_pin_blocked",
|
"dest": "exit_pin_blocked",
|
||||||
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
|
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -3,26 +3,26 @@
|
|||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "enter_location",
|
"source": "enter_location",
|
||||||
"dest": "enter_products",
|
"dest": "enter_products",
|
||||||
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data"
|
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
||||||
|
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "enter_location",
|
"source": "enter_location",
|
||||||
"dest": "standard_pin_authorization",
|
"dest": "location_edit_pin_authorization",
|
||||||
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
||||||
"conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
"conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "standard_pin_authorization",
|
"source": "location_edit_pin_authorization",
|
||||||
"dest": "exit",
|
"dest": "exit",
|
||||||
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
|
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
|
||||||
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute",
|
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
|
||||||
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "standard_pin_authorization",
|
"source": "location_edit_pin_authorization",
|
||||||
"dest": "exit_pin_blocked",
|
"dest": "exit_pin_blocked",
|
||||||
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
|
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,49 +7,28 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "enter_given_name",
|
"source": "enter_family_name",
|
||||||
"dest": "standard_pin_authorization",
|
"dest": "name_edit_pin_authorization",
|
||||||
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
||||||
"conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
"conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"trigger": "scan_data",
|
|
||||||
"source": "standard_pin_authorization",
|
|
||||||
"dest": "exit",
|
|
||||||
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
|
|
||||||
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute",
|
|
||||||
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"trigger": "scan_data",
|
|
||||||
"source": "standard_pin_authorization",
|
|
||||||
"dest": "exit_pin_blocked",
|
|
||||||
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "enter_family_name",
|
"source": "enter_family_name",
|
||||||
"dest": "enter_gender",
|
"dest": "enter_gender",
|
||||||
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"trigger": "scan_data",
|
|
||||||
"source": "enter_family_name",
|
|
||||||
"dest": "standard_pin_authorization",
|
|
||||||
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
||||||
"conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"trigger": "scan_data",
|
|
||||||
"source": "standard_pin_authorization",
|
|
||||||
"dest": "exit",
|
|
||||||
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
|
|
||||||
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute",
|
|
||||||
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "standard_pin_authorization",
|
"source": "name_edit_pin_authorization",
|
||||||
|
"dest": "exit",
|
||||||
|
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
|
||||||
|
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"trigger": "scan_data",
|
||||||
|
"source": "name_edit_pin_authorization",
|
||||||
"dest": "exit_pin_blocked",
|
"dest": "exit_pin_blocked",
|
||||||
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
|
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,14 +9,14 @@
|
|||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "enter_current_pin",
|
"source": "enter_current_pin",
|
||||||
"dest": "exit_pin_blocked",
|
"dest": "exit_pin_blocked",
|
||||||
"conditions": "cic_ussd.state_machine.logic.menu.is_blocked_pin"
|
"conditions": "cic_ussd.state_machine.logic.pin.is_blocked_pin"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "enter_new_pin",
|
"source": "enter_new_pin",
|
||||||
"dest": "new_pin_confirmation",
|
"dest": "new_pin_confirmation",
|
||||||
"after": "cic_ussd.state_machine.logic.pin.save_initial_pin_to_session_data",
|
"after": "cic_ussd.state_machine.logic.pin.save_initial_pin_to_session_data",
|
||||||
"conditions": "cic_ussd.state_machine.logic.menu.is_valid_new_pin"
|
"conditions": "cic_ussd.state_machine.logic.pin.is_valid_new_pin"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
@@ -28,7 +28,7 @@
|
|||||||
"source": "new_pin_confirmation",
|
"source": "new_pin_confirmation",
|
||||||
"dest": "complete",
|
"dest": "complete",
|
||||||
"conditions": "cic_ussd.state_machine.logic.pin.pins_match",
|
"conditions": "cic_ussd.state_machine.logic.pin.pins_match",
|
||||||
"after": "cic_ussd.state_machine.logic.menu.complete_pin_change"
|
"after": "cic_ussd.state_machine.logic.pin.complete_pin_change"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "enter_products",
|
"source": "enter_products",
|
||||||
"dest": "standard_pin_authorization",
|
"dest": "products_edit_pin_authorization",
|
||||||
"conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata",
|
"conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata",
|
||||||
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data"
|
"after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data"
|
||||||
},
|
},
|
||||||
@@ -13,18 +13,19 @@
|
|||||||
"after": [
|
"after": [
|
||||||
"cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
"cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
|
||||||
"cic_ussd.state_machine.logic.user.save_complete_user_metadata"
|
"cic_ussd.state_machine.logic.user.save_complete_user_metadata"
|
||||||
]
|
],
|
||||||
|
"unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "standard_pin_authorization",
|
"source": "products_edit_pin_authorization",
|
||||||
"dest": "exit",
|
"dest": "exit",
|
||||||
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
|
"conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
|
||||||
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
|
"after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "standard_pin_authorization",
|
"source": "products_edit_pin_authorization",
|
||||||
"dest": "exit_pin_blocked",
|
"dest": "exit_pin_blocked",
|
||||||
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
|
"conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@
|
|||||||
{
|
{
|
||||||
"trigger": "scan_data",
|
"trigger": "scan_data",
|
||||||
"source": "metadata_management",
|
"source": "metadata_management",
|
||||||
"dest": "enter_age",
|
"dest": "enter_gender",
|
||||||
"conditions": "cic_ussd.state_machine.logic.menu.menu_two_selected"
|
"conditions": "cic_ussd.state_machine.logic.menu.menu_two_selected"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -76,7 +76,10 @@ en:
|
|||||||
CON Enter current PIN. You have %{remaining_attempts} attempts remaining.
|
CON Enter current PIN. You have %{remaining_attempts} attempts remaining.
|
||||||
0. Back
|
0. Back
|
||||||
enter_new_pin: |-
|
enter_new_pin: |-
|
||||||
CON Enter new PIN again
|
CON Enter your new four number PIN
|
||||||
|
0. Back
|
||||||
|
new_pin_confirmation: |-
|
||||||
|
CON Enter your new four number PIN again
|
||||||
0. Back
|
0. Back
|
||||||
transaction_pin_authorization:
|
transaction_pin_authorization:
|
||||||
first: |-
|
first: |-
|
||||||
@@ -107,6 +110,34 @@ en:
|
|||||||
retry: |-
|
retry: |-
|
||||||
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
|
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
|
||||||
0. Back
|
0. Back
|
||||||
|
name_edit_pin_authorization:
|
||||||
|
first: |-
|
||||||
|
CON Please enter your PIN
|
||||||
|
0. Back
|
||||||
|
retry: |-
|
||||||
|
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
|
||||||
|
0. Back
|
||||||
|
gender_edit_pin_authorization:
|
||||||
|
first: |-
|
||||||
|
CON Please enter your PIN
|
||||||
|
0. Back
|
||||||
|
retry: |-
|
||||||
|
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
|
||||||
|
0. Back
|
||||||
|
location_edit_pin_authorization:
|
||||||
|
first: |-
|
||||||
|
CON Please enter your PIN
|
||||||
|
0. Back
|
||||||
|
retry: |-
|
||||||
|
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
|
||||||
|
0. Back
|
||||||
|
products_edit_pin_authorization:
|
||||||
|
first: |-
|
||||||
|
CON Please enter your PIN
|
||||||
|
0. Back
|
||||||
|
retry: |-
|
||||||
|
CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
|
||||||
|
0. Back
|
||||||
account_balances: |-
|
account_balances: |-
|
||||||
CON Your balances are as follows:
|
CON Your balances are as follows:
|
||||||
balance: %{operational_balance} %{token_symbol}
|
balance: %{operational_balance} %{token_symbol}
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
sw:
|
sw:
|
||||||
kenya:
|
kenya:
|
||||||
initial_language_selection: |-
|
initial_language_selection: |-
|
||||||
CON Welcome to Sarafu
|
CON Karibu Sarafu Network
|
||||||
1. English
|
1. English
|
||||||
2. Kiswahili
|
2. Kiswahili
|
||||||
3. Help
|
3. Help
|
||||||
initial_pin_entry: |-
|
initial_pin_entry: |-
|
||||||
CON Tafadhali weka PIN ili kudhibiti akaunti yako.
|
CON Tafadhali weka pin mpya yenye nambari nne kwa akaunti yako
|
||||||
0. Nyuma
|
0. Nyuma
|
||||||
initial_pin_confirmation: |-
|
initial_pin_confirmation: |-
|
||||||
CON Weka PIN yako tena
|
CON Weka PIN yako tena
|
||||||
@@ -21,12 +21,13 @@ sw:
|
|||||||
CON Weka jinsia yako
|
CON Weka jinsia yako
|
||||||
1. Mwanaume
|
1. Mwanaume
|
||||||
2. Mwanamke
|
2. Mwanamke
|
||||||
|
3. Nyngine
|
||||||
0. Nyuma
|
0. Nyuma
|
||||||
enter_location: |-
|
enter_location: |-
|
||||||
CON Weka eneo lako
|
CON Weka eneo lako
|
||||||
0. Nyuma
|
0. Nyuma
|
||||||
enter_products: |-
|
enter_products: |-
|
||||||
CON Tafadhali weka bidhaa ama huduma unauza
|
CON Weka bidhaa ama huduma unauza
|
||||||
0. Nyuma
|
0. Nyuma
|
||||||
start: |-
|
start: |-
|
||||||
CON Salio %{account_balance} %{account_token_name}
|
CON Salio %{account_balance} %{account_token_name}
|
||||||
@@ -60,7 +61,7 @@ sw:
|
|||||||
Jina: %{full_name}
|
Jina: %{full_name}
|
||||||
Jinsia: %{gender}
|
Jinsia: %{gender}
|
||||||
Eneo: %{location}
|
Eneo: %{location}
|
||||||
Unauza: %{user_bio}
|
Unauza: %{products}
|
||||||
0. Nyuma
|
0. Nyuma
|
||||||
select_preferred_language: |-
|
select_preferred_language: |-
|
||||||
CON Chagua lugha
|
CON Chagua lugha
|
||||||
@@ -77,6 +78,9 @@ sw:
|
|||||||
enter_new_pin: |-
|
enter_new_pin: |-
|
||||||
CON Weka nambari ya siri mpya
|
CON Weka nambari ya siri mpya
|
||||||
0. Nyuma
|
0. Nyuma
|
||||||
|
new_pin_confirmation: |-
|
||||||
|
CON Weka PIN yako tena
|
||||||
|
0. Nyuma
|
||||||
transaction_pin_authorization:
|
transaction_pin_authorization:
|
||||||
first: |-
|
first: |-
|
||||||
CON %{recipient_information} atapokea %{transaction_amount} %{token_symbol} kutoka kwa %{sender_information}.
|
CON %{recipient_information} atapokea %{transaction_amount} %{token_symbol} kutoka kwa %{sender_information}.
|
||||||
@@ -85,9 +89,9 @@ sw:
|
|||||||
retry: |-
|
retry: |-
|
||||||
CON Weka nambari ya siri. Una majaribio %{remaining_attempts} yaliyobaki.
|
CON Weka nambari ya siri. Una majaribio %{remaining_attempts} yaliyobaki.
|
||||||
0. Nyuma
|
0. Nyuma
|
||||||
standard_pin_authorization:
|
display_metadata_pin_authorization:
|
||||||
first: |-
|
first: |-
|
||||||
CON Tafadhali weka PIN yako.
|
CON Tafadhali weka PIN yako
|
||||||
0. Nyuma
|
0. Nyuma
|
||||||
retry: |-
|
retry: |-
|
||||||
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
|
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
|
||||||
@@ -106,12 +110,40 @@ sw:
|
|||||||
retry: |-
|
retry: |-
|
||||||
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
|
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
|
||||||
0. Nyuma
|
0. Nyuma
|
||||||
|
name_edit_pin_authorization:
|
||||||
|
first: |-
|
||||||
|
CON Tafadhali weka PIN yako
|
||||||
|
0. Nyuma
|
||||||
|
retry: |-
|
||||||
|
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
|
||||||
|
0. Nyuma
|
||||||
|
gender_edit_pin_authorization:
|
||||||
|
first: |-
|
||||||
|
CON Tafadhali weka PIN yako
|
||||||
|
0. Nyuma
|
||||||
|
retry: |-
|
||||||
|
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
|
||||||
|
0. Nyuma
|
||||||
|
location_edit_pin_authorization:
|
||||||
|
first: |-
|
||||||
|
CON Tafadhali weka PIN yako
|
||||||
|
0. Nyuma
|
||||||
|
retry: |-
|
||||||
|
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
|
||||||
|
0. Nyuma
|
||||||
|
products_edit_pin_authorization:
|
||||||
|
first: |-
|
||||||
|
CON Tafadhali weka PIN yako
|
||||||
|
0. Nyuma
|
||||||
|
retry: |-
|
||||||
|
CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
|
||||||
|
0. Nyuma
|
||||||
account_balances: |-
|
account_balances: |-
|
||||||
CON Salio zako ni zifuatazo:
|
CON Salio zako ni zifuatazo:
|
||||||
salio: %{operational_balance}
|
salio: %{operational_balance} %{token_symbol}
|
||||||
ushuru: %{tax}
|
ushuru: %{tax} %{token_symbol}
|
||||||
tuzo: %{bonus}
|
tuzo: %{bonus} %{token_symbol}
|
||||||
0. Back
|
0. Nyuma
|
||||||
first_transaction_set: |-
|
first_transaction_set: |-
|
||||||
CON %{first_transaction_set}
|
CON %{first_transaction_set}
|
||||||
1. Mbele
|
1. Mbele
|
||||||
@@ -155,7 +187,7 @@ sw:
|
|||||||
99. Ondoka
|
99. Ondoka
|
||||||
exit_insufficient_balance: |-
|
exit_insufficient_balance: |-
|
||||||
CON Malipo ya %{amount} %{token_symbol} kwa %{recipient_information} halijakamilika kwa sababu salio lako haitoshi.
|
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
|
00. Nyuma
|
||||||
99. Ondoka
|
99. Ondoka
|
||||||
invalid_service_code: |-
|
invalid_service_code: |-
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ COPY contract-migration/testdata/pgp testdata/pgp
|
|||||||
COPY contract-migration/sarafu_declaration.json sarafu_declaration.json
|
COPY contract-migration/sarafu_declaration.json sarafu_declaration.json
|
||||||
COPY contract-migration/keystore keystore
|
COPY contract-migration/keystore keystore
|
||||||
COPY contract-migration/envlist .
|
COPY contract-migration/envlist .
|
||||||
|
COPY contract-migration/scripts scripts/
|
||||||
|
|
||||||
# A shared output dir for environment configs
|
# A shared output dir for environment configs
|
||||||
RUN mkdir -p /tmp/cic/config
|
RUN mkdir -p /tmp/cic/config
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
cic-base[full_graph]==0.1.2b11
|
cic-base[full_graph]==0.1.2b9
|
||||||
sarafu-faucet==0.0.3a3
|
sarafu-faucet==0.0.3a3
|
||||||
cic-eth==0.11.0b14
|
cic-eth==0.11.0b13
|
||||||
cic-types==0.1.0a11
|
cic-types==0.1.0a11
|
||||||
crypto-dev-signer==0.4.14b3
|
crypto-dev-signer==0.4.14b3
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
.data_seeding_variables:
|
|
||||||
variables:
|
|
||||||
APP_NAME: data-seeding
|
|
||||||
DOCKERFILE_PATH: $APP_NAME/docker/Dockerfile
|
|
||||||
|
|
||||||
.data_seeding_changes_target:
|
|
||||||
rules:
|
|
||||||
- changes:
|
|
||||||
- $CONTEXT/$APP_NAME/*
|
|
||||||
|
|
||||||
build-mr-contract-migration:
|
|
||||||
extends:
|
|
||||||
- .data_seeding_changes_target
|
|
||||||
- .py_build_merge_request
|
|
||||||
- .data_seeding_variables
|
|
||||||
|
|
||||||
build-push-contract-migration:
|
|
||||||
extends:
|
|
||||||
- .py_build_push
|
|
||||||
- .data_seeding_variables
|
|
||||||
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
# syntax = docker/dockerfile:1.2
|
|
||||||
FROM python:3.8.6-slim-buster as compile-image
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y --no-install-recommends git gcc g++ libpq-dev gawk jq telnet wget openssl iputils-ping gnupg socat bash procps make python2 cargo
|
|
||||||
|
|
||||||
WORKDIR /root
|
|
||||||
RUN mkdir -vp /usr/local/etc/cic
|
|
||||||
|
|
||||||
COPY data-seeding/requirements.txt .
|
|
||||||
|
|
||||||
ARG EXTRA_INDEX_URL="https://pip.grassrootseconomics.net:8433"
|
|
||||||
RUN pip install --extra-index-url $EXTRA_INDEX_URL -r requirements.txt
|
|
||||||
|
|
||||||
# -------------- begin runtime container ----------------
|
|
||||||
FROM python:3.8.6-slim-buster as runtime-image
|
|
||||||
|
|
||||||
RUN apt-get update
|
|
||||||
RUN apt-get install -y --no-install-recommends gnupg libpq-dev
|
|
||||||
RUN apt-get install -y jq bash iputils-ping socat telnet dnsutils
|
|
||||||
|
|
||||||
COPY --from=compile-image /usr/local/bin/ /usr/local/bin/
|
|
||||||
COPY --from=compile-image /usr/local/etc/cic/ /usr/local/etc/cic/
|
|
||||||
COPY --from=compile-image /usr/local/lib/python3.8/site-packages/ \
|
|
||||||
/usr/local/lib/python3.8/site-packages/
|
|
||||||
|
|
||||||
WORKDIR root/
|
|
||||||
|
|
||||||
ENV EXTRA_INDEX_URL https://pip.grassrootseconomics.net:8433
|
|
||||||
# RUN useradd -u 1001 --create-home grassroots
|
|
||||||
# RUN adduser grassroots sudo && \
|
|
||||||
# echo '%sudo ALL=(ALL) NOPASSWD:ALL' >> /etc/sudoers
|
|
||||||
# WORKDIR /home/grassroots
|
|
||||||
|
|
||||||
COPY data-seeding/ .
|
|
||||||
|
|
||||||
# we copied these from the root build container.
|
|
||||||
# this is dumb though...I guess the compile image should have the same user
|
|
||||||
# RUN chown grassroots:grassroots -R /usr/local/lib/python3.8/site-packages/
|
|
||||||
|
|
||||||
# USER grassroots
|
|
||||||
|
|
||||||
ENTRYPOINT [ ]
|
|
||||||
@@ -446,9 +446,9 @@ services:
|
|||||||
PGPASSWORD: ${DATABASE_PASSWORD:-tralala}
|
PGPASSWORD: ${DATABASE_PASSWORD:-tralala}
|
||||||
CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://redis}
|
CELERY_BROKER_URL: ${CELERY_BROKER_URL:-redis://redis}
|
||||||
CELERY_RESULT_URL: ${CELERY_BROKER_URL:-redis://redis}
|
CELERY_RESULT_URL: ${CELERY_BROKER_URL:-redis://redis}
|
||||||
TASKS_AFRICASTALKING: $TASKS_AFRICASTALKING
|
AFRICASTALKING_API_USERNAME: $AFRICASTALKING_API_USERNAME
|
||||||
TASKS_SMS_DB: $TASKS_SMS_DB
|
AFRICASTALKING_API_KEY: $AFRICASTALKING_API_KEY
|
||||||
TASKS_LOG: $TASKS_LOG
|
AFRICASTALKING_API_SENDER_ID: $AFRICASTALKING_API_SENDER_ID
|
||||||
depends_on:
|
depends_on:
|
||||||
- postgres
|
- postgres
|
||||||
- redis
|
- redis
|
||||||
|
|||||||
Reference in New Issue
Block a user