class RapidProFacadeTestWithRapidProLive(TestCase):
    def setUp(self):
        self.original_rapid_pro_live_setting = settings.RAPIDPRO_LIVE
        settings.RAPIDPRO_LIVE = True
        self.flow = FlowFactory()

        self.expected_payload = '{' \
                                '"phone": ["+256 772 123456"],' \
                                ' "flow": 1234, ' \
                                '"extra": {' \
                                '"product": "Plumpynut",' \
                                ' "sender": "Save the Children",' \
                                ' "contactName": "Test User"' \
                                '}' \
                                '}'

        self.runs_url = settings.RAPIDPRO_URLS['RUNS']
        self.fake_json = [{"run": 1, "phone": contact['phone']}]

    @patch('eums.rapid_pro.rapid_pro_facade.logger.info')
    @patch('requests.post')
    def test_should_start_a_flow_run_for_a_contact(self, mock_post, *_):
        mock_post.return_value = FakeResponse(self.fake_json, 201)
        expected_headers = {'Authorization': 'Token %s' % settings.RAPIDPRO_API_TOKEN,
                            'Content-Type': 'application/json'}
        start_delivery_run(contact_person=contact, item_description=item_description, sender=sender,
                           flow=self.flow.rapid_pro_id)
        mock_post.assert_called_with(settings.RAPIDPRO_URLS['RUNS'], data=self.expected_payload,
                                     headers=expected_headers)

    def tearDown(self):
        settings.RAPIDPRO_LIVE = self.original_rapid_pro_live_setting
        self.flow.delete()
Exemple #2
0
 def setUp(self):
     self.PHONE = '+12065551212'
     self.flow_id = 2436
     self.flow = FlowFactory(label=Flow.Label.IMPLEMENTING_PARTNER)
     requests.get = MagicMock(return_value=MagicMock(
         status_code=200, json=MagicMock(return_value=FLOW_RESPONSE)))
     self.my_hook = reload(my_hook)
Exemple #3
0
    def test_should_return_default_answers_for_delivery(self):
        delivery = DeliveryFactory()
        flow = FlowFactory(label='IMPLEMENTING_PARTNER')

        question_1 = MultipleChoiceQuestionFactory(
            label='deliveryReceived', flow=flow, text='Was Delivery Received?')
        question_2 = TextQuestionFactory(label='dateOfReceipt',
                                         flow=flow,
                                         text='When was Delivery Received?')

        OptionFactory(text='Yes', question=question_1)

        RunFactory(runnable=delivery)

        expected_multiple_choice_answer = {
            'question_label': question_1.label,
            'type': 'multipleChoice',
            'text': question_1.text,
            'value': '',
            'options': ['Yes'],
            'position': question_1.position
        }
        expected_text_answer = {
            'question_label': question_2.label,
            'type': 'text',
            'text': question_2.text,
            'value': '',
            'position': question_2.position
        }
        answers = delivery.answers()

        self.assertEqual(len(answers), 2)
        self.assertIn(expected_multiple_choice_answer, answers)
        self.assertIn(expected_text_answer, answers)
Exemple #4
0
    def setup_multiple_nodes_with_answers(self, number_of_nodes):
        consignee_one = ConsigneeFactory(name='consignee one')
        programme_one = ProgrammeFactory(name='my first programme')
        po_item = PurchaseOrderItemFactory(item=ItemFactory(description='Mama kit'),
                                           purchase_order=PurchaseOrderFactory(order_number=329293))

        flow = FlowFactory(label='WEB')
        question_1 = MultipleChoiceQuestionFactory(text='Was the item received?', label='itemReceived', flow=flow,
                                                   position=1)
        option_1 = OptionFactory(text='Yes', question=question_1)
        question_2 = NumericQuestionFactory(text='How much was received?', label='amountReceived', flow=flow)
        question_3 = MultipleChoiceQuestionFactory(text='What is the quality of the product?', label='qualityOfProduct',
                                                   flow=flow, position=3)
        option_3 = OptionFactory(text='Damaged', question=question_3)
        question_4 = MultipleChoiceQuestionFactory(text='Are you satisfied with the product?',
                                                   label='satisfiedWithProduct', flow=flow, position=4)
        option_4 = OptionFactory(text='Yes', question=question_4)
        question_5 = TextQuestionFactory(label='dateOfReceipt', flow=flow, text='When was Delivery Received?')
        nodes = []

        for index in range(number_of_nodes):
            node = DeliveryNodeFactory(consignee=consignee_one, item=po_item, programme=programme_one,
                                       distribution_plan=DeliveryFactory(track=True),
                                       track=True)

            run_one = RunFactory(runnable=node)
            MultipleChoiceAnswerFactory(question=question_1, run=run_one, value=option_1)
            NumericAnswerFactory(question=question_2, run=run_one, value=5)
            MultipleChoiceAnswerFactory(question=question_3, run=run_one, value=option_3)
            MultipleChoiceAnswerFactory(question=question_4, run=run_one, value=option_4)
            TextAnswerFactory(run=run_one, question=question_5, value='2014-10-10')
            nodes.append(node)

        return nodes
Exemple #5
0
    def test_should_not_return_deliveries_for_ip_if_received_is_false(self):
        first_consignee = ConsigneeFactory()

        date = datetime.date(2014, 07, 9)
        first_delivery = DeliveryFactory(consignee=first_consignee, track=True, delivery_date=date)
        second_delivery = DeliveryFactory(consignee=first_consignee, track=True)

        self.logout()
        self.log_consignee_in(consignee=first_consignee)

        response = self.client.get(ENDPOINT_URL)

        ids = map(lambda delivery: delivery['id'], response.data)

        self.assertEqual(response.status_code, 200)
        self.assertIn(first_delivery.id, ids)
        self.assertIn(second_delivery.id, ids)

        flow = FlowFactory(label=Flow.Label.IMPLEMENTING_PARTNER)
        delivery_received_qn = MultipleChoiceQuestionFactory(label='deliveryReceived', flow=flow)
        OptionFactory(question=delivery_received_qn, text='Yes')
        option_no = OptionFactory(question=delivery_received_qn, text='No')

        run = RunFactory(runnable=first_delivery)
        MultipleChoiceAnswerFactory(run=run, question=delivery_received_qn, value=option_no)
        response = self.client.get(ENDPOINT_URL)

        ids = map(lambda delivery: delivery['id'], response.data)
        self.assertEqual(response.status_code, 200)
        self.assertNotIn(first_delivery.id, ids)
        self.assertIn(second_delivery.id, ids)
    def _create_questions(self):
        flow = FlowFactory(label='IMPLEMENTING_PARTNER')

        self.delivery_received_qtn = MultipleChoiceQuestionFactory(text='Was delivery received?', flow=flow,
                                                                   position=1,
                                                                   label=Question.LABEL.deliveryReceived)
        self.yes_one = OptionFactory(text='Yes', question=self.delivery_received_qtn)
        self.no_one = OptionFactory(text='No', question=self.delivery_received_qtn)

        self.date_received_qtn = TextQuestionFactory(text='When was delivery received?', flow=flow, position=2,
                                                     label='dateOfReceipt')

        self.delivery_in_good_order = MultipleChoiceQuestionFactory(text='Was delivery in good condition?',
                                                                    flow=flow, position=3,
                                                                    label=Question.LABEL.isDeliveryInGoodOrder)
        self.yes_two = OptionFactory(text='Yes', question=self.delivery_in_good_order)
        self.no_two = OptionFactory(text='No', question=self.delivery_in_good_order)

        self.satisfied_with_delivery = MultipleChoiceQuestionFactory(text="Are you satisfied with the delivery?",
                                                                     flow=flow, position=4,
                                                                     label="satisfiedWithDelivery")
        self.yes_three = OptionFactory(text="Yes", question=self.satisfied_with_delivery)
        self.no_three = OptionFactory(text="No", question=self.satisfied_with_delivery)

        self.additional_comments = TextQuestionFactory(text='Additional Remarks', flow=flow, position=5,
                                                       label='additionalDeliveryComments')
Exemple #7
0
 def setUp(self):
     self.PHONE = '+12065551212'
     self.flow_id = 2436
     self.flow_uuid = 'b128ffd2-7ad8-4899-88ab-b7a863c623b5'
     self.flow = FlowFactory(label=Flow.Label.IMPLEMENTING_PARTNER)
     requests.get = MagicMock(return_value=MagicMock(status_code=200, json=MagicMock(return_value=FLOW_RESPONSE)))
     self.my_hook = reload(my_hook)
