def test_temba_merge_contacts(self): contact1 = TembaContact.create( uuid="000-001", name="Bob", urns=["tel:123", "email:[email protected]"], fields=dict(chat_name="bob", age=23), groups=["000-001", "000-002", "000-010"], ) contact2 = TembaContact.create( uuid="000-001", name="Bobby", urns=["tel:234", "twitter:bob"], fields=dict(chat_name="bobz", state="IN"), groups=["000-003", "000-009", "000-011"], ) merged = temba_merge_contacts( contact1, contact2, mutex_group_sets=(("000-001", "000-002", "000-003"), ("000-008", "000-009"), ("000-098", "000-099")), ) self.assertEqual(merged.uuid, "000-001") self.assertEqual(merged.name, "Bob") self.assertEqual(sorted(merged.urns), ["email:[email protected]", "tel:123", "twitter:bob"]) self.assertEqual(merged.fields, dict(chat_name="bob", age=23, state="IN")) self.assertEqual(sorted(merged.groups), ["000-001", "000-009", "000-010", "000-011"])
def test_new_contact(self, mock_get_contact, mock_get_group): url = reverse('api.temba_handler', kwargs=dict(entity='contact', action='new')) # GET is not allowed response = self.url_get('unicef', '%s?%s' % (url, 'contact=C-007&group=G-001&token=1234567890')) self.assertEqual(response.status_code, 405) # forbidden response if you don't include secret token response = self.url_post('unicef', '%s?%s' % (url, 'contact=C-007&group=G-001')) self.assertEqual(response.status_code, 403) # bad request if you forget a parameter response = self.url_post('unicef', '%s?%s' % (url, 'group=G-001&token=1234567890')) self.assertEqual(response.status_code, 400) # make a valid request for new contact in an existing group mock_get_contact.return_value = TembaContact.create(uuid='C-007', name="Jan", urns=['tel:123'], groups=['G-001'], fields=dict(chat_name="jan"), language='eng', modified_on=timezone.now()) response = self.url_post('unicef', '%s?%s' % (url, 'contact=C-007&group=G-001&token=1234567890')) self.assertEqual(response.status_code, 200) # check new contact created contact = Contact.objects.get(uuid='C-007') self.assertEqual(contact.full_name, "Jan") self.assertEqual(contact.chat_name, "jan") self.assertEqual(contact.urn, 'tel:123') self.assertEqual(contact.room, Room.objects.get(uuid='G-001')) # try with new room/group that must be fetched mock_get_contact.return_value = TembaContact.create(uuid='C-008', name="Ken", urns=['tel:234'], groups=['G-007'], fields=dict(chat_name="ken"), language='eng', modified_on=timezone.now()) mock_get_group.return_value = TembaGroup.create(uuid='G-007', name="New group", size=2) response = self.url_post('unicef', '%s?%s' % (url, 'contact=C-008&group=G-007&token=1234567890')) self.assertEqual(response.status_code, 200) new_room = Room.objects.get(uuid='G-007', name="New group") # check new contact and room created contact = Contact.objects.get(uuid='C-008') self.assertEqual(contact.full_name, "Ken") self.assertEqual(contact.chat_name, "ken") self.assertEqual(contact.urn, 'tel:234') self.assertEqual(contact.room, new_room) # check re-activating an inactive room new_room.is_active = False new_room.save() response = self.url_post('unicef', '%s?%s' % (url, 'contact=C-008&group=G-007&token=1234567890')) self.assertEqual(response.status_code, 200) Room.objects.get(uuid='G-007', name="New group", is_active=True) # repeating a request shouldn't create duplicates response = self.url_post('unicef', '%s?%s' % (url, 'contact=C-008&group=G-007&token=1234567890')) self.assertEqual(response.status_code, 200)
def test_create(self, mock_create_contact): mock_create_contact.return_value = TembaContact.create( uuid='C-007', name="Mo Polls", urns=['tel:078123'], groups=['G-001', 'G-005'], fields={'facility_code': 'FC234'}, language='eng', modified_on=timezone.now()) contact = Contact.create( self.unicef, self.user1, "Mo Polls", 'tel:078123', self.region1, self.group1, 'FC234', 'eng') self.assertEqual(contact.name, "Mo Polls") self.assertEqual(contact.urn, 'tel:078123') self.assertEqual(contact.region, self.region1) self.assertEqual(contact.facility_code, 'FC234') self.assertEqual(contact.language, 'eng') self.assertEqual(contact.created_by, self.user1) self.assertIsNotNone(contact.created_on) self.assertEqual(contact.modified_by, self.user1) self.assertIsNotNone(contact.modified_on) # reload and check UUID was updated by push task contact = Contact.objects.get(pk=contact.pk) self.assertEqual(contact.uuid, 'C-007') self.assertEqual(mock_create_contact.call_count, 1)
def test_create(self, mock_create_contact): mock_create_contact.return_value = TembaContact.create( uuid='C-007', name="Mo Chats", urns=['tel:078123'], groups=['G-001'], fields=dict(chat_name="momo"), language='eng', modified_on=timezone.now()) contact = Contact.create(self.unicef, self.user1, "Mo Chats", "momo", 'tel:078123', self.room1) self.assertEqual(contact.full_name, "Mo Chats") self.assertEqual(contact.chat_name, "momo") self.assertEqual(contact.urn, 'tel:078123') self.assertEqual(contact.room, self.room1) self.assertEqual(contact.created_by, self.user1) self.assertIsNotNone(contact.created_on) self.assertEqual(contact.modified_by, self.user1) self.assertIsNotNone(contact.modified_on) # reload and check UUID was updated by push task contact = Contact.objects.get(pk=contact.pk) self.assertEqual(contact.uuid, 'C-007') self.assertEqual(mock_create_contact.call_count, 1)
def test_kwargs_from_temba(self): temba_contact = TembaContact.create(uuid='C-007', name="Jan", urns=['tel:123'], groups=['G-001'], fields=dict(chat_name="jxn"), language='eng', modified_on=timezone.now()) kwargs = Contact.kwargs_from_temba(self.unicef, temba_contact) self.assertEqual(kwargs, dict(org=self.unicef, full_name="Jan", chat_name="jxn", room=self.room1, urn='tel:123', uuid='C-007'))
def test_update_room_groups(self, mock_get_contacts, mock_get_groups): mock_get_groups.return_value = [TembaGroup.create(uuid='G-007', name="New group", size=2)] mock_get_contacts.return_value = [ TembaContact.create(uuid='C-007', name="Jan", urns=['tel:123'], groups=['G-007'], fields=dict(chat_name="jan"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-008', name="Ken", urns=['tel:234'], groups=['G-007'], fields=dict(chat_name="ken"), language='eng', modified_on=timezone.now()) ] # select one new group Room.update_room_groups(self.unicef, ['G-007']) self.assertEqual(self.unicef.rooms.filter(is_active=True).count(), 1) self.assertEqual(self.unicef.rooms.filter(is_active=False).count(), 3) # existing de-activated new_room = Room.objects.get(uuid='G-007') self.assertEqual(new_room.name, "New group") self.assertTrue(new_room.is_active) # check contact changes self.assertEqual(self.unicef.contacts.filter(is_active=True).count(), 2) self.assertEqual(self.unicef.contacts.filter(is_active=False).count(), 5) # existing de-activated jan = Contact.objects.get(uuid='C-007') self.assertEqual(jan.full_name, "Jan") self.assertEqual(jan.chat_name, "jan") self.assertEqual(jan.urn, 'tel:123') self.assertEqual(jan.room, new_room) self.assertTrue(jan.is_active) # change group and contacts on chatpro side Room.objects.filter(name="New group").update(name="Huh?", is_active=False) jan.full_name = "Janet" jan.save() Contact.objects.filter(full_name="Ken").update(is_active=False) # re-select new group Room.update_room_groups(self.unicef, ['G-007']) # local changes should be overwritten self.assertEqual(self.unicef.rooms.get(is_active=True).name, 'New group') self.assertEqual(self.unicef.contacts.filter(is_active=True).count(), 2) Contact.objects.get(full_name="Jan", is_active=True)
def test_temba_merge_contacts(self): contact1 = TembaContact.create(uuid="000-001", name="Bob", urns=['tel:123', 'email:[email protected]'], fields=dict(chat_name="bob", age=23), groups=['000-001', '000-002', '000-010']) contact2 = TembaContact.create(uuid="000-001", name="Bobby", urns=['tel:234', 'twitter:bob'], fields=dict(chat_name="bobz", state='IN'), groups=['000-003', '000-009', '000-011']) merged = temba_merge_contacts(contact1, contact2, mutex_group_sets=( ('000-001', '000-002', '000-003'), ('000-008', '000-009'), ('000-098', '000-099'), )) self.assertEqual(merged.uuid, '000-001') self.assertEqual(merged.name, "Bob") self.assertEqual(sorted(merged.urns), ['email:[email protected]', 'tel:123', 'twitter:bob']) self.assertEqual(merged.fields, dict(chat_name="bob", age=23, state='IN')) self.assertEqual(sorted(merged.groups), ['000-001', '000-009', '000-010', '000-011'])
def temba_merge_contacts(first, second, mutex_group_sets): """ Merges two Temba contacts, with priority given to the first contact """ if first.uuid != second.uuid: # pragma: no cover raise ValueError("Can't merge contacts with different UUIDs") # URNs are merged by scheme first_urns_by_scheme = { u[0]: u[1] for u in [urn.split(':', 1) for urn in first.urns] } urns_by_scheme = { u[0]: u[1] for u in [urn.split(':', 1) for urn in second.urns] } urns_by_scheme.update(first_urns_by_scheme) merged_urns = [ '%s:%s' % (scheme, path) for scheme, path in six.iteritems(urns_by_scheme) ] # fields are simple key based merge merged_fields = second.fields.copy() merged_fields.update(first.fields) # first merge mutually exclusive group sets first_groups = list(first.groups) second_groups = list(second.groups) merged_mutex_groups = [] for group_set in mutex_group_sets: from_first = intersection(first_groups, group_set) if from_first: merged_mutex_groups.append(from_first[0]) else: from_second = intersection(second_groups, group_set) if from_second: merged_mutex_groups.append(from_second[0]) for group in group_set: if group in first_groups: first_groups.remove(group) if group in second_groups: second_groups.remove(group) # then merge the remaining groups merged_groups = merged_mutex_groups + union(first_groups, second_groups) return TembaContact.create(uuid=first.uuid, name=first.name, urns=merged_urns, fields=merged_fields, groups=merged_groups)
def test_get_or_fetch(self, mock_get_contact): mock_get_contact.return_value = TembaContact.create(uuid='C-007', name="Mo Polls", urns=['tel:078123'], groups=['G-001', 'G-005'], fields={'facility_code': 'FC234'}, language='eng', modified_on=timezone.now()) # get locally contact = Contact.get_or_fetch(self.unicef, 'C-001') self.assertEqual(contact.name, "Ann") # fetch remotely contact = Contact.get_or_fetch(self.unicef, 'C-009') self.assertEqual(contact.name, "Mo Polls")
def test_get_or_fetch(self, mock_get_contact): mock_get_contact.return_value = TembaContact.create( uuid='C-007', name="Mo Polls", urns=['tel:078123'], groups=['G-001', 'G-005'], fields={'facility_code': 'FC234'}, language='eng', modified_on=timezone.now()) # get locally contact = Contact.get_or_fetch(self.unicef, 'C-001') self.assertEqual(contact.name, "Ann") # fetch remotely contact = Contact.get_or_fetch(self.unicef, 'C-009') self.assertEqual(contact.name, "Mo Polls")
def test_temba_compare_contacts(self): # no differences first = TembaContact.create( uuid='000-001', name="Ann", urns=['tel:1234'], groups=['000-001'], fields=dict(chat_name="ann"), language='eng', modified_on=timezone.now()) second = TembaContact.create( uuid='000-001', name="Ann", urns=['tel:1234'], groups=['000-001'], fields=dict(chat_name="ann"), language='eng', modified_on=timezone.now()) self.assertIsNone(temba_compare_contacts(first, second)) self.assertIsNone(temba_compare_contacts(second, first)) # different name second = TembaContact.create( uuid='000-001', name="Annie", urns=['tel:1234'], groups=['000-001'], fields=dict(chat_name="ann"), language='eng', modified_on=timezone.now()) self.assertEqual(temba_compare_contacts(first, second), 'name') # different URNs second = TembaContact.create( uuid='000-001', name="Ann", urns=['tel:1234', 'twitter:ann'], groups=['000-001'], fields=dict(chat_name="ann"), language='eng', modified_on=timezone.now()) self.assertEqual(temba_compare_contacts(first, second), 'urns') # different group second = TembaContact.create( uuid='000-001', name="Ann", urns=['tel:1234'], groups=['000-002'], fields=dict(chat_name="ann"), language='eng', modified_on=timezone.now()) self.assertEqual(temba_compare_contacts(first, second), 'groups') self.assertEqual(temba_compare_contacts(first, second, groups=('000-001', '000-002')), 'groups') self.assertIsNone(temba_compare_contacts(first, second, groups=())) self.assertIsNone(temba_compare_contacts(first, second, groups=('000-003', '000-004'))) # different field second = TembaContact.create( uuid='000-001', name="Ann", urns=['tel:1234'], groups=['000-001'], fields=dict(chat_name="annie"), language='eng', modified_on=timezone.now()) self.assertEqual(temba_compare_contacts(first, second), 'fields') self.assertEqual(temba_compare_contacts(first, second, fields=('chat_name', 'gender')), 'fields') self.assertIsNone(temba_compare_contacts(first, second, fields=())) self.assertIsNone(temba_compare_contacts(first, second, fields=('age', 'gender'))) # additional field second = TembaContact.create( uuid='000-001', name="Ann", urns=['tel:1234'], groups=['000-001'], fields=dict(chat_name="ann", age=18), language='eng', modified_on=timezone.now()) self.assertEqual(temba_compare_contacts(first, second), 'fields') self.assertIsNone(temba_compare_contacts(first, second, fields=())) self.assertIsNone(temba_compare_contacts(first, second, fields=('chat_name',)))
def test_new_message(self, mock_get_contact, mock_get_group): url = reverse('api.temba_handler', kwargs=dict(entity='message', action='new')) # GET is not allowed response = self.url_get('unicef', '%s?%s' % (url, 'contact=C-001&text=Hello%20World&group=G-001&token=1234567890')) self.assertEqual(response.status_code, 405) # bad request if you forget a parameter response = self.url_post('unicef', '%s?%s' % (url, 'text=Hello%20World&group=G-001&token=1234567890')) self.assertEqual(response.status_code, 400) # make a valid request for new message from an existing contact to an existing group response = self.url_post('unicef', '%s?%s' % (url, 'contact=C-001&text=Hello%20World&group=G-001&token=1234567890')) self.assertEqual(response.status_code, 200) # check new message created msg = Message.objects.get(text="Hello World") self.assertEqual(msg.contact, self.contact1) self.assertEqual(msg.room, self.room1) # try with new room/group that must be fetched mock_get_group.return_value = TembaGroup.create(uuid='G-007', name="New group", size=2) response = self.url_post('unicef', '%s?%s' % (url, 'contact=C-001&text=Hello%20Again&group=G-007&token=1234567890')) self.assertEqual(response.status_code, 200) new_room = Room.objects.get(uuid='G-007', name="New group") # check new message created msg = Message.objects.get(text="Hello Again") self.assertEqual(msg.contact, self.contact1) self.assertEqual(msg.room, new_room) # try with new contact and new room/group that must be fetched mock_get_group.return_value = TembaGroup.create(uuid='G-008', name="Newest group", size=2) mock_get_contact.return_value = TembaContact.create(uuid='C-007', name="Ken", urns=['tel:234'], groups=['G-008'], fields=dict(chat_name="ken"), language='eng', modified_on=timezone.now()) response = self.url_post('unicef', '%s?%s' % (url, 'contact=001-007&text=Goodbye&group=001-008&token=1234567890')) self.assertEqual(response.status_code, 200) new_contact = Contact.objects.get(uuid='C-007') new_room = Room.objects.get(uuid='G-008', name="Newest group") # check new message created msg = Message.objects.get(text="Goodbye") self.assertEqual(msg.contact, new_contact) self.assertEqual(msg.room, new_room)
def test_kwargs_from_temba(self): temba_contact = TembaContact.create(uuid='C-007', name="Jan", urns=['tel:123'], groups=['G-001'], fields=dict(chat_name="jxn"), language='eng', modified_on=timezone.now()) kwargs = Contact.kwargs_from_temba(self.unicef, temba_contact) self.assertEqual( kwargs, dict(org=self.unicef, full_name="Jan", chat_name="jxn", room=self.room1, urn='tel:123', uuid='C-007'))
def temba_merge_contacts(first, second, mutex_group_sets): """ Merges two Temba contacts, with priority given to the first contact """ if first.uuid != second.uuid: # pragma: no cover raise ValueError("Can't merge contacts with different UUIDs") # URNs are merged by scheme first_urns_by_scheme = {u[0]: u[1] for u in [urn.split(':', 1) for urn in first.urns]} urns_by_scheme = {u[0]: u[1] for u in [urn.split(':', 1) for urn in second.urns]} urns_by_scheme.update(first_urns_by_scheme) merged_urns = ['%s:%s' % (scheme, path) for scheme, path in six.iteritems(urns_by_scheme)] # fields are simple key based merge merged_fields = second.fields.copy() merged_fields.update(first.fields) # first merge mutually exclusive group sets first_groups = list(first.groups) second_groups = list(second.groups) merged_mutex_groups = [] for group_set in mutex_group_sets: from_first = intersection(first_groups, group_set) if from_first: merged_mutex_groups.append(from_first[0]) else: from_second = intersection(second_groups, group_set) if from_second: merged_mutex_groups.append(from_second[0]) for group in group_set: if group in first_groups: first_groups.remove(group) if group in second_groups: second_groups.remove(group) # then merge the remaining groups merged_groups = merged_mutex_groups + union(first_groups, second_groups) return TembaContact.create(uuid=first.uuid, name=first.name, urns=merged_urns, fields=merged_fields, groups=merged_groups)
def test_create(self, mock_create_contact): mock_create_contact.return_value = TembaContact.create(uuid='C-007', name="Mo Chats", urns=['tel:078123'], groups=['G-001'], fields=dict(chat_name="momo"), language='eng', modified_on=timezone.now()) contact = Contact.create(self.unicef, self.user1, "Mo Chats", "momo", 'tel:078123', self.room1) self.assertEqual(contact.full_name, "Mo Chats") self.assertEqual(contact.chat_name, "momo") self.assertEqual(contact.urn, 'tel:078123') self.assertEqual(contact.room, self.room1) self.assertEqual(contact.created_by, self.user1) self.assertIsNotNone(contact.created_on) self.assertEqual(contact.modified_by, self.user1) self.assertIsNotNone(contact.modified_on) # reload and check UUID was updated by push task contact = Contact.objects.get(pk=contact.pk) self.assertEqual(contact.uuid, 'C-007') self.assertEqual(mock_create_contact.call_count, 1)
def test_kwargs_from_temba(self): temba_contact = TembaContact.create( uuid='C-007', name="Jan", urns=['tel:123'], groups=['G-001', 'G-007'], fields={'facility_code': 'FC234', 'gender': 'M'}, language='eng', modified_on=timezone.now()) kwargs = Contact.kwargs_from_temba(self.unicef, temba_contact) self.assertDictEqual(kwargs, { 'uuid': 'C-007', 'org': self.unicef, 'name': "Jan", 'urn': 'tel:123', 'region': self.region1, 'group': self.group3, 'facility_code': 'FC234', 'language': 'eng', }) # try creating contact from them Contact.objects.create(**kwargs)
def test_create(self, mock_create_contact): mock_create_contact.return_value = TembaContact.create(uuid='C-007', name="Mo Polls", urns=['tel:078123'], groups=['G-001', 'G-005'], fields={'facility_code': 'FC234'}, language='eng', modified_on=timezone.now()) contact = Contact.create(self.unicef, self.user1, "Mo Polls", 'tel:078123', self.region1, self.group1, 'FC234', 'eng') self.assertEqual(contact.name, "Mo Polls") self.assertEqual(contact.urn, 'tel:078123') self.assertEqual(contact.region, self.region1) self.assertEqual(contact.facility_code, 'FC234') self.assertEqual(contact.language, 'eng') self.assertEqual(contact.created_by, self.user1) self.assertIsNotNone(contact.created_on) self.assertEqual(contact.modified_by, self.user1) self.assertIsNotNone(contact.modified_on) # reload and check UUID was updated by push task contact = Contact.objects.get(pk=contact.pk) self.assertEqual(contact.uuid, 'C-007') self.assertEqual(mock_create_contact.call_count, 1)
def test_update_room_groups(self, mock_get_contacts, mock_get_groups): mock_get_groups.return_value = [ TembaGroup.create(uuid='G-007', name="New group", size=2) ] mock_get_contacts.return_value = [ TembaContact.create(uuid='C-007', name="Jan", urns=['tel:123'], groups=['G-007'], fields=dict(chat_name="jan"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-008', name="Ken", urns=['tel:234'], groups=['G-007'], fields=dict(chat_name="ken"), language='eng', modified_on=timezone.now()) ] # select one new group Room.update_room_groups(self.unicef, ['G-007']) self.assertEqual(self.unicef.rooms.filter(is_active=True).count(), 1) self.assertEqual(self.unicef.rooms.filter(is_active=False).count(), 3) # existing de-activated new_room = Room.objects.get(uuid='G-007') self.assertEqual(new_room.name, "New group") self.assertTrue(new_room.is_active) # check contact changes self.assertEqual( self.unicef.contacts.filter(is_active=True).count(), 2) self.assertEqual( self.unicef.contacts.filter(is_active=False).count(), 5) # existing de-activated jan = Contact.objects.get(uuid='C-007') self.assertEqual(jan.full_name, "Jan") self.assertEqual(jan.chat_name, "jan") self.assertEqual(jan.urn, 'tel:123') self.assertEqual(jan.room, new_room) self.assertTrue(jan.is_active) # change group and contacts on chatpro side Room.objects.filter(name="New group").update(name="Huh?", is_active=False) jan.full_name = "Janet" jan.save() Contact.objects.filter(full_name="Ken").update(is_active=False) # re-select new group Room.update_room_groups(self.unicef, ['G-007']) # local changes should be overwritten self.assertEqual( self.unicef.rooms.get(is_active=True).name, 'New group') self.assertEqual( self.unicef.contacts.filter(is_active=True).count(), 2) Contact.objects.get(full_name="Jan", is_active=True)
def test_sync_pull_contacts(self, mock_get_contacts): # RapidPro returning no changes mock_get_contacts.return_value = [ TembaContact.create(uuid='C-001', name="Ann", urns=['tel:1234'], groups=['G-001'], fields=dict(chat_name="ann"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-002', name="Bob", urns=['tel:2345'], groups=['G-001'], fields=dict(chat_name="bob"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-003', name="Cat", urns=['tel:3456'], groups=['G-002'], fields=dict(chat_name="cat"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-004', name="Dan", urns=['twitter:danny'], groups=['G-002'], fields=dict(chat_name="dan"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-005', name="Eve", urns=['twitter:evee'], groups=['G-003'], fields=dict(chat_name="eve"), language='eng', modified_on=timezone.now()) ] created, updated, deleted, failed = sync_pull_contacts( self.unicef, Contact) self.assertFalse(created or updated or deleted or failed) # RapidPro returning 1 new, 1 modified, 1 deleted and 2 unsyncable contact mock_get_contacts.return_value = [ TembaContact.create(uuid='C-001', name="Annie", urns=['tel:5678'], groups=['G-002'], fields=dict(chat_name="annie"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-003', name="Cat", urns=['tel:3456'], groups=['G-002'], fields=dict(chat_name="cat"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-004', name="Dan", urns=['twitter:danny'], groups=['G-002'], fields=dict(chat_name="dan"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-005', name="Eve", urns=['twitter:evee'], groups=['G-003'], fields=dict(chat_name="eve"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-007', name="Jim", urns=['twitter:jimbo'], groups=['G-003'], fields=dict(chat_name="jim"), language='eng', modified_on=timezone.now()), TembaContact.create( uuid='C-009', name="Xen", urns=['twitter:xen'], groups=[], # no room group fields=dict(chat_name="xen"), language='eng', modified_on=timezone.now()), TembaContact.create( uuid='C-010', name="Yan", urns=[], groups=['G-003'], # no URN fields=dict(chat_name="yan"), language='eng', modified_on=timezone.now()) ] created, updated, deleted, failed = sync_pull_contacts( self.unicef, Contact) self.assertEqual(sorted(created), ['C-007']) self.assertEqual(sorted(updated), ['C-001']) self.assertEqual(sorted(deleted), ['C-002']) self.assertEqual(sorted(failed), ['C-009', 'C-010']) # check created contact jim = Contact.objects.get(uuid='C-007') self.assertEqual(jim.full_name, "Jim") self.assertEqual(jim.chat_name, "jim") self.assertEqual(jim.urn, 'twitter:jimbo') self.assertEqual(jim.room, self.room3) # check modified contact ann = Contact.objects.get(uuid='C-001') self.assertEqual(ann.full_name, "Annie") self.assertEqual(ann.chat_name, "annie") self.assertEqual(ann.urn, 'tel:5678') self.assertEqual(ann.room, self.room2) # check deleted contact bob = Contact.objects.get(uuid='C-002') self.assertFalse(bob.is_active)
def test_temba_compare_contacts(self): # no differences first = TembaContact.create( uuid="000-001", name="Ann", urns=["tel:1234"], groups=["000-001"], fields=dict(chat_name="ann"), language="eng", modified_on=timezone.now(), ) second = TembaContact.create( uuid="000-001", name="Ann", urns=["tel:1234"], groups=["000-001"], fields=dict(chat_name="ann"), language="eng", modified_on=timezone.now(), ) self.assertIsNone(temba_compare_contacts(first, second)) self.assertIsNone(temba_compare_contacts(second, first)) # different name second = TembaContact.create( uuid="000-001", name="Annie", urns=["tel:1234"], groups=["000-001"], fields=dict(chat_name="ann"), language="eng", modified_on=timezone.now(), ) self.assertEqual(temba_compare_contacts(first, second), "name") # different URNs second = TembaContact.create( uuid="000-001", name="Ann", urns=["tel:1234", "twitter:ann"], groups=["000-001"], fields=dict(chat_name="ann"), language="eng", modified_on=timezone.now(), ) self.assertEqual(temba_compare_contacts(first, second), "urns") # different group second = TembaContact.create( uuid="000-001", name="Ann", urns=["tel:1234"], groups=["000-002"], fields=dict(chat_name="ann"), language="eng", modified_on=timezone.now(), ) self.assertEqual(temba_compare_contacts(first, second), "groups") self.assertEqual(temba_compare_contacts(first, second, groups=("000-001", "000-002")), "groups") self.assertIsNone(temba_compare_contacts(first, second, groups=())) self.assertIsNone(temba_compare_contacts(first, second, groups=("000-003", "000-004"))) # different field second = TembaContact.create( uuid="000-001", name="Ann", urns=["tel:1234"], groups=["000-001"], fields=dict(chat_name="annie"), language="eng", modified_on=timezone.now(), ) self.assertEqual(temba_compare_contacts(first, second), "fields") self.assertEqual(temba_compare_contacts(first, second, fields=("chat_name", "gender")), "fields") self.assertIsNone(temba_compare_contacts(first, second, fields=())) self.assertIsNone(temba_compare_contacts(first, second, fields=("age", "gender"))) # additional field second = TembaContact.create( uuid="000-001", name="Ann", urns=["tel:1234"], groups=["000-001"], fields=dict(chat_name="ann", age=18), language="eng", modified_on=timezone.now(), ) self.assertEqual(temba_compare_contacts(first, second), "fields") self.assertIsNone(temba_compare_contacts(first, second, fields=())) self.assertIsNone(temba_compare_contacts(first, second, fields=("chat_name",)))
def test_sync_pull_contacts(self, mock_get_contacts): # RapidPro returning no changes mock_get_contacts.return_value = [ TembaContact.create(uuid='C-001', name="Ann", urns=['tel:1234'], groups=['G-001'], fields=dict(chat_name="ann"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-002', name="Bob", urns=['tel:2345'], groups=['G-001'], fields=dict(chat_name="bob"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-003', name="Cat", urns=['tel:3456'], groups=['G-002'], fields=dict(chat_name="cat"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-004', name="Dan", urns=['twitter:danny'], groups=['G-002'], fields=dict(chat_name="dan"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-005', name="Eve", urns=['twitter:evee'], groups=['G-003'], fields=dict(chat_name="eve"), language='eng', modified_on=timezone.now()) ] created, updated, deleted, failed = sync_pull_contacts(self.unicef, Contact) self.assertFalse(created or updated or deleted or failed) # RapidPro returning 1 new, 1 modified, 1 deleted and 2 unsyncable contact mock_get_contacts.return_value = [ TembaContact.create(uuid='C-001', name="Annie", urns=['tel:5678'], groups=['G-002'], fields=dict(chat_name="annie"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-003', name="Cat", urns=['tel:3456'], groups=['G-002'], fields=dict(chat_name="cat"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-004', name="Dan", urns=['twitter:danny'], groups=['G-002'], fields=dict(chat_name="dan"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-005', name="Eve", urns=['twitter:evee'], groups=['G-003'], fields=dict(chat_name="eve"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-007', name="Jim", urns=['twitter:jimbo'], groups=['G-003'], fields=dict(chat_name="jim"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-009', name="Xen", urns=['twitter:xen'], groups=[], # no room group fields=dict(chat_name="xen"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-010', name="Yan", urns=[], groups=['G-003'], # no URN fields=dict(chat_name="yan"), language='eng', modified_on=timezone.now()) ] created, updated, deleted, failed = sync_pull_contacts(self.unicef, Contact) self.assertEqual(sorted(created), ['C-007']) self.assertEqual(sorted(updated), ['C-001']) self.assertEqual(sorted(deleted), ['C-002']) self.assertEqual(sorted(failed), ['C-009', 'C-010']) # check created contact jim = Contact.objects.get(uuid='C-007') self.assertEqual(jim.full_name, "Jim") self.assertEqual(jim.chat_name, "jim") self.assertEqual(jim.urn, 'twitter:jimbo') self.assertEqual(jim.room, self.room3) # check modified contact ann = Contact.objects.get(uuid='C-001') self.assertEqual(ann.full_name, "Annie") self.assertEqual(ann.chat_name, "annie") self.assertEqual(ann.urn, 'tel:5678') self.assertEqual(ann.room, self.room2) # check deleted contact bob = Contact.objects.get(uuid='C-002') self.assertFalse(bob.is_active)
def test_sync_with_groups(self, mock_get_contacts, mock_get_groups): mock_get_groups.return_value = [ TembaGroup.create(uuid='G-101', name="New region", size=2), TembaGroup.create(uuid='G-102', name="Other region", size=1) ] mock_get_contacts.return_value = [ TembaContact.create(uuid='C-101', name="Jan", urns=['tel:123'], groups=['G-101', 'G-005'], fields=dict(chat_name="jan"), language='eng', modified_on=timezone.now()), TembaContact.create(uuid='C-102', name="Ken", urns=['tel:234'], groups=['G-101', 'G-006'], fields=dict(chat_name="ken"), language='eng', modified_on=timezone.now()) ] # select one new group Region.sync_with_groups(self.unicef, ['G-101']) self.assertEqual(self.unicef.regions.filter(is_active=True).count(), 1) self.assertEqual( self.unicef.regions.filter(is_active=False).count(), 3) # existing de-activated new_region = Region.objects.get(uuid='G-101') self.assertEqual(new_region.name, "New region") self.assertTrue(new_region.is_active) # check contact changes self.assertEqual( self.unicef.contacts.filter(is_active=True).count(), 2) self.assertEqual( self.unicef.contacts.filter(is_active=False).count(), 5) # existing de-activated jan = Contact.objects.get(uuid='C-101') self.assertEqual(jan.name, "Jan") self.assertEqual(jan.urn, 'tel:123') self.assertEqual(jan.region, new_region) self.assertTrue(jan.is_active) # change group and contacts on chatpro side Region.objects.filter(name="New region").update(name="Huh?", is_active=False) jan.name = "Janet" jan.save() Contact.objects.filter(name="Ken").update(is_active=False) # re-select new group Region.sync_with_groups(self.unicef, ['G-101']) # local changes should be overwritten self.assertEqual( self.unicef.regions.get(is_active=True).name, 'New region') self.assertEqual( self.unicef.contacts.filter(is_active=True).count(), 2) Contact.objects.get(name="Jan", is_active=True)