class TestContactsDataSource(MyJobsBase): def setUp(self): super(TestContactsDataSource, self).setUp() # A company to work with self.company = CompanyFactory(name='right') self.company.save() # A separate company that should not show up in results. self.other_company = CompanyFactory(name='wrong') self.other_company.save() self.partner = PartnerFactory(owner=self.company) self.other_partner = PartnerFactory(owner=self.other_company) self.partner_a = PartnerFactory(owner=self.company, name="aaa") self.partner_b = PartnerFactory(owner=self.company, name="bbb") # An unapproved parther. Associated data should be filtered out. self.partner_unapp = PartnerFactory( owner=self.company, name="unapproved", approval_status__code=Status.UNPROCESSED) # An archived parther. Associated data should be filtered out. self.partner_archived = PartnerFactory(owner=self.company) self.east_tag = TagFactory.create(company=self.company, name='east', hex_color="aaaaaa") self.west_tag = TagFactory.create(company=self.company, name='west', hex_color="bbbbbb") self.left_tag = TagFactory.create(company=self.company, name='left', hex_color="cccccc") self.right_tag = TagFactory.create(company=self.company, name='right', hex_color="dddddd") self.bad_tag = TagFactory.create(company=self.company, name='bad', hex_color="cccccc") self.partner_a.tags.add(self.left_tag) self.partner_b.tags.add(self.right_tag) self.john_user = UserFactory(email="*****@*****.**") self.john = ContactFactory(partner=self.partner_a, name='john adams', user=self.john_user, email="*****@*****.**", last_action_time='2015-10-03') self.john.locations.add( LocationFactory.create(city="Indianapolis", state="IN")) self.john.locations.add( LocationFactory.create(city="Chicago", state="IL")) self.john.tags.add(self.east_tag) self.sue_user = UserFactory(email="*****@*****.**") self.sue = ContactFactory(partner=self.partner_b, name='Sue Baxter', user=self.sue_user, email="*****@*****.**", last_action_time='2015-09-30 13:23') self.sue.locations.add( LocationFactory.create(address_line_one="123", city="Los Angeles", state="CA")) self.sue.locations.add( LocationFactory.create(address_line_one="234", city="Los Angeles", state="CA")) self.sue.tags.add(self.west_tag) # Poision data. Should never show up. self.archived_partner_user = (UserFactory( email="*****@*****.**")) self.archived_partner = ContactFactory( partner=self.partner_archived, name='Archived Partner Contact', user=self.archived_partner_user, email="*****@*****.**", last_action_time='2015-09-30 13:23') self.archived_partner.locations.add( LocationFactory.create(address_line_one="123", city="Nowhere", state="NO")) self.archived_partner.locations.add( LocationFactory.create(address_line_one="234", city="Nowhere", state="NO")) self.archived_partner.tags.add(self.west_tag) # Poision data. Should never show up. self.archived_contact_user = (UserFactory( email="*****@*****.**")) self.archived_contact = ContactFactory( partner=self.partner_b, name='Archived Contact', user=self.archived_contact_user, email="*****@*****.**", last_action_time='2015-09-30 13:23') self.archived_contact.locations.add( LocationFactory.create(address_line_one="123", city="Nowhere", state="NO")) self.archived_contact.locations.add( LocationFactory.create(address_line_one="234", city="Nowhere", state="NO")) self.archived_contact.tags.add(self.west_tag) # Poision data. Should never show up. self.unapproved_partner_user = (UserFactory( email="*****@*****.**")) self.unapproved_partner_contact = ContactFactory( partner=self.partner_unapp, name='Unapproved Partner Contact', user=self.unapproved_partner_user, email="*****@*****.**", last_action_time='2015-09-30 13:23') self.unapproved_partner_contact.locations.add( LocationFactory.create(address_line_one="123", city="Nowhere", state="NO")) self.unapproved_partner_contact.locations.add( LocationFactory.create(address_line_one="234", city="Nowhere", state="NO")) self.unapproved_partner_contact.tags.add(self.west_tag) # Poision data. Should never show up. self.unapproved_contact_user = (UserFactory( email="*****@*****.**")) self.unapproved_contact = ContactFactory( partner=self.partner_b, name='Unapproved Contact', user=self.unapproved_contact_user, email="*****@*****.**", last_action_time='2015-09-30 13:23', approval_status__code=Status.UNPROCESSED) self.unapproved_contact.locations.add( LocationFactory.create(address_line_one="123", city="Nowhere", state="NO")) self.unapproved_contact.locations.add( LocationFactory.create(address_line_one="234", city="Nowhere", state="NO")) self.unapproved_contact.tags.add(self.west_tag) # Poision data. Should never show up. self.wrong_user = UserFactory(email="*****@*****.**") self.wrong = ContactFactory(partner=self.other_partner, name='wrong person', user=self.wrong_user, email="*****@*****.**", last_action_time='2015-09-03') self.wrong.locations.add( LocationFactory.create(city="Los Angeles", state="CA")) self.wrong.tags.add(self.east_tag) self.wrong.tags.add(self.west_tag) self.wrong.tags.add(self.bad_tag) # Archive archived data here. Doing this earlier in the set up results # in odd exceptions. self.partner_archived.archive() self.archived_contact.archive() def test_run_unfiltered(self): """ Make sure we only get data for this user. """ ds = ContactsDataSource() recs = ds.run_unaggregated(self.company, ContactsFilter(), []) names = {r['name'] for r in recs} expected = {self.sue.name, self.john.name} self.assertEqual(expected, names) def test_filter_by_date_range(self): """ Should show only contact with last_action_time in range. """ ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter(date=DateRangeFilter( [datetime(2015, 9, 1), datetime(2015, 9, 30)])), []) names = {r['name'] for r in recs} expected = {self.sue.name} self.assertEqual(expected, names) def test_filter_by_date_before(self): """ Should show only contact with last_action_time before date. """ ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter( date=DateRangeFilter([None, datetime(2015, 9, 30)])), []) names = {r['name'] for r in recs} expected = {self.sue.name} self.assertEqual(expected, names) def test_filter_by_date_after(self): """ Should show only contact with last_action_time after date. """ ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter( date=DateRangeFilter([datetime(2015, 10, 1), None])), []) names = {r['name'] for r in recs} expected = {self.john.name} self.assertEqual(expected, names) def test_filter_by_tags(self): """ Should show only contact with correct tags. """ ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter( tags=AndGroupFilter([OrGroupFilter([MatchFilter('EaSt')])])), []) names = {r['name'] for r in recs} expected = {self.john.name} self.assertEqual(expected, names) def test_filter_by_tags_or(self): """ Show only contact with correct tags in 'or' configuration. """ ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter(tags=AndGroupFilter( [OrGroupFilter([MatchFilter('EaSt'), MatchFilter('wEsT')])])), []) names = {r['name'] for r in recs} expected = {self.john.name, self.sue.name} self.assertEqual(expected, names) def test_filter_by_tags_and(self): """ Show only contact with correct tags in 'and' configuration. """ ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter(tags=AndGroupFilter([ OrGroupFilter([MatchFilter('EaSt')]), OrGroupFilter([MatchFilter('wEsT')]) ])), []) names = {r['name'] for r in recs} expected = set() self.assertEqual(expected, names) # Now try adding another tag. self.john.tags.add(self.west_tag) recs = ds.run_unaggregated( self.company, ContactsFilter(tags=AndGroupFilter([ OrGroupFilter([MatchFilter('EaSt')]), OrGroupFilter([MatchFilter('wEsT')]) ])), []) names = {r['name'] for r in recs} expected = {self.john.name} self.assertEqual(expected, names) def test_filter_untagged(self): """ This indicates that the member selected to filter by untagged. """ self.sue.tags.clear() ds = ContactsDataSource() recs = ds.run_unaggregated(self.company, ContactsFilter(tags=UnlinkedFilter()), []) names = {r['name'] for r in recs} expected = {self.sue.name} self.assertEqual(expected, names) def test_filter_by_state(self): """Should show only contacts with correct state.""" ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter( locations=CompositeAndFilter({'state': MatchFilter('CA')})), []) names = [r['name'] for r in recs] expected = [self.sue.name] self.assertEqual(expected, names) def test_filter_by_city(self): """Should show only contacts with correct city.""" ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter(locations=CompositeAndFilter( {'city': MatchFilter('Los Angeles')})), []) names = [r['name'] for r in recs] expected = [self.sue.name] self.assertEqual(expected, names) def test_filter_by_partners(self): """Should filter by partners.""" ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter( partner=OrGroupFilter([MatchFilter(self.partner_a.pk)])), []) subjects = {r['name'] for r in recs} expected = {self.john.name} self.assertEqual(expected, subjects) def test_filter_by_partner_tags(self): """ Test that we can filter by partner tags. """ ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter(partner_tags=AndGroupFilter( [OrGroupFilter([MatchFilter('rigHt')])])), []) subjects = {r['name'] for r in recs} expected = {self.sue.name} self.assertEqual(expected, subjects) def test_filter_by_partner_tags_untagged(self): """ Check that we can find a record attached to an untagged partner. """ self.partner_b.tags.clear() ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter(partner_tags=UnlinkedFilter()), []) subjects = {r['name'] for r in recs} expected = {self.sue.name} self.assertEqual(expected, subjects) def test_help_city(self): """Check city help works and ignores current city filter.""" ds = ContactsDataSource() recs = ds.help_city( self.company, ContactsFilter(locations=CompositeAndFilter( {'city': MatchFilter('Los Angeles')})), "angel") actual = {r['value'] for r in recs} self.assertEqual({'Los Angeles'}, actual) def test_help_state(self): """Check state help works and ignores current state filter.""" ds = ContactsDataSource() recs = ds.help_state( self.company, ContactsFilter( locations=CompositeAndFilter({'state': MatchFilter('zz')})), "i") actual = {r['value'] for r in recs} self.assertEqual({'IL', 'IN'}, actual) def test_help_tags(self): """Check tags help works at all.""" ds = ContactsDataSource() recs = ds.help_tags(self.company, ContactsFilter(), "E") actual = {r['value'] for r in recs} self.assertEqual({'east', 'west'}, actual) def test_help_partner_tags(self): """ Check partner tags help works at all. """ ds = ContactsDataSource() recs = ds.help_partner_tags(self.company, ContactsFilter(), "t") actual = {r['value'] for r in recs} self.assertEqual({'left', 'right'}, actual) def test_help_tags_colors(self): """Tags should have colors""" ds = ContactsDataSource() recs = ds.help_tags(self.company, ContactsFilter(), "east") self.assertEqual("aaaaaa", recs[0]['hexColor']) def test_help_partner(self): """Check partner help works at all.""" ds = ContactsDataSource() recs = ds.help_partner(self.company, ContactsFilter(), "A") self.assertEqual([{ 'value': self.partner_a.pk, 'display': 'aaa' }], recs) def test_values(self): """Check limiting values works at all.""" ds = ContactsDataSource() recs = ds.run_unaggregated(self.company, ContactsFilter(), ["name", "email"]) expected = [ { 'name': self.john.name, 'email': u'*****@*****.**' }, { 'name': self.sue.name, 'email': u'*****@*****.**' }, ] self.assertEqual(expected, recs) def test_adorn_filter(self): self.maxDiff = 10000 found_filter_items = { 'tags': ['east', 'west'], 'partner': [str(self.partner_a.pk)], 'partner_tags': ['lEft', 'Right'], } expected = { u'partner': { self.partner_a.pk: { 'value': self.partner_a.pk, 'display': u'aaa' }, }, u'tags': { 'east': { 'value': u'east', 'display': u'east', 'hexColor': u'aaaaaa', }, 'west': { 'value': u'west', 'display': u'west', 'hexColor': u'bbbbbb', }, }, u'partner_tags': { 'left': { 'value': u'left', 'display': u'left', 'hexColor': u'cccccc', }, 'right': { 'value': u'right', 'display': u'right', 'hexColor': u'dddddd', }, }, } ds = ContactsDataSource() adorned_filter = ds.adorn_filter_items(self.company, found_filter_items) self.assertEqual(expected, adorned_filter) def test_default_filter(self): """should produce a populated filter object.""" ds = ContactsDataSource() default_filter = ds.get_default_filter(None, self.company) self.assertEquals(datetime.now().year, default_filter.date.dates[1].year) # Take out value dated today. Too hard to run through assertEquals. default_filter.date.dates[1] = None expected = ContactsFilter( date=DateRangeFilter([datetime(2014, 1, 1), None])) self.assertEquals(expected, default_filter)
class MyPartnerTests(MyJobsBase): def setUp(self): super(MyPartnerTests, self).setUp() self.company = CompanyFactory() self.partner = PartnerFactory(owner=self.company) self.contact = ContactFactory(partner=self.partner) def test_contact_to_partner_relationship(self): """ Tests adding a contact to partner's contacts list and tests primary_contact. Also tests if the contact gets deleted the partner stays and turns primary_contact to None. """ self.assertEqual( Contact.objects.filter(partner=self.partner).count(), 1) self.partner.primary_contact = self.contact self.partner.save() self.assertIsNotNone(self.partner.primary_contact) # making sure contact is the contact obj vs a factory object. contact = Contact.objects.get(name=self.contact.name) contact.delete() partner = Partner.objects.get(name=self.partner.name) self.assertFalse( Contact.objects.filter(partner=partner, archived_on__isnull=True)) self.assertIsNone(partner.primary_contact) def test_contact_user_relationship(self): """ Tests adding a User to Contact. Then tests to make sure User cascading delete doesn't delete the Contact and instead turns Contact.user to None. """ self.contact.user = UserFactory(email=self.contact.email) self.contact.save() self.assertIsNotNone(self.contact.user) self.assertEqual(self.contact.name, self.contact.__unicode__()) user = User.objects.get(email=self.contact.email) user.delete() contact = Contact.objects.get(name=self.contact.name) self.assertIsNone(contact.user) def test_location_to_contact_relationship(self): """ Tests adding a Location to Contact. """ location = LocationFactory() # make sure that we can add a location to a contact self.contact.locations.add(location) self.contact.save() self.assertTrue(len(self.contact.locations.all()) > 0) # ensure that we can remove a location self.contact.locations.remove(location) self.assertTrue(len(self.contact.locations.all()) == 0) # make sure that removing a location from a contact doesn't delete that # location entirely self.assertIn(location, Location.objects.all()) def test_bad_filename(self): """ Confirms that non-alphanumeric or underscore characters are being stripped from file names. """ actual_file = path.join(path.abspath(path.dirname(__file__)), 'data', 'test.txt') f = File(open(actual_file)) filenames = [('zz\\x80\\xff*file(copy)na.me.htm)_-)l', 'zzx80xfffilecopyname.htm_l'), ('...', 'unnamed_file'), ('..', 'unnamed_file'), ('../../file.txt', 'file.txt'), ('../..', 'unnamed_file'), ('\.\./file.txt', 'file.txt'), ('fiяыle.txt', 'file.txt')] for filename, expected_filename in filenames: f.name = filename prm_attachment = PRMAttachmentFactory(attachment=f) result = PRMAttachment.objects.get( attachment__contains=expected_filename) result.delete() def test_partner_saved_search_delete_contact(self): """ When a contact gets deleted, we should log it and disable any partner saved searches for that contact """ user = UserFactory(email='*****@*****.**') self.contact.user = user self.contact.save() self.contact = Contact.objects.get(pk=self.contact.pk) owner = UserFactory(email='*****@*****.**') partner_saved_search = PartnerSavedSearchFactory(created_by=owner, provider=self.company, partner=self.partner, user=user, notes='') self.assertTrue(partner_saved_search.is_active) self.contact.delete() partner_saved_search = PartnerSavedSearch.objects.get( pk=partner_saved_search.pk) self.assertFalse(partner_saved_search.is_active) self.assertTrue(self.contact.name in partner_saved_search.notes) def test_tag_added_to_taggable_models(self): tag = TagFactory(company=self.company) tag.save() tag2 = TagFactory(name="bar", company=self.company) tag2.save() cr = ContactRecordFactory(partner=self.partner) # Add tag to models cr.tags.add(tag) self.partner.tags.add(tag) self.partner.save() self.contact.tags.add(tag) self.contact.save() # Check to make sure it was added self.assertEquals(1, len(cr.tags.all())) self.assertEquals(1, len(self.partner.tags.all())) self.assertEquals(1, len(self.contact.tags.all())) # Add a 2nd tag and check self.partner.tags.add(tag2) self.partner.save() self.assertEquals(2, len(self.partner.tags.all())) def test_contact_archived(self): """Test that attempting to delete a contact archives it instead.""" self.assertFalse(self.contact.archived_on) self.contact.archive() self.assertEqual(Contact.objects.count(), 0) self.assertEqual(Contact.all_objects.count(), 1) self.assertTrue(self.contact.archived_on) def test_archived_manager_weirdness(self): """ Demonstrates that archived instances are returned by the ArchivedModel.all_objects manager, not the standard ArchivedModel.objects. """ self.partner.archive() # Try retrieving the archived partner using both managers. The "objects" # manager excludes archived instances so an exception is raised. self.assertRaises(Partner.DoesNotExist, lambda: Partner.objects.get(pk=self.partner.pk)) Partner.all_objects.get(pk=self.partner.pk) # This contact has not been archived (as we demonstrate in a few lines) # but is excluded by the "objects" manager as its partner has been # archived. self.assertRaises(Contact.DoesNotExist, lambda: Contact.objects.get(pk=self.contact.pk)) self.contact = Contact.all_objects.get(pk=self.contact.pk) self.assertFalse(self.contact.archived_on) # The manager used by related objects in this instance excludes # archived partners. As it's basically a Partner.objects.get(id=...), # this fails. self.assertRaises(Partner.DoesNotExist, lambda: self.contact.partner) self.assertEqual(self.contact.partner_id, self.partner.pk) def test_archive_primary_contacts(self): """ Archiving a primary contact should clear that contact's status as the partner's primary contact. Doing otherwise raises exceptions. """ self.partner.primary_contact = self.contact self.partner.save() self.partner.primary_contact.archive() self.partner = Partner.objects.get(pk=self.partner.pk) self.partner.primary_contact def test_models_approved(self): """ By default, new partners, contacts, and contactrecords should be approved. """ contactrecord = ContactRecordFactory(partner=self.partner) for instance in (self.contact, self.partner, contactrecord): self.assertEqual(instance.approval_status.code, Status.APPROVED) def test_contact_locations(self): """ Test that `get_contact_locations` returns a properly formatted string. """ ny = LocationFactory.create_batch(2, city="Albany", state="NY") il = LocationFactory.create(city="Chicago", state="IL") mo = LocationFactory.create(city="St. Louis", state="MO") contacts = ContactFactory.create_batch(4, partner=self.partner) for contact, location in zip(contacts, ny + [il, mo]): contact.locations.add(location) self.assertEqual("Chicago, IL; St. Louis, MO; Albany, NY", "; ".join(self.partner.get_contact_locations())) def test_uncommon_outreach_email_domain(self): """ Adding an uncommon email domain for outreach to a company should work. """ # data migrations aren't run during tests, so we populate manually CommonEmailDomain.objects.create(domain="gmail.com") with self.assertRaises(ValidationError): OutreachEmailDomain.objects.create(company=self.company, domain="gmail.com") def test_outreach_domain_unique_to_company(self): """ Allowed domains should be unique within a company, but not necessarily across PRM. """ OutreachEmailDomain.objects.create(company=self.company, domain="foo.bar") # duplicate domains allowed between companies company = CompanyFactory.create(name="A Whole New World") OutreachEmailDomain.objects.create(company=company, domain="foo.bar") # dupliate domains disallowed within the same company with self.assertRaises(IntegrityError): OutreachEmailDomain.objects.create(company=self.company, domain="foo.bar") def test_contact_record_counts_vs_list(self): """ ContactRecord counts for Communication Records and Referals should match summed counts from contacts. """ contacts = ContactFactory.create_batch(4) contacts[0].name = 'Other name' contacts[1].email = '*****@*****.**' contacts[2].partner = PartnerFactory(name='Other Partner') for contact in contacts: ContactRecordFactory.create(contact_type="job", contact=contact, partner=contact.partner) ContactRecordFactory.create(contact_type='email', contact=contact, partner=contact.partner) contacts[0].email = '*****@*****.**' ContactRecordFactory.create(contact_type='email', contact=contacts[0], partner=contact.partner) queryset = ContactRecord.objects.all() self.assertEqual(queryset.count(), 9) contacts = list(queryset.contacts) sum_referrals = sum([contact['referrals'] for contact in contacts]) sum_records = sum([contact['records'] for contact in contacts]) self.assertEqual(sum_referrals, queryset.referrals) self.assertEqual(sum_records, queryset.communication_activity.count()) def test_contact_record_report_numbers(self): """ Contact records have properties which represent various aggregated values. This test ensures that given a number of contact records, those aggregated numbers are correct. """ email_record = ContactRecordFactory(contact_type="email", partner=self.partner, contact=self.contact) job_record = ContactRecordFactory(contact_type="job", partner=self.partner, contact=self.contact, job_applications=10, job_interviews=6, job_hires=5) phone_record = ContactRecordFactory(contact_type="phone", partner=self.partner, contact=ContactFactory(name="Joe")) records = ContactRecord.objects.all() self.assertEqual(len(records), 3) self.assertEqual(len(records.contacts), 2) # job follow ups don't count as comm activity self.assertEqual(len(records.communication_activity), 2) # only job follow ups count as referrals self.assertEqual(records.referrals, 1) self.assertEqual(records.applications, 10) self.assertEqual(records.interviews, 6) self.assertEqual(records.hires, 5) self.assertEqual(records.emails, 1) self.assertEqual(records.calls, 1)
class TestContactsDataSource(MyJobsBase): def setUp(self): super(TestContactsDataSource, self).setUp() # A company to work with self.company = CompanyFactory(name='right') self.company.save() # A separate company that should not show up in results. self.other_company = CompanyFactory(name='wrong') self.other_company.save() self.partner = PartnerFactory( owner=self.company) self.other_partner = PartnerFactory( owner=self.other_company) self.partner_a = PartnerFactory(owner=self.company, name="aaa") self.partner_b = PartnerFactory(owner=self.company, name="bbb") # An unapproved parther. Associated data should be filtered out. self.partner_unapp = PartnerFactory( owner=self.company, name="unapproved", approval_status__code=Status.UNPROCESSED) # An archived parther. Associated data should be filtered out. self.partner_archived = PartnerFactory(owner=self.company) self.east_tag = TagFactory.create( company=self.company, name='east', hex_color="aaaaaa") self.west_tag = TagFactory.create( company=self.company, name='west', hex_color="bbbbbb") self.left_tag = TagFactory.create( company=self.company, name='left', hex_color="cccccc") self.right_tag = TagFactory.create( company=self.company, name='right', hex_color="dddddd") self.bad_tag = TagFactory.create( company=self.company, name='bad', hex_color="cccccc") self.partner_a.tags.add(self.left_tag) self.partner_b.tags.add(self.right_tag) self.john_user = UserFactory(email="*****@*****.**") self.john = ContactFactory( partner=self.partner_a, name='john adams', user=self.john_user, email="*****@*****.**", last_action_time='2015-10-03') self.john.locations.add( LocationFactory.create( city="Indianapolis", state="IN")) self.john.locations.add( LocationFactory.create( city="Chicago", state="IL")) self.john.tags.add(self.east_tag) self.sue_user = UserFactory(email="*****@*****.**") self.sue = ContactFactory( partner=self.partner_b, name='Sue Baxter', user=self.sue_user, email="*****@*****.**", last_action_time='2015-09-30 13:23') self.sue.locations.add( LocationFactory.create( address_line_one="123", city="Los Angeles", state="CA")) self.sue.locations.add( LocationFactory.create( address_line_one="234", city="Los Angeles", state="CA")) self.sue.tags.add(self.west_tag) # Poision data. Should never show up. self.archived_partner_user = ( UserFactory(email="*****@*****.**")) self.archived_partner = ContactFactory( partner=self.partner_archived, name='Archived Partner Contact', user=self.archived_partner_user, email="*****@*****.**", last_action_time='2015-09-30 13:23') self.archived_partner.locations.add( LocationFactory.create( address_line_one="123", city="Nowhere", state="NO")) self.archived_partner.locations.add( LocationFactory.create( address_line_one="234", city="Nowhere", state="NO")) self.archived_partner.tags.add(self.west_tag) # Poision data. Should never show up. self.archived_contact_user = ( UserFactory(email="*****@*****.**")) self.archived_contact = ContactFactory( partner=self.partner_b, name='Archived Contact', user=self.archived_contact_user, email="*****@*****.**", last_action_time='2015-09-30 13:23') self.archived_contact.locations.add( LocationFactory.create( address_line_one="123", city="Nowhere", state="NO")) self.archived_contact.locations.add( LocationFactory.create( address_line_one="234", city="Nowhere", state="NO")) self.archived_contact.tags.add(self.west_tag) # Poision data. Should never show up. self.unapproved_partner_user = ( UserFactory(email="*****@*****.**")) self.unapproved_partner_contact = ContactFactory( partner=self.partner_unapp, name='Unapproved Partner Contact', user=self.unapproved_partner_user, email="*****@*****.**", last_action_time='2015-09-30 13:23') self.unapproved_partner_contact.locations.add( LocationFactory.create( address_line_one="123", city="Nowhere", state="NO")) self.unapproved_partner_contact.locations.add( LocationFactory.create( address_line_one="234", city="Nowhere", state="NO")) self.unapproved_partner_contact.tags.add(self.west_tag) # Poision data. Should never show up. self.unapproved_contact_user = ( UserFactory(email="*****@*****.**")) self.unapproved_contact = ContactFactory( partner=self.partner_b, name='Unapproved Contact', user=self.unapproved_contact_user, email="*****@*****.**", last_action_time='2015-09-30 13:23', approval_status__code=Status.UNPROCESSED) self.unapproved_contact.locations.add( LocationFactory.create( address_line_one="123", city="Nowhere", state="NO")) self.unapproved_contact.locations.add( LocationFactory.create( address_line_one="234", city="Nowhere", state="NO")) self.unapproved_contact.tags.add(self.west_tag) # Poision data. Should never show up. self.wrong_user = UserFactory(email="*****@*****.**") self.wrong = ContactFactory( partner=self.other_partner, name='wrong person', user=self.wrong_user, email="*****@*****.**", last_action_time='2015-09-03') self.wrong.locations.add( LocationFactory.create( city="Los Angeles", state="CA")) self.wrong.tags.add(self.east_tag) self.wrong.tags.add(self.west_tag) self.wrong.tags.add(self.bad_tag) # Archive archived data here. Doing this earlier in the set up results # in odd exceptions. self.partner_archived.archive() self.archived_contact.archive() def test_run_unfiltered(self): """ Make sure we only get data for this user. """ ds = ContactsDataSource() recs = ds.run_unaggregated(self.company, ContactsFilter(), []) names = {r['name'] for r in recs} expected = {self.sue.name, self.john.name} self.assertEqual(expected, names) def test_filter_by_date_range(self): """ Should show only contact with last_action_time in range. """ ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter( date=DateRangeFilter([ datetime(2015, 9, 1), datetime(2015, 9, 30)])), []) names = {r['name'] for r in recs} expected = {self.sue.name} self.assertEqual(expected, names) def test_filter_by_date_before(self): """ Should show only contact with last_action_time before date. """ ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter( date=DateRangeFilter([None, datetime(2015, 9, 30)])), []) names = {r['name'] for r in recs} expected = {self.sue.name} self.assertEqual(expected, names) def test_filter_by_date_after(self): """ Should show only contact with last_action_time after date. """ ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter( date=DateRangeFilter([datetime(2015, 10, 1), None])), []) names = {r['name'] for r in recs} expected = {self.john.name} self.assertEqual(expected, names) def test_filter_by_tags(self): """ Should show only contact with correct tags. """ ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter(tags=AndGroupFilter([ OrGroupFilter([MatchFilter('EaSt')])])), []) names = {r['name'] for r in recs} expected = {self.john.name} self.assertEqual(expected, names) def test_filter_by_tags_or(self): """ Show only contact with correct tags in 'or' configuration. """ ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter(tags=AndGroupFilter([ OrGroupFilter([MatchFilter('EaSt'), MatchFilter('wEsT')])])), []) names = {r['name'] for r in recs} expected = {self.john.name, self.sue.name} self.assertEqual(expected, names) def test_filter_by_tags_and(self): """ Show only contact with correct tags in 'and' configuration. """ ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter(tags=AndGroupFilter([ OrGroupFilter([MatchFilter('EaSt')]), OrGroupFilter([MatchFilter('wEsT')])])), []) names = {r['name'] for r in recs} expected = set() self.assertEqual(expected, names) # Now try adding another tag. self.john.tags.add(self.west_tag) recs = ds.run_unaggregated( self.company, ContactsFilter(tags=AndGroupFilter([ OrGroupFilter([MatchFilter('EaSt')]), OrGroupFilter([MatchFilter('wEsT')])])), []) names = {r['name'] for r in recs} expected = {self.john.name} self.assertEqual(expected, names) def test_filter_untagged(self): """ This indicates that the member selected to filter by untagged. """ self.sue.tags.clear() ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter(tags=UnlinkedFilter()), []) names = {r['name'] for r in recs} expected = {self.sue.name} self.assertEqual(expected, names) def test_filter_by_state(self): """Should show only contacts with correct state.""" ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter( locations=CompositeAndFilter({'state': MatchFilter('CA')})), []) names = [r['name'] for r in recs] expected = [self.sue.name] self.assertEqual(expected, names) def test_filter_by_city(self): """Should show only contacts with correct city.""" ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter( locations=CompositeAndFilter({ 'city': MatchFilter('Los Angeles')})), []) names = [r['name'] for r in recs] expected = [self.sue.name] self.assertEqual(expected, names) def test_filter_by_partners(self): """Should filter by partners.""" ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter( partner=OrGroupFilter([MatchFilter(self.partner_a.pk)])), []) subjects = {r['name'] for r in recs} expected = {self.john.name} self.assertEqual(expected, subjects) def test_filter_by_partner_tags(self): """ Test that we can filter by partner tags. """ ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter(partner_tags=AndGroupFilter([ OrGroupFilter([MatchFilter('rigHt')])])), []) subjects = {r['name'] for r in recs} expected = {self.sue.name} self.assertEqual(expected, subjects) def test_filter_by_partner_tags_untagged(self): """ Check that we can find a record attached to an untagged partner. """ self.partner_b.tags.clear() ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter(partner_tags=UnlinkedFilter()), []) subjects = {r['name'] for r in recs} expected = {self.sue.name} self.assertEqual(expected, subjects) def test_help_city(self): """Check city help works and ignores current city filter.""" ds = ContactsDataSource() recs = ds.help_city( self.company, ContactsFilter( locations=CompositeAndFilter({ 'city': MatchFilter('Los Angeles')})), "angel") actual = {r['value'] for r in recs} self.assertEqual({'Los Angeles'}, actual) def test_help_state(self): """Check state help works and ignores current state filter.""" ds = ContactsDataSource() recs = ds.help_state( self.company, ContactsFilter( locations=CompositeAndFilter({ 'state': MatchFilter('zz')})), "i") actual = {r['value'] for r in recs} self.assertEqual({'IL', 'IN'}, actual) def test_help_tags(self): """Check tags help works at all.""" ds = ContactsDataSource() recs = ds.help_tags(self.company, ContactsFilter(), "E") actual = {r['value'] for r in recs} self.assertEqual({'east', 'west'}, actual) def test_help_partner_tags(self): """ Check partner tags help works at all. """ ds = ContactsDataSource() recs = ds.help_partner_tags(self.company, ContactsFilter(), "t") actual = {r['value'] for r in recs} self.assertEqual({'left', 'right'}, actual) def test_help_tags_colors(self): """Tags should have colors""" ds = ContactsDataSource() recs = ds.help_tags(self.company, ContactsFilter(), "east") self.assertEqual("aaaaaa", recs[0]['hexColor']) def test_help_partner(self): """Check partner help works at all.""" ds = ContactsDataSource() recs = ds.help_partner(self.company, ContactsFilter(), "A") self.assertEqual( [{'value': self.partner_a.pk, 'display': 'aaa'}], recs) def test_values(self): """Check limiting values works at all.""" ds = ContactsDataSource() recs = ds.run_unaggregated( self.company, ContactsFilter(), ["name", "email"]) expected = [ {'name': self.john.name, 'email': u'*****@*****.**'}, {'name': self.sue.name, 'email': u'*****@*****.**'}, ] self.assertEqual(expected, recs) def test_adorn_filter(self): self.maxDiff = 10000 found_filter_items = { 'tags': ['east', 'west'], 'partner': [str(self.partner_a.pk)], 'partner_tags': ['lEft', 'Right'], } expected = { u'partner': { self.partner_a.pk: {'value': self.partner_a.pk, 'display': u'aaa'}, }, u'tags': { 'east': { 'value': u'east', 'display': u'east', 'hexColor': u'aaaaaa', }, 'west': { 'value': u'west', 'display': u'west', 'hexColor': u'bbbbbb', }, }, u'partner_tags': { 'left': { 'value': u'left', 'display': u'left', 'hexColor': u'cccccc', }, 'right': { 'value': u'right', 'display': u'right', 'hexColor': u'dddddd', }, }, } ds = ContactsDataSource() adorned_filter = ds.adorn_filter_items( self.company, found_filter_items) self.assertEqual(expected, adorned_filter) def test_default_filter(self): """should produce a populated filter object.""" ds = ContactsDataSource() default_filter = ds.get_default_filter(None, self.company) self.assertEquals( datetime.now().year, default_filter.date.dates[1].year) # Take out value dated today. Too hard to run through assertEquals. default_filter.date.dates[1] = None expected = ContactsFilter( date=DateRangeFilter([datetime(2014, 1, 1), None])) self.assertEquals(expected, default_filter)
class MyPartnerTests(MyJobsBase): def setUp(self): super(MyPartnerTests, self).setUp() self.company = CompanyFactory() self.partner = PartnerFactory(owner=self.company) self.contact = ContactFactory(partner=self.partner) def test_contact_to_partner_relationship(self): """ Tests adding a contact to partner's contacts list and tests primary_contact. Also tests if the contact gets deleted the partner stays and turns primary_contact to None. """ self.assertEqual(Contact.objects.filter(partner=self.partner).count(), 1) self.partner.primary_contact = self.contact self.partner.save() self.assertIsNotNone(self.partner.primary_contact) # making sure contact is the contact obj vs a factory object. contact = Contact.objects.get(name=self.contact.name) contact.delete() partner = Partner.objects.get(name=self.partner.name) self.assertFalse(Contact.objects.filter( partner=partner, archived_on__isnull=True)) self.assertIsNone(partner.primary_contact) def test_contact_user_relationship(self): """ Tests adding a User to Contact. Then tests to make sure User cascading delete doesn't delete the Contact and instead turns Contact.user to None. """ self.contact.user = UserFactory(email=self.contact.email) self.contact.save() self.assertIsNotNone(self.contact.user) self.assertEqual(self.contact.name, self.contact.__unicode__()) user = User.objects.get(email=self.contact.email) user.delete() contact = Contact.objects.get(name=self.contact.name) self.assertIsNone(contact.user) def test_location_to_contact_relationship(self): """ Tests adding a Location to Contact. """ location = LocationFactory() # make sure that we can add a location to a contact self.contact.locations.add(location) self.contact.save() self.assertTrue(len(self.contact.locations.all()) > 0) # ensure that we can remove a location self.contact.locations.remove(location) self.assertTrue(len(self.contact.locations.all()) == 0) # make sure that removing a location from a contact doesn't delete that # location entirely self.assertIn(location, Location.objects.all()) def test_bad_filename(self): """ Confirms that non-alphanumeric or underscore characters are being stripped from file names. """ actual_file = path.join(path.abspath(path.dirname(__file__)), 'data', 'test.txt') f = File(open(actual_file)) filenames = [ ('zz\\x80\\xff*file(copy)na.me.htm)_-)l', 'zzx80xfffilecopyname.htm_l'), ('...', 'unnamed_file'), ('..', 'unnamed_file'), ('../../file.txt', 'file.txt'), ('../..', 'unnamed_file'), ('\.\./file.txt', 'file.txt'), ('fiяыle.txt', 'file.txt') ] for filename, expected_filename in filenames: f.name = filename prm_attachment = PRMAttachmentFactory(attachment=f) result = PRMAttachment.objects.get( attachment__contains=expected_filename) result.delete() def test_partner_saved_search_delete_contact(self): """ When a contact gets deleted, we should log it and disable any partner saved searches for that contact """ user = UserFactory(email='*****@*****.**') self.contact.user = user self.contact.save() self.contact = Contact.objects.get(pk=self.contact.pk) owner = UserFactory(email='*****@*****.**') partner_saved_search = PartnerSavedSearchFactory(created_by=owner, provider=self.company, partner=self.partner, user=user, notes='') self.assertTrue(partner_saved_search.is_active) self.contact.delete() partner_saved_search = PartnerSavedSearch.objects.get( pk=partner_saved_search.pk) self.assertFalse(partner_saved_search.is_active) self.assertTrue(self.contact.name in partner_saved_search.notes) def test_tag_added_to_taggable_models(self): tag = TagFactory(company=self.company) tag.save() tag2 = TagFactory(name="bar", company=self.company) tag2.save() cr = ContactRecordFactory(partner=self.partner) # Add tag to models cr.tags.add(tag) self.partner.tags.add(tag) self.partner.save() self.contact.tags.add(tag) self.contact.save() # Check to make sure it was added self.assertEquals(1, len(cr.tags.all())) self.assertEquals(1, len(self.partner.tags.all())) self.assertEquals(1, len(self.contact.tags.all())) # Add a 2nd tag and check self.partner.tags.add(tag2) self.partner.save() self.assertEquals(2, len(self.partner.tags.all())) def test_contact_archived(self): """Test that attempting to delete a contact archives it instead.""" self.assertFalse(self.contact.archived_on) self.contact.archive() self.assertEqual(Contact.objects.count(), 0) self.assertEqual(Contact.all_objects.count(), 1) self.assertTrue(self.contact.archived_on) def test_archived_manager_weirdness(self): """ Demonstrates that archived instances are returned by the ArchivedModel.all_objects manager, not the standard ArchivedModel.objects. """ self.partner.archive() # Try retrieving the archived partner using both managers. The "objects" # manager excludes archived instances so an exception is raised. self.assertRaises(Partner.DoesNotExist, lambda: Partner.objects.get(pk=self.partner.pk)) Partner.all_objects.get(pk=self.partner.pk) # This contact has not been archived (as we demonstrate in a few lines) # but is excluded by the "objects" manager as its partner has been # archived. self.assertRaises(Contact.DoesNotExist, lambda: Contact.objects.get(pk=self.contact.pk)) self.contact = Contact.all_objects.get(pk=self.contact.pk) self.assertFalse(self.contact.archived_on) # The manager used by related objects in this instance excludes # archived partners. As it's basically a Partner.objects.get(id=...), # this fails. self.assertRaises(Partner.DoesNotExist, lambda: self.contact.partner) self.assertEqual(self.contact.partner_id, self.partner.pk) def test_archive_primary_contacts(self): """ Archiving a primary contact should clear that contact's status as the partner's primary contact. Doing otherwise raises exceptions. """ self.partner.primary_contact = self.contact self.partner.save() self.partner.primary_contact.archive() self.partner = Partner.objects.get(pk=self.partner.pk) self.partner.primary_contact def test_models_approved(self): """ By default, new partners, contacts, and contactrecords should be approved. """ contactrecord = ContactRecordFactory(partner=self.partner) for instance in (self.contact, self.partner, contactrecord): self.assertEqual(instance.approval_status.code, Status.APPROVED) def test_contact_locations(self): """ Test that `get_contact_locations` returns a properly formatted string. """ ny = LocationFactory.create_batch(2, city="Albany", state="NY") il = LocationFactory.create(city="Chicago", state="IL") mo = LocationFactory.create(city="St. Louis", state="MO") contacts = ContactFactory.create_batch(4, partner=self.partner) for contact, location in zip(contacts, ny + [il, mo]): contact.locations.add(location) self.assertEqual("Chicago, IL; St. Louis, MO; Albany, NY", "; ".join(self.partner.get_contact_locations())) def test_uncommon_outreach_email_domain(self): """ Adding an uncommon email domain for outreach to a company should work. """ # data migrations aren't run during tests, so we populate manually CommonEmailDomain.objects.create(domain="gmail.com") with self.assertRaises(ValidationError): OutreachEmailDomain.objects.create(company=self.company, domain="gmail.com") def test_outreach_domain_unique_to_company(self): """ Allowed domains should be unique within a company, but not necessarily across PRM. """ OutreachEmailDomain.objects.create(company=self.company, domain="foo.bar") # duplicate domains allowed between companies company = CompanyFactory.create(name="A Whole New World") OutreachEmailDomain.objects.create(company=company, domain="foo.bar") # dupliate domains disallowed within the same company with self.assertRaises(IntegrityError): OutreachEmailDomain.objects.create(company=self.company, domain="foo.bar") def test_contact_record_report_numbers(self): """ Contact records have properties which represent various aggregated values. This test ensures that given a number of contact records, those aggregated numbers are correct. """ email_record = ContactRecordFactory(contact_type="email", partner=self.partner, contact=self.contact) job_record = ContactRecordFactory(contact_type="job", partner=self.partner, contact=self.contact, job_applications=10, job_interviews=6, job_hires=5) phone_record = ContactRecordFactory(contact_type="phone", partner=self.partner, contact=ContactFactory(name="Joe")) records = ContactRecord.objects.all() self.assertEqual(len(records), 3) self.assertEqual(len(records.contacts), 2) # job follow ups don't count as comm activity self.assertEqual(len(records.communication_activity), 2) # only job follow ups count as referrals self.assertEqual(records.referrals, 1) self.assertEqual(records.applications, 10) self.assertEqual(records.interviews, 6) self.assertEqual(records.hires, 5) self.assertEqual(records.emails, 1) self.assertEqual(records.calls, 1)