Exemple #8
0
    def test_should_return_answers_for_delivery_in_the_same_order_as_flow(
            self):
        delivery = DeliveryFactory()
        flow = FlowFactory(label='IMPLEMENTING_PARTNER')

        question_1 = MultipleChoiceQuestionFactory(
            label='deliveryReceived',
            flow=flow,
            text='Was Delivery Received?',
            position=3)
        question_2 = TextQuestionFactory(label='dateOfReceipt',
                                         flow=flow,
                                         text='When was Delivery Received?',
                                         position=1)
        question_3 = TextQuestionFactory(
            label='satisfiedWithProduct',
            flow=flow,
            text='Are you satisfied with product?',
            position=2)

        OptionFactory(text='No', question=question_1)
        OptionFactory(text='Yes', question=question_1)

        RunFactory(runnable=delivery)

        answers = delivery.answers()

        self.assertEqual(len(answers), 3)
        self.assertEqual(question_2.label, answers[0]['question_label'])
        self.assertEqual(question_3.label, answers[1]['question_label'])
        self.assertEqual(question_1.label, answers[2]['question_label'])
class RapidProFacadeTestWithRapidProNotLive(TestCase):
    def setUp(self):
        self.original_rapid_pro_live_setting = settings.RAPIDPRO_LIVE
        settings.RAPIDPRO_LIVE = False
        self.flow = FlowFactory()

    @patch('eums.rapid_pro.fake_endpoints.runs.post')
    def test_should_post_to_fake_rapid_pro_when_starting_a_run(self, mock_post):
        mock_post.return_value = None
        start_delivery_run(contact_person=contact, item_description=item_description, sender=sender,
                           flow=self.flow.rapid_pro_id)
        mock_post.assert_called()

    def tearDown(self):
        settings.RAPIDPRO_LIVE = self.original_rapid_pro_live_setting
        self.flow.delete()
Exemple #10
0
    def test_node_flow_is_middleman_for_non_end_user_node(self):
        middleman_flow = FlowFactory(label=Flow.Label.MIDDLE_MAN)
        runnable = DeliveryNodeFactory(
            tree_position=Flow.Label.IMPLEMENTING_PARTNER)

        self.assertEqual(runnable.flow(), middleman_flow)

        runnable.tree_position = Flow.Label.MIDDLE_MAN

        self.assertEqual(runnable.flow(), middleman_flow)
Exemple #11
0
    def test_should_return_answers_for_delivery(self):
        delivery = DeliveryFactory()
        flow = FlowFactory(label='IMPLEMENTING_PARTNER')

        question_1 = MultipleChoiceQuestionFactory(
            label='deliveryReceived', flow=flow, text='Was Delivery Received?')
        question_2 = TextQuestionFactory(label='dateOfReceipt',
                                         flow=flow,
                                         text='When was Delivery Received?')
        question_3 = NumericQuestionFactory(text='How much was received?',
                                            label='amountReceived',
                                            flow=flow)

        option_yes = OptionFactory(text='Yes', question=question_1)

        run = RunFactory(runnable=delivery)

        multiple_choice_answer = MultipleChoiceAnswerFactory(
            run=run, question=question_1, value=option_yes)
        text_answer = TextAnswerFactory(run=run,
                                        question=question_2,
                                        value='2015-10-10')
        numeric_answer = NumericAnswerFactory(run=run,
                                              question=question_3,
                                              value=10)

        expected_multiple_choice_answer = {
            'question_label': question_1.label,
            'type': 'multipleChoice',
            'text': question_1.text,
            'value': multiple_choice_answer.value.text,
            'options': ['Yes'],
            'position': question_1.position
        }
        expected_text_answer = {
            'question_label': question_2.label,
            'type': 'text',
            'text': question_2.text,
            'value': text_answer.value,
            'position': question_2.position
        }
        expected_numeric_answer = {
            'question_label': question_3.label,
            'type': 'numeric',
            'text': question_3.text,
            'value': numeric_answer.value,
            'position': question_3.position
        }
        answers = delivery.answers()

        self.assertEqual(len(answers), 3)
        self.assertIn(expected_multiple_choice_answer, answers)
        self.assertIn(expected_text_answer, answers)
        self.assertIn(expected_numeric_answer, answers)
Exemple #12
0
    def test_should_return_answers_for_completed_or_scheduled_runs_only(self):
        delivery = DeliveryFactory()
        flow = FlowFactory(label='IMPLEMENTING_PARTNER')

        question_1 = MultipleChoiceQuestionFactory(
            label='deliveryReceived',
            flow=flow,
            text='Was Delivery Received?',
            position=3)
        question_2 = TextQuestionFactory(label='dateOfReceipt',
                                         flow=flow,
                                         text='When was Delivery Received?',
                                         position=1)
        question_3 = TextQuestionFactory(
            label='satisfiedWithProduct',
            flow=flow,
            text='Are you satisfied with product?',
            position=2)

        option_no = OptionFactory(text='No', question=question_1)
        option_yes = OptionFactory(text='Yes', question=question_1)

        run_one = RunFactory(runnable=delivery)

        MultipleChoiceAnswerFactory(question=question_1,
                                    value=option_no,
                                    run=run_one)
        TextAnswerFactory(question=question_2, value="2014-10-10", run=run_one)
        TextAnswerFactory(question=question_3, value="yup", run=run_one)

        answers = delivery.answers()

        self.assertEqual(len(answers), 3)
        self.assertEqual(answers[0]['value'], '2014-10-10')

        run_one.status = 'cancelled'
        run_one.save()

        answers = delivery.answers()

        self.assertEqual(len(answers), 3)
        self.assertEqual(answers[0]['value'], '')

        run_two = RunFactory(runnable=delivery)

        MultipleChoiceAnswerFactory(question=question_1,
                                    value=option_yes,
                                    run=run_two)
        answers = delivery.answers()

        self.assertEqual(len(answers), 3)
        self.assertEqual(answers[0]['value'], '')
        self.assertEqual(answers[1]['value'], '')
        self.assertEqual(answers[2]['value'], 'Yes')
Exemple #13
0
    def setUp(self):
        self.__backup_original_methods()
        self.__mock_ready()
        self.flow_scheduler.settings.RAPIDPRO_LIVE = True
        self.contact = {
            'first_name': 'Test',
            'last_name': 'User',
            'phone': '+256 772 123456'
        }

        self.node = NodeFactory()
        local_celery.app.control.revoke = MagicMock(return_value=None)
        self.node.build_contact = MagicMock(return_value=self.contact)
        Node.objects.get = MagicMock(return_value=self.node)
        Runnable.objects.get = MagicMock(return_value=self.node)

        self.ip_flow = FlowFactory(label=Flow.Label.IMPLEMENTING_PARTNER)
        self.end_user_flow = FlowFactory(label=Flow.Label.END_USER)
        self.middle_man_flow = FlowFactory(label=Flow.Label.MIDDLE_MAN)

        self.MIDDLEMAN_FLOW_ID = 1
        self.END_USER_FLOW_ID = 2
        self.IMPLEMENTING_PARTNER_FLOW_ID = 3
Exemple #14
0
 def setup_flow_with_questions(self, flow_type):
     flow = FlowFactory(label=flow_type)
     delivery_received_qn = MultipleChoiceQuestionFactory(label='deliveryReceived', flow=flow)
     OptionFactory(question=delivery_received_qn, text='Yes')
     OptionFactory(question=delivery_received_qn, text='No')
     TextQuestionFactory(label='dateOfReceipt', flow=flow)
     good_order_qn = MultipleChoiceQuestionFactory(label='isDeliveryInGoodOrder', flow=flow)
     OptionFactory(question=good_order_qn, text='Yes')
     OptionFactory(question=good_order_qn, text='No')
     OptionFactory(question=good_order_qn, text='Incomplete')
     satisfied_qn = MultipleChoiceQuestionFactory(label='areYouSatisfied', flow=flow)
     OptionFactory(question=satisfied_qn, text='Yes')
     OptionFactory(question=satisfied_qn, text='No')
     TextQuestionFactory(label='additionalDeliveryComments', flow=flow)
    def setUp(self):
        web_flow = FlowFactory(label=Flow.Label.WEB)
        question = MultipleChoiceQuestionFactory(label='itemReceived',
                                                 when_answered='update_consignee_inventory',
                                                 flow=web_flow)
        OptionFactory(question=question, text='Yes')
        OptionFactory(question=question, text='No')

        self.consignee = ConsigneeFactory()
        self.item = ItemFactory()
        self.node = DeliveryNodeFactory(consignee=self.consignee, item=PurchaseOrderItemFactory(item=self.item))
        self.was_item_received = MultipleChoiceQuestion.objects.get(label='itemReceived', flow=web_flow)
        self.yes = self.was_item_received.option_set.get(text='Yes')
        self.no = self.was_item_received.option_set.get(text='No')
