Exemple #1
0
    def test_push_label(self, mock_get_labels, mock_create_label):
        mock_get_labels.return_value = MockClientQuery([TembaLabel.create(uuid="L-011", name="Tea", count=213)])

        # check when label with name exists
        self.tea.uuid = None
        self.tea.save()
        self.backend.push_label(self.unicef, self.tea)

        self.tea.refresh_from_db()
        self.assertEqual(self.tea.uuid, "L-011")

        self.assertNotCalled(mock_create_label)

        # check when label doesn't exist
        mock_get_labels.return_value = MockClientQuery([])
        mock_create_label.return_value = TembaLabel.create(uuid="L-012", name="Tea", count=0)

        self.tea.uuid = None
        self.tea.save()
        self.backend.push_label(self.unicef, self.tea)

        self.tea.refresh_from_db()
        self.assertEqual(self.tea.uuid, "L-012")

        mock_create_label.assert_called_once_with(name="Tea")
Exemple #2
0
    def test_pull_labels(self, mock_get_labels):
        # start with one un-synced label
        Label.objects.all().delete()
        self.create_label(self.unicef, None, "Local", "Desc", ["local"], is_synced=False)

        mock_get_labels.return_value = MockClientQuery(
            [
                TembaLabel.create(uuid="L-001", name="Requests", count=45),
                TembaLabel.create(uuid="L-002", name="Feedback", count=32),
                TembaLabel.create(uuid="L-009", name="Flagged", count=21),  # should be ignored
                TembaLabel.create(uuid="L-010", name="Local", count=0),  # should be ignored
            ]
        )

        self.unicef = Org.objects.prefetch_related("labels").get(pk=self.unicef.pk)

        with self.assertNumQueries(8):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_labels(self.unicef)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (2, 0, 0, 2))

        Label.objects.get(uuid=None, name="Local", is_active=True)
        Label.objects.get(uuid="L-001", name="Requests", is_active=True)
        Label.objects.get(uuid="L-002", name="Feedback", is_active=True)

        self.assertEqual(Label.objects.filter(name="Flagged").count(), 0)

        mock_get_labels.return_value = MockClientQuery(
            [
                TembaLabel.create(uuid="L-002", name="Complaints", count=32),
                TembaLabel.create(uuid="L-003", name="Spam", count=13),
            ]
        )

        with self.assertNumQueries(7):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_labels(self.unicef)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (1, 1, 1, 0))

        Label.objects.get(uuid=None, name="Local", is_active=True)
        Label.objects.get(uuid="L-001", name="Requests", is_active=False)
        Label.objects.get(uuid="L-002", name="Complaints", is_active=True)
        Label.objects.get(uuid="L-003", name="Spam", is_active=True)

        # check that no changes means no updates
        with self.assertNumQueries(4):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_labels(self.unicef)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (0, 0, 0, 2))
Exemple #3
0
    def test_fetch_flows(self, mock_get_flows):

        mock_get_flows.side_effect = [
            MockClientQuery([Flow.create(name='Flow 1',
                                         uuid='uuid-25',
                                         labels=[],
                                         archived=False,
                                         expires=720,
                                         created_on=json_date_to_datetime("2015-04-08T12:48:44.320Z"),
                                         runs=Flow.Runs.create(completed=120, active=50, expired=100, interrupted=30))
                             ])]

        with patch("ureport.utils.datetime_to_ms") as mock_datetime_ms:
            mock_datetime_ms.return_value = 500

            with patch('django.core.cache.cache.set') as cache_set_mock:
                flows = fetch_flows(self.org, self.rapidpro_backend)
                expected = dict()
                expected['uuid-25'] = dict(uuid='uuid-25', date_hint="2015-04-08",
                                           created_on="2015-04-08T12:48:44.320Z",
                                           name="Flow 1", runs=300, completed_runs=120, archived=False)

            self.assertEqual(flows, expected)

            cache_set_mock.assert_called_once_with('org:%d:backend:%s:flows' % (self.org.pk, self.rapidpro_backend.slug),
                                                   dict(time=500, results=expected),
                                                   UREPORT_ASYNC_FETCHED_DATA_CACHE_TIME)
