def test_custom_display_text(test_client, init_database, menu_name, language, expecteds, real_at_idx, length, unexpected, menu_nr): with db.session.no_autoflush: start_state = UssdSessionFactory(state="menu_name") mapping = fake_transfer_mapping(length) real_usage1 = TransferUsage.find_or_create('Education') real_usage1.translations = {'en': 'Education', 'sw': 'Elimu'} real_usage2 = TransferUsage.find_or_create('Health') real_usage2.translations = {'en': 'Health', 'sw': 'Afya'} mapping[real_at_idx] = UssdStateMachine.make_usage_mapping(real_usage1) mapping[real_at_idx + 1] = UssdStateMachine.make_usage_mapping(real_usage2) user = standard_user() user.preferred_language = language start_state.session_data = { 'transfer_usage_mapping': mapping, 'usage_menu': menu_nr, 'usage_index_stack': [0, 8] } start_state.user = user menu = UssdMenu(name=menu_name, display_key="ussd.sempo.{}".format(menu_name)) resulting_menu = UssdProcessor.custom_display_text( menu, start_state) for expected in expecteds: assert expected in resulting_menu if unexpected is not None: assert unexpected not in resulting_menu
def test_invalid_user_recipient(mocker, test_client, init_database, standard_user): session = send_enter_recipient_state() state_machine = UssdStateMachine(session, standard_user) state_machine.send_sms = mocker.MagicMock() state_machine.feed_char("1234") assert state_machine.state == "exit_invalid_recipient" assert session.session_data is None
def next_state(session: UssdSession, user_input: str, user: User) -> UssdMenu: state_machine = UssdStateMachine(session, user) state_machine.feed_char(user_input) new_state = state_machine.state session.state = new_state return new_state
def test_standard_recipient(test_client, init_database, standard_user): session = send_enter_recipient_state() recipient_user = UserFactory(phone=make_kenyan_phone(phone())) state_machine = UssdStateMachine(session, standard_user) state_machine.feed_char(recipient_user.phone) assert state_machine.state == "send_token_amount" assert session.get_data('recipient_phone') == recipient_user.phone
def test_invalid_user_recipient(test_client, init_database): session = exchange_token_agent_number_entry_state() user = standard_user() user.phone = phone() state_machine = UssdStateMachine(session, user) state_machine.feed_char("1234") assert state_machine.state == "exit_invalid_token_agent" assert session.session_data is None
def test_change_language_initial(mocker, test_client, init_database, session_factory, user_input, language): session = session_factory() user = standard_user() assert user.preferred_language is None state_machine = UssdStateMachine(session, user) state_machine.feed_char(user_input) assert state_machine.state == "initial_pin_entry" assert user.preferred_language == language
def test_agent_recipient(test_client, init_database, standard_user): session = send_enter_recipient_state() agent_recipient = UserFactory(phone=make_kenyan_phone(phone())) agent_recipient.set_held_role('TOKEN_AGENT', 'token_agent') state_machine = UssdStateMachine(session, standard_user) state_machine.feed_char(agent_recipient.phone) assert state_machine.state == "exit_use_exchange_menu" assert session.session_data is None
def test_state_machine(test_client, init_database, standard_user, session_factory, user_input, expected): session = session_factory() session.session_data = { 'transfer_usage_mapping': fake_transfer_mapping(10), 'usage_menu': 1, 'usage_index_stack': [0, 8] } db.session.commit() state_machine = UssdStateMachine(session, standard_user) state_machine.feed_char(user_input) assert state_machine.state == expected
def test_kenya_state_machine(test_client, init_database, user_factory, session_factory, user_input, expected): from flask import g g.active_organisation = OrganisationFactory(country_code='AU') session = session_factory() user = user_factory() user.phone = phone() state_machine = UssdStateMachine(session, user) state_machine.feed_char(user_input) assert state_machine.state == expected
def test_balance_inquiry(mocker, test_client, init_database): session = UssdSessionFactory(state="balance_inquiry_pin_authorization") user = standard_user() user.phone = phone() state_machine = UssdStateMachine(session, user) inquire_balance = mocker.MagicMock() mocker.patch('server.ussd_tasker.inquire_balance', inquire_balance) state_machine.feed_char('0000') assert state_machine.state == 'complete' inquire_balance.assert_called_with(user)
def test_change_current_pin(mocker, test_client, init_database): session = new_pin_confirmation_state() user = standard_user() state_machine = UssdStateMachine(session, user) state_machine.send_sms = mocker.MagicMock() state_machine.feed_char("2222") assert user.verify_pin("2222") is True state_machine.send_sms.assert_called_with(user.phone, "pin_change_success_sms")
def test_authorize_pin(test_client, init_database, session_factory, user_factory, user_input, expected, before_failed_pin_attempts, after_failed_pin_attempts): session = session_factory() user = user_factory(phone='+6140000000') user.failed_pin_attempts = before_failed_pin_attempts state_machine = UssdStateMachine(session, user) state_machine.feed_char(user_input) assert state_machine.state == expected assert user.failed_pin_attempts == after_failed_pin_attempts
def test_save_directory_info(mocker, test_client, init_database): session = UssdSessionFactory(state="change_my_business_prompt") user = standard_user() user.phone = phone() assert next(filter(lambda x: x.key == 'bio', user.custom_attributes), None) is None state_machine = UssdStateMachine(session, user) state_machine.send_sms = mocker.MagicMock() state_machine.feed_char("My Bio") assert state_machine.state == "exit" bio = next(filter(lambda x: x.key == 'bio', user.custom_attributes), None) assert bio.value == "My Bio"
def test_agent_recipient(test_client, init_database): session = exchange_token_agent_number_entry_state() user = standard_user() user.phone = phone() agent_recipient = UserFactory(phone=make_kenyan_phone(phone())) agent_recipient.set_held_role('TOKEN_AGENT', 'token_agent') state_machine = UssdStateMachine(session, user) state_machine.feed_char(agent_recipient.phone) assert state_machine.state == "exchange_token_amount_entry" assert session.get_data('agent_phone') == agent_recipient.phone
def test_invalid_phone_number( mocker, test_client, init_database, standard_user, create_transfer_account_user, external_reserve_token ): session = send_enter_recipient_state() invalid_recipient_phone = "1" state_machine = UssdStateMachine(session, standard_user) state_machine.send_sms = mocker.MagicMock() state_machine.feed_char(invalid_recipient_phone) assert state_machine.state == "exit_invalid_recipient" assert session.session_data is None assert not state_machine.send_sms.called
def test_change_initial_pin(mocker, test_client, init_database): session = initial_pin_confirmation_state() user = unactivated_user() state_machine = UssdStateMachine(session, user) assert user.pin_hash is None assert user.is_activated is False assert not user.is_phone_verified state_machine.feed_char("0000") assert user.verify_pin("0000") is True assert user.is_activated is True assert user.is_phone_verified
def test_change_language(mocker, test_client, init_database, session_factory, user_input, language): session = session_factory() user = standard_user() user.phone = phone() assert user.preferred_language is None state_machine = UssdStateMachine(session, user) state_machine.send_sms = mocker.MagicMock() state_machine.feed_char(user_input) assert state_machine.state == "complete" assert user.preferred_language == language state_machine.send_sms.assert_called_with(user.phone, "language_change_sms")
def test_opt_out_of_marketplace(mocker, test_client, init_database): session = UssdSessionFactory( state="opt_out_of_market_place_pin_authorization") user = standard_user() user.phone = phone() assert next( filter(lambda x: x.key == 'market_enabled', user.custom_attributes), None) is None state_machine = UssdStateMachine(session, user) state_machine.send_sms = mocker.MagicMock() state_machine.feed_char("0000") assert state_machine.state == "complete" assert user.is_market_enabled == False state_machine.send_sms.assert_called_with(user.phone, "opt_out_of_market_place_sms")
def fake_transfer_mapping(length: int): mapping = [] transfer_usage = TransferUsage.find_or_create("Food") db.session.commit() for i in range(length): mapping.append(UssdStateMachine.make_usage_mapping(transfer_usage)) return mapping
def test_kenya_state_machine(test_client, init_database, user_factory, session_factory, user_input, expected): from flask import g g.active_organisation = OrganisationFactory(country_code='AU') session = session_factory() session.session_data = { 'transfer_usage_mapping': fake_transfer_mapping(10), 'usage_menu': 1, 'usage_index_stack': [0, 8] } user = user_factory() user.phone = phone() db.session.commit() state_machine = UssdStateMachine(session, user) state_machine.feed_char(user_input) assert state_machine.state == expected
def test_send_directory_listing(mocker, test_client, init_database): session = UssdSessionFactory(state="directory_listing") session.session_data = { 'transfer_usage_mapping': fake_transfer_mapping(6), 'usage_menu': 0 } user = standard_user() user.phone = phone() state_machine = UssdStateMachine(session, user) transfer_usage = TransferUsage.find_or_create("Food") send_directory_listing = mocker.MagicMock() mocker.patch('server.ussd_tasker.send_directory_listing', send_directory_listing) state_machine.feed_char('2') assert state_machine.state == 'complete' send_directory_listing.assert_called_with(user, transfer_usage)
def test_invalid_recipient( mocker, test_client, init_database, standard_user, create_transfer_account_user, external_reserve_token ): session = send_enter_recipient_state() invalid_recipient_phone = "+61234567890" state_machine = UssdStateMachine(session, standard_user) state_machine.send_sms = mocker.MagicMock() state_machine.feed_char(invalid_recipient_phone) assert state_machine.state == "exit_invalid_recipient" assert session.session_data is None state_machine.send_sms.assert_called_with( invalid_recipient_phone, "upsell_message_recipient", first_name=standard_user.first_name, last_name=standard_user.last_name, token_name=standard_user.default_organisation.token.name )
def test_exchange_token(mocker, test_client, init_database, create_transfer_account_user): agent_recipient = create_transfer_account_user agent_recipient.phone = make_kenyan_phone(agent_recipient.phone) agent_recipient.set_held_role('TOKEN_AGENT', 'token_agent') exchange_token_confirmation = UssdSessionFactory( state="exchange_token_confirmation", session_data=json.loads("{" + f'"agent_phone": "{agent_recipient.phone}",' '"exchange_amount": "50"' + "}")) user = standard_user() user.phone = phone() state_machine = UssdStateMachine(exchange_token_confirmation, user) exchange_token = mocker.MagicMock() mocker.patch('server.ussd_tasker.exchange_token', exchange_token) state_machine.feed_char("1") assert state_machine.state == "complete" exchange_token.assert_called_with(user, agent_recipient, 50)
def test_send_token(mocker, test_client, init_database, create_transfer_account_user, standard_user): recipient = create_transfer_account_user recipient.phone = make_kenyan_phone(recipient.phone) send_token_confirmation = UssdSessionFactory( state="send_token_confirmation", session_data=json.loads( "{" + f'"recipient_phone": "{recipient.phone}",' '"transaction_amount": "10",' '"transaction_reason_i18n": "A reason",' '"transaction_reason_id": "1"' + "}" ) ) state_machine = UssdStateMachine(send_token_confirmation, standard_user) send_token = mocker.MagicMock() mocker.patch('server.ussd_tasker.send_token', send_token) state_machine.feed_char("1") assert state_machine.state == "complete" send_token.assert_called_with(standard_user, recipient, 10, "A reason", 1)
def test_terms_only_sent_once(mocker, test_client, init_database, mock_sms_apis): session = UssdSessionFactory(state="balance_inquiry_pin_authorization") user = standard_user() user.phone = phone() inquire_balance = mocker.MagicMock() mocker.patch('server.ussd_tasker.inquire_balance', inquire_balance) state_machine = UssdStateMachine(session, user) state_machine.feed_char('0000') db.session.commit() messages = mock_sms_apis assert len(messages) == 1 state_machine = UssdStateMachine(session, user) state_machine.feed_char('0000') assert len(messages) == 1