Exemple #16
0
    def test_should_return_a_deliveries_answers(self):
        delivery = DeliveryFactory()
        flow = FlowFactory(label='IMPLEMENTING_PARTNER')

        question_1 = MultipleChoiceQuestionFactory(label='deliveryReceived', flow=flow, text='Was Delivery Received?')
        question_2 = TextQuestionFactory(label='dateOfReceipt', flow=flow, text='When was Delivery Received?')

        option_yes = OptionFactory(text='Yes', question=question_1)

        run = RunFactory(runnable=delivery)

        MultipleChoiceAnswerFactory(run=run, question=question_1, value=option_yes)
        TextAnswerFactory(run=run, question=question_2, value='2015-10-10')

        response = self.client.get('%s%d/%s/' % (ENDPOINT_URL, delivery.id, 'answers'))

        self.assertEqual(len(response.data), 2)
    def setUp(self):
        self.original_rapid_pro_live_setting = settings.RAPIDPRO_LIVE
        settings.RAPIDPRO_LIVE = True
        self.flow = FlowFactory()

        self.expected_payload = '{' \
                                '"phone": ["+256 772 123456"],' \
                                ' "flow": 1234, ' \
                                '"extra": {' \
                                '"product": "Plumpynut",' \
                                ' "sender": "Save the Children",' \
                                ' "contactName": "Test User"' \
                                '}' \
                                '}'

        self.runs_url = settings.RAPIDPRO_URLS['RUNS']
        self.fake_json = [{"run": 1, "phone": contact['phone']}]
Exemple #18
0
    def setUp(self):
        self.consignee = ConsigneeFactory()
        self.item = ItemFactory()
        self.node = DeliveryNodeFactory(
            consignee=self.consignee,
            item=PurchaseOrderItemFactory(item=self.item))

        web_flow = FlowFactory()
        self.amount_received = NumericQuestionFactory(
            label='amountReceived',
            when_answered='update_consignee_stock_level',
            flow=web_flow)
        self.was_item_received = MultipleChoiceQuestionFactory(
            label='itemReceived',
            when_answered='update_consignee_inventory',
            flow=web_flow)
        self.run = RunFactory(runnable=self.node)

        self.amount_received = NumericQuestion.objects.get(
            label='amountReceived', flow=web_flow)
        self.run = RunFactory(runnable=self.node)
Exemple #19
0
 def setUp(self):
     self.consignee = ConsigneeFactory()
     self.item = ItemFactory()
     self.node = DeliveryNodeFactory(
         consignee=self.consignee,
         item=PurchaseOrderItemFactory(item=self.item))
     web_flow = FlowFactory()
     self.amount_received = NumericQuestionFactory(
         label='amountReceived',
         when_answered='update_consignee_stock_level',
         flow=web_flow)
     self.was_item_received = MultipleChoiceQuestionFactory(
         label='itemReceived',
         when_answered='update_consignee_inventory',
         flow=web_flow)
     option_yes = OptionFactory(question=self.was_item_received, text='Yes')
     OptionFactory(question=self.was_item_received, text='No')
     self.run = RunFactory(runnable=self.node)
     MultipleChoiceAnswerFactory(question=self.was_item_received,
                                 value=option_yes,
                                 run=self.run)
Exemple #20
0
    def test_should_return_answers_to_top_level_nodes_of_a_delivery(self):
        delivery = DeliveryFactory()
        node_one = DeliveryNodeFactory(distribution_plan=delivery)
        node_two = DeliveryNodeFactory(distribution_plan=delivery)

        flow = FlowFactory(label='WEB')

        question_1 = MultipleChoiceQuestionFactory(text='Was the item received?', label='itemReceived', flow=flow,
                                                   position=1)
        option_1 = OptionFactory(text='Yes', question=question_1)

        question_2 = NumericQuestionFactory(text='How much was received?', label='amountReceived', flow=flow)

        question_3 = MultipleChoiceQuestionFactory(text='What is the quality of the product?', label='qualityOfProduct',
                                                   flow=flow, position=3)
        option_3 = OptionFactory(text='Damaged', question=question_3)

        question_4 = MultipleChoiceQuestionFactory(text='Are you satisfied with the product?',
                                                   label='satisfiedWithProduct', flow=flow, position=4)
        option_4 = OptionFactory(text='Yes', question=question_4)

        question_5 = TextQuestionFactory(text='Remarks', label='additionalDeliveryComments',
                                         flow=flow, position=5)
        run_one = RunFactory(runnable=node_one)
        MultipleChoiceAnswerFactory(question=question_1, run=run_one, value=option_1)
        NumericAnswerFactory(question=question_2, run=run_one, value=5)
        MultipleChoiceAnswerFactory(question=question_3, run=run_one, value=option_3)
        MultipleChoiceAnswerFactory(question=question_4, run=run_one, value=option_4)
        TextAnswerFactory(question=question_5, run=run_one, value='Answer1')

        run_two = RunFactory(runnable=node_two)
        MultipleChoiceAnswerFactory(question=question_1, run=run_two, value=option_1)
        NumericAnswerFactory(question=question_2, run=run_two, value=3)
        MultipleChoiceAnswerFactory(question=question_3, run=run_two, value=option_3)
        MultipleChoiceAnswerFactory(question=question_4, run=run_two, value=option_4)
        TextAnswerFactory(question=question_5, run=run_two, value='Answer2')

        response = self.client.get('%s%d/%s/' % (ENDPOINT_URL, delivery.id, 'node_answers'))

        self.assertEqual(len(response.data), 2)
Exemple #21
0
 def setUp(self):
     self.PHONE = '+12065551212'
     self.flow_id = 2436
     self.flow = FlowFactory(rapid_pro_id=self.flow_id, for_runnable_type=Runnable.IMPLEMENTING_PARTNER)