Exemple #4
0
    def test_fetch_flows(self, mock_get_flows):

        mock_get_flows.side_effect = [
            MockClientQuery(
                [
                    Flow.create(
                        name="Flow 1",
                        uuid="uuid-25",
                        labels=[],
                        archived=False,
                        expires=720,
                        created_on=json_date_to_datetime("2015-04-08T12:48:44.320Z"),
                        results=[
                            Flow.FlowResult.create(
                                key="color",
                                name="Color",
                                categories=["Orange", "Blue", "Other", "Nothing"],
                                node_uuids=["42a8e177-9e88-429b-b70a-7d4854423092"],
                            )
                        ],
                        runs=Flow.Runs.create(completed=120, active=50, expired=100, interrupted=30),
                    )
                ]
            )
        ]

        with patch("ureport.utils.datetime_to_ms") as mock_datetime_ms:
            mock_datetime_ms.return_value = 500

            with patch("django.core.cache.cache.set") as cache_set_mock:
                flows = fetch_flows(self.org, self.rapidpro_backend)
                expected = dict()
                expected["uuid-25"] = dict(
                    uuid="uuid-25",
                    date_hint="2015-04-08",
                    created_on="2015-04-08T12:48:44.320Z",
                    name="Flow 1",
                    runs=300,
                    completed_runs=120,
                    archived=False,
                    results=[
                        dict(
                            key="color",
                            name="Color",
                            categories=["Orange", "Blue", "Other", "Nothing"],
                            node_uuids=["42a8e177-9e88-429b-b70a-7d4854423092"],
                        )
                    ],
                )

            self.assertEqual(flows, expected)

            cache_set_mock.assert_called_once_with(
                "org:%d:backend:%s:flows" % (self.org.pk, self.rapidpro_backend.slug),
                dict(time=500, results=expected),
                UREPORT_ASYNC_FETCHED_DATA_CACHE_TIME,
            )
Exemple #5
0
    def test_pull_groups(self, mock_get_groups):
        # start with no groups
        Group.objects.all().delete()

        mock_get_groups.return_value = MockClientQuery(
            [
                TembaGroup.create(uuid="G-001", name="Customers", query=None, count=45),
                TembaGroup.create(uuid="G-002", name="Developers", query="isdev=yes", count=32),
            ]
        )

        with self.assertNumQueries(6):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_groups(self.unicef)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (2, 0, 0, 0))

        Group.objects.get(uuid="G-001", name="Customers", count=45, is_dynamic=False, is_active=True)
        Group.objects.get(uuid="G-002", name="Developers", count=32, is_dynamic=True, is_active=True)

        mock_get_groups.return_value = MockClientQuery(
            [
                TembaGroup.create(uuid="G-002", name="Devs", query="isdev=yes", count=32),
                TembaGroup.create(uuid="G-003", name="Spammers", query=None, count=13),
            ]
        )

        with self.assertNumQueries(7):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_groups(self.unicef)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (1, 1, 1, 0))

        Group.objects.get(uuid="G-001", name="Customers", count=45, is_dynamic=False, is_active=False)
        Group.objects.get(uuid="G-002", name="Devs", count=32, is_dynamic=True, is_active=True)
        Group.objects.get(uuid="G-003", name="Spammers", count=13, is_dynamic=False, is_active=True)

        # check that no changes means no updates
        with self.assertNumQueries(4):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_groups(self.unicef)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (0, 0, 0, 2))
Exemple #6
0
    def test_pull_fields(self, mock_get_fields):
        # start with no fields
        Field.objects.all().delete()

        mock_get_fields.return_value = MockClientQuery(
            [
                TembaField.create(key="nick_name", label="Nickname", value_type="text"),
                TembaField.create(key="age", label="Age", value_type="numeric"),
            ]
        )

        with self.assertNumQueries(6):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_fields(self.unicef)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (2, 0, 0, 0))

        Field.objects.get(key="nick_name", label="Nickname", value_type="T", is_active=True)
        Field.objects.get(key="age", label="Age", value_type="N", is_active=True)

        mock_get_fields.return_value = MockClientQuery(
            [
                TembaField.create(key="age", label="Age (Years)", value_type="numeric"),
                TembaField.create(key="homestate", label="Homestate", value_type="state"),
            ]
        )

        with self.assertNumQueries(7):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_fields(self.unicef)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (1, 1, 1, 0))

        Field.objects.get(key="nick_name", label="Nickname", value_type="T", is_active=False)
        Field.objects.get(key="age", label="Age (Years)", value_type="N", is_active=True)
        Field.objects.get(key="homestate", label="Homestate", value_type="S", is_active=True)

        # check that no changes means no updates
        with self.assertNumQueries(4):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_fields(self.unicef)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (0, 0, 0, 2))
