def test_process_command_send_message_in_reply_to(self): yield self.app_helper.start_conversation(self.conversation) batch_id = self.conversation.batch.key msg = yield self.app_helper.make_stored_inbound( self.conversation, "foo") command = VumiApiCommand.command( 'worker', 'send_message', user_account_key=self.conversation.user_account.key, conversation_key=self.conversation.key, command_data={ u'batch_id': batch_id, u'content': u'foo', u'to_addr': u'to_addr', u'msg_options': { u'transport_name': u'smpp_transport', u'in_reply_to': msg['message_id'], u'transport_type': u'sms', u'from_addr': u'default10080', }, }) yield self.app.consume_control_command(command) [sent_msg] = self.app_helper.get_dispatched_outbound() self.assertEqual(sent_msg['to_addr'], msg['from_addr']) self.assertEqual(sent_msg['content'], 'foo') self.assertEqual(sent_msg['in_reply_to'], msg['message_id'])
def send_metrics_command(self, account_key, conversation_key, worker_name): cmd = VumiApiCommand.command( worker_name, 'collect_metrics', conversation_key=conversation_key, user_account_key=account_key) return self.command_publisher.publish_message(cmd)
def test_command(self): cmd = VumiApiCommand.command( 'worker', 'my_cmd', 'arg1', 'arg2', kw1=1, kw2=2) self.assertEqual(cmd['worker_name'], 'worker') self.assertEqual(cmd['command'], 'my_cmd') self.assertEqual(cmd['args'], ['arg1', 'arg2']) self.assertEqual(cmd['kwargs'], {'kw1': 1, 'kw2': 2})
def test_process_command_send_message_in_reply_to(self): conversation = yield self.setup_conversation() yield self.app_helper.start_conversation(conversation) batch_id = conversation.batch.key msg = yield self.app_helper.make_stored_inbound(conversation, "foo") command = VumiApiCommand.command( 'worker', 'send_message', user_account_key=conversation.user_account.key, conversation_key=conversation.key, command_data={ u'batch_id': batch_id, u'content': u'foo', u'to_addr': u'to_addr', u'msg_options': { u'transport_name': u'smpp_transport', u'in_reply_to': msg['message_id'], u'transport_type': u'sms', u'from_addr': u'default10080', }, }) yield self.app.consume_control_command(command) [sent_msg] = self.app_helper.get_dispatched_outbound() self.assertEqual(sent_msg['to_addr'], msg['from_addr']) self.assertEqual(sent_msg['content'], 'foo') self.assertEqual(sent_msg['in_reply_to'], msg['message_id'])
def test_action_bulk_send_no_dedupe(self): group = self.app_helper.create_group_with_contacts(u'test_group', 0) channel = self.app_helper.create_channel(supports_generic_sends=True) conv_helper = self.app_helper.create_conversation_helper( started=True, channel=channel, groups=[group]) response = self.client.post( conv_helper.get_action_view_url('bulk_send'), { 'message': 'I am ham, not spam.', 'dedupe': False }) self.assertRedirects(response, conv_helper.get_view_url('show')) [bulk_send_cmd] = self.app_helper.get_api_commands_sent() conversation = conv_helper.get_conversation() self.assertEqual( bulk_send_cmd, VumiApiCommand.command( '%s_application' % (conversation.conversation_type, ), 'bulk_send', user_account_key=conversation.user_account.key, conversation_key=conversation.key, batch_id=conversation.batch.key, msg_options={}, delivery_class=conversation.delivery_class, content='I am ham, not spam.', dedupe=False))
def test_command(self): cmd = VumiApiCommand.command('worker', 'my_cmd', 'arg1', 'arg2', kw1=1, kw2=2) self.assertEqual(cmd['worker_name'], 'worker') self.assertEqual(cmd['command'], 'my_cmd') self.assertEqual(cmd['args'], ['arg1', 'arg2']) self.assertEqual(cmd['kwargs'], {'kw1': 1, 'kw2': 2})
def test_conversation_command(self): cmd = VumiApiCommand.conversation_command( 'worker', 'my_cmd', 'me', 'conv', 'arg1', 'arg2', kw1=1, kw2=2) self.assertEqual(cmd['worker_name'], 'worker') self.assertEqual(cmd['command'], 'my_cmd') self.assertEqual(cmd['args'], ['arg1', 'arg2']) self.assertEqual(cmd['kwargs'], { 'user_account_key': 'me', 'conversation_key': 'conv', 'kw1': 1, 'kw2': 2, })
def handle_event(self, event, handler_config): """ From an account and conversation, this finds a batch and a tag. While there could be multiple batches per conversation and multiple tags per batch, this assumes lists of one, and takes the first entry of each list TODO: Turn this into a generic API Command Sender? An Example of a event_dispatcher.yaml config file, with mapped conversations in the config: transport_name: event_dispatcher event_handlers: sign_up_handler: go.vumitools.handler.SendMessageCommandHandler account_handler_configs: '73ad76ec8c2e40858dc9d6b934049d95': - - ['a6a20571e77f4aa89a8b10a771b005bc', sign_up] - - [ sign_up_handler, { worker_name: 'multi_survey_application', conversation_key: 'a6a20571e77f4aa89a8b10a771b005bc' } ] """ log.info( "SendMessageCommandHandler handling event: %s with config: %s" % (event, handler_config)) user_api = self.get_user_api(event.payload['account_key']) conv = yield user_api.conversation_store.get_conversation_by_key( event.payload['conversation_key']) conv = user_api.wrap_conversation(conv) command_data = event.payload['content'] command_data['batch_id'] = conv.batch.key command_data['msg_options'] = { 'helper_metadata': { 'go': { 'user_account': event.payload['account_key'] }, }, } sm_cmd = VumiApiCommand.command( handler_config['worker_name'], "send_message", command_data=command_data, conversation_key=handler_config['conversation_key'], account_key=event.payload['account_key']) log.info("Publishing command: %s" % sm_cmd) self.dispatcher.api_command_publisher.publish_message(sm_cmd)
def test_stop(self): rtr_helper = self.router_helper.create_router_helper(started=True) response = self.client.post(rtr_helper.get_view_url('stop')) self.assertRedirects(response, rtr_helper.get_view_url('show')) router = rtr_helper.get_router() self.assertTrue(router.stopping()) [start_cmd] = self.router_helper.get_api_commands_sent() self.assertEqual( start_cmd, VumiApiCommand.command( '%s_router' % (router.router_type,), 'stop', user_account_key=router.user_account.key, router_key=router.key))
def handle_reconcile_cache(self, worker_name, command, account_key, conversation_key): user = get_user_by_account_key(account_key) user_api = vumi_api_for_user(user) conversation = user_api.get_wrapped_conversation(conversation_key) if conversation is None: raise CommandError('Conversation does not exist') return VumiApiCommand.command(worker_name, command, user_account_key=account_key, conversation_key=conversation_key)
def test_action_send_jsbox_post(self): conv_helper = self.setup_conversation(started=True) response = self.client.post( conv_helper.get_action_view_url('send_jsbox'), {}, follow=True) self.assertRedirects(response, conv_helper.get_view_url('show')) [send_jsbox_cmd] = self.app_helper.get_api_commands_sent() conversation = conv_helper.get_conversation() self.assertEqual(send_jsbox_cmd, VumiApiCommand.command( '%s_application' % (conversation.conversation_type,), 'send_jsbox', user_account_key=conversation.user_account.key, conversation_key=conversation.key, batch_id=conversation.batch.key))
def handle_event(self, event, handler_config): """ From an account and conversation, this finds a batch and a tag. While there could be multiple batches per conversation and multiple tags per batch, this assumes lists of one, and takes the first entry of each list TODO: Turn this into a generic API Command Sender? An Example of a event_dispatcher.yaml config file, with mapped conversations in the config: transport_name: event_dispatcher event_handlers: sign_up_handler: go.vumitools.handler.SendMessageCommandHandler account_handler_configs: '73ad76ec8c2e40858dc9d6b934049d95': - - ['a6a20571e77f4aa89a8b10a771b005bc', sign_up] - - [ sign_up_handler, { worker_name: 'multi_survey_application', conversation_key: 'a6a20571e77f4aa89a8b10a771b005bc' } ] """ log.info( "SendMessageCommandHandler handling event: %s with config: %s" % ( event, handler_config)) user_api = self.get_user_api(event.payload['account_key']) conv = yield user_api.conversation_store.get_conversation_by_key( event.payload['conversation_key']) conv = user_api.wrap_conversation(conv) command_data = event.payload['content'] command_data['batch_id'] = conv.batch.key command_data['msg_options'] = { 'helper_metadata': { 'go': {'user_account': event.payload['account_key']}, }, } sm_cmd = VumiApiCommand.command( handler_config['worker_name'], "send_message", command_data=command_data, conversation_key=handler_config['conversation_key'], account_key=event.payload['account_key'] ) log.info("Publishing command: %s" % sm_cmd) self.dispatcher.api_command_publisher.publish_message(sm_cmd)
def test_stop(self): rtr_helper = self.router_helper.create_router_helper(started=True) response = self.client.post(rtr_helper.get_view_url('stop')) self.assertRedirects(response, rtr_helper.get_view_url('show')) router = rtr_helper.get_router() self.assertTrue(router.stopping()) [start_cmd] = self.router_helper.get_api_commands_sent() self.assertEqual( start_cmd, VumiApiCommand.command('%s_router' % (router.router_type, ), 'stop', user_account_key=router.user_account.key, router_key=router.key))
def test_start(self): conv = self.user_helper.create_conversation(u'dummy') response = self.client.post( self.get_view_url(conv, 'start'), follow=True) self.assertRedirects(response, self.get_view_url(conv, 'show')) [msg] = response.context['messages'] self.assertEqual(str(msg), "Dummy Conversation started") conv = self.user_helper.get_conversation(conv.key) self.assertTrue(conv.starting()) [start_cmd] = self.get_api_commands_sent() self.assertEqual(start_cmd, VumiApiCommand.command( '%s_application' % (conv.conversation_type,), 'start', user_account_key=conv.user_account.key, conversation_key=conv.key))
def test_action_send_jsbox_post(self): conv_helper = self.setup_conversation(started=True) response = self.client.post( conv_helper.get_action_view_url('send_jsbox'), {}, follow=True) self.assertRedirects(response, conv_helper.get_view_url('show')) [send_jsbox_cmd] = self.app_helper.get_api_commands_sent() conversation = conv_helper.get_conversation() self.assertEqual( send_jsbox_cmd, VumiApiCommand.command( '%s_application' % (conversation.conversation_type, ), 'send_jsbox', user_account_key=conversation.user_account.key, conversation_key=conversation.key, batch_id=conversation.batch.key))
def test_action_send_survey_post(self): group = self.app_helper.create_group_with_contacts(u'test_group', 0) channel = self.app_helper.create_channel(supports_generic_sends=True) conv_helper = self.app_helper.create_conversation_helper( started=True, channel=channel, groups=[group]) response = self.client.post( conv_helper.get_action_view_url('send_survey'), {}, follow=True) self.assertRedirects(response, conv_helper.get_view_url('show')) [send_survey_cmd] = self.app_helper.get_api_commands_sent() conversation = conv_helper.get_conversation() self.assertEqual(send_survey_cmd, VumiApiCommand.command( '%s_application' % (conversation.conversation_type,), 'send_survey', user_account_key=conversation.user_account.key, conversation_key=conversation.key, batch_id=conversation.batch.key, msg_options={}, delivery_class=conversation.delivery_class))
def test_action_bulk_send_dedupe(self): group = self.app_helper.create_group_with_contacts(u'test_group', 0) channel = self.app_helper.create_channel(supports_generic_sends=True) conv_helper = self.app_helper.create_conversation_helper( started=True, channel=channel, groups=[group]) response = self.client.post( conv_helper.get_action_view_url('bulk_send'), {'message': 'I am ham, not spam.', 'dedupe': True}) self.assertRedirects(response, conv_helper.get_view_url('show')) [bulk_send_cmd] = self.app_helper.get_api_commands_sent() conversation = conv_helper.get_conversation() self.assertEqual(bulk_send_cmd, VumiApiCommand.command( '%s_application' % (conversation.conversation_type,), 'bulk_send', user_account_key=conversation.user_account.key, conversation_key=conversation.key, batch_id=conversation.batch.key, msg_options={}, delivery_class=conversation.delivery_class, content='I am ham, not spam.', dedupe=True))
def test_conversation_command(self): cmd = VumiApiCommand.conversation_command('worker', 'my_cmd', 'me', 'conv', 'arg1', 'arg2', kw1=1, kw2=2) self.assertEqual(cmd['worker_name'], 'worker') self.assertEqual(cmd['command'], 'my_cmd') self.assertEqual(cmd['args'], ['arg1', 'arg2']) self.assertEqual( cmd['kwargs'], { 'user_account_key': 'me', 'conversation_key': 'conv', 'kw1': 1, 'kw2': 2, })
def test_start(self): conv = self.user_helper.create_conversation(u'dummy') response = self.client.post(self.get_view_url(conv, 'start'), follow=True) self.assertRedirects(response, self.get_view_url(conv, 'show')) [msg] = response.context['messages'] self.assertEqual(str(msg), "Dummy Conversation started") conv = self.user_helper.get_conversation(conv.key) self.assertTrue(conv.starting()) [start_cmd] = self.get_api_commands_sent() self.assertEqual( start_cmd, VumiApiCommand.command('%s_application' % (conv.conversation_type, ), 'start', user_account_key=conv.user_account.key, conversation_key=conv.key))
def test_action_bulk_send_confirm(self): """ Test action with confirmation required """ # TODO: Break this test into smaller bits and move them to a more # appropriate module. user_account = self.app_helper.get_or_create_user().get_user_account() user_account.msisdn = u'+27761234567' user_account.confirm_start_conversation = True user_account.save() # Start the conversation group = self.app_helper.create_group_with_contacts(u'test_group', 0) channel = self.app_helper.create_channel(supports_generic_sends=True) conv_helper = self.app_helper.create_conversation_helper( started=True, channel=channel, groups=[group]) # POST the action with a mock token manager self.monkey_patch( TokenManager, 'generate_token', lambda s: ('abcdef', '123456')) response = self.client.post( conv_helper.get_action_view_url('bulk_send'), {'message': 'I am ham, not spam.', 'dedupe': True}) self.assertRedirects(response, conv_helper.get_view_url('show')) # Check that we get a confirmation message [token_send_cmd] = self.app_helper.get_api_commands_sent() conversation = conv_helper.get_conversation() self.assertEqual( VumiApiCommand.command( '%s_application' % (conversation.conversation_type,), 'send_message', user_account_key=conversation.user_account.key, conversation_key=conversation.key, command_data=dict( batch_id=conversation.batch.key, to_addr=u'+27761234567', msg_options={ 'helper_metadata': {'go': {'sensitive': True}}, }, content=RegexMatcher(r'Please visit http://[^/]+/t/abcdef/' r' to start your conversation.')), ), token_send_cmd) # GET the token URL confirm_response = self.client.get( reverse('token', kwargs={'token': 'abcdef'})) self.assertRedirects( confirm_response, conv_helper.get_view_url('confirm') + '?token=6-abcdef123456') # POST the full token to the confirmation URL final_response = self.client.post( conv_helper.get_view_url('confirm'), {'token': '6-abcdef123456'}) self.assertRedirects(final_response, conv_helper.get_view_url('show')) [bulk_send_cmd] = self.app_helper.get_api_commands_sent() self.assertEqual(bulk_send_cmd, VumiApiCommand.command( '%s_application' % (conversation.conversation_type,), 'bulk_send', user_account_key=conversation.user_account.key, conversation_key=conversation.key, batch_id=conversation.batch.key, msg_options={}, delivery_class=conversation.delivery_class, content='I am ham, not spam.', dedupe=True))
def send_metrics_command(self, account_key, conversation_key, worker_name): cmd = VumiApiCommand.command(worker_name, 'collect_metrics', conversation_key=conversation_key, user_account_key=account_key) return self.command_publisher.publish_message(cmd)
def test_badly_constructed_command(self): with LogCatcher() as logs: yield self.worker_helper.dispatch_raw('vumi.api', VumiApiCommand()) [error] = logs.errors self.assertTrue( "No worker publisher available" in error['message'][0])
def publish_command(self, worker_name, command, *args, **kw): cmd = VumiApiCommand.command(worker_name, command, *args, **kw) d = self.worker_helper.dispatch_raw('vumi.api', cmd) return d.addCallback(lambda _: cmd)
def dispatch_command(self, command, *args, **kw): cmd = VumiApiCommand.command(self._worker_name(), command, *args, **kw) yield self.worker_helper.dispatch_raw('vumi.api', cmd) yield self.dispatch_commands_to_app()
def dispatch_command(self, command, *args, **kw): cmd = VumiApiCommand.command( self._worker_name(), command, *args, **kw) yield self.worker_helper.dispatch_raw('vumi.api', cmd) yield self.dispatch_commands_to_app()
def test_action_bulk_send_confirm(self): """ Test action with confirmation required """ # TODO: Break this test into smaller bits and move them to a more # appropriate module. user_account = self.app_helper.get_or_create_user().get_user_account() user_account.msisdn = u'+27761234567' user_account.confirm_start_conversation = True user_account.save() # Start the conversation group = self.app_helper.create_group_with_contacts(u'test_group', 0) channel = self.app_helper.create_channel(supports_generic_sends=True) conv_helper = self.app_helper.create_conversation_helper( started=True, channel=channel, groups=[group]) # POST the action with a mock token manager self.monkey_patch(TokenManager, 'generate_token', lambda s: ('abcdef', '123456')) response = self.client.post( conv_helper.get_action_view_url('bulk_send'), { 'message': 'I am ham, not spam.', 'dedupe': True }) self.assertRedirects(response, conv_helper.get_view_url('show')) # Check that we get a confirmation message [token_send_cmd] = self.app_helper.get_api_commands_sent() conversation = conv_helper.get_conversation() self.assertEqual( VumiApiCommand.command( '%s_application' % (conversation.conversation_type, ), 'send_message', user_account_key=conversation.user_account.key, conversation_key=conversation.key, command_data=dict(batch_id=conversation.batch.key, to_addr=u'+27761234567', msg_options={ 'helper_metadata': { 'go': { 'sensitive': True } }, }, content=RegexMatcher( r'Please visit http://[^/]+/t/abcdef/' r' to start your conversation.')), ), token_send_cmd) # GET the token URL confirm_response = self.client.get( reverse('token', kwargs={'token': 'abcdef'})) self.assertRedirects( confirm_response, conv_helper.get_view_url('confirm') + '?token=6-abcdef123456') # POST the full token to the confirmation URL final_response = self.client.post(conv_helper.get_view_url('confirm'), {'token': '6-abcdef123456'}) self.assertRedirects(final_response, conv_helper.get_view_url('show')) [bulk_send_cmd] = self.app_helper.get_api_commands_sent() self.assertEqual( bulk_send_cmd, VumiApiCommand.command( '%s_application' % (conversation.conversation_type, ), 'bulk_send', user_account_key=conversation.user_account.key, conversation_key=conversation.key, batch_id=conversation.batch.key, msg_options={}, delivery_class=conversation.delivery_class, content='I am ham, not spam.', dedupe=True))