Exemple #22
0
class HookTest(APITestCase):
    def setUp(self):
        self.PHONE = '+12065551212'
        self.flow_id = 2436
        self.flow = FlowFactory(rapid_pro_id=self.flow_id, for_runnable_type=Runnable.IMPLEMENTING_PARTNER)

    def tearDown(self):
        Alert.objects.all().delete()

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    def test_should_record_an_answer_of_type_multiple_choice_for_a_node_from_request_data(self, *_):
        uuid = '2ff9fab3-4c12-400e-a2fe-4551fa1ebc18'

        question = MultipleChoiceQuestionFactory(uuids=[uuid], text='Was item received?', label='productReceived',
                                                 flow=self.flow)

        Option.objects.get_or_create(text='Yes', question=question)
        Option.objects.get_or_create(text='No', question=question)

        delivery = DeliveryFactory()
        run = RunFactory(phone=self.PHONE, runnable=delivery)

        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, 'Yes', 'Yes', 'productReceived')

        response = self.client.post(HOOK_URL, url_params)

        expected_question = MultipleChoiceQuestion.objects.get(uuids=[uuid])
        yes_option = expected_question.option_set.get(text='Yes')

        answers = MultipleChoiceAnswer.objects.filter(question__uuids=[uuid], run=run)
        created_answer = answers.first()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(created_answer.value, yes_option)
        self.assertEqual(delivery.answers()[0]['value'], created_answer.value.text)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    def test_should_record_an_answer_of_type_multiple_choice_for_a_node__with_multiple_uuids_from_request_data(self, *_):
        uuids = ['2ff9fab3-4c12-400e-a2fe-4551fa1ebc18', 'abc9c005-7a7c-44f8-b946-e970a361b6cf']

        question = MultipleChoiceQuestionFactory(
            uuids=[uuids], text='Was item received?', label='productReceived', flow=self.flow)

        Option.objects.get_or_create(text='Yes', question=question)
        Option.objects.get_or_create(text='No', question=question)

        run = RunFactory(phone=self.PHONE)

        uuid_for_no = uuids[1]
        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid_for_no, 'No', 'No', 'productReceived')

        response = self.client.post(HOOK_URL, url_params)
        expected_question = MultipleChoiceQuestion.objects.get(uuids=[uuids])
        no_option = expected_question.option_set.get(text='No')

        answers = MultipleChoiceAnswer.objects.filter(question__uuids=[uuids], run=run)
        created_answer = answers.first()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(created_answer.value, no_option)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    def test_should_record_an_answer_of_type_text_for_a_node_from_request_data(self, *_):
        uuid = 'abc9c005-7a7c-44f8-b946-e970a361b6cf'

        TextQuestionFactory(uuids=[uuid], text='What date was it received?', label='dateOfReceipt',
                            flow=self.flow)

        run = RunFactory(phone=('%s' % self.PHONE))
        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, 'Some Text', None, 'dateOfReceipt')

        response = self.client.post(HOOK_URL, url_params)

        answers = TextAnswer.objects.filter(question__uuids=[uuid], run=run)
        created_answer = answers.first()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(created_answer.value, 'Some Text')

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    def test_should_record_an_answer_of_type_numeric_for_a_node_from_request_data(self, *_):
        uuid = '6c1cf92d-59b8-4bd3-815b-783abd3dfad9'

        NumericQuestionFactory(uuids=[uuid], text='How much was received?', label='amountReceived',
                               flow=self.flow)

        run = RunFactory(phone=('%s' % self.PHONE))
        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, 42, None, 'amountReceived')

        response = self.client.post(HOOK_URL, url_params)

        answers = NumericAnswer.objects.filter(question__uuids=[uuid], run=run)
        created_answer = answers.first()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(created_answer.value, 42)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.api.rapid_pro_hooks.hook._schedule_next_run')
    @patch('eums.models.RunQueue.dequeue')
    def test_should_dequeue_next_node_when_question_is_final(self, mock_run_queue_dequeue, mock_schedule_next_run, *_):
        mock_schedule_next_run.return_value = None
        uuid = '6c1cf92d-59b8-4bd3-815b-783abd3dfad9'

        question = NumericQuestionFactory(uuids=[uuid], text='How much was received?', label='amountReceived',
                                          flow=self.flow)

        node = DeliveryNodeFactory()

        RunFactory(runnable=node, phone=self.PHONE)

        mock_run_queue_dequeue.return_value = RunQueueFactory(runnable=node, contact_person_id=node.contact_person_id)

        self.flow.end_nodes = [[question.id, Flow.NO_OPTION]]
        self.flow.save()
        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, '42', None, 'amountReceived')
        self.client.post(HOOK_URL, url_params)

        mock_schedule_next_run.assert_called_with(node)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.api.rapid_pro_hooks.hook._schedule_next_run')
    @patch('eums.models.RunQueue.dequeue')
    def test_should_mark_run_as_complete_when_question_is_final(self, mock_run_queue_dequeue,
                                                                mock_schedule_next_run, *_):
        mock_schedule_next_run.return_value = None
        uuid = '6c1cf92d-59b8-4bd3-815b-783abd3dfad9'

        question = NumericQuestionFactory(uuids=[uuid], text='How much was received?',
                                          label='amountReceived', flow=self.flow)

        node = DeliveryNodeFactory()
        run = RunFactory(runnable=node, phone=self.PHONE,
                         status=Run.STATUS.scheduled)

        mock_run_queue_dequeue.return_value = RunQueueFactory(
            runnable=node,
            contact_person_id=node.contact_person_id)
        self.flow.end_nodes = [[question.id, Flow.NO_OPTION]]
        self.flow.save()

        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, '42', None, 'amountReceived')
        self.client.post(HOOK_URL, url_params)

        run = Run.objects.get(id=run.id)
        self.assertEqual(run.status, Run.STATUS.completed)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.api.rapid_pro_hooks.hook._schedule_next_run')
    @patch('eums.models.RunQueue.dequeue')
    def test_should_not_mark_run_as_complete_when_question_is_not_final(self, mock_run_queue_dequeue,
                                                                        mock_schedule_next_run, *_):
        mock_schedule_next_run.return_value = None

        uuid = '6c1cf92d-59b8-4bd3-815b-783abd3dfad9'

        NumericQuestionFactory(uuids=[uuid], text='How much was received?', flow=self.flow,
                               label='amountReceived')

        node = DeliveryNodeFactory()
        original_status = Run.STATUS.scheduled
        run = RunFactory(runnable=node, phone=self.PHONE,
                         status=original_status)
        mock_run_queue_dequeue.return_value = RunQueueFactory(
            runnable=node,
            contact_person_id=node.contact_person_id)

        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, '42', None, 'amountReceived')
        self.client.post(HOOK_URL, url_params)

        run = Run.objects.get(id=run.id)
        self.assertEqual(run.status, original_status)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.api.rapid_pro_hooks.hook._schedule_next_run')
    @patch('eums.models.RunQueue.dequeue')
    def test_should_mark_run_returned_by_dequeue_as_started(self, mock_run_queue_dequeue, mock_schedule_next_run, *_):
        uuid = '6c1cf92d-59b8-4bd3-815b-783abd3dfad9'

        mock_schedule_next_run.return_value = None
        question = NumericQuestionFactory(uuids=[uuid], text='How much was received?',
                                          label='amountReceived', flow=self.flow,)

        node = DeliveryNodeFactory()
        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, '42', None, 'amountReceived')

        RunFactory(runnable=node, phone=self.PHONE)

        next_run = RunQueueFactory(runnable=node,
                                   contact_person_id=node.contact_person_id)
        mock_run_queue_dequeue.return_value = next_run

        self.flow.end_nodes = [[question.id, Flow.NO_OPTION]]
        self.flow.save()

        self.client.post(HOOK_URL, url_params)

        run_returned_by_dequeue = RunQueue.objects.get(id=next_run.id)

        self.assertEqual(run_returned_by_dequeue.status, RunQueue.STATUS.started)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.services.response_alert_handler.ResponseAlertHandler.process')
    @patch('eums.api.rapid_pro_hooks.hook._schedule_next_run')
    @patch('eums.models.RunQueue.dequeue')
    def test_should_call_alert_handler_when_last_question_answered(self, mock_run_queue_dequeue,
                                                                   mock_schedule_next_run,
                                                                   mock_response_alert_handler_process, *_):
        question = NumericQuestionFactory(uuids=['1234'], text='some text', label='someLabel', flow=self.flow)

        node = DeliveryNodeFactory()
        RunFactory(runnable=node, phone=self.PHONE, status=Run.STATUS.scheduled)

        self.flow.end_nodes = [[question.id, Flow.NO_OPTION]]
        self.flow.save()

        url_params = self._create_rapid_pro_url_params(self.PHONE, '1234', '42', None, 'someLabel')
        self.client.post(HOOK_URL, url_params)

        self.assertTrue(mock_response_alert_handler_process.called)

    def _create_rapid_pro_url_params(self, phone, uuid, text="Yes", category=None, label=""):
        return {u'run': [u'4621789'], u'relayer': [u'138'], u'text': [u'%s' % text], u'flow': [u'%s' % self.flow_id],
                u'phone': [u'%s' % phone], u'step': [u'%s' % uuid],
                u'values': [u'[{"category": {"eng": "%s"}, "time": "2014-10-22T11:56:52.836354Z", '
                            u'"text": "Yes", "rule_value": "Yes", "value": "Yes", "label": "%s"}]' % (category, label)],
                u'time': [u'2014-10-22T11:57:35.606372Z']}
Exemple #23
0
    def test_node_flow_is_end_user_for_end_user_node(self):
        end_user_flow = FlowFactory(label=Flow.Label.END_USER)
        runnable = DeliveryNodeFactory(tree_position=Flow.Label.END_USER)

        self.assertEqual(runnable.flow(), end_user_flow)
 def setUp(self):
     self.original_rapid_pro_live_setting = settings.RAPIDPRO_LIVE
     settings.RAPIDPRO_LIVE = False
     self.flow = FlowFactory()