Exemple #7
0
    def test_fetch_flows(self, mock_get_flows):
        mock_get_flows.return_value = MockClientQuery(
            [
                TembaFlow.create(uuid="0001-0001", name="Registration", archived=False,),
                TembaFlow.create(uuid="0002-0002", name="Follow Up", archived=False,),
                TembaFlow.create(uuid="0003-0003", name="Other Flow", archived=True,),
            ]
        )

        flows = self.backend.fetch_flows(self.unicef)

        self.assertEqual(flows, [Flow("0002-0002", "Follow Up"), Flow("0001-0001", "Registration")])

        mock_get_flows.assert_called_once_with()
Exemple #8
0
    def test_fetch_contact_messages(self, mock_get_messages):
        d1 = datetime(2015, 1, 2, 13, 0, tzinfo=pytz.UTC)
        d2 = datetime(2015, 1, 2, 14, 0, tzinfo=pytz.UTC)
        d3 = datetime(2015, 1, 2, 15, 0, tzinfo=pytz.UTC)

        mock_get_messages.return_value = MockClientQuery(
            [
                TembaMessage.create(
                    id=102,
                    broadcast=201,
                    contact=ObjectRef.create(uuid="C-001", name="Ann"),
                    text="Welcome",
                    type="inbox",
                    direction="out",
                    visibility="visible",
                    labels=[],
                    created_on=d3,
                ),
                TembaMessage.create(
                    id=101,
                    broadcast=None,
                    contact=ObjectRef.create(uuid="C-001", name="Ann"),
                    text="Hello",
                    type="inbox",
                    direction="in",
                    visibility="archived",
                    labels=[
                        ObjectRef.create(uuid="L-001", name="AIDS"),
                        ObjectRef.create(uuid="L-111", name="Flagged"),
                    ],
                    created_on=d2,
                ),
            ]
        )

        messages = self.backend.fetch_contact_messages(self.unicef, self.ann, d1, d3)

        self.assertEqual(len(messages), 1)
        self.assertIsInstance(messages[0], Outgoing)
        self.assertEqual(messages[0].backend_broadcast_id, 201)
        self.assertEqual(messages[0].contact, self.ann)
        self.assertEqual(messages[0].text, "Welcome")
        self.assertEqual(messages[0].created_on, d3)
Exemple #9
0
    def test_pull_messages(self, mock_get_messages):
        d1 = now() - timedelta(hours=10)
        d2 = now() - timedelta(hours=9)
        d3 = now() - timedelta(hours=8)
        d4 = now() - timedelta(hours=7)
        d5 = now() - timedelta(hours=6)

        mock_get_messages.side_effect = [
            MockClientQuery(
                [
                    TembaMessage.create(
                        id=101,
                        contact=ObjectRef.create(uuid="C-001", name="Ann"),
                        type="inbox",
                        text="What is aids?",
                        visibility="visible",
                        labels=[
                            ObjectRef.create(uuid="L-001", name="AIDS"),  # existing label
                            ObjectRef.create(uuid="L-009", name="Flagged"),  # pseudo-label
                        ],
                        created_on=d1,
                    ),
                    TembaMessage.create(
                        id=102,
                        contact=ObjectRef.create(uuid="C-002", name="Bob"),
                        type="inbox",
                        text="Can I catch Hiv?",
                        visibility="visible",
                        labels=[ObjectRef.create(uuid="L-007", name="Important")],  # new label
                        created_on=d2,
                    ),
                    TembaMessage.create(
                        id=103,
                        contact=ObjectRef.create(uuid="C-003", name="Cat"),
                        type="inbox",
                        text="I think I'm pregnant",
                        visibility="visible",
                        labels=[],
                        created_on=d3,
                    ),
                    TembaMessage.create(
                        id=104,
                        contact=ObjectRef.create(uuid="C-004", name="Don"),
                        type="flow",
                        text="Php is amaze",
                        visibility="visible",
                        labels=[],
                        created_on=d4,
                    ),
                    TembaMessage.create(
                        id=105,
                        contact=ObjectRef.create(uuid="C-005", name="Eve"),
                        type="flow",
                        text="Thanks for the pregnancy/HIV info",
                        visibility="visible",
                        labels=[],
                        created_on=d5,
                    ),
                ]
            )
        ]

        self.assertEqual(self.backend.pull_messages(self.unicef, d1, d5), (5, 0, 0, 0))

        self.assertEqual(Contact.objects.filter(is_stub=False).count(), 2)
        self.assertEqual(Contact.objects.filter(is_stub=True).count(), 3)
        self.assertEqual(Message.objects.filter(is_handled=False).count(), 5)

        msg1 = Message.objects.get(backend_id=101, type="I", text="What is aids?", is_archived=False, is_flagged=True)
        important = Label.objects.get(org=self.unicef, uuid="L-007", name="Important")

        self.assertEqual(set(msg1.labels.all()), {self.aids})

        # a message is updated in RapidPro
        mock_get_messages.side_effect = [
            MockClientQuery(
                [
                    TembaMessage.create(
                        id=101,
                        contact=ObjectRef.create(uuid="C-001", name="Ann"),
                        type="inbox",
                        text="What is aids?",
                        visibility="archived",
                        labels=[
                            ObjectRef.create(uuid="L-001", name="AIDS"),
                            ObjectRef.create(uuid="L-007", name="Important"),
                        ],
                        created_on=d1,
                    )
                ]
            )
        ]

        self.assertEqual(self.backend.pull_messages(self.unicef, d1, d5), (0, 1, 0, 0))

        msg1 = Message.objects.get(backend_id=101, type="I", text="What is aids?", is_archived=True, is_flagged=False)

        self.assertEqual(set(msg1.labels.all()), {self.aids, important})
