# standard imports import json import datetime # external imports from cic_types.condiments import MetadataPointer # local imports from cic_ussd.account.balance import get_cached_available_balance from cic_ussd.account.metadata import get_cached_preferred_language from cic_ussd.account.statement import ( get_cached_statement, parse_statement_transactions, statement_transaction_set ) from cic_ussd.account.tokens import get_default_token_symbol from cic_ussd.account.transaction import from_wei, to_wei from cic_ussd.cache import cache_data, cache_data_key from cic_ussd.menu.ussd_menu import UssdMenu from cic_ussd.metadata import PersonMetadata from cic_ussd.phone_number import Support from cic_ussd.processor.menu import response from cic_ussd.processor.util import parse_person_metadata from cic_ussd.translation import translation_for # test imports def test_menu_processor(activated_account, balances, cache_balances, cache_default_token_data, cache_preferences, cache_person_metadata, cache_statement, celery_session_worker, generic_ussd_session, init_database, load_chain_spec, load_support_phone, load_ussd_menu, mock_get_adjusted_balance, mock_sync_balance_api_query, mock_transaction_list_query, valid_recipient): preferred_language = get_cached_preferred_language(activated_account.blockchain_address) available_balance = get_cached_available_balance(activated_account.blockchain_address) token_symbol = get_default_token_symbol() with_available_balance = 'ussd.account_balances.available_balance' with_fees = 'ussd.account_balances.with_fees' ussd_menu = UssdMenu.find_by_name('account_balances') name = ussd_menu.get('name') resp = response(activated_account, 'ussd.account_balances', name, init_database, generic_ussd_session) assert resp == translation_for(with_available_balance, preferred_language, available_balance=available_balance, token_symbol=token_symbol) identifier = bytes.fromhex(activated_account.blockchain_address) key = cache_data_key(identifier, MetadataPointer.BALANCES_ADJUSTED) adjusted_balance = 45931650.64654012 cache_data(key, json.dumps(adjusted_balance)) resp = response(activated_account, 'ussd.account_balances', name, init_database, generic_ussd_session) tax_wei = to_wei(int(available_balance)) - int(adjusted_balance) tax = from_wei(int(tax_wei)) assert resp == translation_for(key=with_fees, preferred_language=preferred_language, available_balance=available_balance, tax=tax, token_symbol=token_symbol) cached_statement = get_cached_statement(activated_account.blockchain_address) statement = json.loads(cached_statement) statement_transactions = parse_statement_transactions(statement) transaction_sets = [statement_transactions[tx:tx + 3] for tx in range(0, len(statement_transactions), 3)] first_transaction_set = [] middle_transaction_set = [] last_transaction_set = [] if transaction_sets: first_transaction_set = statement_transaction_set(preferred_language, transaction_sets[0]) if len(transaction_sets) >= 2: middle_transaction_set = statement_transaction_set(preferred_language, transaction_sets[1]) if len(transaction_sets) >= 3: last_transaction_set = statement_transaction_set(preferred_language, transaction_sets[2]) display_key = 'ussd.first_transaction_set' ussd_menu = UssdMenu.find_by_name('first_transaction_set') name = ussd_menu.get('name') resp = response(activated_account, display_key, name, init_database, generic_ussd_session) assert resp == translation_for(display_key, preferred_language, first_transaction_set=first_transaction_set) display_key = 'ussd.middle_transaction_set' ussd_menu = UssdMenu.find_by_name('middle_transaction_set') name = ussd_menu.get('name') resp = response(activated_account, display_key, name, init_database, generic_ussd_session) assert resp == translation_for(display_key, preferred_language, middle_transaction_set=middle_transaction_set) display_key = 'ussd.last_transaction_set' ussd_menu = UssdMenu.find_by_name('last_transaction_set') name = ussd_menu.get('name') resp = response(activated_account, display_key, name, init_database, generic_ussd_session) assert resp == translation_for(display_key, preferred_language, last_transaction_set=last_transaction_set) display_key = 'ussd.display_user_metadata' ussd_menu = UssdMenu.find_by_name('display_user_metadata') name = ussd_menu.get('name') identifier = bytes.fromhex(activated_account.blockchain_address) person_metadata = PersonMetadata(identifier) cached_person_metadata = person_metadata.get_cached_metadata() resp = response(activated_account, display_key, name, init_database, generic_ussd_session) assert resp == parse_person_metadata(cached_person_metadata, display_key, preferred_language) display_key = 'ussd.account_balances_pin_authorization' ussd_menu = UssdMenu.find_by_name('account_balances_pin_authorization') name = ussd_menu.get('name') resp = response(activated_account, display_key, name, init_database, generic_ussd_session) assert resp == translation_for(f'{display_key}.first', preferred_language) activated_account.failed_pin_attempts = 1 resp = response(activated_account, display_key, name, init_database, generic_ussd_session) retry_pin_entry = translation_for('ussd.retry_pin_entry', preferred_language, remaining_attempts=2) assert resp == translation_for(f'{display_key}.retry', preferred_language, retry_pin_entry=retry_pin_entry) activated_account.failed_pin_attempts = 0 display_key = 'ussd.start' ussd_menu = UssdMenu.find_by_name('start') name = ussd_menu.get('name') resp = response(activated_account, display_key, name, init_database, generic_ussd_session) assert resp == translation_for(display_key, preferred_language, account_balance=available_balance, account_token_name=token_symbol) display_key = 'ussd.start' ussd_menu = UssdMenu.find_by_name('start') name = ussd_menu.get('name') older_timestamp = (activated_account.created - datetime.timedelta(days=35)) activated_account.created = older_timestamp init_database.flush() response(activated_account, display_key, name, init_database, generic_ussd_session) assert mock_get_adjusted_balance['timestamp'] == int((datetime.datetime.now() - datetime.timedelta(days=30)).timestamp()) display_key = 'ussd.transaction_pin_authorization' ussd_menu = UssdMenu.find_by_name('transaction_pin_authorization') name = ussd_menu.get('name') generic_ussd_session['data'] = { 'recipient_phone_number': valid_recipient.phone_number, 'transaction_amount': '15' } resp = response(activated_account, display_key, name, init_database, generic_ussd_session) user_input = generic_ussd_session.get('data').get('transaction_amount') transaction_amount = to_wei(value=int(user_input)) tx_recipient_information = valid_recipient.standard_metadata_id() tx_sender_information = activated_account.standard_metadata_id() assert resp == translation_for(f'{display_key}.first', preferred_language, recipient_information=tx_recipient_information, transaction_amount=from_wei(transaction_amount), token_symbol=token_symbol, sender_information=tx_sender_information) display_key = 'ussd.exit_insufficient_balance' ussd_menu = UssdMenu.find_by_name('exit_insufficient_balance') name = ussd_menu.get('name') generic_ussd_session['data'] = { 'recipient_phone_number': valid_recipient.phone_number, 'transaction_amount': '85' } transaction_amount = generic_ussd_session.get('data').get('transaction_amount') transaction_amount = to_wei(value=int(transaction_amount)) resp = response(activated_account, display_key, name, init_database, generic_ussd_session) assert resp == translation_for(display_key, preferred_language, amount=from_wei(transaction_amount), token_symbol=token_symbol, recipient_information=tx_recipient_information, token_balance=available_balance) display_key = 'ussd.exit_invalid_menu_option' ussd_menu = UssdMenu.find_by_name('exit_invalid_menu_option') name = ussd_menu.get('name') resp = response(activated_account, display_key, name, init_database, generic_ussd_session) assert resp == translation_for(display_key, preferred_language, support_phone=Support.phone_number) display_key = 'ussd.exit_successful_transaction' ussd_menu = UssdMenu.find_by_name('exit_successful_transaction') name = ussd_menu.get('name') generic_ussd_session['data'] = { 'recipient_phone_number': valid_recipient.phone_number, 'transaction_amount': '15' } transaction_amount = generic_ussd_session.get('data').get('transaction_amount') transaction_amount = to_wei(value=int(transaction_amount)) resp = response(activated_account, display_key, name, init_database, generic_ussd_session) assert resp == translation_for(display_key, preferred_language, transaction_amount=from_wei(transaction_amount), token_symbol=token_symbol, recipient_information=tx_recipient_information, sender_information=tx_sender_information)