Exemple #25
0
    def test_should_return_answers_for_all_first_level_nodes_in_a_delivery(
            self):
        delivery = DeliveryFactory()
        node_one = DeliveryNodeFactory(distribution_plan=delivery)
        node_two = DeliveryNodeFactory(distribution_plan=delivery)

        flow = FlowFactory(label='WEB')

        question_1 = MultipleChoiceQuestionFactory(
            text='Was the item received?',
            label='itemReceived',
            flow=flow,
            position=1)
        option_1 = OptionFactory(text='Yes', question=question_1)

        question_2 = NumericQuestionFactory(text='How much was received?',
                                            label='amountReceived',
                                            flow=flow)

        question_3 = MultipleChoiceQuestionFactory(
            text='What is the quality of the product?',
            label='qualityOfProduct',
            flow=flow,
            position=3)
        option_3 = OptionFactory(text='Damaged', question=question_3)

        question_4 = MultipleChoiceQuestionFactory(
            text='Are you satisfied with the product?',
            label='satisfiedWithProduct',
            flow=flow,
            position=4)
        option_4 = OptionFactory(text='Yes', question=question_4)

        question_5 = TextQuestionFactory(text='Remarks',
                                         label='additionalDeliveryComments',
                                         flow=flow,
                                         position=5)
        run_one = RunFactory(runnable=node_one)
        MultipleChoiceAnswerFactory(question=question_1,
                                    run=run_one,
                                    value=option_1)
        NumericAnswerFactory(question=question_2, run=run_one, value=5)
        MultipleChoiceAnswerFactory(question=question_3,
                                    run=run_one,
                                    value=option_3)
        MultipleChoiceAnswerFactory(question=question_4,
                                    run=run_one,
                                    value=option_4)
        TextAnswerFactory(question=question_5, run=run_one, value="Answer")

        run_two = RunFactory(runnable=node_two)
        MultipleChoiceAnswerFactory(question=question_1,
                                    run=run_two,
                                    value=option_1)
        NumericAnswerFactory(question=question_2, run=run_two, value=3)
        MultipleChoiceAnswerFactory(question=question_3,
                                    run=run_two,
                                    value=option_3)
        MultipleChoiceAnswerFactory(question=question_4,
                                    run=run_two,
                                    value=option_4)
        TextAnswerFactory(question=question_5, run=run_two, value="Answer")

        node_answers = delivery.node_answers()

        expected_multiple_choice_answer = {
            'question_label': question_1.label,
            'type': 'multipleChoice',
            'text': question_1.text,
            'value': 'Yes',
            'options': ['Yes'],
            'position': question_1.position
        }
        expected_text_answer = {
            'question_label': question_5.label,
            'type': 'text',
            'text': question_5.text,
            'value': 'Answer',
            'position': question_5.position
        }

        self.assertEqual(len(node_answers), 2)

        self.assertIn(node_answers[0]['id'], [node_one.id, node_two.id])
        self.assertEqual(len(node_answers[0]['answers']), 5)
        self.assertIn(expected_multiple_choice_answer,
                      node_answers[0]['answers'])

        self.assertIn(node_answers[1]['id'], [node_one.id, node_two.id])
        self.assertEqual(len(node_answers[1]['answers']), 5)
        self.assertIn(expected_text_answer, node_answers[1]['answers'])
Exemple #26
0
    def test_should_know_question_given_label(self):
        label = 'someLabel'
        flow = FlowFactory()
        question = NumericQuestionFactory(label=label, flow=flow)

        self.assertEqual(flow.question_with(label=label), question)
Exemple #27
0
    def test_should_know_question_given_label(self):
        label = 'someLabel'
        flow = FlowFactory()
        question = NumericQuestionFactory(label=label, flow=flow)

        self.assertEqual(flow.question_with(label=label), question)
Exemple #28
0
class HookTest(AuthenticatedAPITestCase):
    def setUp(self):
        self.PHONE = '+12065551212'
        self.flow_id = 2436
        self.flow = FlowFactory(label=Flow.Label.IMPLEMENTING_PARTNER)
        requests.get = MagicMock(return_value=MagicMock(
            status_code=200, json=MagicMock(return_value=FLOW_RESPONSE)))
        self.my_hook = reload(my_hook)

    def tearDown(self):
        Alert.objects.all().delete()
        Run.objects.all().delete()
        Runnable.objects.all().delete()
        RunQueue.objects.all().delete()

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    def test_should_record_an_answer_of_type_multiple_choice_for_a_node_from_request_data(
            self, *_):
        uuid = '5b0f1f19-767f-47f1-97a5-b9b32c45a47c'

        question = MultipleChoiceQuestionFactory(text='Was product received?',
                                                 label='productReceived',
                                                 flow=self.flow)

        Option.objects.get_or_create(text='Yes', question=question)
        Option.objects.get_or_create(text='No', question=question)

        delivery = DeliveryFactory()
        run = RunFactory(phone=self.PHONE, runnable=delivery)

        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, 'Yes',
                                                       'Yes',
                                                       'productReceived')

        response = self.client.post(HOOK_URL, url_params)

        expected_question = MultipleChoiceQuestion.objects.get(
            label='productReceived')
        yes_option = expected_question.option_set.get(text='Yes')

        answers = MultipleChoiceAnswer.objects.filter(
            question__label='productReceived', run=run)
        created_answer = answers.first()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(created_answer.value, yes_option)
        self.assertEqual(delivery.answers()[0]['value'],
                         created_answer.value.text)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    def test_should_record_an_answer_of_type_multiple_choice_for_a_node_with_multiple_uuids_from_request_data(
            self, *_):
        uuids = [
            '2ff9fab3-4c12-400e-a2fe-4551fa1ebc18',
            'abc9c005-7a7c-44f8-b946-e970a361b6cf'
        ]

        question = MultipleChoiceQuestionFactory(text='Was item received?',
                                                 label='productReceived',
                                                 flow=self.flow)

        Option.objects.get_or_create(text='Yes', question=question)
        Option.objects.get_or_create(text='No', question=question)

        run = RunFactory(phone=self.PHONE)

        uuid_for_no = uuids[1]
        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid_for_no,
                                                       'No', 'No',
                                                       'productReceived')

        response = self.client.post(HOOK_URL, url_params)
        expected_question = MultipleChoiceQuestion.objects.get(
            label='productReceived')
        no_option = expected_question.option_set.get(text='No')

        answers = MultipleChoiceAnswer.objects.filter(
            question__label='productReceived', run=run)
        created_answer = answers.first()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(created_answer.value, no_option)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    def test_should_record_an_answer_of_type_text_for_a_node_from_request_data(
            self, *_):
        uuid = 'b3fad71f-ca0a-4212-b7f9-892dd3dc4c4b'

        TextQuestionFactory(text='What date was it received?',
                            label='dateOfReceipt',
                            flow=self.flow)

        run = RunFactory(phone=('%s' % self.PHONE))
        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid,
                                                       '21/12/2015', None,
                                                       'dateOfReceipt')

        response = self.client.post(HOOK_URL, url_params)

        answers = TextAnswer.objects.filter(question__label='dateOfReceipt',
                                            run=run)
        created_answer = answers.first()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(created_answer.value, '2015-12-21')

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    def test_should_record_an_answer_of_type_numeric_for_a_node_from_request_data(
            self, *_):
        uuid = '18aed9e2-125c-4c6d-a73d-c7ecdb53aa8c'

        NumericQuestionFactory(text='How much was received?',
                               label='amountReceived',
                               flow=self.flow)

        run = RunFactory(phone=('%s' % self.PHONE))
        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, 42,
                                                       None, 'amountReceived')

        response = self.client.post(HOOK_URL, url_params)

        answers = NumericAnswer.objects.filter(
            question__label='amountReceived', run=run)
        created_answer = answers.first()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(created_answer.value, 42)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.api.rapid_pro_hooks.hook._dequeue_next_run')
    @patch('eums.models.RunQueue.dequeue')
    def test_should_dequeue_next_node_when_question_is_a_final_end_node(
            self, mock_run_queue_dequeue, mock_dequeue_next_run, *_):
        uuid = '18aed9e2-125c-4c6d-a73d-c7ecdb53aa8c'
        question = NumericQuestionFactory(text='How much was received?',
                                          label='amountReceived',
                                          flow=self.flow)
        self.flow.final_end_nodes = [[question.id, Flow.NO_OPTION]]
        self.flow.save()

        node = DeliveryNodeFactory()
        next_node = copy.deepcopy(node)
        current_run = RunFactory(runnable=node, phone=self.PHONE)
        next_runqueue = RunQueueFactory(
            runnable=next_node, contact_person_id=node.contact_person_id)

        mock_run_queue_dequeue.return_value = next_runqueue

        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, '42',
                                                       None, 'amountReceived')
        self.client.post(HOOK_URL, url_params)

        mock_dequeue_next_run.assert_called_with(node.contact_person_id, 10)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.api.rapid_pro_hooks.hook._dequeue_next_run')
    def test_should_mark_run_as_complete_when_question_is_a_final_end_node(
            self, mock_schedule_next_run, *_):
        mock_schedule_next_run.return_value = None
        uuid = '18aed9e2-125c-4c6d-a73d-c7ecdb53aa8c'
        question = NumericQuestionFactory(text='How much was received?',
                                          label='amountReceived',
                                          flow=self.flow)
        self.flow.final_end_nodes = [[question.id, Flow.NO_OPTION]]
        self.flow.save()

        node = DeliveryNodeFactory()
        current_run = RunFactory(runnable=node, phone=self.PHONE)

        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, '42',
                                                       None, 'amountReceived')
        self.client.post(HOOK_URL, url_params)

        run = Run.objects.get(id=current_run.id)
        self.assertEqual(run.status, Run.STATUS.completed)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.api.rapid_pro_hooks.hook._dequeue_next_run')
    @patch('eums.models.RunQueue.dequeue')
    def test_should_not_mark_run_as_complete_when_question_is_not_end_node(
            self, mock_run_queue_dequeue, mock_schedule_next_run, *_):
        uuid = '18aed9e2-125c-4c6d-a73d-c7ecdb53aa8c'
        mock_schedule_next_run.return_value = None
        NumericQuestionFactory(text='How much was received?',
                               flow=self.flow,
                               label='amountReceived')

        node = DeliveryNodeFactory()
        original_status = Run.STATUS.scheduled
        run = RunFactory(runnable=node,
                         phone=self.PHONE,
                         status=original_status)
        mock_run_queue_dequeue.return_value = RunQueueFactory(
            runnable=node, contact_person_id=node.contact_person_id)

        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, '42',
                                                       None, 'amountReceived')
        self.client.post(HOOK_URL, url_params)

        run = Run.objects.get(id=run.id)
        self.assertEqual(run.status, original_status)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.models.RunQueue.dequeue')
    def test_should_mark_run_returned_by_dequeue_as_started(
            self, mock_run_queue_dequeue, *_):
        uuid = '18aed9e2-125c-4c6d-a73d-c7ecdb53aa8c'

        question = NumericQuestionFactory(
            text='How much was received?',
            label='amountReceived',
            flow=self.flow,
        )
        self.flow.final_end_nodes = [[question.id, Flow.NO_OPTION]]
        self.flow.save()

        current_node = DeliveryNodeFactory()
        next_node = copy.deepcopy(current_node)

        RunFactory(runnable=current_node, phone=self.PHONE)
        next_run_queue = RunQueueFactory(
            runnable=next_node,
            contact_person_id=current_node.contact_person_id)

        mock_run_queue_dequeue.return_value = next_run_queue

        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, '42',
                                                       None, 'amountReceived')
        self.client.post(HOOK_URL, url_params)

        run_returned_by_dequeue = RunQueue.objects.get(id=next_run_queue.id)

        self.assertEqual(run_returned_by_dequeue.status,
                         RunQueue.STATUS.started)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.services.response_alert_handler.ResponseAlertHandler.process')
    @patch('eums.api.rapid_pro_hooks.hook._dequeue_next_run')
    @patch('eums.models.RunQueue.dequeue')
    def test_should_call_alert_handler_when_last_question_answered(
            self, mock_run_queue_dequeue, mock_dequeue_next_run,
            mock_response_alert_handler_process, *_):
        question = NumericQuestionFactory(text='some text',
                                          label='someLabel',
                                          flow=self.flow)

        node = DeliveryNodeFactory()
        RunFactory(runnable=node,
                   phone=self.PHONE,
                   status=Run.STATUS.scheduled)

        self.flow.final_end_nodes = [[question.id, Flow.NO_OPTION]]
        self.flow.save()

        url_params = self._create_rapid_pro_url_params(self.PHONE, '1234',
                                                       '42', None, 'someLabel')
        self.client.post(HOOK_URL, url_params)

        self.assertTrue(mock_response_alert_handler_process.called)

    def _create_rapid_pro_url_params(self,
                                     phone,
                                     uuid,
                                     text="Yes",
                                     category=None,
                                     label=""):
        return {
            u'run': [u'4621789'],
            u'relayer': [u'138'],
            u'text': [u'%s' % text],
            u'flow': [u'%s' % self.flow_id],
            u'phone': [u'%s' % phone],
            u'step': [u'%s' % uuid],
            u'values': [
                u'[{"category": {"eng": "%s"}, "time": "2014-10-22T11:56:52.836354Z", '
                u'"text": "Yes", "rule_value": "Yes", "value": "Yes", "label": "%s"}]'
                % (category, label)
            ],
            u'time': [u'2014-10-22T11:57:35.606372Z']
        }