Exemple #10
0
    def test_pull_contacts(self, mock_get_contacts):
        # start with nothing...
        Group.objects.all().delete()
        Field.objects.all().delete()
        Contact.objects.all().delete()

        mock_get_contacts.side_effect = [
            # first call to get active contacts will return two fetches of 2 and 1 contacts
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-001",
                        name="Bob McFlow",
                        language="eng",
                        urns=["twitter:bobflow"],
                        groups=[ObjectRef.create(uuid="G-001", name="Customers")],
                        fields={"age": "34"},
                        stopped=False,
                        blocked=False,
                    ),
                    TembaContact.create(
                        uuid="C-002",
                        name="Jim McMsg",
                        language="fre",
                        urns=["tel:+250783835665"],
                        groups=[ObjectRef.create(uuid="G-002", name="Spammers")],
                        fields={"age": "67"},
                        stopped=False,
                        blocked=False,
                    ),
                ],
                [
                    TembaContact.create(
                        uuid="C-003",
                        name="Ann McPoll",
                        language="eng",
                        urns=["tel:+250783835664"],
                        groups=[],
                        fields={"age": "35"},
                        stopped=True,
                        blocked=False,
                    )
                ],
            ),
            # second call to get deleted contacts returns a contact we don't have
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-004",
                        name=None,
                        language=None,
                        urns=[],
                        groups=[],
                        fields=None,
                        stopped=True,
                        blocked=False,
                    )
                ]
            ),
        ]

        with self.assertNumQueries(16):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_contacts(self.unicef, None, None)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (3, 0, 0, 0))

        bob = Contact.objects.get(uuid="C-001")
        jim = Contact.objects.get(uuid="C-002")
        ann = Contact.objects.get(uuid="C-003")

        self.assertEqual(set(Contact.objects.filter(is_active=True)), {bob, jim, ann})
        self.assertEqual(set(Contact.objects.filter(is_active=False)), set())

        # stub contact groups will have been created too
        customers = Group.objects.get(org=self.unicef, uuid="G-001", name="Customers", is_active=False)
        spammers = Group.objects.get(org=self.unicef, uuid="G-002", name="Spammers", is_active=False)

        self.assertEqual(bob.name, "Bob McFlow")
        self.assertEqual(bob.language, "eng")
        self.assertEqual(set(bob.groups.all()), {customers})
        self.assertEqual(bob.get_fields(), {"age": "34"})

        mock_get_contacts.side_effect = [
            # first call to get active contacts will just one updated contact
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-001",
                        name="Bob McFlough",
                        language="fre",
                        urns=["twitter:bobflow"],
                        groups=[ObjectRef.create(uuid="G-002", name="Spammers")],
                        fields={"age": "35"},
                        stopped=True,
                        blocked=False,
                    )
                ]
            ),
            # second call to get deleted contacts returns Jim
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-002",
                        name=None,
                        language=None,
                        urns=[],
                        groups=[],
                        fields=None,
                        stopped=True,
                        blocked=False,
                    )
                ]
            ),
        ]

        with self.assertNumQueries(13):
            self.assertEqual(self.backend.pull_contacts(self.unicef, None, None), (0, 1, 1, 0))

        self.assertEqual(set(Contact.objects.filter(is_active=True)), {bob, ann})
        self.assertEqual(set(Contact.objects.filter(is_active=False)), {jim})

        self.assertEqual(jim.groups.count(), 0)  # de-activated contacts are removed from groups

        bob.refresh_from_db()
        self.assertEqual(bob.name, "Bob McFlough")
        self.assertEqual(bob.language, "fre")
        self.assertEqual(set(bob.groups.all()), {spammers})
        self.assertEqual(bob.get_fields(), {"age": "35"})

        mock_get_contacts.side_effect = [
            # first call to get active contacts will return a contact with only a change to URNs.. which we don't track
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-001",
                        name="Bob McFlough",
                        language="fre",
                        urns=["twitter:bobflow22"],
                        groups=[ObjectRef.create(uuid="G-002", name="Spammers")],
                        fields={"age": "35"},
                        stopped=True,
                        blocked=False,
                    )
                ]
            ),
            MockClientQuery([]),
        ]

        with self.assertNumQueries(3):
            self.assertEqual(self.backend.pull_contacts(self.unicef, None, None), (0, 0, 0, 1))

        self.assertEqual(set(Contact.objects.filter(is_active=True)), {bob, ann})
        self.assertEqual(set(Contact.objects.filter(is_active=False)), {jim})
