Merge branch 'philip/management-integration-tests' into 'master'
Philip/management integration tests See merge request grassrootseconomics/cic-internal-integration!159
This commit is contained in:
		
						commit
						1a931eced4
					
				@ -31,7 +31,7 @@ function handleNoMergeGet(db, digest, keystore) {
 | 
			
		||||
					doh(e);
 | 
			
		||||
				});
 | 
			
		||||
			}).catch((e) => {
 | 
			
		||||
				console.error('mesage', e);
 | 
			
		||||
				console.error('message', e);
 | 
			
		||||
				doh(e);
 | 
			
		||||
			});
 | 
			
		||||
		})
 | 
			
		||||
@ -46,7 +46,7 @@ function handleServerMergePost(data, db, digest, keystore, signer) {
 | 
			
		||||
			let e = undefined;
 | 
			
		||||
			let s = undefined;
 | 
			
		||||
			if (v === undefined) {
 | 
			
		||||
				s = new Syncable(digest, data);
 | 
			
		||||
				s = new Syncable(digest, o);
 | 
			
		||||
				s.onwrap = (e) => {
 | 
			
		||||
					whohoo(e.toJSON());
 | 
			
		||||
				};
 | 
			
		||||
 | 
			
		||||
@ -56,7 +56,7 @@ class AfricasTalkingNotifier:
 | 
			
		||||
            response = self.api_client.send(message=message, recipients=[recipient])
 | 
			
		||||
            logg.debug(f'africastalking response no-sender-id {response}')
 | 
			
		||||
 | 
			
		||||
        recipients = response.get('Recipients')
 | 
			
		||||
        recipients = response.get('SMSMessageData').get('Recipients')
 | 
			
		||||
 | 
			
		||||
        if len(recipients) != 1:
 | 
			
		||||
            status = response.get('SMSMessageData').get('Message')
 | 
			
		||||
 | 
			
		||||
@ -28,6 +28,7 @@ packages =
 | 
			
		||||
	cic_notify
 | 
			
		||||
	cic_notify.db
 | 
			
		||||
	cic_notify.db.models
 | 
			
		||||
	cic_notify.ext
 | 
			
		||||
	cic_notify.tasks.sms
 | 
			
		||||
	cic_notify.runnable
 | 
			
		||||
scripts =
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										4
									
								
								apps/cic-ussd/.config/test/integration.ini
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								apps/cic-ussd/.config/test/integration.ini
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,4 @@
 | 
			
		||||
[test]
 | 
			
		||||
gift_value = 50.00
 | 
			
		||||
server_url = http://localhost:63315/
 | 
			
		||||
token_symbol = GFT
 | 
			
		||||
@ -238,13 +238,43 @@
 | 
			
		||||
            "description": "Menu to display a user's entire profile",
 | 
			
		||||
            "display_key": "ussd.kenya.display_user_metadata",
 | 
			
		||||
            "name": "display_user_metadata",
 | 
			
		||||
            "parent": "account_management"
 | 
			
		||||
            "parent": "metadata_management"
 | 
			
		||||
        },
 | 
			
		||||
        "41": {
 | 
			
		||||
            "description": "The recipient is not in the system",
 | 
			
		||||
            "display_key": "ussd.kenya.exit_invalid_recipient",
 | 
			
		||||
            "name": "exit_invalid_recipient",
 | 
			
		||||
            "parent": null
 | 
			
		||||
        },
 | 
			
		||||
        "42": {
 | 
			
		||||
            "description": "Pin entry menu for changing name data.",
 | 
			
		||||
            "display_key": "ussd.kenya.name_edit_pin_authorization",
 | 
			
		||||
            "name": "name_edit_pin_authorization",
 | 
			
		||||
            "parent": "metadata_management"
 | 
			
		||||
        },
 | 
			
		||||
        "43": {
 | 
			
		||||
            "description": "Pin entry menu for changing gender data.",
 | 
			
		||||
            "display_key": "ussd.kenya.gender_edit_pin_authorization",
 | 
			
		||||
            "name": "gender_edit_pin_authorization",
 | 
			
		||||
            "parent": "metadata_management"
 | 
			
		||||
        },
 | 
			
		||||
        "44": {
 | 
			
		||||
            "description": "Pin entry menu for changing location data.",
 | 
			
		||||
            "display_key": "ussd.kenya.location_edit_pin_authorization",
 | 
			
		||||
            "name": "location_edit_pin_authorization",
 | 
			
		||||
            "parent": "metadata_management"
 | 
			
		||||
        },
 | 
			
		||||
        "45": {
 | 
			
		||||
            "description": "Pin entry menu for changing products data.",
 | 
			
		||||
            "display_key": "ussd.kenya.products_edit_pin_authorization",
 | 
			
		||||
            "name": "products_edit_pin_authorization",
 | 
			
		||||
            "parent": "metadata_management"
 | 
			
		||||
        },
 | 
			
		||||
        "46": {
 | 
			
		||||
            "description": "Pin confirmation for pin change.",
 | 
			
		||||
            "display_key": "ussd.kenya.new_pin_confirmation",
 | 
			
		||||
            "name": "new_pin_confirmation",
 | 
			
		||||
            "parent": "metadata_management"
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -78,28 +78,27 @@ class MetadataRequestsHandler(Metadata):
 | 
			
		||||
        :param data: The data to be stored in the metadata server.
 | 
			
		||||
        :type data: dict|str
 | 
			
		||||
        """
 | 
			
		||||
        data = json.dumps(data).encode('utf-8')
 | 
			
		||||
        data = json.dumps(data)
 | 
			
		||||
        result = make_request(method='POST', url=self.url, data=data, headers=self.headers)
 | 
			
		||||
        metadata_http_error_handler(result=result)
 | 
			
		||||
        metadata = result.content
 | 
			
		||||
        metadata = result.json()
 | 
			
		||||
        self.edit(data=metadata)
 | 
			
		||||
 | 
			
		||||
    def edit(self, data: bytes):
 | 
			
		||||
    def edit(self, data: Union[Dict, str]):
 | 
			
		||||
        """ This function is responsible for editing data in the metadata server corresponding to a unique pointer.
 | 
			
		||||
        :param data: The data to be edited in the metadata server.
 | 
			
		||||
        :type data: bytes
 | 
			
		||||
        :type data: dict
 | 
			
		||||
        """
 | 
			
		||||
        cic_meta_signer = Signer()
 | 
			
		||||
        signature = cic_meta_signer.sign_digest(data=data)
 | 
			
		||||
        algorithm = cic_meta_signer.get_operational_key().get('algo')
 | 
			
		||||
        decoded_data = data.decode('utf-8')
 | 
			
		||||
        formatted_data = {
 | 
			
		||||
            'm': data.decode('utf-8'),
 | 
			
		||||
            'm': json.dumps(data),
 | 
			
		||||
            's': {
 | 
			
		||||
                'engine': self.engine,
 | 
			
		||||
                'algo': algorithm,
 | 
			
		||||
                'data': signature,
 | 
			
		||||
                'digest': json.loads(data).get('digest'),
 | 
			
		||||
                'digest': data.get('digest'),
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        formatted_data = json.dumps(formatted_data)
 | 
			
		||||
@ -110,19 +109,32 @@ class MetadataRequestsHandler(Metadata):
 | 
			
		||||
            decoded_identifier = self.identifier.decode("utf-8")
 | 
			
		||||
        except UnicodeDecodeError:
 | 
			
		||||
            decoded_identifier = self.identifier.hex()
 | 
			
		||||
        logg.info(f'identifier: {decoded_identifier}. metadata pointer: {self.metadata_pointer} set to: {decoded_data}.')
 | 
			
		||||
        logg.info(f'identifier: {decoded_identifier}. metadata pointer: {self.metadata_pointer} set to: {data}.')
 | 
			
		||||
 | 
			
		||||
    def query(self):
 | 
			
		||||
        """This function is responsible for querying the metadata server for data corresponding to a unique pointer."""
 | 
			
		||||
        """
 | 
			
		||||
        :return:
 | 
			
		||||
        :rtype:
 | 
			
		||||
        """
 | 
			
		||||
        # retrieve the  metadata
 | 
			
		||||
        result = make_request(method='GET', url=self.url)
 | 
			
		||||
        metadata_http_error_handler(result=result)
 | 
			
		||||
        response_data = result.json()
 | 
			
		||||
        data = json.loads(response_data)
 | 
			
		||||
        if not isinstance(data, dict):
 | 
			
		||||
            raise ValueError(f'Invalid data object: {data}.')
 | 
			
		||||
 | 
			
		||||
        # json serialize retrieved data
 | 
			
		||||
        result_data = result.json()
 | 
			
		||||
 | 
			
		||||
        # validate result data format
 | 
			
		||||
        if not isinstance(result_data, dict):
 | 
			
		||||
            raise ValueError(f'Invalid result data object: {result_data}.')
 | 
			
		||||
 | 
			
		||||
        if result.status_code == 200 and self.cic_type == ':cic.person':
 | 
			
		||||
            # validate person metadata
 | 
			
		||||
            person = Person()
 | 
			
		||||
            deserialized_person = person.deserialize(person_data=data)
 | 
			
		||||
            data = json.dumps(deserialized_person.serialize())
 | 
			
		||||
            cache_data(self.metadata_pointer, data=data)
 | 
			
		||||
            person_data = person.deserialize(person_data=result_data)
 | 
			
		||||
 | 
			
		||||
            # format new person data for caching
 | 
			
		||||
            data = json.dumps(person_data.serialize())
 | 
			
		||||
 | 
			
		||||
            # cache metadata
 | 
			
		||||
            cache_data(key=self.metadata_pointer, data=data)
 | 
			
		||||
            logg.debug(f'caching: {data} with key: {self.metadata_pointer}')
 | 
			
		||||
 | 
			
		||||
@ -47,14 +47,13 @@ class Signer:
 | 
			
		||||
        logg.debug(f'using signing key: {key_id}, algorithm: {key_algorithm}')
 | 
			
		||||
        return gpg_keys[0]
 | 
			
		||||
 | 
			
		||||
    def sign_digest(self, data: bytes):
 | 
			
		||||
    def sign_digest(self, data: dict):
 | 
			
		||||
        """
 | 
			
		||||
        :param data:
 | 
			
		||||
        :type data:
 | 
			
		||||
        :return:
 | 
			
		||||
        :rtype:
 | 
			
		||||
        """
 | 
			
		||||
        data = json.loads(data)
 | 
			
		||||
        digest = data['digest']
 | 
			
		||||
        key_id = self.get_operational_key().get('keyid')
 | 
			
		||||
        signature = self.gpg.sign(digest, passphrase=self.gpg_passphrase, keyid=key_id)
 | 
			
		||||
 | 
			
		||||
@ -251,9 +251,9 @@ def process_display_user_metadata(user: Account, display_key: str):
 | 
			
		||||
        identifier=blockchain_address_to_metadata_pointer(blockchain_address=user.blockchain_address),
 | 
			
		||||
        cic_type=':cic.person'
 | 
			
		||||
    )
 | 
			
		||||
    user_metadata = get_cached_data(key)
 | 
			
		||||
    if user_metadata:
 | 
			
		||||
        user_metadata = json.loads(user_metadata)
 | 
			
		||||
    cached_metadata = get_cached_data(key)
 | 
			
		||||
    if cached_metadata:
 | 
			
		||||
        user_metadata = json.loads(cached_metadata)
 | 
			
		||||
        contact_data = get_contact_data_from_vcard(vcard=user_metadata.get('vcard'))
 | 
			
		||||
        logg.debug(f'{contact_data}')
 | 
			
		||||
        full_name = f'{contact_data.get("given")} {contact_data.get("family")}'
 | 
			
		||||
@ -433,7 +433,8 @@ def process_request(user_input: str, user: Account, ussd_session: Optional[dict]
 | 
			
		||||
                    'exit_invalid_pin',
 | 
			
		||||
                    'exit_invalid_new_pin',
 | 
			
		||||
                    'exit_pin_mismatch',
 | 
			
		||||
                    'exit_invalid_request'
 | 
			
		||||
                    'exit_invalid_request',
 | 
			
		||||
                    'exit_successful_transaction'
 | 
			
		||||
                ] and person_metadata is not None:
 | 
			
		||||
                    return UssdMenu.find_by_name(name='start')
 | 
			
		||||
                else:
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@ import bcrypt
 | 
			
		||||
 | 
			
		||||
# local imports
 | 
			
		||||
from cic_ussd.db.models.account import AccountStatus, Account
 | 
			
		||||
from cic_ussd.encoder import PasswordEncoder, create_password_hash
 | 
			
		||||
from cic_ussd.encoder import PasswordEncoder, create_password_hash, check_password_hash
 | 
			
		||||
from cic_ussd.operations import persist_session_to_db_task, create_or_update_session
 | 
			
		||||
from cic_ussd.redis import InMemoryStore
 | 
			
		||||
 | 
			
		||||
@ -78,9 +78,13 @@ def save_initial_pin_to_session_data(state_machine_data: Tuple[str, dict, Accoun
 | 
			
		||||
 | 
			
		||||
    # set initial pin data
 | 
			
		||||
    initial_pin = create_password_hash(user_input)
 | 
			
		||||
    session_data = {
 | 
			
		||||
        'initial_pin': initial_pin
 | 
			
		||||
    }
 | 
			
		||||
    if ussd_session.get('session_data'):
 | 
			
		||||
        session_data = ussd_session.get('session_data')
 | 
			
		||||
        session_data['initial_pin'] = initial_pin
 | 
			
		||||
    else:
 | 
			
		||||
        session_data = {
 | 
			
		||||
            'initial_pin': initial_pin
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
    # create new in memory ussd session with current ussd session data
 | 
			
		||||
    create_or_update_session(
 | 
			
		||||
@ -103,9 +107,8 @@ def pins_match(state_machine_data: Tuple[str, dict, Account]) -> bool:
 | 
			
		||||
    """
 | 
			
		||||
    user_input, ussd_session, user = state_machine_data
 | 
			
		||||
    initial_pin = ussd_session.get('session_data').get('initial_pin')
 | 
			
		||||
    fernet = PasswordEncoder(PasswordEncoder.key)
 | 
			
		||||
    initial_pin = fernet.decrypt(initial_pin.encode())
 | 
			
		||||
    return bcrypt.checkpw(user_input.encode(), initial_pin)
 | 
			
		||||
    logg.debug(f'USSD SESSION:  {ussd_session}')
 | 
			
		||||
    return check_password_hash(user_input, initial_pin)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def complete_pin_change(state_machine_data: Tuple[str, dict, Account]):
 | 
			
		||||
 | 
			
		||||
@ -64,13 +64,17 @@ def process_gender_user_input(user: Account, user_input: str):
 | 
			
		||||
    if user.preferred_language == 'en':
 | 
			
		||||
        if user_input == '1':
 | 
			
		||||
            gender = 'Male'
 | 
			
		||||
        else:
 | 
			
		||||
        elif user_input == '2':
 | 
			
		||||
            gender = 'Female'
 | 
			
		||||
        elif user_input == '3':
 | 
			
		||||
            gender = 'Other'
 | 
			
		||||
    else:
 | 
			
		||||
        if user_input == '1':
 | 
			
		||||
            gender = 'Mwanaume'
 | 
			
		||||
        else:
 | 
			
		||||
        elif user_input == '2':
 | 
			
		||||
            gender = 'Mwanamke'
 | 
			
		||||
        elif user_input == '3':
 | 
			
		||||
            gender = 'Nyingine'
 | 
			
		||||
    return gender
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -88,14 +92,18 @@ def save_metadata_attribute_to_session_data(state_machine_data: Tuple[str, dict,
 | 
			
		||||
    key = ''
 | 
			
		||||
    if 'given_name' in current_state:
 | 
			
		||||
        key = 'given_name'
 | 
			
		||||
    elif 'family_name' in current_state:
 | 
			
		||||
 | 
			
		||||
    if 'family_name' in current_state:
 | 
			
		||||
        key = 'family_name'
 | 
			
		||||
    elif 'gender' in current_state:
 | 
			
		||||
 | 
			
		||||
    if 'gender' in current_state:
 | 
			
		||||
        key = 'gender'
 | 
			
		||||
        user_input = process_gender_user_input(user=user, user_input=user_input)
 | 
			
		||||
    elif 'location' in current_state:
 | 
			
		||||
 | 
			
		||||
    if 'location' in current_state:
 | 
			
		||||
        key = 'location'
 | 
			
		||||
    elif 'products' in current_state:
 | 
			
		||||
 | 
			
		||||
    if 'products' in current_state:
 | 
			
		||||
        key = 'products'
 | 
			
		||||
 | 
			
		||||
    # check if there is existing session data
 | 
			
		||||
@ -121,12 +129,20 @@ def format_user_metadata(metadata: dict, user: Account):
 | 
			
		||||
    gender = metadata.get('gender')
 | 
			
		||||
    given_name = metadata.get('given_name')
 | 
			
		||||
    family_name = metadata.get('family_name')
 | 
			
		||||
    location = {
 | 
			
		||||
        "area_name": metadata.get('location')
 | 
			
		||||
    }
 | 
			
		||||
    products = []
 | 
			
		||||
    if metadata.get('products'):
 | 
			
		||||
 | 
			
		||||
    # check whether there's existing location data
 | 
			
		||||
    if isinstance(metadata.get('location'), dict):
 | 
			
		||||
        location = metadata.get('location')
 | 
			
		||||
    else:
 | 
			
		||||
        location = {
 | 
			
		||||
            "area_name": metadata.get('location')
 | 
			
		||||
        }
 | 
			
		||||
    # check whether it is a list
 | 
			
		||||
    if isinstance(metadata.get('products'), list):
 | 
			
		||||
        products = metadata.get('products')
 | 
			
		||||
    else:
 | 
			
		||||
        products = metadata.get('products').split(',')
 | 
			
		||||
 | 
			
		||||
    phone_number = user.phone_number
 | 
			
		||||
    date_registered = int(user.created.replace().timestamp())
 | 
			
		||||
    blockchain_address = user.blockchain_address
 | 
			
		||||
@ -192,28 +208,27 @@ def edit_user_metadata_attribute(state_machine_data: Tuple[str, dict, Account]):
 | 
			
		||||
    # validate user metadata
 | 
			
		||||
    person = Person()
 | 
			
		||||
    user_metadata = json.loads(user_metadata)
 | 
			
		||||
    deserialized_person = person.deserialize(person_data=user_metadata)
 | 
			
		||||
 | 
			
		||||
    # edit specific metadata attribute
 | 
			
		||||
    if given_name:
 | 
			
		||||
        deserialized_person.given_name = given_name
 | 
			
		||||
    elif family_name:
 | 
			
		||||
        deserialized_person.family_name = family_name
 | 
			
		||||
    elif gender:
 | 
			
		||||
        deserialized_person.gender = gender
 | 
			
		||||
    elif location:
 | 
			
		||||
        user_metadata['given_name'] = given_name
 | 
			
		||||
    if family_name:
 | 
			
		||||
        user_metadata['family_name'] = family_name
 | 
			
		||||
    if gender:
 | 
			
		||||
        user_metadata['gender'] = gender
 | 
			
		||||
    if location:
 | 
			
		||||
        # get existing location metadata:
 | 
			
		||||
        location_data = user_metadata.get('location')
 | 
			
		||||
        location_data['area_name'] = location
 | 
			
		||||
        deserialized_person.location = location_data
 | 
			
		||||
    elif products:
 | 
			
		||||
        deserialized_person.products = products
 | 
			
		||||
        user_metadata['location'] = location_data
 | 
			
		||||
    if products:
 | 
			
		||||
        user_metadata['products'] = products
 | 
			
		||||
 | 
			
		||||
    edited_metadata = deserialized_person.serialize()
 | 
			
		||||
    user_metadata = format_user_metadata(metadata=user_metadata, user=user)
 | 
			
		||||
 | 
			
		||||
    s_edit_person_metadata = celery.signature(
 | 
			
		||||
        'cic_ussd.tasks.metadata.edit_person_metadata',
 | 
			
		||||
        [blockchain_address, edited_metadata]
 | 
			
		||||
        'cic_ussd.tasks.metadata.create_person_metadata',
 | 
			
		||||
        [blockchain_address, user_metadata]
 | 
			
		||||
    )
 | 
			
		||||
    s_edit_person_metadata.apply_async(queue='cic-ussd')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -19,4 +19,6 @@ def translation_for(key: str, preferred_language: Optional[str] = None, **kwargs
 | 
			
		||||
    """
 | 
			
		||||
    if preferred_language:
 | 
			
		||||
        i18n.set('locale', preferred_language)
 | 
			
		||||
    else:
 | 
			
		||||
        i18n.set('locale', i18n.config.get('fallback'))
 | 
			
		||||
    return i18n.t(key, **kwargs)
 | 
			
		||||
 | 
			
		||||
@ -1,4 +1,4 @@
 | 
			
		||||
cic_base[full_graph]~=0.1.2b2
 | 
			
		||||
cic-eth~=0.11.0b9
 | 
			
		||||
cic-notify~=0.4.0a4
 | 
			
		||||
cic_base[full_graph]~=0.1.2b14
 | 
			
		||||
cic-eth~=0.11.0b15
 | 
			
		||||
cic-notify~=0.4.0a5
 | 
			
		||||
cic-types~=0.1.0a10
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,10 @@
 | 
			
		||||
  "enter_new_pin",
 | 
			
		||||
  "new_pin_confirmation",
 | 
			
		||||
  "display_user_metadata",
 | 
			
		||||
  "standard_pin_authorization",
 | 
			
		||||
  "name_edit_pin_authorization",
 | 
			
		||||
  "gender_edit_pin_authorization",
 | 
			
		||||
  "location_edit_pin_authorization",
 | 
			
		||||
  "products_edit_pin_authorization",
 | 
			
		||||
  "account_balances_pin_authorization",
 | 
			
		||||
  "account_statement_pin_authorization",
 | 
			
		||||
  "account_balances"
 | 
			
		||||
 | 
			
		||||
@ -1,7 +1,11 @@
 | 
			
		||||
pytest==6.0.1
 | 
			
		||||
Faker==8.1.2
 | 
			
		||||
faker-e164==0.1.0
 | 
			
		||||
pytest==6.2.4
 | 
			
		||||
pytest-alembic==0.2.5
 | 
			
		||||
pytest-celery==0.0.0a1
 | 
			
		||||
pytest-cov==2.10.1
 | 
			
		||||
pytest-mock==3.3.1
 | 
			
		||||
pytest-ordering==0.6
 | 
			
		||||
pytest-redis==2.0.0
 | 
			
		||||
requests-mock==1.8.0
 | 
			
		||||
requests-mock==1.8.0
 | 
			
		||||
tavern==1.14.2
 | 
			
		||||
@ -6,6 +6,7 @@ from cic_types.pytest import *
 | 
			
		||||
from tests.fixtures.config import *
 | 
			
		||||
from tests.fixtures.db import *
 | 
			
		||||
from tests.fixtures.celery import *
 | 
			
		||||
from tests.fixtures.integration import *
 | 
			
		||||
from tests.fixtures.user import *
 | 
			
		||||
from tests.fixtures.ussd_session import *
 | 
			
		||||
from tests.fixtures.redis import *
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										249
									
								
								apps/cic-ussd/tests/fixtures/integration.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										249
									
								
								apps/cic-ussd/tests/fixtures/integration.py
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,249 @@
 | 
			
		||||
# standard imports
 | 
			
		||||
 | 
			
		||||
# external imports
 | 
			
		||||
 | 
			
		||||
import pytest
 | 
			
		||||
from faker import Faker
 | 
			
		||||
 | 
			
		||||
# local imports
 | 
			
		||||
 | 
			
		||||
# test imports
 | 
			
		||||
from tests.helpers.accounts import phone_number, pin_number, session_id
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
fake = Faker()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='function')
 | 
			
		||||
def generate_phone_number() -> str:
 | 
			
		||||
    return phone_number()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='function')
 | 
			
		||||
def generate_session_id() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_account_phone_number() -> str:
 | 
			
		||||
    return phone_number()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_account_phone_number() -> str:
 | 
			
		||||
    return phone_number()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_account_pin_number() -> str:
 | 
			
		||||
    return pin_number()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_account_pin_number() -> str:
 | 
			
		||||
    return pin_number()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_metadata_entry_session_id() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_metadata_entry_session_id() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_transaction_session_id() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_transaction_session_id() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_account_given_name() -> str:
 | 
			
		||||
    return fake.first_name()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_account_given_name() -> str:
 | 
			
		||||
    return fake.first_name()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_account_family_name() -> str:
 | 
			
		||||
    return fake.last_name()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_account_family_name() -> str:
 | 
			
		||||
    return fake.last_name()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_account_location() -> str:
 | 
			
		||||
    return fake.city()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_account_location() -> str:
 | 
			
		||||
    return fake.city()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_account_product() -> str:
 | 
			
		||||
    return fake.color_name()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_account_product() -> str:
 | 
			
		||||
    return fake.color_name()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_account_verify_balance_session_id() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_account_verify_balance_session_id() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_profile_management_session_id() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_profile_management_session_id() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_account_change_given_name() -> str:
 | 
			
		||||
    return fake.first_name()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_account_change_given_name() -> str:
 | 
			
		||||
    return fake.first_name()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_account_change_family_name() -> str:
 | 
			
		||||
    return fake.last_name()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_account_change_family_name() -> str:
 | 
			
		||||
    return fake.last_name()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_account_change_location() -> str:
 | 
			
		||||
    return fake.city()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_account_change_location() -> str:
 | 
			
		||||
    return fake.city()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_account_change_product() -> str:
 | 
			
		||||
    return fake.color_name()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_account_change_product() -> str:
 | 
			
		||||
    return fake.color_name()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_profile_management_session_id_1() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_profile_management_session_id_1() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_profile_management_session_id_2() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_profile_management_session_id_2() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_profile_management_session_id_3() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_profile_management_session_id_3() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_profile_management_session_id_4() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_profile_management_session_id_4() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_account_management_session_id() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_account_management_session_id() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_account_management_session_id_1() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_account_management_session_id_1() -> str:
 | 
			
		||||
    return session_id()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def first_account_new_pin_number() -> str:
 | 
			
		||||
    return pin_number()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def second_account_new_pin_number() -> str:
 | 
			
		||||
    return pin_number()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def gift_value(load_config):
 | 
			
		||||
    return load_config.get('TEST_GIFT_VALUE')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def server_url(load_config):
 | 
			
		||||
    return load_config.get('TEST_SERVER_URL')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@pytest.fixture(scope='session')
 | 
			
		||||
def token_symbol(load_config):
 | 
			
		||||
    return load_config.get('TEST_TOKEN_SYMBOL')
 | 
			
		||||
							
								
								
									
										26
									
								
								apps/cic-ussd/tests/helpers/accounts.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								apps/cic-ussd/tests/helpers/accounts.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,26 @@
 | 
			
		||||
# standard imports
 | 
			
		||||
import random
 | 
			
		||||
import uuid
 | 
			
		||||
 | 
			
		||||
# external imports
 | 
			
		||||
from faker import Faker
 | 
			
		||||
from faker_e164.providers import E164Provider
 | 
			
		||||
 | 
			
		||||
# local imports
 | 
			
		||||
 | 
			
		||||
# test imports
 | 
			
		||||
 | 
			
		||||
fake = Faker()
 | 
			
		||||
fake.add_provider(E164Provider)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def phone_number() -> str:
 | 
			
		||||
    return fake.e164('KE')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def session_id() -> str:
 | 
			
		||||
    return uuid.uuid4().hex
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def pin_number() -> int:
 | 
			
		||||
    return random.randint(1000, 9999)
 | 
			
		||||
							
								
								
									
										11
									
								
								apps/cic-ussd/tests/integration/ext/validator.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								apps/cic-ussd/tests/integration/ext/validator.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,11 @@
 | 
			
		||||
import logging
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
logg = logging.getLogger()
 | 
			
		||||
logg.setLevel(logging.DEBUG)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def validate_response(response, expected_response):
 | 
			
		||||
    """Makes sure that the response received matches the expected response"""
 | 
			
		||||
    logg.debug(f'RESPONSE: {response.content.decode("utf-8")}')
 | 
			
		||||
    assert response.content.decode('utf-8') == expected_response
 | 
			
		||||
							
								
								
									
										2
									
								
								apps/cic-ussd/tests/integration/run.sh
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										2
									
								
								apps/cic-ussd/tests/integration/run.sh
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,2 @@
 | 
			
		||||
#!/bin/bash
 | 
			
		||||
PYTHONPATH=. py.test --debug -vv --log-level debug -s --log-cli-level debug
 | 
			
		||||
@ -0,0 +1,466 @@
 | 
			
		||||
test_name: Test the creation of accounts through the cic_user_ussd_server entrypoint.
 | 
			
		||||
marks:
 | 
			
		||||
  - usefixtures:
 | 
			
		||||
    - gift_value
 | 
			
		||||
    - server_url
 | 
			
		||||
    - token_symbol
 | 
			
		||||
    - generate_session_id
 | 
			
		||||
    - first_account_phone_number
 | 
			
		||||
    - second_account_phone_number
 | 
			
		||||
    - first_account_pin_number
 | 
			
		||||
    - second_account_pin_number
 | 
			
		||||
    - first_account_family_name
 | 
			
		||||
    - second_account_family_name
 | 
			
		||||
    - first_account_given_name
 | 
			
		||||
    - second_account_given_name
 | 
			
		||||
    - first_account_location
 | 
			
		||||
    - second_account_location
 | 
			
		||||
    - first_account_product
 | 
			
		||||
    - second_account_product
 | 
			
		||||
    - first_metadata_entry_session_id
 | 
			
		||||
    - second_metadata_entry_session_id
 | 
			
		||||
  - first
 | 
			
		||||
 | 
			
		||||
stages:
 | 
			
		||||
  - name: Initiate account creation process [first account].
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{generate_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: ""
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '175'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "END Your account is being created. You will receive an SMS when your account is ready.\nAkaunti yako ya Sarafu inatayarishwa. Utapokea ujumbe wa SMS akaunti yako ikiwa tayari.\n"
 | 
			
		||||
 | 
			
		||||
  - name: Initiate account creation process [second account].
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{generate_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: ""
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '175'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "END Your account is being created. You will receive an SMS when your account is ready.\nAkaunti yako ya Sarafu inatayarishwa. Utapokea ujumbe wa SMS akaunti yako ikiwa tayari.\n"
 | 
			
		||||
    delay_after: 5
 | 
			
		||||
 | 
			
		||||
  - name: Initaite account metadata entry [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: ""
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '61'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Welcome to Sarafu Network\n1. English\n2. Kiswahili\n3. Help"
 | 
			
		||||
 | 
			
		||||
  - name: Initaite account metadata entry [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: ""
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '61'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Welcome to Sarafu Network\n1. English\n2. Kiswahili\n3. Help"
 | 
			
		||||
 | 
			
		||||
  - name: Select preferred language [English]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "1"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '64'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Please enter a new four number PIN for your account.\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Select preferred language [Kiswahili]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '71'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Tafadhali weka pin mpya yenye nambari nne kwa akaunti yako\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Enter pin number [{first_account_pin_number} - first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "1*{first_account_pin_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '44'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Enter your four number PIN again\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Enter pin number [second_account_pin_number - second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*{second_account_pin_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '31'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Weka PIN yako tena\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Pin number confirmation [first_account_pin_number - first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "1*{first_account_pin_number}*{first_account_pin_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '28'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Enter first name\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Pin number confirmation [{second_account_pin_number} - second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*{second_account_pin_number}*{second_account_pin_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '37'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Weka jina lako la kwanza\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Enter first name [first_account_given_name - first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '29'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Enter family name\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Enter first name [second_account_given_name - second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '37'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Weka jina lako la mwisho\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Enter last name [first_account_family_name - first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '51'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Enter gender\n1. Male\n2. Female\n3. Other\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Enter last name [second_account_family_name - second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '64'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Weka jinsia yako\n1. Mwanaume\n2. Mwanamke\n3. Nyngine\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Select gender [Male - first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}*1"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '31'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Enter your location\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Select gender [Female - second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}*2"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '27'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Weka eneo lako\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Enter location [first_account_location - first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}*1*{first_account_location}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '55'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Please enter a product or service you offer\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Enter location [second_account_location - second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}*2*{second_account_location}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '42'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Weka bidhaa ama huduma unauza\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Enter product [first_account_product - first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "1*{first_account_pin_number}*{first_account_pin_number}*{first_account_given_name}*{first_account_family_name}*1*{first_account_location}*{first_account_product}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '51'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Balance {gift_value} {token_symbol}\n1. Send\n2. My Account\n3. Help"
 | 
			
		||||
    delay_before: 10
 | 
			
		||||
 | 
			
		||||
  - name: Enter product [second_account_product - second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_metadata_entry_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*{second_account_pin_number}*{second_account_pin_number}*{second_account_given_name}*{second_account_family_name}*2*{second_account_location}*{second_account_product}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '56'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Salio {gift_value} {token_symbol}\n1. Tuma\n2. Akaunti yangu\n3. Usaidizi"
 | 
			
		||||
    delay_before: 10
 | 
			
		||||
@ -0,0 +1,587 @@
 | 
			
		||||
test_name: Test performing account management operations.
 | 
			
		||||
marks:
 | 
			
		||||
  - usefixtures:
 | 
			
		||||
    - server_url
 | 
			
		||||
    - token_symbol
 | 
			
		||||
    - first_account_pin_number
 | 
			
		||||
    - second_account_pin_number
 | 
			
		||||
    - first_account_phone_number
 | 
			
		||||
    - second_account_phone_number
 | 
			
		||||
    - first_account_management_session_id
 | 
			
		||||
    - second_account_management_session_id
 | 
			
		||||
    - first_account_management_session_id_1
 | 
			
		||||
    - second_account_management_session_id_1
 | 
			
		||||
    - first_account_new_pin_number
 | 
			
		||||
    - second_account_new_pin_number
 | 
			
		||||
  - fourth
 | 
			
		||||
 | 
			
		||||
stages:
 | 
			
		||||
  - name: Account management start menu [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_account_management_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: ""
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '51'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Balance 58.00 {token_symbol}\n1. Send\n2. My Account\n3. Help"
 | 
			
		||||
 | 
			
		||||
  - name: Account management start menu [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_account_management_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: ""
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '56'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Salio 42.00 {token_symbol}\n1. Tuma\n2. Akaunti yangu\n3. Usaidizi"
 | 
			
		||||
 | 
			
		||||
  - name: Account management menu [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_account_management_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "2"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '105'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON My account\n1. My profile\n2. Change language\n3. Check balance\n4. Check statement\n5. Change PIN\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Account management menu [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_account_management_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '148'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Akaunti yangu\n1. Wasifu wangu\n2. Chagua lugha utakayotumia\n3. Angalia salio\n4. Angalia taarifa ya matumizi\n5. Badilisha nambari ya siri\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Language change [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_account_management_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "2*2"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '51'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Choose language\n1. English\n2. Kiswahili\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Language change [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_account_management_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*2"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '51'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Chagua lugha\n1. Kingereza\n2. Kiswahili\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Select language [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_account_management_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "2*2*2"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '30'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "END Asante kwa kutumia huduma."
 | 
			
		||||
 | 
			
		||||
  - name: Select language [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_account_management_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*2*1"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '36'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "END Thank you for using the service."
 | 
			
		||||
 | 
			
		||||
  - name: Second account management start menu [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: ""
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '56'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Salio 58.00 {token_symbol}\n1. Tuma\n2. Akaunti yangu\n3. Usaidizi"
 | 
			
		||||
 | 
			
		||||
  - name: Second account management start menu [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: ""
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '51'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Balance 42.00 {token_symbol}\n1. Send\n2. My Account\n3. Help"
 | 
			
		||||
 | 
			
		||||
  - name: Second account management menu [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "2"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '148'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Akaunti yangu\n1. Wasifu wangu\n2. Chagua lugha utakayotumia\n3. Angalia salio\n4. Angalia taarifa ya matumizi\n5. Badilisha nambari ya siri\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Second account management menu [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '105'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON My account\n1. My profile\n2. Change language\n3. Check balance\n4. Check statement\n5. Change PIN\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Check balance [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "2*3"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '49'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Tafadhali weka PIN yako kuona salio.\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Check balance [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*3"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '50'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Please enter your PIN to view balances\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Display balances [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "2*3*{first_account_pin_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Salio zako ni zifuatazo:\n  salio: 58.00 {token_symbol}\n  ushuru:  {token_symbol}\n  tuzo:  {token_symbol}\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Display balances [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*3*{second_account_pin_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Your balances are as follows:\n  balance: 42.00 {token_symbol}\n  fees:  {token_symbol}\n  rewards:  {token_symbol}\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Resume account management menu [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "2*3*{first_account_pin_number}*0"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '148'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Akaunti yangu\n1. Wasifu wangu\n2. Chagua lugha utakayotumia\n3. Angalia salio\n4. Angalia taarifa ya matumizi\n5. Badilisha nambari ya siri\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Resume account management menu [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*3*{second_account_pin_number}*0"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '105'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON My account\n1. My profile\n2. Change language\n3. Check balance\n4. Check statement\n5. Change PIN\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Change pin number [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "2*3*{first_account_pin_number}*0*5"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '34'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Weka nambari ya siri.\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Change pin number [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*3*{second_account_pin_number}*0*5"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '30'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Enter current PIN.\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Enter old pin [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "2*3*{first_account_pin_number}*0*5*{first_account_pin_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '38'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Weka nambari ya siri mpya\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Enter old pin [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*3*{second_account_pin_number}*0*5*{second_account_pin_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '42'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Enter your new four number PIN\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Enter new pin [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "2*3*{first_account_pin_number}*0*5*{first_account_pin_number}*{first_account_new_pin_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '31'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Weka PIN yako tena\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Enter new pin [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*3*{second_account_pin_number}*0*5*{second_account_pin_number}*{second_account_new_pin_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '48'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Enter your new four number PIN again\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Enter new pin confirmation [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "2*3*{first_account_pin_number}*0*5*{first_account_pin_number}*{first_account_new_pin_number}*{first_account_new_pin_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '91'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Ombi lako limetumwa. Utapokea uthibitishaji wa SMS kwa muda mfupi.\n00. Nyuma\n99. Ondoka"
 | 
			
		||||
 | 
			
		||||
  - name: Enter new pin confirmation [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_account_management_session_id_1}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "2*3*{second_account_pin_number}*0*5*{second_account_pin_number}*{second_account_new_pin_number}*{second_account_new_pin_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '82'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Your request has been sent. You will receive an SMS shortly.\n00. Back\n99. Exit"
 | 
			
		||||
							
								
								
									
										1573
									
								
								apps/cic-ussd/tests/integration/test_profile_management.tavern.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1573
									
								
								apps/cic-ussd/tests/integration/test_profile_management.tavern.yaml
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										282
									
								
								apps/cic-ussd/tests/integration/test_transactions.tavern.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										282
									
								
								apps/cic-ussd/tests/integration/test_transactions.tavern.yaml
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,282 @@
 | 
			
		||||
test_name: Test that the two test accounts can trade with each other.
 | 
			
		||||
marks:
 | 
			
		||||
  - usefixtures:
 | 
			
		||||
    - gift_value
 | 
			
		||||
    - server_url
 | 
			
		||||
    - token_symbol
 | 
			
		||||
    - first_account_family_name
 | 
			
		||||
    - second_account_family_name
 | 
			
		||||
    - first_account_given_name
 | 
			
		||||
    - second_account_given_name
 | 
			
		||||
    - first_account_phone_number
 | 
			
		||||
    - second_account_phone_number
 | 
			
		||||
    - first_account_pin_number
 | 
			
		||||
    - second_account_pin_number
 | 
			
		||||
    - first_transaction_session_id
 | 
			
		||||
    - second_transaction_session_id
 | 
			
		||||
    - first_account_verify_balance_session_id
 | 
			
		||||
    - second_account_verify_balance_session_id
 | 
			
		||||
  - second
 | 
			
		||||
 | 
			
		||||
stages:
 | 
			
		||||
  - name: Transactions start menu [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_transaction_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: ""
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '51'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Balance {gift_value} {token_symbol}\n1. Send\n2. My Account\n3. Help"
 | 
			
		||||
 | 
			
		||||
  - name: Transactions start menu [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_transaction_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: ""
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '56'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Salio {gift_value} {token_symbol}\n1. Tuma\n2. Akaunti yangu\n3. Usaidizi"
 | 
			
		||||
 | 
			
		||||
  - name: Initate transcation attempt [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_transaction_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "1"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '30'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Enter phone number\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Initate transcation attempt [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_transaction_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "1"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '33'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Weka nambari ya simu\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Enter phone number [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_transaction_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "1*{second_account_phone_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '24'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Enter amount\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Enter phone number [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_transaction_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "1*{first_account_phone_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '25'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Weka kiwango\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Enter transcation amount [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_transaction_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "1*{second_account_phone_number}*17"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON {second_account_given_name} {second_account_family_name} {second_account_phone_number} will receive 17.00 {token_symbol} from {first_account_given_name} {first_account_family_name} {first_account_phone_number}.\nPlease enter your PIN to confirm.\n0. Back"
 | 
			
		||||
 | 
			
		||||
  - name: Enter transcation amount [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_transaction_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "1*{first_account_phone_number}*25"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON {first_account_given_name} {first_account_family_name} {first_account_phone_number} atapokea 25.00 {token_symbol} kutoka kwa {second_account_given_name} {second_account_family_name} {second_account_phone_number}.\nTafadhali weka nambari yako ya siri kudhibitisha.\n0. Nyuma"
 | 
			
		||||
 | 
			
		||||
  - name: Pin to authorize transaction [first account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_transaction_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: "1*{second_account_phone_number}*17*{first_account_pin_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Your request has been sent. {second_account_given_name} {second_account_family_name} {second_account_phone_number} will receive 17.00 {token_symbol} from {first_account_given_name} {first_account_family_name} {first_account_phone_number}.\n00. Back\n99. Exit"
 | 
			
		||||
 | 
			
		||||
  - name: Pin to authorize transaction [second account]
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_transaction_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: "1*{first_account_phone_number}*25*{second_account_pin_number}"
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Ombi lako limetumwa. {first_account_given_name} {first_account_family_name} {first_account_phone_number} atapokea 25.00 {token_symbol} kutoka kwa {second_account_given_name} {second_account_family_name} {second_account_phone_number}.\n00. Nyuma\n99. Ondoka"
 | 
			
		||||
 | 
			
		||||
  - name: Verify balance changes [first account]
 | 
			
		||||
    delay_before: 10
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{first_account_verify_balance_session_id}"
 | 
			
		||||
        phoneNumber: "{first_account_phone_number}"
 | 
			
		||||
        text: ""
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '51'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Balance 58.00 {token_symbol}\n1. Send\n2. My Account\n3. Help"
 | 
			
		||||
 | 
			
		||||
  - name: Verify balance changes [second account]
 | 
			
		||||
    delay_before: 10
 | 
			
		||||
    request:
 | 
			
		||||
      url: "{server_url}"
 | 
			
		||||
      data:
 | 
			
		||||
        serviceCode: "*483*46#"
 | 
			
		||||
        sessionId: "{second_account_verify_balance_session_id}"
 | 
			
		||||
        phoneNumber: "{second_account_phone_number}"
 | 
			
		||||
        text: ""
 | 
			
		||||
      headers:
 | 
			
		||||
        content-type: "application/x-www-form-urlencoded"
 | 
			
		||||
      method: POST
 | 
			
		||||
    response:
 | 
			
		||||
      status_code:
 | 
			
		||||
        - 200
 | 
			
		||||
      headers:
 | 
			
		||||
        Content-Length: '56'
 | 
			
		||||
        Content-Type: "text/plain"
 | 
			
		||||
      verify_response_with:
 | 
			
		||||
        function: ext.validator:validate_response
 | 
			
		||||
        extra_kwargs:
 | 
			
		||||
          expected_response: "CON Salio 42.00 {token_symbol}\n1. Tuma\n2. Akaunti yangu\n3. Usaidizi"
 | 
			
		||||
@ -4,12 +4,13 @@
 | 
			
		||||
    "source": "enter_gender",
 | 
			
		||||
    "dest": "enter_location",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.validator.is_valid_gender_selection"
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.validator.is_valid_gender_selection",
 | 
			
		||||
    "unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "enter_gender",
 | 
			
		||||
    "dest": "standard_pin_authorization",
 | 
			
		||||
    "dest": "gender_edit_pin_authorization",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
 | 
			
		||||
    "conditions": [
 | 
			
		||||
      "cic_ussd.state_machine.logic.validator.has_cached_user_metadata",
 | 
			
		||||
@ -18,15 +19,14 @@
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "standard_pin_authorization",
 | 
			
		||||
    "source": "gender_edit_pin_authorization",
 | 
			
		||||
    "dest": "exit",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute",
 | 
			
		||||
    "unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "standard_pin_authorization",
 | 
			
		||||
    "source": "gender_edit_pin_authorization",
 | 
			
		||||
    "dest": "exit_pin_blocked",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
@ -3,26 +3,26 @@
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "enter_location",
 | 
			
		||||
    "dest": "enter_products",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data"
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
 | 
			
		||||
    "unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "enter_location",
 | 
			
		||||
    "dest": "standard_pin_authorization",
 | 
			
		||||
    "dest": "location_edit_pin_authorization",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "standard_pin_authorization",
 | 
			
		||||
    "source": "location_edit_pin_authorization",
 | 
			
		||||
    "dest": "exit",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute",
 | 
			
		||||
    "unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "standard_pin_authorization",
 | 
			
		||||
    "source": "location_edit_pin_authorization",
 | 
			
		||||
    "dest": "exit_pin_blocked",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -7,49 +7,28 @@
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "enter_given_name",
 | 
			
		||||
    "dest": "standard_pin_authorization",
 | 
			
		||||
    "source": "enter_family_name",
 | 
			
		||||
    "dest": "name_edit_pin_authorization",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "standard_pin_authorization",
 | 
			
		||||
    "dest": "exit",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute",
 | 
			
		||||
    "unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "standard_pin_authorization",
 | 
			
		||||
    "dest": "exit_pin_blocked",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "enter_family_name",
 | 
			
		||||
    "dest": "enter_gender",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "enter_family_name",
 | 
			
		||||
    "dest": "standard_pin_authorization",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "standard_pin_authorization",
 | 
			
		||||
    "dest": "exit",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute",
 | 
			
		||||
    "unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "standard_pin_authorization",
 | 
			
		||||
    "source": "name_edit_pin_authorization",
 | 
			
		||||
    "dest": "exit",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "name_edit_pin_authorization",
 | 
			
		||||
    "dest": "exit_pin_blocked",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -9,14 +9,14 @@
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "enter_current_pin",
 | 
			
		||||
    "dest": "exit_pin_blocked",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.menu.is_blocked_pin"
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.pin.is_blocked_pin"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "enter_new_pin",
 | 
			
		||||
    "dest": "new_pin_confirmation",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.pin.save_initial_pin_to_session_data",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.menu.is_valid_new_pin"
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.pin.is_valid_new_pin"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
@ -28,7 +28,7 @@
 | 
			
		||||
    "source": "new_pin_confirmation",
 | 
			
		||||
    "dest": "complete",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.pin.pins_match",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.menu.complete_pin_change"
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.pin.complete_pin_change"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,7 @@
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "enter_products",
 | 
			
		||||
    "dest": "standard_pin_authorization",
 | 
			
		||||
    "dest": "products_edit_pin_authorization",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data"
 | 
			
		||||
  },
 | 
			
		||||
@ -13,18 +13,19 @@
 | 
			
		||||
    "after": [
 | 
			
		||||
      "cic_ussd.state_machine.logic.user.save_metadata_attribute_to_session_data",
 | 
			
		||||
      "cic_ussd.state_machine.logic.user.save_complete_user_metadata"
 | 
			
		||||
    ]
 | 
			
		||||
    ],
 | 
			
		||||
    "unless": "cic_ussd.state_machine.logic.validator.has_cached_user_metadata"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "standard_pin_authorization",
 | 
			
		||||
    "source": "products_edit_pin_authorization",
 | 
			
		||||
    "dest": "exit",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.pin.is_authorized_pin",
 | 
			
		||||
    "after": "cic_ussd.state_machine.logic.user.edit_user_metadata_attribute"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "standard_pin_authorization",
 | 
			
		||||
    "source": "products_edit_pin_authorization",
 | 
			
		||||
    "dest": "exit_pin_blocked",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.pin.is_locked_account"
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -8,7 +8,7 @@
 | 
			
		||||
  {
 | 
			
		||||
    "trigger": "scan_data",
 | 
			
		||||
    "source": "metadata_management",
 | 
			
		||||
    "dest": "enter_age",
 | 
			
		||||
    "dest": "enter_gender",
 | 
			
		||||
    "conditions": "cic_ussd.state_machine.logic.menu.menu_two_selected"
 | 
			
		||||
  },
 | 
			
		||||
  {
 | 
			
		||||
 | 
			
		||||
@ -6,7 +6,7 @@ en:
 | 
			
		||||
      2. Kiswahili
 | 
			
		||||
      3. Help
 | 
			
		||||
    initial_pin_entry: |-
 | 
			
		||||
      CON Please enter a new four number PIN for your account. 
 | 
			
		||||
      CON Please enter a new four number PIN for your account.
 | 
			
		||||
      0. Back
 | 
			
		||||
    initial_pin_confirmation: |-
 | 
			
		||||
      CON Enter your four number PIN again
 | 
			
		||||
@ -76,7 +76,10 @@ en:
 | 
			
		||||
        CON Enter current PIN. You have %{remaining_attempts} attempts remaining.
 | 
			
		||||
        0. Back
 | 
			
		||||
    enter_new_pin: |-
 | 
			
		||||
      CON Enter new PIN again
 | 
			
		||||
      CON Enter your new four number PIN
 | 
			
		||||
      0. Back
 | 
			
		||||
    new_pin_confirmation: |-
 | 
			
		||||
      CON Enter your new four number PIN again
 | 
			
		||||
      0. Back
 | 
			
		||||
    transaction_pin_authorization:
 | 
			
		||||
      first: |-
 | 
			
		||||
@ -107,6 +110,34 @@ en:
 | 
			
		||||
      retry: |-
 | 
			
		||||
        CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
 | 
			
		||||
        0. Back
 | 
			
		||||
    name_edit_pin_authorization:
 | 
			
		||||
      first: |-
 | 
			
		||||
        CON Please enter your PIN
 | 
			
		||||
        0. Back
 | 
			
		||||
      retry: |-
 | 
			
		||||
        CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
 | 
			
		||||
        0. Back
 | 
			
		||||
    gender_edit_pin_authorization:
 | 
			
		||||
      first: |-
 | 
			
		||||
        CON Please enter your PIN
 | 
			
		||||
        0. Back
 | 
			
		||||
      retry: |-
 | 
			
		||||
        CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
 | 
			
		||||
        0. Back
 | 
			
		||||
    location_edit_pin_authorization:
 | 
			
		||||
      first: |-
 | 
			
		||||
        CON Please enter your PIN
 | 
			
		||||
        0. Back
 | 
			
		||||
      retry: |-
 | 
			
		||||
        CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
 | 
			
		||||
        0. Back
 | 
			
		||||
    products_edit_pin_authorization:
 | 
			
		||||
      first: |-
 | 
			
		||||
        CON Please enter your PIN
 | 
			
		||||
        0. Back
 | 
			
		||||
      retry: |-
 | 
			
		||||
        CON Please enter your PIN. You have %{remaining_attempts} attempts remaining
 | 
			
		||||
        0. Back
 | 
			
		||||
    account_balances: |-
 | 
			
		||||
      CON Your balances are as follows:
 | 
			
		||||
        balance: %{operational_balance} %{token_symbol}
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,7 @@ sw:
 | 
			
		||||
      CON Weka jinsia yako
 | 
			
		||||
      1. Mwanaume
 | 
			
		||||
      2. Mwanamke
 | 
			
		||||
      3. Nyngine 
 | 
			
		||||
      3. Nyngine
 | 
			
		||||
      0. Nyuma
 | 
			
		||||
    enter_location: |-
 | 
			
		||||
      CON Weka eneo lako
 | 
			
		||||
@ -61,7 +61,7 @@ sw:
 | 
			
		||||
        Jina: %{full_name}
 | 
			
		||||
        Jinsia: %{gender}
 | 
			
		||||
        Eneo: %{location}
 | 
			
		||||
        Unauza: %{user_bio}
 | 
			
		||||
        Unauza: %{products}
 | 
			
		||||
      0. Nyuma
 | 
			
		||||
    select_preferred_language: |-
 | 
			
		||||
      CON Chagua lugha
 | 
			
		||||
@ -78,6 +78,9 @@ sw:
 | 
			
		||||
    enter_new_pin: |-
 | 
			
		||||
      CON Weka nambari ya siri mpya
 | 
			
		||||
      0. Nyuma
 | 
			
		||||
    new_pin_confirmation: |-
 | 
			
		||||
      CON Weka PIN yako tena
 | 
			
		||||
      0. Nyuma
 | 
			
		||||
    transaction_pin_authorization:
 | 
			
		||||
      first: |-
 | 
			
		||||
        CON %{recipient_information} atapokea %{transaction_amount} %{token_symbol} kutoka kwa %{sender_information}.
 | 
			
		||||
@ -86,9 +89,9 @@ sw:
 | 
			
		||||
      retry: |-
 | 
			
		||||
        CON Weka nambari ya siri. Una majaribio %{remaining_attempts} yaliyobaki.
 | 
			
		||||
        0. Nyuma
 | 
			
		||||
    standard_pin_authorization:
 | 
			
		||||
    display_metadata_pin_authorization:
 | 
			
		||||
      first: |-
 | 
			
		||||
        CON Tafadhali weka PIN yako.
 | 
			
		||||
        CON Tafadhali weka PIN yako
 | 
			
		||||
        0. Nyuma
 | 
			
		||||
      retry: |-
 | 
			
		||||
        CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
 | 
			
		||||
@ -107,12 +110,40 @@ sw:
 | 
			
		||||
      retry: |-
 | 
			
		||||
        CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
 | 
			
		||||
        0. Nyuma
 | 
			
		||||
    name_edit_pin_authorization:
 | 
			
		||||
      first: |-
 | 
			
		||||
        CON Tafadhali weka PIN yako
 | 
			
		||||
        0. Nyuma
 | 
			
		||||
      retry: |-
 | 
			
		||||
        CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
 | 
			
		||||
        0. Nyuma
 | 
			
		||||
    gender_edit_pin_authorization:
 | 
			
		||||
      first: |-
 | 
			
		||||
        CON Tafadhali weka PIN yako
 | 
			
		||||
        0. Nyuma
 | 
			
		||||
      retry: |-
 | 
			
		||||
        CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
 | 
			
		||||
        0. Nyuma
 | 
			
		||||
    location_edit_pin_authorization:
 | 
			
		||||
      first: |-
 | 
			
		||||
        CON Tafadhali weka PIN yako
 | 
			
		||||
        0. Nyuma
 | 
			
		||||
      retry: |-
 | 
			
		||||
        CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
 | 
			
		||||
        0. Nyuma
 | 
			
		||||
    products_edit_pin_authorization:
 | 
			
		||||
      first: |-
 | 
			
		||||
        CON Tafadhali weka PIN yako
 | 
			
		||||
        0. Nyuma
 | 
			
		||||
      retry: |-
 | 
			
		||||
        CON Tafadhali weka PIN yako. Una majaribio %{remaining_attempts} yaliyobaki.
 | 
			
		||||
        0. Nyuma
 | 
			
		||||
    account_balances: |-
 | 
			
		||||
      CON Salio zako ni zifuatazo:
 | 
			
		||||
        salio: %{operational_balance}
 | 
			
		||||
        ushuru: %{tax}
 | 
			
		||||
        tuzo: %{bonus}
 | 
			
		||||
      0. Back
 | 
			
		||||
        salio: %{operational_balance} %{token_symbol}
 | 
			
		||||
        ushuru: %{tax} %{token_symbol}
 | 
			
		||||
        tuzo: %{bonus} %{token_symbol}
 | 
			
		||||
      0. Nyuma
 | 
			
		||||
    first_transaction_set: |-
 | 
			
		||||
      CON %{first_transaction_set}
 | 
			
		||||
      1. Mbele
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user