Exemple #29
0
 def setUp(self):
     self.PHONE = '+12065551212'
     self.flow_id = 2436
     self.flow = FlowFactory(label=Flow.Label.IMPLEMENTING_PARTNER)
     requests.get = MagicMock(return_value=MagicMock(status_code=200, json=MagicMock(return_value=FLOW_RESPONSE)))
Exemple #30
0
class HookTest(AuthenticatedAPITestCase):
    def setUp(self):
        self.PHONE = '+12065551212'
        self.flow_id = 2436
        self.flow_uuid = 'b128ffd2-7ad8-4899-88ab-b7a863c623b5'
        self.flow = FlowFactory(label=Flow.Label.IMPLEMENTING_PARTNER)
        requests.get = MagicMock(return_value=MagicMock(status_code=200, json=MagicMock(return_value=FLOW_RESPONSE)))
        self.my_hook = reload(my_hook)

    def tearDown(self):
        Alert.objects.all().delete()
        Run.objects.all().delete()
        Runnable.objects.all().delete()
        RunQueue.objects.all().delete()

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    def test_should_record_an_answer_of_type_multiple_choice_for_a_node_from_request_data(self, *_):
        uuid = '5b0f1f19-767f-47f1-97a5-b9b32c45a47c'

        question = MultipleChoiceQuestionFactory(text='Was product received?', label='productReceived', flow=self.flow)

        Option.objects.get_or_create(text='Yes', question=question)
        Option.objects.get_or_create(text='No', question=question)

        delivery = DeliveryFactory()
        run = RunFactory(phone=self.PHONE, runnable=delivery)

        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, 'Yes', 'Yes', 'productReceived')

        response = self.client.post(HOOK_URL, url_params)

        expected_question = MultipleChoiceQuestion.objects.get(label='productReceived')
        yes_option = expected_question.option_set.get(text='Yes')

        answers = MultipleChoiceAnswer.objects.filter(question__label='productReceived', run=run)
        created_answer = answers.first()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(created_answer.value, yes_option)
        self.assertEqual(delivery.answers()[0]['value'], created_answer.value.text)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    def test_should_record_an_answer_of_type_multiple_choice_for_a_node_with_multiple_uuids_from_request_data(self, *_):
        uuids = ['2ff9fab3-4c12-400e-a2fe-4551fa1ebc18', 'abc9c005-7a7c-44f8-b946-e970a361b6cf']

        question = MultipleChoiceQuestionFactory(text='Was item received?', label='productReceived', flow=self.flow)

        Option.objects.get_or_create(text='Yes', question=question)
        Option.objects.get_or_create(text='No', question=question)

        run = RunFactory(phone=self.PHONE)

        uuid_for_no = uuids[1]
        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid_for_no, 'No', 'No', 'productReceived')

        response = self.client.post(HOOK_URL, url_params)
        expected_question = MultipleChoiceQuestion.objects.get(label='productReceived')
        no_option = expected_question.option_set.get(text='No')

        answers = MultipleChoiceAnswer.objects.filter(question__label='productReceived', run=run)
        created_answer = answers.first()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(created_answer.value, no_option)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    def test_should_record_an_answer_of_type_text_for_a_node_from_request_data(self, *_):
        uuid = 'b3fad71f-ca0a-4212-b7f9-892dd3dc4c4b'

        TextQuestionFactory(text='What date was it received?', label='dateOfReceipt', flow=self.flow)

        run = RunFactory(phone=('%s' % self.PHONE))
        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, '21/12/2015', None, 'dateOfReceipt')

        response = self.client.post(HOOK_URL, url_params)

        answers = TextAnswer.objects.filter(question__label='dateOfReceipt', run=run)
        created_answer = answers.first()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(created_answer.value, '2015-12-21')

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    def test_should_record_an_answer_of_type_numeric_for_a_node_from_request_data(self, *_):
        uuid = '18aed9e2-125c-4c6d-a73d-c7ecdb53aa8c'

        NumericQuestionFactory(text='How much was received?', label='amountReceived', flow=self.flow)

        run = RunFactory(phone=('%s' % self.PHONE))
        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, 42, None, 'amountReceived')

        response = self.client.post(HOOK_URL, url_params)

        answers = NumericAnswer.objects.filter(question__label='amountReceived', run=run)
        created_answer = answers.first()

        self.assertEqual(response.status_code, 200)
        self.assertEqual(created_answer.value, 42)


    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.api.rapid_pro_hooks.hook._dequeue_next_run')
    @patch('eums.models.RunQueue.dequeue')
    def test_should_dequeue_next_node_when_question_is_a_final_end_node(self, mock_run_queue_dequeue,
                                                                        mock_dequeue_next_run, *_):
        uuid = '18aed9e2-125c-4c6d-a73d-c7ecdb53aa8c'
        question = NumericQuestionFactory(text='How much was received?', label='amountReceived', flow=self.flow)
        self.flow.final_end_nodes = [[question.id, Flow.NO_OPTION]]
        self.flow.save()

        node = DeliveryNodeFactory()
        next_node = copy.deepcopy(node)
        current_run = RunFactory(runnable=node, phone=self.PHONE)
        next_runqueue = RunQueueFactory(runnable=next_node, contact_person_id=node.contact_person_id)

        mock_run_queue_dequeue.return_value = next_runqueue

        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, '42', None, 'amountReceived')
        self.client.post(HOOK_URL, url_params)

        mock_dequeue_next_run.assert_called_with(node.contact_person_id, 10)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.api.rapid_pro_hooks.hook._dequeue_next_run')
    def test_should_mark_run_as_complete_when_question_is_a_final_end_node(self,
                                                                           mock_schedule_next_run, *_):
        mock_schedule_next_run.return_value = None
        uuid = '18aed9e2-125c-4c6d-a73d-c7ecdb53aa8c'
        question = NumericQuestionFactory(text='How much was received?', label='amountReceived', flow=self.flow)
        self.flow.final_end_nodes = [[question.id, Flow.NO_OPTION]]
        self.flow.save()

        node = DeliveryNodeFactory()
        current_run = RunFactory(runnable=node, phone=self.PHONE)

        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, '42', None, 'amountReceived')
        self.client.post(HOOK_URL, url_params)

        run = Run.objects.get(id=current_run.id)
        self.assertEqual(run.status, Run.STATUS.completed)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.api.rapid_pro_hooks.hook._dequeue_next_run')
    @patch('eums.models.RunQueue.dequeue')
    def test_should_not_mark_run_as_complete_when_question_is_not_end_node(self, mock_run_queue_dequeue,
                                                                           mock_schedule_next_run, *_):
        uuid = '18aed9e2-125c-4c6d-a73d-c7ecdb53aa8c'
        mock_schedule_next_run.return_value = None
        NumericQuestionFactory(text='How much was received?', flow=self.flow, label='amountReceived')

        node = DeliveryNodeFactory()
        original_status = Run.STATUS.scheduled
        run = RunFactory(runnable=node, phone=self.PHONE, status=original_status)
        mock_run_queue_dequeue.return_value = RunQueueFactory(runnable=node, contact_person_id=node.contact_person_id)

        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, '42', None, 'amountReceived')
        self.client.post(HOOK_URL, url_params)

        run = Run.objects.get(id=run.id)
        self.assertEqual(run.status, original_status)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.models.RunQueue.dequeue')
    def test_should_mark_run_returned_by_dequeue_as_started(self, mock_run_queue_dequeue, *_):
        uuid = '18aed9e2-125c-4c6d-a73d-c7ecdb53aa8c'

        question = NumericQuestionFactory(text='How much was received?', label='amountReceived', flow=self.flow, )
        self.flow.final_end_nodes = [[question.id, Flow.NO_OPTION]]
        self.flow.save()

        current_node = DeliveryNodeFactory()
        next_node = copy.deepcopy(current_node)

        RunFactory(runnable=current_node, phone=self.PHONE)
        next_run_queue = RunQueueFactory(runnable=next_node, contact_person_id=current_node.contact_person_id)

        mock_run_queue_dequeue.return_value = next_run_queue

        url_params = self._create_rapid_pro_url_params(self.PHONE, uuid, '42', None, 'amountReceived')
        self.client.post(HOOK_URL, url_params)

        run_returned_by_dequeue = RunQueue.objects.get(id=next_run_queue.id)

        self.assertEqual(run_returned_by_dequeue.status, RunQueue.STATUS.started)

    @patch('eums.api.rapid_pro_hooks.hook.logger.info')
    @patch('eums.services.response_alert_handler.ResponseAlertHandler.process')
    @patch('eums.api.rapid_pro_hooks.hook._dequeue_next_run')
    @patch('eums.models.RunQueue.dequeue')
    def test_should_call_alert_handler_when_last_question_answered(self, mock_run_queue_dequeue,
                                                                   mock_dequeue_next_run,
                                                                   mock_response_alert_handler_process, *_):
        question = NumericQuestionFactory(text='some text', label='someLabel', flow=self.flow)

        node = DeliveryNodeFactory()
        RunFactory(runnable=node, phone=self.PHONE, status=Run.STATUS.scheduled)

        self.flow.final_end_nodes = [[question.id, Flow.NO_OPTION]]
        self.flow.save()

        url_params = self._create_rapid_pro_url_params(self.PHONE, '1234', '42', None, 'someLabel')
        self.client.post(HOOK_URL, url_params)

        self.assertTrue(mock_response_alert_handler_process.called)

    def _create_rapid_pro_url_params(self, phone, uuid, text="Yes", category=None, label=""):
        return {u'run': [u'4621789'], u'relayer': [u'138'], u'text': [u'%s' % text], u'flow': [u'%s' % self.flow_id],
                u'phone': [u'%s' % phone], u'step': [u'%s' % uuid], u'flow_uuid': [u'%s' % self.flow_uuid],
                u'values': [u'[{"category": {"eng": "%s"}, "time": "2014-10-22T11:56:52.836354Z", '
                            u'"text": "Yes", "rule_value": "Yes", "value": "Yes", "label": "%s"}]' % (category, label)],
                u'time': [u'2014-10-22T11:57:35.606372Z']}
