Ejemplo n.º 1
0
    def test_group_changes(self):
        flow = self.create_flow("Test")
        nodes = flow.get_definition()["nodes"]

        contact1 = self.create_contact("Joe", phone="1234")
        contact2 = self.create_contact("Frank", phone="2345")
        contact3 = self.create_contact("Anne", phone="3456")

        group1 = self.create_group("Group 1", contacts=[contact3])
        group2 = self.create_group("Group 2", contacts=[])
        group3 = self.create_group("Group 3", contacts=[contact1, contact2])

        # simulate a flow start which adds contacts 1 and 2 to groups 1 and 2, and removes them from group 3
        start1 = FlowStart.create(flow,
                                  self.admin,
                                  contacts=[contact1, contact2])
        (MockSessionWriter(contact1, flow,
                           start=start1).visit(nodes[0]).add_contact_groups([
                               group1, group2
                           ]).remove_contact_groups([group3
                                                     ]).complete().save())
        (MockSessionWriter(contact2, flow,
                           start=start1).visit(nodes[0]).add_contact_groups([
                               group1, group2
                           ]).remove_contact_groups([group3
                                                     ]).complete().save())

        # and another which adds contact 3 to group 3
        start2 = FlowStart.create(flow, self.admin, contacts=[contact3])
        (MockSessionWriter(contact3, flow, start=start2).visit(
            nodes[0]).add_contact_groups([group3]).complete().save())

        t0 = timezone.now()

        self.assertEqual({contact1, contact2, contact3},
                         set(group1.contacts.all()))
        self.assertEqual({contact1, contact2}, set(group2.contacts.all()))
        self.assertEqual({contact3}, set(group3.contacts.all()))

        # can run with --dry-run to preview changes
        call_command("undo_footgun", start=start1.id, dry_run=True, quiet=True)

        self.assertEqual({contact1, contact2, contact3},
                         set(group1.contacts.all()))
        self.assertEqual({contact1, contact2}, set(group2.contacts.all()))
        self.assertEqual({contact3}, set(group3.contacts.all()))

        # no contacts will have had modified_on updated
        self.assertEqual(0, Contact.objects.filter(modified_on__gt=t0).count())

        # and then actually make database changes
        call_command("undo_footgun", start=start1.id, quiet=True)

        self.assertEqual({contact3}, set(group1.contacts.all()))
        self.assertEqual(set(), set(group2.contacts.all()))
        self.assertEqual({contact1, contact2, contact3},
                         set(group3.contacts.all()))

        # contacts 1 and 2 will have had modified_on updated
        self.assertEqual(2, Contact.objects.filter(modified_on__gt=t0).count())
Ejemplo n.º 2
0
    def test_queue_interrupt_by_session(self):
        jim = self.create_contact("Jim", "+12065551212")

        flow = self.get_flow("favorites")
        flow_nodes = flow.as_json()["nodes"]
        color_prompt = flow_nodes[0]
        color_split = flow_nodes[2]

        (MockSessionWriter(jim, flow).visit(color_prompt).send_msg(
            "What is your favorite color?",
            self.channel).visit(color_split).wait().save())

        run = FlowRun.objects.get(contact=jim)
        session = run.session
        run.release("U")

        self.assert_org_queued(self.org, "batch")
        self.assert_queued_batch_task(
            self.org,
            {
                "type": "interrupt_sessions",
                "org_id": self.org.id,
                "task": {
                    "session_ids": [session.id]
                },
                "queued_on": matchers.ISODate(),
            },
        )
Ejemplo n.º 3
0
    def test_from_flow_run(self):
        contact = self.create_contact("Jim", phone="0979111111")
        flow = self.get_flow("color_v13")
        nodes = flow.get_definition()["nodes"]
        (MockSessionWriter(contact, flow).visit(nodes[0]).send_msg(
            "What is your favorite color?", self.channel).wait().save())
        run = contact.runs.get()

        self.assertEqual(
            {
                "type": "flow_entered",
                "created_on": matchers.ISODate(),
                "flow": {
                    "uuid": str(flow.uuid),
                    "name": "Colors"
                },
                "logs_url": None,
            },
            Event.from_flow_run(self.org, self.admin, run),
        )

        # customer support get access to logs
        self.assertEqual(
            {
                "type": "flow_entered",
                "created_on": matchers.ISODate(),
                "flow": {
                    "uuid": str(flow.uuid),
                    "name": "Colors"
                },
                "logs_url": f"/flowsession/json/{run.session.uuid}/",
            },
            Event.from_flow_run(self.org, self.customer_support, run),
        )