Exemple #11
0
    def test_contact_sync(self, mock_get_groups, mock_get_fields, mock_get_contacts):
        # start with no groups or fields
        Group.objects.all().delete()
        Field.objects.all().delete()

        fetch_size = 250
        num_fetches = 4
        num_groups = 50
        num_fields = 50
        names = ["Ann", "Bob", "Cat"]
        field_values = ["12345", None]
        groups_in = 5

        # setup get_fields
        fields = [
            TembaField.create(key="field_%d" % f, label="Field #%d" % f, value_type="text")
            for f in range(0, num_fields)
        ]
        mock_get_fields.return_value = MockClientQuery(fields)

        # sync fields
        start = time.time()
        self.assertEqual((num_fields, 0, 0, 0), self.backend.pull_fields(self.unicef))

        print("Initial field sync: %f secs" % (time.time() - start))

        # setup get_groups
        groups = [
            TembaGroup.create(uuid="G0000000-0000-0000-0000-00000000%04d" % g, name="Group #%d" % g, count=0)
            for g in range(0, num_groups)
        ]
        mock_get_groups.return_value = MockClientQuery(groups)

        # sync groups
        start = time.time()
        self.assertEqual((num_groups, 0, 0, 0), self.backend.pull_groups(self.unicef))

        print("Initial group sync: %f secs" % (time.time() - start))

        # setup get_contacts to return multiple fetches of contacts
        active_fetches = []
        for b in range(0, num_fetches):
            batch = []
            for c in range(0, fetch_size):
                num = b * fetch_size + c
                batch.append(
                    TembaContact.create(
                        uuid="C0000000-0000-0000-0000-00000000%04d" % num,
                        name=names[num % len(names)],
                        language="eng",
                        urns=["tel:+26096415%04d" % num],
                        groups=[
                            ObjectRef.create(uuid="G0000000-0000-0000-0000-00000000%04d" % g, name="Group #%d" % g)
                            for g in range(0, groups_in)
                        ],
                        fields={
                            "custom_field_%d" % f: field_values[f % len(field_values)] for f in range(0, num_fields)
                        },
                        stopped=False,
                        blocked=False,
                    )
                )
            active_fetches.append(batch)

        mock_get_contacts.side_effect = [MockClientQuery(*active_fetches), MockClientQuery([])]  # no deleted contacts

        start = time.time()
        num_created, num_updated, num_deleted, num_ignored = self.backend.pull_contacts(self.unicef, None, None)

        print("Initial contact sync: %f secs" % (time.time() - start))

        self.assertEqual((num_created, num_updated, num_deleted), (num_fetches * fetch_size, 0, 0))

        # slowest_queries = sorted(connection.queries, key=lambda q: q['time'], reverse=True)[:10]

        # for q in slowest_queries:
        #    print "%s -- %s" % (q['time'], q['sql'])

        # simulate a subsequent sync with no changes
        mock_get_contacts.side_effect = [MockClientQuery(*active_fetches), MockClientQuery([])]
        start = time.time()
        num_created, num_updated, num_deleted, num_ignored = self.backend.pull_contacts(self.unicef, None, None)
        self.assertEqual((num_created, num_updated, num_deleted), (0, 0, 0))

        print("Contact sync with no changes: %f secs" % (time.time() - start))

        # simulate an update of 1 field value
        for batch in active_fetches:
            for c in batch:
                c.fields["custom_field_1"] = "UPDATED"

        mock_get_contacts.side_effect = [MockClientQuery(*active_fetches), MockClientQuery([])]
        start = time.time()
        num_created, num_updated, num_deleted, num_ignored = self.backend.pull_contacts(self.unicef, None, None)
        self.assertEqual((num_created, num_updated, num_deleted), (0, num_fetches * fetch_size, 0))

        print("Contact sync with 1 field value changes: %f secs" % (time.time() - start))

        # simulate an update of 10 field values
        for batch in active_fetches:
            for c in batch:
                for f in (10, 11, 12, 13, 14, 15, 16, 17, 18, 19):
                    c.fields["custom_field_%d" % f] = "UPDATED"

        mock_get_contacts.side_effect = [MockClientQuery(*active_fetches), MockClientQuery([])]
        start = time.time()
        num_created, num_updated, num_deleted, num_ignored = self.backend.pull_contacts(self.unicef, None, None)
        self.assertEqual((num_created, num_updated, num_deleted), (0, num_fetches * fetch_size, 0))

        print("Contact sync with 10 field value changes: %f secs" % (time.time() - start))