Exemple #31
0
 def setup_flow(self):
     self.ip_flow = FlowFactory(label=Flow.Label.IMPLEMENTING_PARTNER)
Exemple #32
0
    def test_delivery_flow_is_ipflow_for_ip(self):
        ip_flow = FlowFactory(label=Flow.Label.IMPLEMENTING_PARTNER)
        runnable = DeliveryFactory()

        self.assertEqual(runnable.flow(), ip_flow)
Exemple #33
0
 def setUp(self):
     self.PHONE = '+12065551212'
     self.flow_id = 2436
     self.flow = FlowFactory.create(rapid_pro_id=self.flow_id)
Exemple #34
0
    def test_should_know_question_given_uuid(self):
        uuid = ["some uuid"]
        flow = FlowFactory()
        question = NumericQuestionFactory(uuids=uuid, flow=flow)

        self.assertEqual(flow.question_with(uuid=uuid), question)
Exemple #35
0
 def setUp(self):
     self.flow_ip = FlowFactory(label=Flow.Label.IMPLEMENTING_PARTNER)
     FlowFactory(label=Flow.Label.END_USER)
     FlowFactory(label=Flow.Label.MIDDLE_MAN)
     super(AlertEndpointTest, self).setUp()
Exemple #36
0
    def setup_nodes_with_answers(self):
        DistributionPlanNode.append_positive_answers = MagicMock(return_value=None)
        ip = ConsigneeFactory(name='ip one')
        middle_man = ConsigneeFactory(name='middle man one', type=Consignee.TYPES.middle_man)
        end_user_one = ConsigneeFactory(name='consignee one', type=Consignee.TYPES.end_user)
        end_user_two = ConsigneeFactory(name='consignee two', type=Consignee.TYPES.end_user)
        programme_one = ProgrammeFactory(name='my first programme')
        programme_two = ProgrammeFactory(name='my second programme')
        programme_three = ProgrammeFactory(name='my third programme')
        purchase_order_item = PurchaseOrderItemFactory(item=ItemFactory(description='Mama kit'),
                                                       purchase_order=PurchaseOrderFactory(order_number=329293))
        release_order_item = ReleaseOrderItemFactory(item=ItemFactory(description='Baba bla bla'),
                                                     release_order=ReleaseOrderFactory(waybill=5540322))

        ip_node_one = DeliveryNodeFactory(consignee=ip, item=purchase_order_item, quantity=1500,
                                          programme=programme_one, track=True,
                                          distribution_plan=DeliveryFactory(track=True),
                                          location='Fort portal', tree_position=Flow.Label.IMPLEMENTING_PARTNER)
        ip_node_two = DeliveryNodeFactory(consignee=ip, item=release_order_item, quantity=100,
                                          distribution_plan=DeliveryFactory(track=True), programme=programme_two,
                                          location='Kampala', tree_position=Flow.Label.IMPLEMENTING_PARTNER, track=True)
        ip_node_three = DeliveryNodeFactory(consignee=ip, item=release_order_item, quantity=100,
                                            distribution_plan=DeliveryFactory(track=True), programme=programme_two,
                                            location='Gulu', tree_position=Flow.Label.IMPLEMENTING_PARTNER, track=True)
        ip_node_four = DeliveryNodeFactory(consignee=ip, item=purchase_order_item, quantity=100,
                                           distribution_plan=DeliveryFactory(track=True), programme=programme_three,
                                           location='Gulu', tree_position=Flow.Label.IMPLEMENTING_PARTNER, track=True)

        middle_man_node = DeliveryNodeFactory(consignee=middle_man, item=purchase_order_item,
                                              programme=programme_one, location='Wakiso', track=True,
                                              tree_position=Flow.Label.MIDDLE_MAN, parents=[(ip_node_one, 1500)],
                                              distribution_plan=None)
        end_user_node_one = DeliveryNodeFactory(consignee=end_user_one,
                                                item=purchase_order_item, parents=[(middle_man_node, 1000)],
                                                programme=programme_one, location='Amuru', track=True,
                                                distribution_plan=None)
        end_user_node_two = DeliveryNodeFactory(consignee=end_user_two, item=purchase_order_item, track=True,
                                                parents=[(middle_man_node, 500)], programme=programme_one,
                                                distribution_plan=None)
        assign_to_self_node = DeliveryNodeFactory(consignee=ip, item=purchase_order_item,
                                                  tree_position=Flow.Label.END_USER, parents=[(ip_node_four, 93)],
                                                  programme=programme_three, distribution_plan=None,
                                                  is_assigned_to_self=True)

        # IP_ITEM Flow and Questions
        ip_item_flow = FlowFactory(label=Flow.Label.IMPLEMENTING_PARTNER)
        ip_item_question_1 = MultipleChoiceQuestionFactory(text='Was the item received?', label='itemReceived',
                                                           when_answered='update_consignee_inventory',
                                                           flow=ip_item_flow, position=1)
        ip_item_option_1 = OptionFactory(text='Yes', question=ip_item_question_1)
        ip_item_option_no = OptionFactory(text='No', question=ip_item_question_1)
        ip_item_question_2 = NumericQuestionFactory(text='How much was received?', label='amountReceived',
                                                    when_answered='update_consignee_stock_level', flow=ip_item_flow,
                                                    position=3)
        ip_item_question_3 = MultipleChoiceQuestionFactory(text='What is the quality of the product?',
                                                           label='qualityOfProduct',
                                                           flow=ip_item_flow, position=3)
        ip_item_option_2 = OptionFactory(text='Good', question=ip_item_question_3)
        ip_item_option_3 = OptionFactory(text='Damaged', question=ip_item_question_3)
        ip_item_question_4 = MultipleChoiceQuestionFactory(text='Are you satisfied with the product?',
                                                           label='satisfiedWithProduct', flow=ip_item_flow, position=4)
        ip_item_option_4 = OptionFactory(text='Yes', question=ip_item_question_4)
        ip_item_option_5 = OptionFactory(text='No', question=ip_item_question_4)

        # MIDDLE_MAN Flow and Questions
        middle_man_flow = FlowFactory(label=Flow.Label.MIDDLE_MAN)
        mm_question_1 = MultipleChoiceQuestionFactory(text='Was product received?', label='productReceived',
                                                      flow=middle_man_flow, position=1)
        mm_option_1 = OptionFactory(text='Yes', question=mm_question_1)
        mm_option_2 = OptionFactory(text='No', question=mm_question_1)
        mm_question_2 = TextQuestionFactory(label='dateOfReceipt', flow=middle_man_flow,
                                            text='When was item received?', position=2)
        mm_question_3 = NumericQuestionFactory(text='What is the amount received?', label='amountReceived',
                                               flow=middle_man_flow, position=3)

        end_user_flow = FlowFactory(label=Flow.Label.END_USER)
        eu_question_1 = MultipleChoiceQuestionFactory(text='Was the item received?', label='itemReceived',
                                                      flow=end_user_flow, position=1)
        eu_option_1 = OptionFactory(text='Yes', question=eu_question_1)
        eu_question_2 = NumericQuestionFactory(text='How much was received?', label='amountReceived',
                                               flow=end_user_flow)
        eu_question_3 = MultipleChoiceQuestionFactory(text='What is the quality of the product?',
                                                      label='qualityOfProduct', flow=end_user_flow, position=3)
        eu_option_3 = OptionFactory(text='Damaged', question=eu_question_3)
        eu_option_3_1 = OptionFactory(text='Good', question=eu_question_3)
        eu_question_4 = MultipleChoiceQuestionFactory(text='Are you satisfied with the product?',
                                                      label='satisfiedWithProduct', flow=end_user_flow, position=4)
        eu_option_4 = OptionFactory(text='Yes', question=eu_question_4)
        eu_question_5 = TextQuestionFactory(label='dateOfReceipt', flow=end_user_flow,
                                            text='When was Delivery Received?')

        ip_run_one = RunFactory(runnable=ip_node_one)
        MultipleChoiceAnswerFactory(question=ip_item_question_1, run=ip_run_one, value=ip_item_option_1)
        NumericAnswerFactory(question=ip_item_question_2, run=ip_run_one, value=1500)
        MultipleChoiceAnswerFactory(question=ip_item_question_3, run=ip_run_one, value=ip_item_option_2)
        MultipleChoiceAnswerFactory(question=ip_item_question_4, run=ip_run_one, value=ip_item_option_4)

        ip_run_three = RunFactory(runnable=ip_node_three)
        MultipleChoiceAnswerFactory(question=ip_item_question_1, run=ip_run_three, value=ip_item_option_no)

        ip_run_two = RunFactory(runnable=ip_node_two)
        MultipleChoiceAnswerFactory(question=ip_item_question_1, run=ip_run_two, value=ip_item_option_1)
        NumericAnswerFactory(question=ip_item_question_2, run=ip_run_two, value=50)
        MultipleChoiceAnswerFactory(question=ip_item_question_3, run=ip_run_two, value=ip_item_option_3)
        MultipleChoiceAnswerFactory(question=ip_item_question_4, run=ip_run_two, value=ip_item_option_5)

        middle_man_node_run = RunFactory(runnable=middle_man_node)
        MultipleChoiceAnswerFactory(question=mm_question_1, run=middle_man_node_run, value=mm_option_1)
        TextAnswerFactory(question=mm_question_2, run=middle_man_node_run, value='2014-9-25')
        NumericAnswerFactory(question=mm_question_3, run=middle_man_node_run, value=1501, remark='Some remark 2')

        end_user_run_one = RunFactory(runnable=end_user_node_one)
        MultipleChoiceAnswerFactory(question=eu_question_1, run=end_user_run_one, value=eu_option_1)
        NumericAnswerFactory(question=eu_question_2, run=end_user_run_one, value=5)
        MultipleChoiceAnswerFactory(question=eu_question_3, run=end_user_run_one, value=eu_option_3)
        MultipleChoiceAnswerFactory(question=eu_question_4, run=end_user_run_one, value=eu_option_4)
        TextAnswerFactory(run=end_user_run_one, question=eu_question_5, value='2014-10-10')

        end_user_run_two = RunFactory(runnable=end_user_node_two)
        MultipleChoiceAnswerFactory(question=eu_question_1, run=end_user_run_two, value=eu_option_1)
        NumericAnswerFactory(question=eu_question_2, run=end_user_run_two, value=500)
        MultipleChoiceAnswerFactory(question=eu_question_3, run=end_user_run_two, value=eu_option_3)
        MultipleChoiceAnswerFactory(question=eu_question_4, run=end_user_run_two, value=eu_option_4)
        TextAnswerFactory(question=eu_question_5, run=end_user_run_two, value='2013-12-12')

        assign_to_self_run = RunFactory(runnable=assign_to_self_node)
        MultipleChoiceAnswerFactory(question=eu_question_1, run=assign_to_self_run, value=eu_option_1)
        NumericAnswerFactory(question=eu_question_2, run=assign_to_self_run, value=500)
        TextAnswerFactory(question=eu_question_5, run=assign_to_self_run, value='2013-12-14')
        MultipleChoiceAnswerFactory(question=eu_question_3, run=assign_to_self_run, value=eu_option_3_1)
        MultipleChoiceAnswerFactory(question=eu_question_4, run=assign_to_self_run, value=eu_option_4)

        return end_user_node_one, purchase_order_item, release_order_item, end_user_node_two, ip_node_two, ip, assign_to_self_node