Ejemplo n.º 4
0
    def test_status_changes(self):
        flow = self.create_flow("Test")
        nodes = flow.get_definition()["nodes"]

        contact1 = self.create_contact("Joe", phone="1234")
        contact2 = self.create_contact("Frank", phone="2345")
        contact3 = self.create_contact("Anne", phone="3456")

        # simulate a flow start which adds blocks contact1 and stops contact2
        start1 = FlowStart.create(flow,
                                  self.admin,
                                  contacts=[contact1, contact2])
        (MockSessionWriter(contact1, flow, start=start1).visit(
            nodes[0]).set_contact_status("blocked").complete().save())
        (MockSessionWriter(contact2, flow, start=start1).visit(
            nodes[0]).set_contact_status("stopped").complete().save())

        t0 = timezone.now()

        self.assertEqual({contact1}, set(Contact.objects.filter(status="B")))
        self.assertEqual({contact2}, set(Contact.objects.filter(status="S")))
        self.assertEqual({contact3}, set(Contact.objects.filter(status="A")))

        # can run with --dry-run to preview changes
        call_command("undo_footgun", start=start1.id, dry_run=True, quiet=True)

        self.assertEqual({contact1}, set(Contact.objects.filter(status="B")))
        self.assertEqual({contact2}, set(Contact.objects.filter(status="S")))
        self.assertEqual({contact3}, set(Contact.objects.filter(status="A")))

        # no contacts will have had modified_on updated
        self.assertEqual(0, Contact.objects.filter(modified_on__gt=t0).count())

        # and then actually make database changes
        call_command("undo_footgun", start=start1.id, quiet=True)

        self.assertEqual({contact1, contact2, contact3},
                         set(Contact.objects.filter(status="A")))
Ejemplo n.º 5
0
    def test_recalc_node_counts(self):
        contact1 = self.create_contact("Ben Haggerty", phone="+12065552020")
        contact2 = self.create_contact("Joe", phone="+12065550002")
        contact3 = self.create_contact("Frank", phone="+12065550003")

        def check_node_count_rebuild(flow, assert_count):
            node_counts = FlowNodeCount.get_totals(flow)

            call_command("recalc_node_counts", flow_id=flow.id)

            new_counts = FlowNodeCount.get_totals(flow)
            self.assertEqual(new_counts, node_counts)
            self.assertEqual(assert_count, sum(new_counts.values()))

        flow = self.get_flow("favorites_v13")
        nodes = flow.get_definition()["nodes"]

        color_prompt = nodes[0]
        color_other = nodes[1]
        color_split = nodes[2]
        beer_prompt = nodes[3]
        beer_split = nodes[5]
        name_prompt = nodes[6]
        name_split = nodes[7]
        name_reply = nodes[8]

        session1 = MockSessionWriter(
            contact1,
            flow).visit(color_prompt).visit(color_split).wait().save()
        session2 = MockSessionWriter(
            contact2,
            flow).visit(color_prompt).visit(color_split).wait().save()
        session3 = MockSessionWriter(
            contact3,
            flow).visit(color_prompt).visit(color_split).wait().save()

        # recalculate node counts and check they are the same
        check_node_count_rebuild(flow, 3)

        (session1.resume(self.create_incoming_msg(
            contact1,
            "Blue")).visit(beer_prompt).visit(beer_split).wait().save())
        (session2.resume(self.create_incoming_msg(
            contact2,
            "Beige")).visit(color_other).visit(color_split).wait().save())
        (session3.resume(self.create_incoming_msg(
            contact3,
            "Amber")).visit(color_other).visit(color_split).wait().save())

        check_node_count_rebuild(flow, 3)

        (session1.resume(self.create_incoming_msg(
            contact1,
            "Primus")).visit(name_prompt).visit(name_split).wait().save())
        (session2.resume(self.create_incoming_msg(
            contact2,
            "Orange")).visit(color_other).visit(color_split).wait().save())
        (session3.resume(self.create_incoming_msg(
            contact3,
            "Amber")).visit(color_other).visit(color_split).wait().save())

        check_node_count_rebuild(flow, 3)

        # contact1 replies with name to complete the flow
        (session1.resume(self.create_incoming_msg(
            contact1, "Bob")).visit(name_reply).complete().save())

        check_node_count_rebuild(flow, 2)