Exemple #12
0
    def test_pull_contacts(self, mock_get_contacts):

        Contact.objects.all().delete()

        # empty fetches
        mock_get_contacts.side_effect = [
            # first call to get active contacts
            MockClientQuery([]),
            # second call to get deleted contacts
            MockClientQuery([]),
        ]

        with self.assertNumQueries(0):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_contacts(self.nigeria, None, None)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (0, 0, 0, 0))

        # fecthed contact not in configured group get ignored
        mock_get_contacts.side_effect = [
            # first call to get active contacts will return two fetches of 2 and 1 contacts
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-001",
                        name="Bob McFlow",
                        language="eng",
                        urns=["twitter:bobflow"],
                        groups=[ObjectRef.create(uuid="G-001", name="Customers")],
                        fields={"age": "34"},
                        stopped=False,
                        blocked=False,
                    ),
                    TembaContact.create(
                        uuid="C-002",
                        name="Jim McMsg",
                        language="fre",
                        urns=["tel:+250783835665"],
                        groups=[ObjectRef.create(uuid="G-002", name="Spammers")],
                        fields={"age": "67"},
                        stopped=False,
                        blocked=False,
                    ),
                ],
                [
                    TembaContact.create(
                        uuid="C-003",
                        name="Ann McPoll",
                        language="eng",
                        urns=["tel:+250783835664"],
                        groups=[],
                        fields={"age": "35"},
                        stopped=True,
                        blocked=False,
                    )
                ],
            ),
            # second call to get deleted contacts returns a contact we don't have
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-004",
                        name=None,
                        language=None,
                        urns=[],
                        groups=[],
                        fields=None,
                        stopped=True,
                        blocked=False,
                    )
                ]
            ),
        ]

        with self.assertNumQueries(10):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_contacts(self.nigeria, None, None)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (3, 0, 0, 0))

        mock_get_contacts.side_effect = [
            # first call to get active contacts will return two fetches of 2 and 1 contacts
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-001",
                        name="Bob McFlow",
                        language="eng",
                        urns=["twitter:bobflow"],
                        groups=[ObjectRef.create(uuid="G-001", name="ureporters")],
                        fields={"age": "34"},
                        stopped=False,
                        blocked=False,
                    ),
                    TembaContact.create(
                        uuid="C-002",
                        name="Jim McMsg",
                        language="fre",
                        urns=["tel:+250783835665"],
                        groups=[ObjectRef.create(uuid="G-002", name="Spammers")],
                        fields={"age": "67"},
                        stopped=False,
                        blocked=False,
                    ),
                ],
                [
                    TembaContact.create(
                        uuid="C-003",
                        name="Ann McPoll",
                        language="eng",
                        urns=["tel:+250783835664"],
                        groups=[],
                        fields={"age": "35"},
                        stopped=True,
                        blocked=False,
                    )
                ],
            ),
            # second call to get deleted contacts returns a contact we don't have
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-004",
                        name=None,
                        language=None,
                        urns=[],
                        groups=[],
                        fields=None,
                        stopped=True,
                        blocked=False,
                    )
                ]
            ),
        ]

        with self.assertNumQueries(10):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_contacts(self.nigeria, None, None)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (0, 0, 0, 3))

        Contact.objects.all().delete()

        mock_get_contacts.side_effect = [
            # first call to get active contacts will return two fetches of 2 and 1 contacts
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-001",
                        name="Bob McFlow",
                        language="eng",
                        urns=["twitter:bobflow"],
                        groups=[ObjectRef.create(uuid="G-001", name="ureporters")],
                        fields={"age": "34"},
                        stopped=False,
                        blocked=False,
                    ),
                    TembaContact.create(
                        uuid="C-002",
                        name="Jim McMsg",
                        language="fre",
                        urns=["tel:+250783835665"],
                        groups=[ObjectRef.create(uuid="G-001", name="ureporters")],
                        fields={"age": "67"},
                        stopped=False,
                        blocked=False,
                    ),
                ],
                [
                    TembaContact.create(
                        uuid="C-003",
                        name="Ann McPoll",
                        language="eng",
                        urns=["tel:+250783835664"],
                        groups=[],
                        fields={"age": "35"},
                        stopped=True,
                        blocked=False,
                    )
                ],
            ),
            # second call to get deleted contacts returns a contact we don't have
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-004",
                        name=None,
                        language=None,
                        urns=[],
                        groups=[],
                        fields=None,
                        stopped=True,
                        blocked=False,
                    )
                ]
            ),
        ]

        with self.assertNumQueries(10):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_contacts(self.nigeria, None, None)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (3, 0, 0, 0))

        Contact.objects.all().delete()

        mock_get_contacts.side_effect = [
            # first call to get active contacts will return two fetches of 2 and 1 contacts
            # all included in the reporters
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-001",
                        name="Bob McFlow",
                        language="eng",
                        urns=["twitter:bobflow"],
                        groups=[ObjectRef.create(uuid="G-001", name="ureporters")],
                        fields={"age": "34"},
                        stopped=False,
                        blocked=False,
                    ),
                    TembaContact.create(
                        uuid="C-002",
                        name="Jim McMsg",
                        language="fre",
                        urns=["tel:+250783835665"],
                        groups=[ObjectRef.create(uuid="G-001", name="ureporters")],
                        fields={"age": "67"},
                        stopped=False,
                        blocked=False,
                    ),
                ],
                [
                    TembaContact.create(
                        uuid="C-003",
                        name="Ann McPoll",
                        language="eng",
                        urns=["tel:+250783835664"],
                        groups=[ObjectRef.create(uuid="G-001", name="ureporters")],
                        fields={"age": "35"},
                        stopped=True,
                        blocked=False,
                    )
                ],
            ),
            # second call to get deleted contacts returns a contact we don't have
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-004",
                        name=None,
                        language=None,
                        urns=[],
                        groups=[],
                        fields=None,
                        stopped=True,
                        blocked=False,
                    )
                ]
            ),
        ]

        with self.assertNumQueries(10):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_contacts(self.nigeria, None, None)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (3, 0, 0, 0))

        contact_jan = Contact.objects.filter(uuid="C-001").first()
        self.assertFalse(contact_jan.born)
        self.assertFalse(contact_jan.state)

        mock_get_contacts.side_effect = [
            # first call to get active contacts
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-001",
                        name="Jan",
                        urns=["tel:123"],
                        groups=[
                            ObjectRef.create(uuid="G-001", name="ureporters"),
                            ObjectRef.create(uuid="G-007", name="Actors"),
                        ],
                        fields={
                            "registration_date": "2014-01-02T03:04:05.000000Z",
                            "state": "Nigeria > Lagos",
                            "lga": "Nigeria > Lagos > Oyo",
                            "occupation": "Student",
                            "born": "1990",
                            "gender": "Male",
                        },
                        language="eng",
                    ),
                    TembaContact.create(
                        uuid="C-002",
                        name="Jim McMsg",
                        language="fre",
                        urns=["tel:+250783835665"],
                        groups=[ObjectRef.create(uuid="G-001", name="ureporters")],
                        fields={"age": "67", "born": "1992"},
                        stopped=False,
                        blocked=False,
                    ),
                ]
            ),
            # second call to get deleted contacts returns a contact we don't have
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-004",
                        name=None,
                        language=None,
                        urns=[],
                        groups=[],
                        fields=None,
                        stopped=True,
                        blocked=False,
                    )
                ]
            ),
        ]

        with self.assertNumQueries(10):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_contacts(self.nigeria, None, None)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (0, 2, 0, 0))

        contact_jan = Contact.objects.filter(uuid="C-001").first()

        self.assertTrue(contact_jan.born)
        self.assertEqual(contact_jan.born, 1990)
        self.assertTrue(contact_jan.state)
        self.assertEqual(contact_jan.state, "R-LAGOS")

        self.assertTrue(Contact.objects.filter(uuid="C-002", is_active=True))

        mock_get_contacts.side_effect = [
            # first call to get active contacts
            MockClientQuery([]),
            # second call to get deleted contacts
            MockClientQuery(
                [
                    TembaContact.create(
                        uuid="C-002",
                        name=None,
                        language=None,
                        urns=[],
                        groups=[],
                        fields=None,
                        stopped=True,
                        blocked=False,
                    )
                ]
            ),
        ]

        with self.assertNumQueries(3):
            num_created, num_updated, num_deleted, num_ignored = self.backend.pull_contacts(self.nigeria, None, None)

        self.assertEqual((num_created, num_updated, num_deleted, num_ignored), (0, 0, 1, 0))

        self.assertFalse(Contact.objects.filter(uuid="C-002", is_active=True))
Exemple #13
0
    def test_sync_local_to_changes(self):
        Contact.objects.all().delete()  # start with no contacts...

        fetches = MockClientQuery([
            TembaContact.create(uuid="C-001", name="Anne", blocked=False),
            TembaContact.create(uuid="C-002", name="Bob", blocked=False),
            TembaContact.create(uuid="C-003", name="Colin", blocked=False),
            TembaContact.create(uuid="C-004", name="Donald", blocked=True)
        ])
        deleted_fetches = MockClientQuery([])  # no deleted contacts this time

        self.assertEqual(sync_local_to_changes(self.unicef, self.syncer, fetches, deleted_fetches), (3, 0, 0, 1))

        fetches = MockClientQuery([
            TembaContact.create(uuid="C-005", name="Edward", blocked=False),  # new contact
            TembaContact.create(uuid="C-006", name="Frank", blocked=False),   # new contact
        ])
        deleted_fetches = MockClientQuery([
            TembaContact.create(uuid="C-001", name=None, blocked=None),       # deleted
        ])

        self.assertEqual(sync_local_to_changes(self.unicef, self.syncer, fetches, deleted_fetches), (2, 0, 1, 0))

        fetches = MockClientQuery([
            TembaContact.create(uuid="C-002", name="Bob", blocked=True),   # blocked so locally invalid
            TembaContact.create(uuid="C-003", name="Colm", blocked=False),  # changed name
        ])
        deleted_fetches = MockClientQuery([])

        self.assertEqual(sync_local_to_changes(self.unicef, self.syncer, fetches, deleted_fetches), (0, 1, 1, 0))

        fetches = MockClientQuery([
            TembaContact.create(uuid="CF-001", name="Anne", blocked=False),
            TembaContact.create(uuid="CF-002", name="Bob", blocked=False),
            TembaContact.create(uuid="CF-003", name="Colin", blocked=False),
            TembaContact.create(uuid="CF-004", name="Donald", blocked=True)
        ])
        deleted_fetches = MockClientQuery([])  # no deleted contacts this time

        self.assertEqual(sync_local_to_changes(self.unicef, self.syncer2, fetches, deleted_fetches), (3, 0, 0, 1))

        fetches = MockClientQuery([
            TembaContact.create(uuid="CF-005", name="Edward", blocked=False),  # new contact
            TembaContact.create(uuid="CF-006", name="Frank", blocked=False),   # new contact
        ])
        deleted_fetches = MockClientQuery([
            TembaContact.create(uuid="CF-001", name=None, blocked=None),       # deleted
        ])

        self.assertEqual(sync_local_to_changes(self.unicef, self.syncer2, fetches, deleted_fetches), (2, 0, 1, 0))

        fetches = MockClientQuery([
            TembaContact.create(uuid="CF-002", name="Bob", blocked=True),   # blocked so locally invalid
            TembaContact.create(uuid="CF-003", name="Colm", blocked=False),  # changed name
        ])
        deleted_fetches = MockClientQuery([])

        self.assertEqual(sync_local_to_changes(self.unicef, self.syncer2, fetches, deleted_fetches), (0, 1, 1, 0))