예제 #1
0
 def test_duplicate_company(self):
     company1 = CompanyFactory()
     company1.save()
     company2 = CompanyFactory(name="Acme corp")
     company2.save()
     self.businessunit.company_set.add(company1)
     self.businessunit.title = "Acme corp"
     add_company(self.businessunit)
     self.assertEqual(self.businessunit.company_set.all()[0], company2)
예제 #2
0
    def test_subsidiary_rename(self):
        company1 = CompanyFactory()
        company1.save()
        bu1 = self.businessunit
        bu1.title = "Acme corp"
        bu2 = BusinessUnitFactory(title=bu1.title)
        bu2.save()
        self.businessunit.company_set.add(company1)

        # Test that a company was created for both business units
        add_company(bu1)
        companies = bu1.company_set.all()
        self.assertEqual(len(companies), 1)
        co = companies[0]
        self.assertEqual(co.name, bu1.title)

        # Add the 2nd business unit
        add_company(bu2)

        # Both units should be attached to that company
        self.assertEqual(bu1.company_set.all()[0], bu2.company_set.all()[0])
        self.assertEqual(bu1.company_set.all().count(), 1) 
        self.assertIn(bu1, co.job_source_ids.all())
        self.assertIn(bu2, co.job_source_ids.all())
        self.assertEqual(co.name, bu1.title)
        self.assertEqual(co.name, bu2.title)

        bu2.title = "New company name"
        add_company(bu1)
        add_company(bu2)
        self.assertEqual(len(co.job_source_ids.all()), 1)
        self.assertNotEqual(bu1.company_set.all(), bu2.company_set.all())
        self.assertEqual(co.name, bu1.title)
        self.assertEqual(len(bu2.company_set.all()), 1)
        co2 = bu2.company_set.all()[0]
        self.assertEqual(co2.name, bu2.title)
        self.assertNotEqual(co2.name, bu1.title)
        self.assertNotEqual(co.name, bu2.title)
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)
예제 #4
0
class JobFeedTestCase(DirectSEOBase):

    def setUp(self):
        super(JobFeedTestCase, self).setUp()
        self.businessunit = BusinessUnitFactory(id=0)
        self.buid_id = self.businessunit.id
        self.numjobs = 14
        self.testdir = os.path.join(os.path.abspath(os.path.dirname(__file__)), 
                                    'data')
        self.company = CompanyFactory()
        self.company.job_source_ids.add(self.businessunit)
        self.company.save()
        self.conn = Solr("http://127.0.0.1:8983/solr/seo")
        self.emptyfeed = os.path.join(self.testdir, "dseo_feed_0.no_jobs.xml")
        self.malformed_feed = os.path.join(self.testdir, 'dseo_malformed_feed_0.xml')
        self.invalid_feed = os.path.join(self.testdir, 'dseo_invalid_feed_0.xml')
        self.unused_field_feed = os.path.join(self.testdir, 'dseo_feed_1.xml')
        self.no_onet_feed = os.path.join(self.testdir, 'dseo_feed_no_onets.xml')

        #Ensures DATA_DIR used by import_jobs.download_feed_file exists
        data_path = DATA_DIR
        if not os.path.exists(data_path):
            os.mkdir(data_path)

    def test_company_canonical_microsite(self):
        # Test that canonical microsites is correctly added to solr
        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])

        jobs = results.solr_jobs()
        self.assertEqual(jobs[0]['company_canonical_microsite_exact'], None)

        self.company.canonical_microsite = "http://test.jobs"
        self.company.save()

        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])

        jobs = results.solr_jobs()
        self.assertEqual(jobs[0]['company_canonical_microsite_exact'],
                         'http://test.jobs')

    def test_company_enhanced(self):
        # Test that company enhanced check is correctly added to solr
        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])

        jobs = results.solr_jobs()
        self.assertFalse(jobs[0]['company_enhanced'])

        self.company.enhanced = True
        self.company.save()

        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])

        jobs = results.solr_jobs()
        self.assertTrue(jobs[0]['company_enhanced'])

    def test_company_member(self):
        # Test that company member check is correctly added to solr
        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])
        jobs = results.solr_jobs()
        self.assertTrue(jobs[0]['company_member'])

        self.company.member = False
        self.company.save()

        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])

        jobs = results.solr_jobs()
        self.assertFalse(jobs[0]['company_member'])

    def test_company_digital_strategies_customer(self):
        # Test that digial strategies customer check is correctly added to solr
        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])

        jobs = results.solr_jobs()
        self.assertFalse(jobs[0]['company_digital_strategies_customer'])

        self.company.digital_strategies_customer = True
        self.company.save()

        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])

        jobs = results.solr_jobs()
        self.assertTrue(jobs[0]['company_digital_strategies_customer'])

    def test_no_markdown_newline_breaks(self):
        # Test that non-markdown businessunits have newlines converted to breaks
        no_markdown_bu = BusinessUnitFactory.build(id=5, enable_markdown=False)
        results = DEv2JobFeed(
                    'seo/tests/data/dseo_feed_0.xml', 
                    jsid=no_markdown_bu.id,
                    markdown=no_markdown_bu.enable_markdown) 
        jobs = results.solr_jobs()
        self.assertNotEqual(jobs[0]['html_description'].find('Operations<br />'), -1)
        
    def test_markdown_no_newline_breaks(self):
        # Test that markdown businessunits do not have newlines converted to breaks
        results = DEv2JobFeed(
                    'seo/tests/data/dseo_feed_0.xml', 
                    jsid=self.businessunit.id,
                    markdown = self.businessunit.enable_markdown) 
        jobs = results.solr_jobs()
        self.assertEqual(jobs[0]['html_description'].find('Operations<br />'), -1)

    def test_unused_fields(self):
        # Test that new fields don't break existing code
        results = DEv2JobFeed(self.unused_field_feed,
                                        jsid=self.businessunit.id)
        jobs = results.solr_jobs()
        self.assertEqual(len(results.jobparse()), 1)

    def test_unescape(self):
        """Tests that escaped html characters are unescaped when imported"""
        results = DEv2JobFeed(
                    'seo/tests/data/dseo_feed_0.escaped_chars.xml', 
                    jsid=0) 
        jobs = results.solr_jobs()
        self.assertEqual(results.job_source_name.find('&#162;'), -1)
        self.assertEqual(jobs[0]['description'].find('&amp;'), -1)

    def test_markdown_code_blocks(self):
        #test that code blocks are not in html job descriptions
        results = DEv2JobFeed(
                    'seo/tests/data/dseo_feed_0.markdown.xml', 
                    jsid=0) 
        jobs = results.solr_jobs()
        for job in jobs:
            self.assertEqual(job['html_description'].find('<code>'), -1)
            self.assertEqual(job['html_description'].find('</code>'), -1)
            self.assertEqual(job['html_description'].find('<pre>'), -1)
            self.assertEqual(job['html_description'].find('<h1>'), -1)
            self.assertEqual(job['html_description'].find('##'), -1)
            self.assertNotEqual(job['html_description'].find('<h4>'), -1)
            self.assertNotEqual(job['html_description'].find('<h6>'), -1)
            self.assertNotEqual(job['html_description'].find('<li>'), -1)
            self.assertNotEqual(job['html_description'].find('</li>'), -1)

    def test_no_null_values(self):
        # test that there's no literal null in html 'city' entry
        results = DEv2JobFeed(
                    'seo/tests/data/dseo_feed_0.markdown.xml', 
                    jsid=0) 
        jobs = results.solr_jobs()
        for job in jobs:
            self.assertNotEqual(job['city'], 'null')
        
    def test_dev2_feed(self):
        filepath = download_feed_file(self.buid_id)
        results = DEv2JobFeed(filepath)
        jobs = results.jobparse()
        self.assertEqual(results.jsid, self.buid_id)
        self.assertEqual(results.job_source_name, self.businessunit.title)
        self.assertEqual(len(jobs), self.numjobs)

    def test_mocids(self):
        """
        Tests that mocid fields exist when jobs are imported from a feed and
        added to a solr connnection
        
        """
        filepath = download_feed_file(self.buid_id)
        results = DEv2JobFeed(filepath)
        jobs = results.solr_jobs()
        # Since we're going to be adding/updating data in the Solr index, we're
        # hardcoding in the local Solr instance so that we don't accidentally
        # alter production data.
        self.conn.add(jobs)
        num_hits = self.conn.search(q="*:*",
                                    fq="buid:%s -mocid:[* TO *]" % self.buid_id)
        self.assertEqual(num_hits.hits, self.numjobs)
        for job in jobs:
            self.assertTrue('mocid' in job)

    def test_empty_feed(self):
        """
        Test that the schema for the v2 DirectEmployers feed file schema
        allows for empty feed files.
        
        """
        results = DEv2JobFeed(self.emptyfeed)
        # If the schema is such that empty feed files are considered invalid,
        # trying to run jobparse() will throw an exception.
        self.assertEqual(len(results.jobparse()), 0)

    def test_empty_solr(self):
        """
        Tests for the proper behavior when encountering a job-less, but
        otherwise valid, feed file. The proper behavior is to delete any
        jobs associated with that BusinessUnit from the Solr index.

        """
        # Normal download-and-parse operation on a feed file with jobs.
        update_solr(self.buid_id)
        results = self.conn.search(q="*:*", fq="buid:%s" % self.buid_id)
        self.assertEqual(results.hits, self.numjobs)

        # Download-and-parse operation on a feed file with no jobs. Expected
        # behavior is to delete all jobs.
        self._get_feedfile()
        update_solr(self.buid_id, download=False)
        results = self.conn.search(q="*:*", fq="buid:%s" % self.buid_id)
        self.assertEqual(results.hits, 0)

    def test_zipcode(self):
        """
        Tests to ensure proper behavior of zipcode field in being entered in
        Solr.

        """
        filepath = download_feed_file(self.buid_id)
        dbresults = DEv2JobFeed(filepath)
        solrresults = dbresults.solr_jobs()

        zips_from_feedfile = ['30269', '30269', '48332', '30269', '30269',
                              '30269', '30269', '30269', '48332', '48332',
                              '30269', None, '30269', '30269']

        solrzips = [i['zipcode'] for i in solrresults]
        for coll in [solrzips]:
            self.assertItemsEqual(zips_from_feedfile, coll)

    def test_salt_date(self):
        """
        Test to ensure that job postings show up in a quasi-random
        fashion by sorting by the `salted_date` attribute in the index
        vice strictly by `date_new`.
        
        """
        filepath = download_feed_file(self.buid_id)
        jobs = DEv2JobFeed(filepath)
        solrjobs = jobs.solr_jobs()
        self.conn.add(solrjobs)
        results = self.conn.search(q="*:*", sort="salted_date asc")
        self.assertEqual(self.numjobs, results.hits)
        # We can't really test for inequality between the two result sets,
        # since sometimes results.docs will equal results2.docs.
        results2 = self.conn.search(q="*:*", sort="date_new asc")
        self.assertItemsEqual(results2.docs, results.docs)

    def test_date_updated(self):
        """
        Test to ensure proper behavior of date updated field when added to
        Solr.

        """
        filepath = download_feed_file(self.buid_id)
        jobs = DEv2JobFeed(filepath)
        solrjobs = jobs.solr_jobs()
        self.conn.add(solrjobs)
        dates_updated = [datetime.datetime.strptime("4/16/2015 11:35:13 PM",
                                                    "%m/%d/%Y %I:%M:%S %p"),
                         datetime.datetime.strptime("4/16/2015 11:35:14 PM",
                                                    "%m/%d/%Y %I:%M:%S %p"),
                         datetime.datetime.strptime("4/16/2015 11:35:15 PM",
                                                    "%m/%d/%Y %I:%M:%S %p")]
        solr_dates = [i['date_updated'] for i in solrjobs]
        for solr_date in solr_dates:
            self.assertIn(solr_date, dates_updated)
        
    def _get_feedfile(self):
        # Download the 'real' feed file then copy the empty feed file in its
        # place.
        realfeed = download_feed_file(self.buid_id)
        shutil.copyfile(realfeed, "%s.bak" % realfeed)
        shutil.copyfile(self.emptyfeed, realfeed)

    def test_parse_malformed_feed(self):
        """
        Test that a malformed feedfile does not cause an unhandled exception.

        """
        result = DEv2JobFeed(self.malformed_feed, jsid=0)

    def test_parse_invalid_feed(self):
        """
        Test that a feed file that fails validation does not cause an unhandled
        exception. 

        """
        result = DEv2JobFeed(self.invalid_feed, jsid=0)

    def test_no_onets(self):
        result = DEv2JobFeed(self.no_onet_feed, jsid=0)
        jobs = result.solr_jobs()
        self.assertEqual(jobs[0]['onet'], '')

    def test_on_sites_by_buid(self):
        business_unit = BusinessUnitFactory(pk=77)

        results = DEv2JobFeed('seo/tests/data/dseo_feed_0.xml',
                              jsid=business_unit.id,
                              markdown=business_unit.enable_markdown)
        jobs = results.solr_jobs()
        for job in jobs:
            self.assertItemsEqual(job['on_sites'], [0])

        site_package = SitePackageFactory(owner=self.company)
        business_unit.site_packages.add(site_package)

        results = DEv2JobFeed('seo/tests/data/dseo_feed_0.xml',
                              jsid=business_unit.id,
                              markdown=business_unit.enable_markdown)
        jobs = results.solr_jobs()
        for job in jobs:
            self.assertItemsEqual(job['on_sites'], [site_package.pk])

        site_package2 = SitePackageFactory(owner=self.company)
        business_unit.site_packages.add(site_package2)

        results = DEv2JobFeed('seo/tests/data/dseo_feed_0.xml',
                              jsid=business_unit.id,
                              markdown=business_unit.enable_markdown)
        jobs = results.solr_jobs()
        for job in jobs:
            self.assertItemsEqual(job['on_sites'], [site_package.pk,
                                                    site_package2.pk])

        site_package2.delete()
        site_package.delete()
        business_unit.delete()
예제 #5
0
class TestPasswordExpiration(TestCase):
    """Test password expiration"""
    def setUp(self):
        super(TestPasswordExpiration, self).setUp()

        (self.user, _) = User.objects.create_user(password='******',
                                                  email='*****@*****.**')
        self.strict = CompanyFactory(password_expiration=True, name='strict')
        self.strict_role = RoleFactory(company=self.strict, name="Admin")
        self.loose = CompanyFactory(password_expiration=False, name='loose')
        self.loose_role = RoleFactory(company=self.loose, name="Admin")
        self.user.roles.add(self.strict_role)
        self.user.roles.add(self.loose_role)

        # Reload from db to get correct password state.
        self.user = User.objects.get(pk=self.user.pk)

    def test_no_company(self):
        """Users with no company should not have password expiration"""
        self.user.roles.clear()
        self.assertEqual(False, self.user.has_password_expiration())
        self.assertEqual(False, self.user.is_password_expired())

        self.user.password = '******'
        self.user.save()
        self.assertEqual(None, self.user.password_last_modified)
        self.assertEqual(0, self.user.userpasswordhistory_set.count())

    def test_use_loose_companies_only(self):
        """Making the strict company loose should disable expiration."""
        self.strict.password_expiration = False
        self.strict.save()
        self.assertEqual(False, self.user.has_password_expiration())

    def test_use_stricter_company(self):
        """Users with any strict company should have password expiration"""
        self.assertEqual(True, self.user.has_password_expiration())

    def test_first_expirable_login(self):
        """is_password_expired is True when the user has never logged in."""
        self.assertEqual(True, self.user.is_password_expired())

    def test_login_within_expire_window(self):
        """is_password_expired is False when in the expiration window."""
        self.user.password_last_modified = (timezone.now() -
                                            datetime.timedelta(days=1))
        self.user.save()
        self.assertEqual(False, self.user.is_password_expired())

    def test_login_out_of_expire_window(self):
        """is_password_expired is True when past the expiration window."""
        days = settings.PASSWORD_EXPIRATION_DAYS
        self.user.password_last_modified = (timezone.now() -
                                            datetime.timedelta(days))
        self.user.save()
        self.assertEqual(True, self.user.is_password_expired())

    def test_change_password(self):
        """
        Changing password for a user in a company does sets pasword last
        modified time.
        """
        before_password_set = timezone.now()
        self.user.set_password('somepass2')
        self.user.save()
        self.assertGreater(self.user.password_last_modified,
                           before_password_set)
        self.assertEqual(1, self.user.userpasswordhistory_set.count())

    def test_history_limit(self):
        """
        Adding to the password history should exceed the history limit.
        """
        limit = settings.PASSWORD_HISTORY_ENTRIES
        for i in range(0, limit + 2):
            date = (datetime.datetime(2016, 1, 1, tzinfo=pytz.UTC) +
                    datetime.timedelta(days=i))
            self.user.add_password_to_history('entry-%d' % i, date)
            self.assertLess(0, self.user.userpasswordhistory_set.count())
            self.assertLessEqual(self.user.userpasswordhistory_set.count(),
                                 limit)
        hashes = set(h.password_hash
                     for h in self.user.userpasswordhistory_set.all())
        self.assertNotIn('entry-0', hashes)
        self.assertEquals(limit, len(hashes))

    def test_is_password_in_history(self):
        """
        Don't let the user reuse a password they used recently.
        """
        limit = settings.PASSWORD_HISTORY_ENTRIES
        for i in range(0, limit + 1):
            self.user.set_password('entry-%d' % i)
            self.user.save()
        self.assertFalse(self.user.is_password_in_history('entry-0'))
        for i in range(1, limit + 1):
            entry = 'entry-%d' % i
            self.assertTrue(self.user.is_password_in_history(entry), entry)

    def test_is_password_in_history_disabled(self):
        """
        Disable history checking if password expiration is off.
        """
        limit = settings.PASSWORD_HISTORY_ENTRIES
        for i in range(0, limit):
            self.user.set_password('entry-%d' % i)
            self.user.save()
        self.strict.password_expiration = False
        self.strict.save()
        for i in range(0, limit):
            entry = 'entry-%d' % i
            self.assertFalse(self.user.is_password_in_history(entry), entry)

    def test_lockout_counter(self):
        """
        Keep track of failed login attempts.
        """
        limit = settings.PASSWORD_ATTEMPT_LOCKOUT
        for i in range(0, limit):
            self.assertFalse(self.user.is_locked_out(), 'iteration %d' % i)
            self.user.note_failed_login()
        self.assertTrue(self.user.is_locked_out())
        self.user.reset_lockout()
        self.assertFalse(self.user.is_locked_out())
예제 #6
0
class TestPasswordExpiration(TestCase):
    """Test password expiration"""

    def setUp(self):
        super(TestPasswordExpiration, self).setUp()

        (self.user, _) = User.objects.create_user(
            password='******',
            email='*****@*****.**')
        self.strict = CompanyFactory(password_expiration=True, name='strict')
        self.strict_role = RoleFactory(company=self.strict, name="Admin")
        self.loose = CompanyFactory(password_expiration=False, name='loose')
        self.loose_role = RoleFactory(company=self.loose, name="Admin")
        self.user.roles.add(self.strict_role)
        self.user.roles.add(self.loose_role)

        # Reload from db to get correct password state.
        self.user = User.objects.get(pk=self.user.pk)

    def test_no_company(self):
        """Users with no company should not have password expiration"""
        self.user.roles.clear()
        self.assertEqual(
            False,
            self.user.has_password_expiration())
        self.assertEqual(
            False,
            self.user.is_password_expired())

        self.user.password = '******'
        self.user.save()
        self.assertEqual(None, self.user.password_last_modified)
        self.assertEqual(0, self.user.userpasswordhistory_set.count())

    def test_use_loose_companies_only(self):
        """Making the strict company loose should disable expiration."""
        self.strict.password_expiration = False
        self.strict.save()
        self.assertEqual(False, self.user.has_password_expiration())

    def test_use_stricter_company(self):
        """Users with any strict company should have password expiration"""
        self.assertEqual(True, self.user.has_password_expiration())

    def test_first_expirable_login(self):
        """is_password_expired is True when the user has never logged in."""
        self.assertEqual(True, self.user.is_password_expired())

    def test_login_within_expire_window(self):
        """is_password_expired is False when in the expiration window."""
        self.user.password_last_modified = (
            timezone.now() - datetime.timedelta(days=1))
        self.user.save()
        self.assertEqual(False, self.user.is_password_expired())

    def test_login_out_of_expire_window(self):
        """is_password_expired is True when past the expiration window."""
        days = settings.PASSWORD_EXPIRATION_DAYS
        self.user.password_last_modified = (
            timezone.now() - datetime.timedelta(days))
        self.user.save()
        self.assertEqual(True, self.user.is_password_expired())

    def test_change_password(self):
        """
        Changing password for a user in a company does sets pasword last
        modified time.
        """
        before_password_set = timezone.now()
        self.user.set_password('somepass2')
        self.user.save()
        self.assertGreater(
            self.user.password_last_modified, before_password_set)
        self.assertEqual(1, self.user.userpasswordhistory_set.count())

    def test_history_limit(self):
        """
        Adding to the password history should exceed the history limit.
        """
        limit = settings.PASSWORD_HISTORY_ENTRIES
        for i in range(0, limit + 2):
            date = (
                datetime.datetime(2016, 1, 1, tzinfo=pytz.UTC) +
                datetime.timedelta(days=i))
            self.user.add_password_to_history('entry-%d' % i, date)
            self.assertLess(0, self.user.userpasswordhistory_set.count())
            self.assertLessEqual(
                self.user.userpasswordhistory_set.count(),
                limit)
        hashes = set(
            h.password_hash
            for h in self.user.userpasswordhistory_set.all())
        self.assertNotIn('entry-0', hashes)
        self.assertEquals(limit, len(hashes))

    def test_is_password_in_history(self):
        """
        Don't let the user reuse a password they used recently.
        """
        limit = settings.PASSWORD_HISTORY_ENTRIES
        for i in range(0, limit + 1):
            self.user.set_password('entry-%d' % i)
            self.user.save()
        self.assertFalse(self.user.is_password_in_history('entry-0'))
        for i in range(1, limit + 1):
            entry = 'entry-%d' % i
            self.assertTrue(self.user.is_password_in_history(entry), entry)

    def test_is_password_in_history_disabled(self):
        """
        Disable history checking if password expiration is off.
        """
        limit = settings.PASSWORD_HISTORY_ENTRIES
        for i in range(0, limit):
            self.user.set_password('entry-%d' % i)
            self.user.save()
        self.strict.password_expiration = False
        self.strict.save()
        for i in range(0, limit):
            entry = 'entry-%d' % i
            self.assertFalse(self.user.is_password_in_history(entry), entry)

    def test_lockout_counter(self):
        """
        Keep track of failed login attempts.
        """
        limit = settings.PASSWORD_ATTEMPT_LOCKOUT
        for i in range(0, limit):
            self.assertFalse(self.user.is_locked_out(), 'iteration %d' % i)
            self.user.note_failed_login()
        self.assertTrue(self.user.is_locked_out())
        self.user.reset_lockout()
        self.assertFalse(self.user.is_locked_out())
예제 #7
0
class TestCommRecordsDataSource(MyJobsBase):
    def setUp(self):
        super(TestCommRecordsDataSource, 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_a = PartnerFactory(owner=self.company,
                                        uri='http://www.example.com/',
                                        data_source="zap",
                                        name="aaa")
        self.partner_b = PartnerFactory(owner=self.company,
                                        uri='http://www.asdf.com/',
                                        data_source="bcd",
                                        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.north_tag = TagFactory.create(company=self.company,
                                           name='north',
                                           hex_color="cccccc")
        self.south_tag = TagFactory.create(company=self.company,
                                           name='south',
                                           hex_color="dddddd")
        self.left_tag = TagFactory.create(company=self.company,
                                          name='left',
                                          hex_color="eeeeee")
        self.right_tag = TagFactory.create(company=self.company,
                                           name='right',
                                           hex_color="ffffff")
        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.north_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.south_tag)

        self.partner_a.primary_contact = self.john
        self.partner_b.primary_contact = self.sue

        self.partner_a.save()
        self.partner_b.save()

        self.record_1 = ContactRecordFactory(subject='record 1',
                                             date_time='2015-09-30 13:23',
                                             contact=self.john,
                                             contact_type="Email",
                                             partner=self.partner_a,
                                             location='Indianapolis, IN',
                                             tags=[self.east_tag])
        self.record_2 = ContactRecordFactory(subject='record 2',
                                             date_time='2015-01-01',
                                             contact=self.john,
                                             contact_type="Meeting Or Event",
                                             partner=self.partner_a,
                                             location='Indianapolis, IN',
                                             tags=[self.east_tag])
        self.record_3 = ContactRecordFactory(subject='record 3',
                                             date_time='2015-10-03',
                                             contact=self.sue,
                                             contact_type="Phone",
                                             partner=self.partner_b,
                                             location='Los Angeles, CA',
                                             tags=[self.west_tag])

        # Archive archived data here. Doing this earlier in the set up results
        # in odd exceptions.
        self.partner_archived.archive()

    def test_run_unfiltered(self):
        """Make sure we only get data for this user."""
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(self.company, CommRecordsFilter(), [])
        subjects = {r['subject'] for r in recs}
        expected = {
            self.record_1.subject,
            self.record_2.subject,
            self.record_3.subject,
        }
        self.assertEqual(expected, subjects)

    def test_filter_by_date_range(self):
        """Should show only commrec with last_action_time in range."""
        ds = CommRecordsDataSource()
        date_range = DateRangeFilter(
            [datetime(2015, 9, 1), datetime(2015, 9, 30)])
        recs = ds.run_unaggregated(self.company,
                                   CommRecordsFilter(date_time=date_range), [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_date_before(self):
        """Should show only commrec with last_action_time before date."""
        ds = CommRecordsDataSource()
        date_range = DateRangeFilter([None, datetime(2015, 9, 30)])
        recs = ds.run_unaggregated(self.company,
                                   CommRecordsFilter(date_time=date_range), [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject, self.record_2.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_date_after(self):
        """Should show only commrec with last_action_time after date."""
        ds = CommRecordsDataSource()
        date_range = DateRangeFilter([datetime(2015, 10, 1), None])
        recs = ds.run_unaggregated(self.company,
                                   CommRecordsFilter(date_time=date_range), [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_state(self):
        """Should show only commrecs with correct state."""
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(
                locations=CompositeAndFilter({'state': MatchFilter('CA')})),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_city(self):
        """Should show only commrecs with correct city."""
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(locations=CompositeAndFilter(
                {'city': MatchFilter('Los Angeles')})), [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_tags(self):
        """
        Show only commrec with correct tags.

        """
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(
                tags=AndGroupFilter([OrGroupFilter([MatchFilter('EaSt')])])),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject, self.record_2.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_tags_unlinked(self):
        """
       Only return untagged commrecs.

        """
        self.record_1.tags.clear()
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(self.company,
                                   CommRecordsFilter(tags=UnlinkedFilter()),
                                   [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_tags_or(self):
        """Show only commrec with correct tags in 'or' configuration."""
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(tags=AndGroupFilter(
                [OrGroupFilter([MatchFilter('EaSt'),
                                MatchFilter('wEsT')])])), [])
        subjects = {r['subject'] for r in recs}
        expected = {
            self.record_1.subject,
            self.record_2.subject,
            self.record_3.subject,
        }
        self.assertEqual(expected, subjects)

    def test_filter_by_tags_and(self):
        """Show only commrec with correct tags in 'and' configuration."""
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(tags=AndGroupFilter([
                OrGroupFilter([MatchFilter('EaSt')]),
                OrGroupFilter([MatchFilter('wEsT')])
            ])), [])
        subjects = {r['subject'] for r in recs}
        expected = set()
        self.assertEqual(expected, subjects)

        # Now try adding another tag.
        self.record_1.tags.add(self.west_tag)
        self.record_1.save()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(tags=AndGroupFilter([
                OrGroupFilter([MatchFilter('EaSt')]),
                OrGroupFilter([MatchFilter('wEsT')])
            ])), [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_communication_type(self):
        """Check communication_type filter works at all."""
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(
                communication_type=OrGroupFilter([MatchFilter('email')])), [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_partner(self):
        """
        Check partner filter works at all.

        """
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(
                partner=OrGroupFilter([MatchFilter(self.partner_a.pk)])), [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject, self.record_2.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_contact(self):
        """
        Check partner filter works at all.

        """
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(
                contact=OrGroupFilter([MatchFilter(self.sue.pk)])), [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_contact_tags(self):
        """
        Test that we can filter by contact tags.

        """
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(contact_tags=AndGroupFilter(
                [OrGroupFilter([MatchFilter('sOuTh')])])), [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_contact_tags_untagged(self):
        """
        Check that we can find a record attached to an untagged contact.

        """
        self.sue.tags.clear()
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company, CommRecordsFilter(contact_tags=UnlinkedFilter()), [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_partner_tags(self):
        """
        Test that we can filter by partner tags.

        """
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(partner_tags=AndGroupFilter(
                [OrGroupFilter([MatchFilter('rigHt')])])), [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        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 = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company, CommRecordsFilter(partner_tags=UnlinkedFilter()), [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)

    def test_help_city(self):
        """
        Check city help works and ignores current city filter.

        """
        ds = CommRecordsDataSource()
        recs = ds.help_city(
            self.company,
            CommRecordsFilter(
                locations=CompositeAndFilter({'city': MatchFilter("zz")})),
            "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 = CommRecordsDataSource()
        recs = ds.help_state(
            self.company,
            CommRecordsFilter(
                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 = CommRecordsDataSource()
        recs = ds.help_tags(self.company, CommRecordsFilter(), "E")
        actual = {r['value'] for r in recs}
        self.assertEqual({'east', 'west'}, actual)

    def test_help_contact_tags(self):
        """
        Check contact tags help works at all.

        """
        ds = CommRecordsDataSource()
        recs = ds.help_contact_tags(self.company, CommRecordsFilter(), "O")
        actual = {r['value'] for r in recs}
        self.assertEqual({'north', 'south'}, actual)

    def test_help_partner_tags(self):
        """
        Check partner tags help works at all.

        """
        ds = CommRecordsDataSource()
        recs = ds.help_partner_tags(self.company, CommRecordsFilter(), "t")
        actual = {r['value'] for r in recs}
        self.assertEqual({'left', 'right'}, actual)

    def test_help_tags_colors(self):
        """
        Tags should have colors

        """
        ds = CommRecordsDataSource()
        recs = ds.help_tags(self.company, CommRecordsFilter(), "east")
        self.assertEqual("aaaaaa", recs[0]['hexColor'])

    def test_help_communication_types(self):
        """
        Check communication_types help works at all.

        """
        ds = CommRecordsDataSource()
        recs = ds.help_communication_type(self.company, CommRecordsFilter(),
                                          "ph")
        actual = {r['value'] for r in recs}
        expected = {'phone', 'job', 'meetingorevent', 'email', 'pssemail'}
        self.assertEqual(expected, actual)

    def test_help_partner(self):
        """
        Check partner help works at all.

        """
        ds = CommRecordsDataSource()
        recs = ds.help_partner(self.company, CommRecordsFilter(), "A")
        self.assertEqual([{
            'value': self.partner_a.pk,
            'display': self.partner_a.name
        }], recs)

    def test_help_contact(self):
        """
        Check contact help works at all.

        """
        ds = CommRecordsDataSource()
        recs = ds.help_contact(self.company, CommRecordsFilter(), "U")
        self.assertEqual([{
            'value': self.sue.pk,
            'display': self.sue.name
        }], recs)

    def test_values(self):
        """
        Check limiting values works at all

        """
        self.maxDiff = 10000
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(self.company, CommRecordsFilter(),
                                   ["partner", "subject"])
        expected = [
            {
                'partner': u'aaa',
                'subject': u'record 1'
            },
            {
                'partner': u'aaa',
                'subject': u'record 2'
            },
            {
                'partner': u'bbb',
                'subject': u'record 3'
            },
        ]
        self.assertEqual(expected, recs)

    def test_adorn_filter(self):
        self.maxDiff = 10000
        found_filter_items = {
            'tags': ['east', 'west'],
            'communication_type': ['Email'],
            'partner': [str(self.partner_a.pk)],
            'contact': [str(self.sue.pk)],
            'contact_tags': ['nOrth', 'south'],
            'partner_tags': ['lEft', 'riGht'],
        }

        expected = {
            u'partner': {
                self.partner_a.pk: {
                    'value': self.partner_a.pk,
                    'display': u'aaa'
                },
            },
            u'contact': {
                self.sue.pk: {
                    'value': self.sue.pk,
                    'display': u'Sue Baxter'
                },
            },
            u'tags': {
                u'east': {
                    'value': u'east',
                    'display': u'east',
                    'hexColor': u'aaaaaa',
                },
                u'west': {
                    'value': u'west',
                    'display': u'west',
                    'hexColor': u'bbbbbb',
                },
            },
            u'communication_type': {
                'email': {
                    'value': 'email',
                    'display': 'Email'
                }
            },
            u'contact_tags': {
                u'north': {
                    'value': u'north',
                    'display': u'north',
                    'hexColor': u'cccccc',
                },
                u'south': {
                    'value': u'south',
                    'display': u'south',
                    'hexColor': u'dddddd',
                },
            },
            u'partner_tags': {
                u'left': {
                    'value': u'left',
                    'display': u'left',
                    'hexColor': u'eeeeee',
                },
                u'right': {
                    'value': u'right',
                    'display': u'right',
                    'hexColor': u'ffffff',
                },
            },
        }

        ds = CommRecordsDataSource()
        result = ds.adorn_filter_items(self.company, found_filter_items)
        self.assertEqual(expected, result)

    def test_default_filter(self):
        """
        should produce a populated filter object.

        """
        ds = CommRecordsDataSource()
        default_filter = ds.get_default_filter(None, self.company)
        self.assertEquals(datetime.now().year,
                          default_filter.date_time.dates[1].year)
        # Take out value dated today. Too hard to run through assertEquals.
        default_filter.date_time.dates[1] = None
        expected = CommRecordsFilter(
            date_time=DateRangeFilter([datetime(2014, 1, 1), None]))
        self.assertEquals(expected, default_filter)
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)
예제 #9
0
class JobFeedTestCase(DirectSEOBase):

    def setUp(self):
        super(JobFeedTestCase, self).setUp()
        self.businessunit = BusinessUnitFactory(id=0)
        self.buid_id = self.businessunit.id
        self.numjobs = 14
        self.testdir = os.path.join(os.path.abspath(os.path.dirname(__file__)),
                                    'data')
        self.company = CompanyFactory()
        self.company.job_source_ids.add(self.businessunit)
        self.company.save()
        self.conn = Solr("http://127.0.0.1:8983/solr/seo")
        self.emptyfeed = os.path.join(self.testdir, "dseo_feed_0.no_jobs.xml")
        self.malformed_feed = os.path.join(self.testdir, 'dseo_malformed_feed_0.xml')
        self.invalid_feed = os.path.join(self.testdir, 'dseo_invalid_feed_0.xml')
        self.unused_field_feed = os.path.join(self.testdir, 'dseo_feed_1.xml')
        self.no_onet_feed = os.path.join(self.testdir, 'dseo_feed_no_onets.xml')

        # Ensures DATA_DIR used by import_jobs.download_feed_file exists
        data_path = DATA_DIR
        if not os.path.exists(data_path):
            os.mkdir(data_path)

    def test_company_canonical_microsite(self):
        # Test that canonical microsites is correctly added to solr
        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])

        jobs = results.solr_jobs()
        self.assertEqual(jobs[0]['company_canonical_microsite_exact'], None)

        self.company.canonical_microsite = "http://test.jobs"
        self.company.save()

        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])

        jobs = results.solr_jobs()
        self.assertEqual(jobs[0]['company_canonical_microsite_exact'],
                         'http://test.jobs')

    def test_company_enhanced(self):
        # Test that company enhanced check is correctly added to solr
        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])

        jobs = results.solr_jobs()
        self.assertFalse(jobs[0]['company_enhanced'])

        self.company.enhanced = True
        self.company.save()

        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])

        jobs = results.solr_jobs()
        self.assertTrue(jobs[0]['company_enhanced'])

    def test_company_member(self):
        # Test that company member check is correctly added to solr
        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])
        jobs = results.solr_jobs()
        self.assertTrue(jobs[0]['company_member'])

        self.company.member = False
        self.company.save()

        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])

        jobs = results.solr_jobs()
        self.assertFalse(jobs[0]['company_member'])

    def test_company_digital_strategies_customer(self):
        # Test that digial strategies customer check is correctly added to solr
        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])

        jobs = results.solr_jobs()
        self.assertFalse(jobs[0]['company_digital_strategies_customer'])

        self.company.digital_strategies_customer = True
        self.company.save()

        results = DEv2JobFeed(
            'seo/tests/data/dseo_feed_0.xml',
            jsid=self.businessunit.id,
            company=self.businessunit.company_set.all()[0])

        jobs = results.solr_jobs()
        self.assertTrue(jobs[0]['company_digital_strategies_customer'])

    def test_no_markdown_newline_breaks(self):
        # Test that non-markdown businessunits have newlines converted to breaks
        no_markdown_bu = BusinessUnitFactory.build(id=5, enable_markdown=False)
        results = DEv2JobFeed(
                    'seo/tests/data/dseo_feed_0.xml',
                    jsid=no_markdown_bu.id,
                    markdown=no_markdown_bu.enable_markdown)
        jobs = results.solr_jobs()
        self.assertNotEqual(jobs[0]['html_description'].find('Operations<br />'), -1)

    def test_markdown_no_newline_breaks(self):
        # Test that markdown businessunits do not have newlines converted to breaks
        results = DEv2JobFeed(
                    'seo/tests/data/dseo_feed_0.xml',
                    jsid=self.businessunit.id,
                    markdown = self.businessunit.enable_markdown)
        jobs = results.solr_jobs()
        self.assertEqual(jobs[0]['html_description'].find('Operations<br />'), -1)

    def test_unused_fields(self):
        # Test that new fields don't break existing code
        results = DEv2JobFeed(self.unused_field_feed,
                                        jsid=self.businessunit.id)
        jobs = results.solr_jobs()
        self.assertEqual(len(results.jobparse()), 1)

    def test_unescape(self):
        """Tests that escaped html characters are unescaped when imported"""
        results = DEv2JobFeed(
                    'seo/tests/data/dseo_feed_0.escaped_chars.xml',
                    jsid=0)
        jobs = results.solr_jobs()
        self.assertEqual(results.job_source_name.find('&#162;'), -1)
        self.assertEqual(jobs[0]['description'].find('&amp;'), -1)

    def test_markdown_code_blocks(self):
        # test that code blocks are not in html job descriptions
        results = DEv2JobFeed(
                    'seo/tests/data/dseo_feed_0.markdown.xml',
                    jsid=0)
        jobs = results.solr_jobs()
        for job in jobs:
            self.assertEqual(job['html_description'].find('<code>'), -1)
            self.assertEqual(job['html_description'].find('</code>'), -1)
            self.assertEqual(job['html_description'].find('<pre>'), -1)
            self.assertEqual(job['html_description'].find('<h1>'), -1)
            self.assertEqual(job['html_description'].find('##'), -1)
            self.assertNotEqual(job['html_description'].find('<h4>'), -1)
            self.assertNotEqual(job['html_description'].find('<h6>'), -1)
            self.assertNotEqual(job['html_description'].find('<li>'), -1)
            self.assertNotEqual(job['html_description'].find('</li>'), -1)

    def test_no_null_values(self):
        # test that there's no literal null in html 'city' entry
        results = DEv2JobFeed(
                    'seo/tests/data/dseo_feed_0.markdown.xml',
                    jsid=0)
        jobs = results.solr_jobs()
        for job in jobs:
            self.assertNotEqual(job['city'], 'null')

    def test_dev2_feed(self):
        filepath = download_feed_file(self.buid_id)
        results = DEv2JobFeed(filepath)
        jobs = results.jobparse()
        self.assertEqual(results.jsid, self.buid_id)
        self.assertEqual(results.job_source_name, self.businessunit.title)
        self.assertEqual(len(jobs), self.numjobs)

    def test_mocids(self):
        """
        Tests that mocid fields exist when jobs are imported from a feed and
        added to a solr connnection

        """
        filepath = download_feed_file(self.buid_id)
        results = DEv2JobFeed(filepath)
        jobs = results.solr_jobs()
        # Since we're going to be adding/updating data in the Solr index, we're
        # hardcoding in the local Solr instance so that we don't accidentally
        # alter production data.
        self.conn.add(jobs)
        num_hits = self.conn.search(q="*:*",
                                    fq="buid:%s -mocid:[* TO *]" % self.buid_id)
        self.assertEqual(num_hits.hits, self.numjobs)
        for job in jobs:
            self.assertTrue('mocid' in job)

    def test_empty_feed(self):
        """
        Test that the schema for the v2 DirectEmployers feed file schema
        allows for empty feed files.

        """
        results = DEv2JobFeed(self.emptyfeed)
        # If the schema is such that empty feed files are considered invalid,
        # trying to run jobparse() will throw an exception.
        self.assertEqual(len(results.jobparse()), 0)

    def test_empty_solr(self):
        """
        Tests for the proper behavior when encountering a job-less, but
        otherwise valid, feed file. The proper behavior is to delete any
        jobs associated with that BusinessUnit from the Solr index.

        """
        # Normal download-and-parse operation on a feed file with jobs.
        update_solr(self.buid_id)
        results = self.conn.search(q="*:*", fq="buid:%s" % self.buid_id)
        self.assertEqual(results.hits, self.numjobs)

        # Download-and-parse operation on a feed file with no jobs. Expected
        # behavior is to delete all jobs.
        self._get_feedfile()
        update_solr(self.buid_id, download=False)
        results = self.conn.search(q="*:*", fq="buid:%s" % self.buid_id)
        self.assertEqual(results.hits, 0)

    def test_zipcode(self):
        """
        Tests to ensure proper behavior of zipcode field in being entered in
        Solr.

        """
        filepath = download_feed_file(self.buid_id)
        dbresults = DEv2JobFeed(filepath)
        solrresults = dbresults.solr_jobs()

        zips_from_feedfile = ['30269', '30269', '48332', '30269', '30269',
                              '30269', '30269', '30269', '48332', '48332',
                              '30269', None, '30269', '30269']

        solrzips = [i['zipcode'] for i in solrresults]
        for coll in [solrzips]:
            self.assertItemsEqual(zips_from_feedfile, coll)

    def test_salt_date(self):
        """
        Test to ensure that job postings show up in a quasi-random
        fashion by sorting by the `salted_date` attribute in the index
        vice strictly by `date_new`.

        """
        filepath = download_feed_file(self.buid_id)
        jobs = DEv2JobFeed(filepath)
        solrjobs = jobs.solr_jobs()
        self.conn.add(solrjobs)
        results = self.conn.search(q="*:*", sort="salted_date asc")
        self.assertEqual(self.numjobs, results.hits)
        # We can't really test for inequality between the two result sets,
        # since sometimes results.docs will equal results2.docs.
        results2 = self.conn.search(q="*:*", sort="date_new asc")
        self.assertItemsEqual(results2.docs, results.docs)

    def test_date_updated(self):
        """
        Test to ensure proper behavior of date updated field when added to
        Solr.

        """
        filepath = download_feed_file(self.buid_id)
        jobs = DEv2JobFeed(filepath)
        solrjobs = jobs.solr_jobs()
        self.conn.add(solrjobs)
        dates_updated = [datetime.datetime.strptime("4/16/2015 11:35:13 PM",
                                                    "%m/%d/%Y %I:%M:%S %p"),
                         datetime.datetime.strptime("4/16/2015 11:35:14 PM",
                                                    "%m/%d/%Y %I:%M:%S %p"),
                         datetime.datetime.strptime("4/16/2015 11:35:15 PM",
                                                    "%m/%d/%Y %I:%M:%S %p")]
        solr_dates = [i['date_updated'] for i in solrjobs]
        for solr_date in solr_dates:
            self.assertIn(solr_date, dates_updated)

    def _get_feedfile(self):
        # Download the 'real' feed file then copy the empty feed file in its
        # place.
        realfeed = download_feed_file(self.buid_id)
        shutil.copyfile(realfeed, "%s.bak" % realfeed)
        shutil.copyfile(self.emptyfeed, realfeed)

    def test_parse_malformed_feed(self):
        """
        Test that a malformed feedfile does not cause an unhandled exception.

        """
        result = DEv2JobFeed(self.malformed_feed, jsid=0)

    def test_parse_invalid_feed(self):
        """
        Test that a feed file that fails validation does not cause an unhandled
        exception.

        """
        result = DEv2JobFeed(self.invalid_feed, jsid=0)

    def test_no_onets(self):
        result = DEv2JobFeed(self.no_onet_feed, jsid=0)
        jobs = result.solr_jobs()
        self.assertEqual(jobs[0]['onet'], '')

    def test_on_sites_by_buid(self):
        business_unit = BusinessUnitFactory(pk=77)

        results = DEv2JobFeed('seo/tests/data/dseo_feed_0.xml',
                              jsid=business_unit.id,
                              markdown=business_unit.enable_markdown)
        jobs = results.solr_jobs()
        for job in jobs:
            self.assertItemsEqual(job['on_sites'], [0])

        site_package = SitePackageFactory(owner=self.company)
        business_unit.site_packages.add(site_package)

        results = DEv2JobFeed('seo/tests/data/dseo_feed_0.xml',
                              jsid=business_unit.id,
                              markdown=business_unit.enable_markdown)
        jobs = results.solr_jobs()
        for job in jobs:
            self.assertItemsEqual(job['on_sites'], [site_package.pk])

        site_package2 = SitePackageFactory(owner=self.company)
        business_unit.site_packages.add(site_package2)

        results = DEv2JobFeed('seo/tests/data/dseo_feed_0.xml',
                              jsid=business_unit.id,
                              markdown=business_unit.enable_markdown)
        jobs = results.solr_jobs()
        for job in jobs:
            self.assertItemsEqual(job['on_sites'], [site_package.pk,
                                                    site_package2.pk])

        site_package2.delete()
        site_package.delete()
        business_unit.delete()
예제 #10
0
class ModelTests(MyJobsBase):
    def setUp(self):
        super(ModelTests, self).setUp()
        self.user = User.objects.create(email='*****@*****.**')
        self.company = CompanyFactory()
        CompanyProfile.objects.create(company=self.company)
        self.site = SeoSiteFactory()  #domain='buckconsoltants.jobs')
        self.bu = BusinessUnitFactory()
        self.site.business_units.add(self.bu)
        self.site.save()
        self.company.job_source_ids.add(self.bu)
        self.company.save()

        # Use the newly created site for testing instead of secure.my.jobs.
        settings.SITE = self.site

        self.request_data = {
            'title': 'title',
            'company': self.company.id,
            'reqid': '1',
            'description': 'sadfljasdfljasdflasdfj',
            'link': 'www.google.com',
            'on_sites': '0',
            'apply_info': '',
        }

        self.request_location = {
            'city': 'Indianapolis',
            'state': 'Indiana',
            'state_short': 'IN',
            'country': 'United States',
            'country_short': 'USA',
            'zipcode': '46268',
        }

        self.site_package_data = {
            'name': 'Test Site Package',
        }

    def test_job_creation_and_deletion(self):
        locations = JobLocationFactory.create_batch(5)
        job = JobFactory(owner=self.company, created_by=self.user)
        job.locations = locations
        job.save()
        self.assertEqual(Job.objects.all().count(), 1)
        self.assertEqual(JobLocation.objects.all().count(), 5)
        job.delete()
        self.assertEqual(Job.objects.all().count(), 0)
        self.assertEqual(JobLocation.objects.all().count(), 0)

    def test_add_remove_job_locations(self):
        """
        Regression test, job locations that were removed from a job weren't
        being removed from Solr
        Tests that adding or removing locations results in Solr updates after
        a job save
        """
        locations = JobLocationFactory.create_batch(2)
        job = JobFactory(owner=self.company,
                         created_by=self.user,
                         locations=locations)

        self.assertEqual(self.ms_solr.search('*:*').hits, 2)

        guid = locations[0].guid
        job.locations.remove(locations[0])
        self.assertEqual(self.ms_solr.search('guid:%s' % guid).hits, 0)
        self.assertEqual(
            self.ms_solr.search('guid:%s' % locations[1].guid).hits, 1)

        job.locations.remove(locations[1])
        self.assertEqual(self.ms_solr.search('*:*').hits, 0)

    def test_job_add_to_solr(self):
        job = JobFactory(owner=self.company, created_by=self.user)
        job.locations.add(JobLocationFactory())
        job.add_to_solr()

        guids = " OR ".join(job.guids())
        query = "guid:%s" % guids
        self.assertEqual(self.ms_solr.search(query).hits, 1)

    def test_job_remove_from_solr(self):
        job = JobFactory(owner=self.company, created_by=self.user)
        locations = JobLocationFactory.create_batch(2)
        job.locations = locations
        job.save()
        job.remove_from_solr()

        guids = " OR ".join(job.guids())
        query = "guid:%s" % guids
        self.assertEqual(self.ms_solr.search(query).hits, 0)

    def test_job_generate_guid(self):
        guid = '1' * 32

        # Confirm that pre-assigned guids are not being overwritten.
        location = JobLocationFactory(guid=guid)
        self.assertEqual(guid, location.guid)
        location.delete()

        # Confirm that if a guid isn't assigned one is getting assigned
        # to it properly.
        location = JobLocationFactory()
        self.assertIsNotNone(location.guid)
        self.assertNotEqual(location.guid, guid)

    def test_site_package_make_unique_for_site(self):
        package = SitePackage.objects.create(**self.site_package_data)
        package.make_unique_for_site(self.site)
        self.assertEqual(self.site.site_package, package)
        package.delete()

        package = SitePackage.objects.create(**self.site_package_data)
        for x in range(100, 110):
            site = SeoSiteFactory(id=x, domain="%s.jobs" % x)
            package.sites.add(site)

        # Site packages with existing sites associated with it should still
        # only end up with one associated site.
        site = SeoSiteFactory(id=4000, domain="4000.jobs")
        package.make_unique_for_site(site)
        self.assertEqual(site.site_package, package)

    def test_site_package_make_unique_for_company(self):
        package = SitePackage.objects.create(**self.site_package_data)
        package.make_unique_for_company(self.company)
        self.assertEqual(self.company.site_package, package)
        package.delete()

        package = SitePackage.objects.create(**self.site_package_data)
        first = []
        for x in range(1000, 1003):
            site = SeoSiteFactory(id=x, domain="%s.jobs" % x)
            package.sites.add(site)
            first.append(site.pk)
        self.assertItemsEqual(package.sites.all().values_list('id', flat=True),
                              first)
        second = [self.site.pk]
        for x in range(100, 103):
            site = SeoSiteFactory(id=x, domain="%s.jobs" % x)
            site.business_units.add(self.bu)
            site.save()
            second.append(site.pk)
        # Site packages with existing sites associated with it should
        # only end up with the sites for a company.
        package.make_unique_for_company(self.company)
        self.assertEqual(self.company.site_package, package)
        self.assertItemsEqual(package.sites.all().values_list('id', flat=True),
                              second)

    def create_purchased_job(self, pk=None):
        if not hasattr(self, 'package'):
            self.package = SitePackageFactory(owner=self.company)
        if not hasattr(self, 'product'):
            self.product = ProductFactory(package=self.package,
                                          owner=self.company)
        if not hasattr(self, 'purchased_product'):
            self.purchased_product = PurchasedProductFactory(
                product=self.product, owner=self.company)
        exp_date = date.today() + timedelta(self.product.posting_window_length)
        self.assertEqual(self.purchased_product.expiration_date, exp_date)
        return PurchasedJobFactory(owner=self.company,
                                   created_by=self.user,
                                   purchased_product=self.purchased_product,
                                   pk=pk)

    def test_purchased_job_add(self):
        self.create_purchased_job()
        self.assertEqual(PurchasedJob.objects.all().count(), 1)
        self.assertEqual(SitePackage.objects.all().count(), 1)
        self.assertEqual(Request.objects.all().count(), 1)
        package = SitePackage.objects.get()
        job = PurchasedJob.objects.get()
        self.assertItemsEqual(job.site_packages.all(), [package])

    def test_purchased_job_add_to_solr(self):
        job = self.create_purchased_job()
        job.locations.add(JobLocationFactory())
        job.save()
        # Add to solr and delete from solr shouldn't be called until
        # the job is approved.
        guids = " OR ".join(job.guids())
        query = "guid:%s" % guids
        self.assertEqual(self.ms_solr.search(query).hits, 0)
        job.is_approved = True

        # Jobs won't be added/deleted until it's confirmed that the
        # purchased product is paid for as well.
        job.purchased_product.paid = True
        job.purchased_product.save()
        job.save()
        # Now that the job is approved, it should've been sent to solr.
        guids = " OR ".join(job.guids())
        query = "guid:%s" % guids
        self.assertEqual(self.ms_solr.search(query).hits, 1)

    def test_purchased_product_jobs_remaining(self):
        num_jobs_allowed = Product._meta.get_field_by_name('num_jobs_allowed')
        expected_num_jobs = num_jobs_allowed[0].default
        for x in range(50, 50 + expected_num_jobs):
            if hasattr(self, 'purchased_product'):
                self.assertTrue(self.purchased_product.can_post_more())
            self.create_purchased_job()
            expected_num_jobs -= 1
            self.assertEqual(self.purchased_product.jobs_remaining,
                             expected_num_jobs)
        self.assertFalse(self.purchased_product.can_post_more())

    def test_invoice_sent_to_specific_email(self):
        """
        When `other_recipients` is specified, `send_invoice_email` should
        send invoices to those email addresses.

        """
        self.create_purchased_job()
        group, _ = Group.objects.get_or_create(name=Product.ADMIN_GROUP_NAME)

        # No one to receive the email.
        self.purchased_product.invoice.send_invoice_email()
        self.assertEqual(len(mail.outbox), 0)

        # Only recipient is specified recipient.
        other_recipients = ['*****@*****.**', '*****@*****.**']
        self.purchased_product.invoice.send_invoice_email(
            other_recipients=other_recipients)

        self.assertItemsEqual(mail.outbox[0].to, other_recipients)

    def test_invoice_sent_to_admins(self):
        """
        When a company has postajob admins, invoices should be sent to each of
        them, unless the behavior is disabled by passing
        `send_to_admins=False`.

        """

        self.create_purchased_job()
        group, _ = Group.objects.get_or_create(name=Product.ADMIN_GROUP_NAME)

        # No one to receive the email.
        self.purchased_product.invoice.send_invoice_email()
        self.assertEqual(len(mail.outbox), 0)

        # Only recipients are admins.
        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        self.user.groups.add(group)
        self.purchased_product.invoice.send_invoice_email()
        self.assertItemsEqual(mail.outbox[0].to, [u'*****@*****.**'])
        self.assertItemsEqual(mail.outbox[0].from_email, '*****@*****.**')

        self.purchased_product.invoice.send_invoice_email(
            send_to_admins=False, other_recipients=['*****@*****.**'])

        # Only one in .to should be [email protected]
        self.assertEquals(len(mail.outbox[1].to), 1)
        self.assertItemsEqual(mail.outbox[1].to, ['*****@*****.**'])

    def test_invoice_sent_to_admins_and_others(self):
        """
        If a company has postajob admins and `other_recipients` is specified,
        emails should be sent to both groups.

        """
        self.create_purchased_job()
        group, _ = Group.objects.get_or_create(name=Product.ADMIN_GROUP_NAME)

        # No one to receive the email.
        self.purchased_product.invoice.send_invoice_email()
        self.assertEqual(len(mail.outbox), 0)

        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        self.user.groups.add(group)

        self.site.email_domain = 'test.domain'
        self.site.save()

        # Recipients are admins + specified recipients.
        self.purchased_product.invoice.send_invoice_email(
            other_recipients=['*****@*****.**'])
        self.assertItemsEqual(mail.outbox[0].to,
                              ['*****@*****.**', u'*****@*****.**'])
        self.assertEqual(mail.outbox[0].from_email, '*****@*****.**')

    def test_invoice_unchanged_after_purchased_product_deletion(self):
        self.create_purchased_job()
        invoice = self.purchased_product.invoice
        invoice.send_invoice_email(other_recipients=['*****@*****.**'])
        old_email = mail.outbox.pop()

        self.purchased_product.delete()
        invoice.send_invoice_email(other_recipients=['*****@*****.**'])
        new_email = mail.outbox.pop()

        self.assertEqual(old_email.body, new_email.body)

    def test_invoice_unchanged_after_product_changed(self):
        self.create_purchased_job()
        invoice = self.purchased_product.invoice
        invoice.send_invoice_email(other_recipients=['*****@*****.**'])
        old_email = mail.outbox.pop()

        self.purchased_product.product.name = 'new name'
        self.purchased_product.product.save()
        invoice.send_invoice_email(other_recipients=['*****@*****.**'])
        new_email = mail.outbox.pop()

        self.assertEqual(old_email.body, new_email.body)

    def test_productgrouping_add_delete(self):
        self.create_purchased_job()
        ProductGrouping.objects.create(display_title='Test Grouping',
                                       explanation='Test Grouping',
                                       name='Test Grouping',
                                       owner=self.company)
        self.assertEqual(ProductGrouping.objects.all().count(), 1)
        grouping = ProductGrouping.objects.get()

        order = ProductOrder.objects.create(product=self.product,
                                            group=grouping)
        grouping_products = grouping.products.all().values_list('pk',
                                                                flat=True)
        self.assertItemsEqual(grouping_products, [order.product.pk])

        grouping.delete()
        self.assertEqual(ProductGrouping.objects.all().count(), 0)
        self.assertEqual(ProductOrder.objects.all().count(), 0)

    def test_request_generation(self):
        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        self.user.make_purchased_microsite_admin()

        self.create_purchased_job()
        self.assertEqual(PurchasedJob.objects.all().count(), 1)
        self.assertEqual(Request.objects.all().count(), 1)
        self.assertEqual(len(mail.outbox), 1)
        self.assertItemsEqual(mail.outbox[0].from_email, '*****@*****.**')
        mail.outbox = []

        # Already approved jobs should not generate an additional request.
        PurchasedJobFactory(owner=self.company,
                            created_by=self.user,
                            purchased_product=self.purchased_product,
                            is_approved=True)

        self.assertEqual(PurchasedJob.objects.all().count(), 2)
        self.assertEqual(Request.objects.all().count(), 1)
        self.assertEqual(len(mail.outbox), 0)

    def test_offlinepurchase_create_purchased_products(self):
        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        offline_purchase = OfflinePurchaseFactory(owner=self.company,
                                                  created_by=self.user)
        package = SitePackageFactory(owner=self.company)
        product = ProductFactory(package=package, owner=self.company)

        for x in range(1, 15):
            PurchasedProduct.objects.all().delete()
            OfflineProduct.objects.all().delete()
            OfflineProductFactory(product=product,
                                  offline_purchase=offline_purchase,
                                  product_quantity=x)
            offline_purchase.create_purchased_products(self.company)
            self.assertEqual(PurchasedProduct.objects.all().count(), x)

        product_two = ProductFactory(package=package, owner=self.company)
        for x in range(1, 15):
            PurchasedProduct.objects.all().delete()
            OfflineProduct.objects.all().delete()
            OfflineProductFactory(product=product,
                                  offline_purchase=offline_purchase,
                                  product_quantity=x)
            OfflineProductFactory(product=product_two,
                                  offline_purchase=offline_purchase,
                                  product_quantity=x)
            offline_purchase.create_purchased_products(self.company)
            self.assertEqual(PurchasedProduct.objects.all().count(), x * 2)

    def test_offlinepurchase_filter_by_sites(self):
        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            product = ProductFactory(package=site_package, owner=self.company)
            for y in range(1, 5):
                purchase = OfflinePurchaseFactory(owner=self.company,
                                                  created_by=self.user)
                OfflineProduct.objects.create(product=product,
                                              offline_purchase=purchase)
            count = OfflinePurchase.objects.filter_by_sites([site]).count()
            self.assertEqual(count, 4)

        self.assertEqual(OfflinePurchase.objects.all().count(), 60)

    def test_invoice_filter_by_sites(self):
        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            product = ProductFactory(package=site_package, owner=self.company)
            for y in range(1, 5):
                # OfflinePurchaseFactory() automatically creates the invoice.
                purchase = OfflinePurchaseFactory(owner=self.company,
                                                  created_by=self.user)
                OfflineProduct.objects.create(product=product,
                                              offline_purchase=purchase)
            # Confirm it correctly picks up Invoices associated with
            # OfflinePurchases.
            self.assertEqual(
                Invoice.objects.filter_by_sites([site]).count(), 4)
            for y in range(1, 5):
                # PurchasedProductFactory() also automatically creates
                # the invoice.
                PurchasedProductFactory(product=product, owner=self.company)
            # Confirm it correctly picks up Invoices associated with
            # PurchasedProducts.
            self.assertEqual(
                Invoice.objects.filter_by_sites([site]).count(), 8)

        self.assertEqual(Invoice.objects.all().count(), 120)

    def test_product_filter_by_sites(self):
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            for y in range(1, 5):
                ProductFactory(package=site_package, owner=self.company)
            self.assertEqual(
                Product.objects.filter_by_sites([site]).count(), 4)

        self.assertEqual(Product.objects.all().count(), 60)

    def test_request_filter_by_sites(self):
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            product = ProductFactory(package=site_package, owner=self.company)
            purchased_product = PurchasedProductFactory(product=product,
                                                        owner=self.company)
            for y in range(1, 5):
                # Unapproved purchased jobs should create Requests.
                PurchasedJobFactory(owner=self.company,
                                    created_by=self.user,
                                    purchased_product=purchased_product)
            self.assertEqual(
                Request.objects.filter_by_sites([site]).count(), 4)

        self.assertEqual(Request.objects.all().count(), 60)

    def test_purchasedproduct_filter_by_sites(self):
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            for y in range(1, 5):
                product = ProductFactory(package=site_package,
                                         owner=self.company)
                PurchasedProductFactory(product=product, owner=self.company)
            count = PurchasedProduct.objects.filter_by_sites([site]).count()
            self.assertEqual(count, 4)

        self.assertEqual(PurchasedProduct.objects.all().count(), 60)

    def test_job_filter_by_sites(self):
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            for y in range(1, 5):
                job = JobFactory(owner=self.company, created_by=self.user)
                job.site_packages.add(site_package)
                job.save()
            self.assertEqual(Job.objects.filter_by_sites([site]).count(), 4)

        self.assertEqual(Job.objects.all().count(), 60)

    def test_purchasedjob_filter_by_sites(self):
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            product = ProductFactory(package=site_package, owner=self.company)
            purchased_product = PurchasedProductFactory(product=product,
                                                        owner=self.company)
            for y in range(1, 5):
                job = PurchasedJobFactory(owner=self.company,
                                          created_by=self.user,
                                          purchased_product=purchased_product)
                job.site_packages.add(site_package)
                job.save()
            count = PurchasedJob.objects.filter_by_sites([site]).count()
            self.assertEqual(count, 4)

        self.assertEqual(PurchasedJob.objects.all().count(), 60)

    def test_productgrouping_filter_by_sites(self):
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            product = ProductFactory(package=site_package, owner=self.company)
            for y in range(1, 5):
                grouping = ProductGroupingFactory(owner=self.company,
                                                  display_order=y)
                ProductOrder.objects.create(product=product,
                                            group=grouping,
                                            display_order=y)
            count = ProductGrouping.objects.filter_by_sites([site]).count()
            self.assertEqual(count, 4)

        self.assertEqual(ProductGrouping.objects.all().count(), 60)

    def test_sitepackage_filter_by_sites(self):
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            for y in range(1, 5):
                site_package = SitePackageFactory(owner=self.company)
                site_package.sites.add(site)
                site_package.save()
            count = SitePackage.objects.filter_by_sites([site]).count()
            self.assertEqual(count, 4)
            count = Package.objects.filter_by_sites([site]).count()
            self.assertEqual(count, 4)

        self.assertEqual(SitePackage.objects.all().count(), 60)
        self.assertEqual(Package.objects.all().count(), 60)

    def test_product_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        ProductFactory(package=single_site_package, owner=self.company)
        ProductFactory(package=both_sites_package, owner=self.company)

        self.assertEqual(Product.objects.all().count(), 2)

        # Confirm that filtering by both sites gets both jobs.
        both_sites = [site_in_both_packages, self.site]
        count = Product.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one job only
        # gets one job.
        count = Product.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both jobs gets
        # both jobs.
        count = (Product.objects.filter_by_sites([site_in_both_packages
                                                  ]).count())
        self.assertEqual(count, 2)

    def test_job_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        job_on_both = JobFactory(owner=self.company, created_by=self.user)
        job_on_both.site_packages.add(both_sites_package)
        job_on_both.save()

        job_on_new_site = JobFactory(owner=self.company, created_by=self.user)
        job_on_new_site.site_packages.add(single_site_package)
        job_on_new_site.save()

        self.assertEqual(Job.objects.all().count(), 2)

        # Confirm that filtering by both sites gets both jobs.
        both_sites = [site_in_both_packages, self.site]
        count = Job.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one job only
        # gets one job.
        self.assertEqual(Job.objects.filter_by_sites([self.site]).count(), 1)

        # Confirm that filtering by the site the site that has both jobs gets
        # both jobs.
        count = Job.objects.filter_by_sites([site_in_both_packages]).count()
        self.assertEqual(count, 2)

    def test_purchasedproduct_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        single_site_product = ProductFactory(package=single_site_package,
                                             owner=self.company)
        PurchasedProductFactory(product=single_site_product,
                                owner=self.company)

        both_sites_product = ProductFactory(package=both_sites_package,
                                            owner=self.company)
        PurchasedProductFactory(product=both_sites_product, owner=self.company)

        self.assertEqual(PurchasedProduct.objects.all().count(), 2)

        # Confirm that filtering by both sites gets both products.
        both_sites = [site_in_both_packages, self.site]
        count = PurchasedProduct.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one product only
        # gets one product.
        count = PurchasedProduct.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both products
        #  gets both jobs.
        objs = (PurchasedProduct.objects.filter_by_sites(
            [site_in_both_packages]))
        count = objs.count()
        self.assertEqual(count, 2)

    def test_purchasedjob_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        single_site_product = ProductFactory(package=single_site_package,
                                             owner=self.company)
        single_site_purchasedproduct = PurchasedProductFactory(
            product=single_site_product, owner=self.company)

        both_sites_product = ProductFactory(package=both_sites_package,
                                            owner=self.company)
        both_sites_purchasedproduct = PurchasedProductFactory(
            product=both_sites_product, owner=self.company)

        PurchasedJobFactory(owner=self.company,
                            created_by=self.user,
                            purchased_product=single_site_purchasedproduct)
        PurchasedJobFactory(owner=self.company,
                            created_by=self.user,
                            purchased_product=both_sites_purchasedproduct)

        self.assertEqual(PurchasedJob.objects.all().count(), 2)

        # Confirm that filtering by both sites gets both jobs.
        both_sites = [site_in_both_packages, self.site]
        count = PurchasedJob.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one job only
        # gets one job.
        count = PurchasedJob.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both jobs gets
        # both jobs.
        objs = PurchasedJob.objects.filter_by_sites([site_in_both_packages])
        count = objs.count()
        self.assertEqual(count, 2)

    def test_sitepackage_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        self.assertEqual(SitePackage.objects.all().count(), 2)
        self.assertEqual(Package.objects.all().count(), 2)

        # Confirm that filtering by both sites gets both packages.
        both_sites = [site_in_both_packages, self.site]
        count = SitePackage.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)
        count = Package.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one package only
        # gets one package.
        count = SitePackage.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)
        count = Package.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both packages
        # gets both packages.
        objs = SitePackage.objects.filter_by_sites([site_in_both_packages])
        count = objs.count()
        self.assertEqual(count, 2)
        count = (Package.objects.filter_by_sites([site_in_both_packages
                                                  ]).count())
        self.assertEqual(count, 2)

    def test_productgrouping_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        single_site_product = ProductFactory(package=single_site_package,
                                             owner=self.company)
        single_site_grouping = ProductGroupingFactory(owner=self.company)
        ProductOrder.objects.create(product=single_site_product,
                                    group=single_site_grouping)

        both_sites_product = ProductFactory(package=both_sites_package,
                                            owner=self.company)
        both_sites_grouping = ProductGroupingFactory(owner=self.company)
        ProductOrder.objects.create(product=both_sites_product,
                                    group=both_sites_grouping)

        # Confirm that filtering by both sites gets both groupings.
        both_sites = [site_in_both_packages, self.site]
        count = ProductGrouping.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one grouping only
        # gets one grouping.
        count = ProductGrouping.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both jobs gets
        # both jobs.
        objs = ProductGrouping.objects.filter_by_sites([site_in_both_packages])
        count = objs.count()
        self.assertEqual(count, 2)

    def test_offlinepurchase_filter_by_site_multiple_sites(self):
        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        single_site_product = ProductFactory(package=single_site_package,
                                             owner=self.company)
        single_site_purchase = OfflinePurchaseFactory(owner=self.company,
                                                      created_by=self.user)
        OfflineProduct.objects.create(product=single_site_product,
                                      offline_purchase=single_site_purchase)

        both_sites_product = ProductFactory(package=both_sites_package,
                                            owner=self.company)
        both_sites_purchase = OfflinePurchaseFactory(owner=self.company,
                                                     created_by=self.user)
        OfflineProduct.objects.create(product=both_sites_product,
                                      offline_purchase=both_sites_purchase)

        # Confirm that filtering by both sites gets both groupings.
        both_sites = [site_in_both_packages, self.site]
        count = OfflinePurchase.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one grouping only
        # gets one grouping.
        count = OfflinePurchase.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both jobs gets
        # both jobs.
        objs = OfflinePurchase.objects.filter_by_sites([site_in_both_packages])
        count = objs.count()
        self.assertEqual(count, 2)

    def test_invoice_from_offlinepurchase_filter_by_site_multiple_sites(self):
        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        single_site_product = ProductFactory(package=single_site_package,
                                             owner=self.company)
        single_site_purchase = OfflinePurchaseFactory(owner=self.company,
                                                      created_by=self.user)
        OfflineProduct.objects.create(product=single_site_product,
                                      offline_purchase=single_site_purchase)

        both_sites_product = ProductFactory(package=both_sites_package,
                                            owner=self.company)
        both_sites_purchase = OfflinePurchaseFactory(owner=self.company,
                                                     created_by=self.user)
        OfflineProduct.objects.create(product=both_sites_product,
                                      offline_purchase=both_sites_purchase)

        # Confirm that filtering by both sites gets both groupings.
        both_sites = [site_in_both_packages, self.site]
        count = Invoice.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one grouping only
        # gets one grouping.
        count = Invoice.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both jobs gets
        # both jobs.
        count = (Invoice.objects.filter_by_sites([site_in_both_packages
                                                  ]).count())
        self.assertEqual(count, 2)

    def test_invoice_from_purchasedproduct_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        single_site_product = ProductFactory(package=single_site_package,
                                             owner=self.company)
        PurchasedProductFactory(product=single_site_product,
                                owner=self.company)

        both_sites_product = ProductFactory(package=both_sites_package,
                                            owner=self.company)
        PurchasedProductFactory(product=both_sites_product, owner=self.company)

        self.assertEqual(Invoice.objects.all().count(), 2)

        # Confirm that filtering by both sites gets both products.
        both_sites = [site_in_both_packages, self.site]
        count = Invoice.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one product only
        # gets one product.
        count = Invoice.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both products
        #  gets both jobs.
        count = (Invoice.objects.filter_by_sites([site_in_both_packages
                                                  ]).count())
        self.assertEqual(count, 2)

    def test_request_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        single_site_product = ProductFactory(package=single_site_package,
                                             owner=self.company)
        single_site_purchasedproduct = PurchasedProductFactory(
            product=single_site_product, owner=self.company)
        # Unapproved PurchasedJobs generate Requests.
        PurchasedJobFactory(owner=self.company,
                            created_by=self.user,
                            purchased_product=single_site_purchasedproduct)

        both_sites_product = ProductFactory(package=both_sites_package,
                                            owner=self.company)
        both_sites_purchasedproduct = PurchasedProductFactory(
            product=both_sites_product, owner=self.company)
        PurchasedJobFactory(owner=self.company,
                            created_by=self.user,
                            purchased_product=both_sites_purchasedproduct)

        self.assertEqual(Request.objects.all().count(), 2)

        # Confirm that filtering by both sites gets both products.
        both_sites = [site_in_both_packages, self.site]
        count = Request.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one product only
        # gets one product.
        count = Request.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both products
        #  gets both jobs.
        count = (Request.objects.filter_by_sites([site_in_both_packages
                                                  ]).count())
        self.assertEqual(count, 2)

    def test_request_on_purchasedjob_update(self):
        # Creating a PurchasedJob for a Product that requires approval
        # creates a Request
        job = PurchasedJobFactory(owner=self.company, created_by=self.user)
        self.assertEqual(Request.objects.count(), 1)

        # Re-saving that job should not create a new request.
        job.save()
        self.assertEqual(Request.objects.count(), 1)

        # Approving the job should also not create a new request.
        job.is_approved = True
        job.save()
        self.assertEqual(Request.objects.count(), 1)

        # Marking the job as not approved and saving it should not create
        # a new request if no action was taken on the old request.
        job.is_approved = False
        job.save()
        self.assertEqual(Request.objects.count(), 1)

        # Marking the job as not approved and saving it should create
        # a new request if there is no pending request.
        request = Request.objects.get()
        request.action_taken = True
        request.save()
        job.save()
        self.assertEqual(Request.objects.count(), 2)

    def test_enable_posting(self):
        """
        Attempting to automatically enable posting for a company should result
        in a valid site package owned by that company.

        """
        AppAccessFactory(name='Posting')
        company = CompanyFactory(name='Posting Company')
        site = SeoSite.objects.create(domain='somewhere.jobs')
        # sanity checks
        self.assertIsNone(site.canonical_company)
        self.assertEqual(company.enabled_access, [])

        package = enable_posting(company, site)

        # Django caches model instances
        company = Company.objects.get(pk=company.pk)
        site = SeoSite.objects.get(pk=site.pk)

        self.assertEqual(site.canonical_company, company)
        self.assertIn("Posting", company.enabled_access)
        self.assertIn(site, package.sites.all())
        self.assertTrue(
            LoginBlock.objects.filter(
                name="Posting Company Login Block").exists())

    def test_enable_marketplace(self):
        """
        Attempting to automatically enable posting for a company should result
        in a valid site package owned by that company.

        """
        AppAccessFactory(name='MarketPlace')
        company = CompanyFactory(name='Marketplace Company')
        site = SeoSite.objects.create(domain='somewhereelse.jobs')
        # sanity checks
        self.assertIsNone(site.canonical_company)
        self.assertEqual(company.enabled_access, [])

        package = enable_marketplace(company, site)

        # Django caches model instances
        company = Company.objects.get(pk=company.pk)
        site = SeoSite.objects.get(pk=site.pk)

        self.assertEqual(site.canonical_company, company)
        self.assertIn("MarketPlace", company.enabled_access)
        self.assertIn(site, package.sites.all())
        self.assertTrue(
            LoginBlock.objects.filter(
                name="Marketplace Company Login Block").exists())

    def test_create_login_block(self):
        """
        Ensures that a login block is createed with the correct associations
        and a valid template.

        """
        company = CompanyFactory(name='Marketplace Company')
        site = SeoSite.objects.create(domain='somewhereelse.jobs')

        template = raw_base_template(LoginBlock)
        response = self.client.get("/login", follow=True)
        login_block = create_login_block(company, site)

        # validate that the correct template was assigned to the login block
        self.assertEqual(login_block.template, template)
예제 #11
0
class ModelTests(MyJobsBase):
    def setUp(self):
        super(ModelTests, self).setUp()
        self.user = User.objects.create(email='*****@*****.**')
        self.company = CompanyFactory()
        CompanyProfile.objects.create(company=self.company)
        self.site = SeoSiteFactory()#domain='buckconsoltants.jobs')
        self.bu = BusinessUnitFactory()
        self.site.business_units.add(self.bu)
        self.site.save()
        self.company.job_source_ids.add(self.bu)
        self.company.save()

        # Use the newly created site for testing instead of secure.my.jobs.
        settings.SITE = self.site

        self.request_data = {
            'title': 'title',
            'company': self.company.id,
            'reqid': '1',
            'description': 'sadfljasdfljasdflasdfj',
            'link': 'www.google.com',
            'on_sites': '0',
            'apply_info': '',
        }

        self.request_location = {
            'city': 'Indianapolis',
            'state': 'Indiana',
            'state_short': 'IN',
            'country': 'United States',
            'country_short': 'USA',
            'zipcode': '46268',
        }

        self.site_package_data = {
            'name': 'Test Site Package',
        }

    def test_job_creation_and_deletion(self):
        locations = JobLocationFactory.create_batch(5)
        job = JobFactory(owner=self.company, created_by=self.user)
        job.locations = locations
        job.save()
        self.assertEqual(Job.objects.all().count(), 1)
        self.assertEqual(JobLocation.objects.all().count(), 5)
        job.delete()
        self.assertEqual(Job.objects.all().count(), 0)
        self.assertEqual(JobLocation.objects.all().count(), 0)

    def test_add_remove_job_locations(self):
        """
        Regression test, job locations that were removed from a job weren't
        being removed from Solr
        Tests that adding or removing locations results in Solr updates after
        a job save
        """
        locations = JobLocationFactory.create_batch(2)
        job = JobFactory(
            owner=self.company, created_by=self.user, locations=locations)

        self.assertEqual(self.ms_solr.search('*:*').hits, 2)

        guid = locations[0].guid
        job.locations.remove(locations[0])
        self.assertEqual(self.ms_solr.search('guid:%s' % guid).hits, 0)
        self.assertEqual(self.ms_solr.search('guid:%s' %
                                             locations[1].guid).hits, 1)

        job.locations.remove(locations[1])
        self.assertEqual(self.ms_solr.search('*:*').hits, 0)

    def test_job_add_to_solr(self):
        job = JobFactory(owner=self.company, created_by=self.user)
        job.locations.add(JobLocationFactory())
        job.add_to_solr()

        guids = " OR ".join(job.guids())
        query = "guid:%s" % guids
        self.assertEqual(self.ms_solr.search(query).hits, 1)

    def test_job_remove_from_solr(self):
        job = JobFactory(owner=self.company, created_by=self.user)
        locations = JobLocationFactory.create_batch(2)
        job.locations = locations
        job.save()
        job.remove_from_solr()

        guids = " OR ".join(job.guids())
        query = "guid:%s" % guids
        self.assertEqual(self.ms_solr.search(query).hits, 0)

    def test_job_generate_guid(self):
        guid = '1'*32

        # Confirm that pre-assigned guids are not being overwritten.
        location = JobLocationFactory(guid=guid)
        self.assertEqual(guid, location.guid)
        location.delete()

        # Confirm that if a guid isn't assigned one is getting assigned
        # to it properly.
        location = JobLocationFactory()
        self.assertIsNotNone(location.guid)
        self.assertNotEqual(location.guid, guid)

    def test_site_package_make_unique_for_site(self):
        package = SitePackage.objects.create(**self.site_package_data)
        package.make_unique_for_site(self.site)
        self.assertEqual(self.site.site_package, package)
        package.delete()

        package = SitePackage.objects.create(**self.site_package_data)
        for x in range(100, 110):
            site = SeoSiteFactory(id=x, domain="%s.jobs" % x)
            package.sites.add(site)

        # Site packages with existing sites associated with it should still
        # only end up with one associated site.
        site = SeoSiteFactory(id=4000, domain="4000.jobs")
        package.make_unique_for_site(site)
        self.assertEqual(site.site_package, package)

    def test_site_package_make_unique_for_company(self):
        package = SitePackage.objects.create(**self.site_package_data)
        package.make_unique_for_company(self.company)
        self.assertEqual(self.company.site_package, package)
        package.delete()

        package = SitePackage.objects.create(**self.site_package_data)
        first = []
        for x in range(1000, 1003):
            site = SeoSiteFactory(id=x, domain="%s.jobs" % x)
            package.sites.add(site)
            first.append(site.pk)
        self.assertItemsEqual(package.sites.all().values_list('id', flat=True),
                              first)
        second = [self.site.pk]
        for x in range(100, 103):
            site = SeoSiteFactory(id=x, domain="%s.jobs" % x)
            site.business_units.add(self.bu)
            site.save()
            second.append(site.pk)
        # Site packages with existing sites associated with it should
        # only end up with the sites for a company.
        package.make_unique_for_company(self.company)
        self.assertEqual(self.company.site_package, package)
        self.assertItemsEqual(package.sites.all().values_list('id', flat=True),
                              second)

    def create_purchased_job(self, pk=None):
        if not hasattr(self, 'package'):
            self.package = SitePackageFactory(owner=self.company)
        if not hasattr(self, 'product'):
            self.product = ProductFactory(
                package=self.package, owner=self.company)
        if not hasattr(self, 'purchased_product'):
            self.purchased_product = PurchasedProductFactory(
                product=self.product, owner=self.company)
        exp_date = date.today() + timedelta(self.product.posting_window_length)
        self.assertEqual(self.purchased_product.expiration_date, exp_date)
        return PurchasedJobFactory(
            owner=self.company, created_by=self.user,
            purchased_product=self.purchased_product, pk=pk)

    def test_purchased_job_add(self):
        self.create_purchased_job()
        self.assertEqual(PurchasedJob.objects.all().count(), 1)
        self.assertEqual(SitePackage.objects.all().count(), 1)
        self.assertEqual(Request.objects.all().count(), 1)
        package = SitePackage.objects.get()
        job = PurchasedJob.objects.get()
        self.assertItemsEqual(job.site_packages.all(), [package])

    def test_purchased_job_add_to_solr(self):
        job = self.create_purchased_job()
        job.locations.add(JobLocationFactory())
        job.save()
        # Add to solr and delete from solr shouldn't be called until
        # the job is approved.
        guids = " OR ".join(job.guids())
        query = "guid:%s" % guids
        self.assertEqual(self.ms_solr.search(query).hits, 0)
        job.is_approved = True

        # Jobs won't be added/deleted until it's confirmed that the
        # purchased product is paid for as well.
        job.purchased_product.paid = True
        job.purchased_product.save()
        job.save()
        # Now that the job is approved, it should've been sent to solr.
        guids = " OR ".join(job.guids())
        query = "guid:%s" % guids
        self.assertEqual(self.ms_solr.search(query).hits, 1)

    def test_purchased_product_jobs_remaining(self):
        num_jobs_allowed = Product._meta.get_field_by_name('num_jobs_allowed')
        expected_num_jobs = num_jobs_allowed[0].default
        for x in range(50, 50 + expected_num_jobs):
            if hasattr(self, 'purchased_product'):
                self.assertTrue(self.purchased_product.can_post_more())
            self.create_purchased_job()
            expected_num_jobs -= 1
            self.assertEqual(self.purchased_product.jobs_remaining,
                             expected_num_jobs)
        self.assertFalse(self.purchased_product.can_post_more())

    def test_invoice_sent_to_specific_email(self):
        """
        When `other_recipients` is specified, `send_invoice_email` should
        send invoices to those email addresses.

        """
        self.create_purchased_job()
        group, _ = Group.objects.get_or_create(name=Product.ADMIN_GROUP_NAME)

        # No one to receive the email.
        self.purchased_product.invoice.send_invoice_email()
        self.assertEqual(len(mail.outbox), 0)

        # Only recipient is specified recipient.
        other_recipients = ['*****@*****.**', '*****@*****.**']
        self.purchased_product.invoice.send_invoice_email(
            other_recipients=other_recipients)

        self.assertItemsEqual(mail.outbox[0].to, other_recipients)

    def test_invoice_sent_to_admins(self):
        """
        When a company has postajob admins, invoices should be sent to each of
        them, unless the behavior is disabled by passing
        `send_to_admins=False`.

        """

        self.create_purchased_job()
        group, _ = Group.objects.get_or_create(name=Product.ADMIN_GROUP_NAME)

        # No one to receive the email.
        self.purchased_product.invoice.send_invoice_email()
        self.assertEqual(len(mail.outbox), 0)

        # Only recipients are admins.
        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        self.user.groups.add(group)
        self.purchased_product.invoice.send_invoice_email()
        self.assertItemsEqual(mail.outbox[0].to,
                              [u'*****@*****.**'])
        self.assertItemsEqual(mail.outbox[0].from_email,
                              '*****@*****.**')

        self.purchased_product.invoice.send_invoice_email(
            send_to_admins=False, other_recipients=['*****@*****.**'])

        # Only one in .to should be [email protected]
        self.assertEquals(len(mail.outbox[1].to), 1)
        self.assertItemsEqual(mail.outbox[1].to, ['*****@*****.**'])

    def test_invoice_sent_to_admins_and_others(self):
        """
        If a company has postajob admins and `other_recipients` is specified,
        emails should be sent to both groups.

        """
        self.create_purchased_job()
        group, _ = Group.objects.get_or_create(name=Product.ADMIN_GROUP_NAME)

        # No one to receive the email.
        self.purchased_product.invoice.send_invoice_email()
        self.assertEqual(len(mail.outbox), 0)

        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        self.user.groups.add(group)

        self.site.email_domain = 'test.domain'
        self.site.save()

        # Recipients are admins + specified recipients.
        self.purchased_product.invoice.send_invoice_email(
            other_recipients=['*****@*****.**'])
        self.assertItemsEqual(mail.outbox[0].to,
                              ['*****@*****.**', u'*****@*****.**'])
        self.assertEqual(mail.outbox[0].from_email,
                         '*****@*****.**')


    def test_invoice_unchanged_after_purchased_product_deletion(self):
        self.create_purchased_job()
        invoice = self.purchased_product.invoice
        invoice.send_invoice_email(other_recipients=['*****@*****.**'])
        old_email = mail.outbox.pop()

        self.purchased_product.delete()
        invoice.send_invoice_email(other_recipients=['*****@*****.**'])
        new_email = mail.outbox.pop()

        self.assertEqual(old_email.body, new_email.body)

    def test_invoice_unchanged_after_product_changed(self):
        self.create_purchased_job()
        invoice = self.purchased_product.invoice
        invoice.send_invoice_email(other_recipients=['*****@*****.**'])
        old_email = mail.outbox.pop()

        self.purchased_product.product.name = 'new name'
        self.purchased_product.product.save()
        invoice.send_invoice_email(other_recipients=['*****@*****.**'])
        new_email = mail.outbox.pop()

        self.assertEqual(old_email.body, new_email.body)

    def test_productgrouping_add_delete(self):
        self.create_purchased_job()
        ProductGrouping.objects.create(display_title='Test Grouping',
                                       explanation='Test Grouping',
                                       name='Test Grouping',
                                       owner=self.company)
        self.assertEqual(ProductGrouping.objects.all().count(), 1)
        grouping = ProductGrouping.objects.get()

        order = ProductOrder.objects.create(product=self.product,
                                            group=grouping)
        grouping_products = grouping.products.all().values_list('pk',
                                                                flat=True)
        self.assertItemsEqual(grouping_products, [order.product.pk])

        grouping.delete()
        self.assertEqual(ProductGrouping.objects.all().count(), 0)
        self.assertEqual(ProductOrder.objects.all().count(), 0)

    def test_request_generation(self):
        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        self.user.make_purchased_microsite_admin()

        self.create_purchased_job()
        self.assertEqual(PurchasedJob.objects.all().count(), 1)
        self.assertEqual(Request.objects.all().count(), 1)
        self.assertEqual(len(mail.outbox), 1)
        self.assertItemsEqual(mail.outbox[0].from_email,
                              '*****@*****.**')
        mail.outbox = []

        # Already approved jobs should not generate an additional request.
        PurchasedJobFactory(
            owner=self.company, created_by=self.user,
            purchased_product=self.purchased_product, is_approved=True)

        self.assertEqual(PurchasedJob.objects.all().count(), 2)
        self.assertEqual(Request.objects.all().count(), 1)
        self.assertEqual(len(mail.outbox), 0)

    def test_offlinepurchase_create_purchased_products(self):
        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        offline_purchase = OfflinePurchaseFactory(
            owner=self.company, created_by=self.user)
        package = SitePackageFactory(owner=self.company)
        product = ProductFactory(package=package, owner=self.company)

        for x in range(1, 15):
            PurchasedProduct.objects.all().delete()
            OfflineProduct.objects.all().delete()
            OfflineProductFactory(
                product=product,
                offline_purchase=offline_purchase,
                product_quantity=x)
            offline_purchase.create_purchased_products(self.company)
            self.assertEqual(PurchasedProduct.objects.all().count(), x)

        product_two = ProductFactory(package=package, owner=self.company)
        for x in range(1, 15):
            PurchasedProduct.objects.all().delete()
            OfflineProduct.objects.all().delete()
            OfflineProductFactory(product=product,
                                  offline_purchase=offline_purchase,
                                  product_quantity=x)
            OfflineProductFactory(product=product_two,
                                  offline_purchase=offline_purchase,
                                  product_quantity=x)
            offline_purchase.create_purchased_products(self.company)
            self.assertEqual(PurchasedProduct.objects.all().count(), x*2)

    def test_offlinepurchase_filter_by_sites(self):
        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            product = ProductFactory(package=site_package, owner=self.company)
            for y in range(1, 5):
                purchase = OfflinePurchaseFactory(owner=self.company,
                                                  created_by=self.user)
                OfflineProduct.objects.create(product=product,
                                              offline_purchase=purchase)
            count = OfflinePurchase.objects.filter_by_sites([site]).count()
            self.assertEqual(count, 4)

        self.assertEqual(OfflinePurchase.objects.all().count(), 60)

    def test_invoice_filter_by_sites(self):
        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            product = ProductFactory(package=site_package, owner=self.company)
            for y in range(1, 5):
                # OfflinePurchaseFactory() automatically creates the invoice.
                purchase = OfflinePurchaseFactory(owner=self.company,
                                                  created_by=self.user)
                OfflineProduct.objects.create(product=product,
                                              offline_purchase=purchase)
            # Confirm it correctly picks up Invoices associated with
            # OfflinePurchases.
            self.assertEqual(Invoice.objects.filter_by_sites([site]).count(),
                             4)
            for y in range(1, 5):
                # PurchasedProductFactory() also automatically creates
                # the invoice.
                PurchasedProductFactory(product=product, owner=self.company)
            # Confirm it correctly picks up Invoices associated with
            # PurchasedProducts.
            self.assertEqual(Invoice.objects.filter_by_sites([site]).count(),
                             8)

        self.assertEqual(Invoice.objects.all().count(), 120)

    def test_product_filter_by_sites(self):
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            for y in range(1, 5):
                ProductFactory(package=site_package, owner=self.company)
            self.assertEqual(Product.objects.filter_by_sites([site]).count(),
                             4)

        self.assertEqual(Product.objects.all().count(), 60)

    def test_request_filter_by_sites(self):
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            product = ProductFactory(package=site_package, owner=self.company)
            purchased_product = PurchasedProductFactory(product=product,
                                                        owner=self.company)
            for y in range(1, 5):
                # Unapproved purchased jobs should create Requests.
                PurchasedJobFactory(owner=self.company, created_by=self.user,
                                    purchased_product=purchased_product)
            self.assertEqual(Request.objects.filter_by_sites([site]).count(),
                             4)

        self.assertEqual(Request.objects.all().count(), 60)

    def test_purchasedproduct_filter_by_sites(self):
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            for y in range(1, 5):
                product = ProductFactory(package=site_package,
                                         owner=self.company)
                PurchasedProductFactory(product=product, owner=self.company)
            count = PurchasedProduct.objects.filter_by_sites([site]).count()
            self.assertEqual(count, 4)

        self.assertEqual(PurchasedProduct.objects.all().count(), 60)

    def test_job_filter_by_sites(self):
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            for y in range(1, 5):
                job = JobFactory(owner=self.company, created_by=self.user)
                job.site_packages.add(site_package)
                job.save()
            self.assertEqual(Job.objects.filter_by_sites([site]).count(), 4)

        self.assertEqual(Job.objects.all().count(), 60)

    def test_purchasedjob_filter_by_sites(self):
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            product = ProductFactory(package=site_package, owner=self.company)
            purchased_product = PurchasedProductFactory(product=product,
                                                        owner=self.company)
            for y in range(1, 5):
                job = PurchasedJobFactory(owner=self.company,
                                          created_by=self.user,
                                          purchased_product=purchased_product)
                job.site_packages.add(site_package)
                job.save()
            count = PurchasedJob.objects.filter_by_sites([site]).count()
            self.assertEqual(count, 4)

        self.assertEqual(PurchasedJob.objects.all().count(), 60)

    def test_productgrouping_filter_by_sites(self):
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            site_package = SitePackageFactory(owner=self.company)
            site_package.make_unique_for_site(site)
            product = ProductFactory(package=site_package, owner=self.company)
            for y in range(1, 5):
                grouping = ProductGroupingFactory(owner=self.company,
                                                  display_order=y)
                ProductOrder.objects.create(product=product, group=grouping,
                                            display_order=y)
            count = ProductGrouping.objects.filter_by_sites([site]).count()
            self.assertEqual(count, 4)

        self.assertEqual(ProductGrouping.objects.all().count(), 60)

    def test_sitepackage_filter_by_sites(self):
        for x in range(8800, 8815):
            domain = 'testsite-%s.jobs' % x
            site = SeoSiteFactory(id=x, domain=domain, name=domain)
            for y in range(1, 5):
                site_package = SitePackageFactory(owner=self.company)
                site_package.sites.add(site)
                site_package.save()
            count = SitePackage.objects.filter_by_sites([site]).count()
            self.assertEqual(count, 4)
            count = Package.objects.filter_by_sites([site]).count()
            self.assertEqual(count, 4)

        self.assertEqual(SitePackage.objects.all().count(), 60)
        self.assertEqual(Package.objects.all().count(), 60)

    def test_product_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        ProductFactory(package=single_site_package, owner=self.company)
        ProductFactory(package=both_sites_package, owner=self.company)

        self.assertEqual(Product.objects.all().count(), 2)

        # Confirm that filtering by both sites gets both jobs.
        both_sites = [site_in_both_packages, self.site]
        count = Product.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one job only
        # gets one job.
        count = Product.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both jobs gets
        # both jobs.
        count = (Product
                 .objects
                 .filter_by_sites([site_in_both_packages])
                 .count())
        self.assertEqual(count, 2)

    def test_job_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        job_on_both = JobFactory(owner=self.company, created_by=self.user)
        job_on_both.site_packages.add(both_sites_package)
        job_on_both.save()

        job_on_new_site = JobFactory(owner=self.company, created_by=self.user)
        job_on_new_site.site_packages.add(single_site_package)
        job_on_new_site.save()

        self.assertEqual(Job.objects.all().count(), 2)

        # Confirm that filtering by both sites gets both jobs.
        both_sites = [site_in_both_packages, self.site]
        count = Job.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one job only
        # gets one job.
        self.assertEqual(Job.objects.filter_by_sites([self.site]).count(), 1)

        # Confirm that filtering by the site the site that has both jobs gets
        # both jobs.
        count = Job.objects.filter_by_sites([site_in_both_packages]).count()
        self.assertEqual(count, 2)

    def test_purchasedproduct_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        single_site_product = ProductFactory(package=single_site_package,
                                             owner=self.company)
        PurchasedProductFactory(product=single_site_product,
                                owner=self.company)

        both_sites_product = ProductFactory(package=both_sites_package,
                                            owner=self.company)
        PurchasedProductFactory(product=both_sites_product, owner=self.company)

        self.assertEqual(PurchasedProduct.objects.all().count(), 2)

        # Confirm that filtering by both sites gets both products.
        both_sites = [site_in_both_packages, self.site]
        count = PurchasedProduct.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one product only
        # gets one product.
        count = PurchasedProduct.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both products
        #  gets both jobs.
        objs = (PurchasedProduct
                .objects
                .filter_by_sites([site_in_both_packages]))
        count = objs.count()
        self.assertEqual(count, 2)

    def test_purchasedjob_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        single_site_product = ProductFactory(package=single_site_package,
                                             owner=self.company)
        single_site_purchasedproduct = PurchasedProductFactory(
            product=single_site_product, owner=self.company)

        both_sites_product = ProductFactory(package=both_sites_package,
                                            owner=self.company)
        both_sites_purchasedproduct = PurchasedProductFactory(
            product=both_sites_product, owner=self.company
        )

        PurchasedJobFactory(owner=self.company, created_by=self.user,
                            purchased_product=single_site_purchasedproduct)
        PurchasedJobFactory(owner=self.company, created_by=self.user,
                            purchased_product=both_sites_purchasedproduct)

        self.assertEqual(PurchasedJob.objects.all().count(), 2)

        # Confirm that filtering by both sites gets both jobs.
        both_sites = [site_in_both_packages, self.site]
        count = PurchasedJob.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one job only
        # gets one job.
        count = PurchasedJob.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both jobs gets
        # both jobs.
        objs = PurchasedJob.objects.filter_by_sites([site_in_both_packages])
        count = objs.count()
        self.assertEqual(count, 2)

    def test_sitepackage_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        self.assertEqual(SitePackage.objects.all().count(), 2)
        self.assertEqual(Package.objects.all().count(), 2)

        # Confirm that filtering by both sites gets both packages.
        both_sites = [site_in_both_packages, self.site]
        count = SitePackage.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)
        count = Package.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one package only
        # gets one package.
        count = SitePackage.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)
        count = Package.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both packages
        # gets both packages.
        objs = SitePackage.objects.filter_by_sites([site_in_both_packages])
        count = objs.count()
        self.assertEqual(count, 2)
        count = (Package
                 .objects
                 .filter_by_sites([site_in_both_packages])
                 .count())
        self.assertEqual(count, 2)

    def test_productgrouping_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        single_site_product = ProductFactory(package=single_site_package,
                                             owner=self.company)
        single_site_grouping = ProductGroupingFactory(owner=self.company)
        ProductOrder.objects.create(product=single_site_product,
                                    group=single_site_grouping)

        both_sites_product = ProductFactory(package=both_sites_package,
                                            owner=self.company)
        both_sites_grouping = ProductGroupingFactory(owner=self.company)
        ProductOrder.objects.create(product=both_sites_product,
                                    group=both_sites_grouping)

        # Confirm that filtering by both sites gets both groupings.
        both_sites = [site_in_both_packages, self.site]
        count = ProductGrouping.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one grouping only
        # gets one grouping.
        count = ProductGrouping.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both jobs gets
        # both jobs.
        objs = ProductGrouping.objects.filter_by_sites([site_in_both_packages])
        count = objs.count()
        self.assertEqual(count, 2)

    def test_offlinepurchase_filter_by_site_multiple_sites(self):
        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        single_site_product = ProductFactory(package=single_site_package,
                                             owner=self.company)
        single_site_purchase = OfflinePurchaseFactory(owner=self.company,
                                                      created_by=self.user)
        OfflineProduct.objects.create(product=single_site_product,
                                      offline_purchase=single_site_purchase)

        both_sites_product = ProductFactory(package=both_sites_package,
                                            owner=self.company)
        both_sites_purchase = OfflinePurchaseFactory(owner=self.company,
                                                     created_by=self.user)
        OfflineProduct.objects.create(product=both_sites_product,
                                      offline_purchase=both_sites_purchase)

        # Confirm that filtering by both sites gets both groupings.
        both_sites = [site_in_both_packages, self.site]
        count = OfflinePurchase.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one grouping only
        # gets one grouping.
        count = OfflinePurchase.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both jobs gets
        # both jobs.
        objs = OfflinePurchase.objects.filter_by_sites([site_in_both_packages])
        count = objs.count()
        self.assertEqual(count, 2)

    def test_invoice_from_offlinepurchase_filter_by_site_multiple_sites(self):
        role = RoleFactory(company=self.company)
        self.user.roles.add(role)
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        single_site_product = ProductFactory(package=single_site_package,
                                             owner=self.company)
        single_site_purchase = OfflinePurchaseFactory(owner=self.company,
                                                      created_by=self.user)
        OfflineProduct.objects.create(product=single_site_product,
                                      offline_purchase=single_site_purchase)

        both_sites_product = ProductFactory(package=both_sites_package,
                                            owner=self.company)
        both_sites_purchase = OfflinePurchaseFactory(owner=self.company,
                                                     created_by=self.user)
        OfflineProduct.objects.create(product=both_sites_product,
                                      offline_purchase=both_sites_purchase)

        # Confirm that filtering by both sites gets both groupings.
        both_sites = [site_in_both_packages, self.site]
        count = Invoice.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one grouping only
        # gets one grouping.
        count = Invoice.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both jobs gets
        # both jobs.
        count = (Invoice
                 .objects
                 .filter_by_sites([site_in_both_packages])
                 .count())
        self.assertEqual(count, 2)

    def test_invoice_from_purchasedproduct_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        single_site_product = ProductFactory(package=single_site_package,
                                             owner=self.company)
        PurchasedProductFactory(product=single_site_product,
                                owner=self.company)

        both_sites_product = ProductFactory(package=both_sites_package,
                                            owner=self.company)
        PurchasedProductFactory(product=both_sites_product, owner=self.company)

        self.assertEqual(Invoice.objects.all().count(), 2)

        # Confirm that filtering by both sites gets both products.
        both_sites = [site_in_both_packages, self.site]
        count = Invoice.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one product only
        # gets one product.
        count = Invoice.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both products
        #  gets both jobs.
        count = (Invoice
                 .objects
                 .filter_by_sites([site_in_both_packages])
                 .count())
        self.assertEqual(count, 2)

    def test_request_filter_by_site_multiple_sites(self):
        site_in_both_packages = SeoSiteFactory(domain='secondsite.jobs', id=7)

        single_site_package = SitePackageFactory(owner=self.company)
        single_site_package.make_unique_for_site(site_in_both_packages)

        both_sites_package = SitePackageFactory(owner=self.company)
        both_sites_package.sites.add(site_in_both_packages)
        both_sites_package.sites.add(self.site)
        both_sites_package.save()

        single_site_product = ProductFactory(package=single_site_package,
                                             owner=self.company)
        single_site_purchasedproduct = PurchasedProductFactory(
            product=single_site_product, owner=self.company)
        # Unapproved PurchasedJobs generate Requests.
        PurchasedJobFactory(owner=self.company, created_by=self.user,
                            purchased_product=single_site_purchasedproduct)

        both_sites_product = ProductFactory(package=both_sites_package,
                                            owner=self.company)
        both_sites_purchasedproduct = PurchasedProductFactory(
            product=both_sites_product, owner=self.company)
        PurchasedJobFactory(owner=self.company, created_by=self.user,
                            purchased_product=both_sites_purchasedproduct)

        self.assertEqual(Request.objects.all().count(), 2)

        # Confirm that filtering by both sites gets both products.
        both_sites = [site_in_both_packages, self.site]
        count = Request.objects.filter_by_sites(both_sites).count()
        self.assertEqual(count, 2)

        # Confirm that filtering by the site that only has one product only
        # gets one product.
        count = Request.objects.filter_by_sites([self.site]).count()
        self.assertEqual(count, 1)

        # Confirm that filtering by the site the site that has both products
        #  gets both jobs.
        count = (Request
                 .objects
                 .filter_by_sites([site_in_both_packages])
                 .count())
        self.assertEqual(count, 2)

    def test_request_on_purchasedjob_update(self):
        # Creating a PurchasedJob for a Product that requires approval
        # creates a Request
        job = PurchasedJobFactory(owner=self.company, created_by=self.user)
        self.assertEqual(Request.objects.count(), 1)

        # Re-saving that job should not create a new request.
        job.save()
        self.assertEqual(Request.objects.count(), 1)

        # Approving the job should also not create a new request.
        job.is_approved = True
        job.save()
        self.assertEqual(Request.objects.count(), 1)

        # Marking the job as not approved and saving it should not create
        # a new request if no action was taken on the old request.
        job.is_approved = False
        job.save()
        self.assertEqual(Request.objects.count(), 1)

        # Marking the job as not approved and saving it should create
        # a new request if there is no pending request.
        request = Request.objects.get()
        request.action_taken = True
        request.save()
        job.save()
        self.assertEqual(Request.objects.count(), 2)

    def test_enable_posting(self):
        """
        Attempting to automatically enable posting for a company should result
        in a valid site package owned by that company.

        """
        AppAccessFactory(name='Posting')
        company = CompanyFactory(name='Posting Company')
        site = SeoSite.objects.create(domain='somewhere.jobs')
        # sanity checks
        self.assertIsNone(site.canonical_company)
        self.assertEqual(company.enabled_access, [])

        package = enable_posting(company, site)

        # Django caches model instances
        company = Company.objects.get(pk=company.pk)
        site = SeoSite.objects.get(pk=site.pk)

        self.assertEqual(site.canonical_company, company)
        self.assertIn("Posting", company.enabled_access)
        self.assertIn(site, package.sites.all())
        self.assertTrue(LoginBlock.objects.filter(
            name="Posting Company Login Block").exists())

    def test_enable_marketplace(self):
        """
        Attempting to automatically enable posting for a company should result
        in a valid site package owned by that company.

        """
        AppAccessFactory(name='MarketPlace')
        company = CompanyFactory(name='Marketplace Company')
        site = SeoSite.objects.create(domain='somewhereelse.jobs')
        # sanity checks
        self.assertIsNone(site.canonical_company)
        self.assertEqual(company.enabled_access, [])

        package = enable_marketplace(company, site)

        # Django caches model instances
        company = Company.objects.get(pk=company.pk)
        site = SeoSite.objects.get(pk=site.pk)

        self.assertEqual(site.canonical_company, company)
        self.assertIn("MarketPlace", company.enabled_access)
        self.assertIn(site, package.sites.all())
        self.assertTrue(LoginBlock.objects.filter(
            name="Marketplace Company Login Block").exists())

    def test_create_login_block(self):
        """
        Ensures that a login block is createed with the correct associations
        and a valid template.

        """
        company = CompanyFactory(name='Marketplace Company')
        site = SeoSite.objects.create(domain='somewhereelse.jobs')

        template = raw_base_template(LoginBlock)
        response = self.client.get("/login", follow=True)
        login_block = create_login_block(company, site)

        # validate that the correct template was assigned to the login block
        self.assertEqual(login_block.template, template)
class TestCommRecordsDataSource(MyJobsBase):
    def setUp(self):
        super(TestCommRecordsDataSource, 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_a = PartnerFactory(
            owner=self.company,
            uri='http://www.example.com/',
            data_source="zap",
            name="aaa")
        self.partner_b = PartnerFactory(
            owner=self.company,
            uri='http://www.asdf.com/',
            data_source="bcd",
            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.north_tag = TagFactory.create(
            company=self.company, name='north', hex_color="cccccc")
        self.south_tag = TagFactory.create(
            company=self.company, name='south', hex_color="dddddd")
        self.left_tag = TagFactory.create(
            company=self.company, name='left', hex_color="eeeeee")
        self.right_tag = TagFactory.create(
            company=self.company, name='right', hex_color="ffffff")
        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.north_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.south_tag)

        self.partner_a.primary_contact = self.john
        self.partner_b.primary_contact = self.sue

        self.partner_a.save()
        self.partner_b.save()

        self.record_1 = ContactRecordFactory(
            subject='record 1',
            date_time='2015-09-30 13:23',
            contact=self.john,
            contact_type="Email",
            partner=self.partner_a,
            location='Indianapolis, IN',
            tags=[self.east_tag])
        self.record_2 = ContactRecordFactory(
            subject='record 2',
            date_time='2015-01-01',
            contact=self.john,
            contact_type="Meeting Or Event",
            partner=self.partner_a,
            location='Indianapolis, IN',
            tags=[self.east_tag])
        self.record_3 = ContactRecordFactory(
            subject='record 3',
            date_time='2015-10-03',
            contact=self.sue,
            contact_type="Phone",
            partner=self.partner_b,
            location='Los Angeles, CA',
            tags=[self.west_tag])

        # Archive archived data here. Doing this earlier in the set up results
        # in odd exceptions.
        self.partner_archived.archive()

    def test_run_unfiltered(self):
        """Make sure we only get data for this user."""
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(self.company, CommRecordsFilter(), [])
        subjects = {r['subject'] for r in recs}
        expected = {
            self.record_1.subject,
            self.record_2.subject,
            self.record_3.subject,
        }
        self.assertEqual(expected, subjects)

    def test_filter_by_date_range(self):
        """Should show only commrec with last_action_time in range."""
        ds = CommRecordsDataSource()
        date_range = DateRangeFilter([
            datetime(2015, 9, 1),
            datetime(2015, 9, 30)])
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(date_time=date_range),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_date_before(self):
        """Should show only commrec with last_action_time before date."""
        ds = CommRecordsDataSource()
        date_range = DateRangeFilter(
            [None, datetime(2015, 9, 30)])
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(date_time=date_range),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject, self.record_2.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_date_after(self):
        """Should show only commrec with last_action_time after date."""
        ds = CommRecordsDataSource()
        date_range = DateRangeFilter(
            [datetime(2015, 10, 1), None])
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(date_time=date_range),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_state(self):
        """Should show only commrecs with correct state."""
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(
                locations=CompositeAndFilter({'state': MatchFilter('CA')})),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_city(self):
        """Should show only commrecs with correct city."""
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(
                locations=CompositeAndFilter({
                    'city': MatchFilter('Los Angeles')})),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_tags(self):
        """
        Show only commrec with correct tags.

        """
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(tags=AndGroupFilter([
                OrGroupFilter([MatchFilter('EaSt')])])),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject, self.record_2.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_tags_unlinked(self):
        """
       Only return untagged commrecs.

        """
        self.record_1.tags.clear()
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(tags=UnlinkedFilter()),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_tags_or(self):
        """Show only commrec with correct tags in 'or' configuration."""
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(tags=AndGroupFilter([
                OrGroupFilter([MatchFilter('EaSt'), MatchFilter('wEsT')])])),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {
            self.record_1.subject,
            self.record_2.subject,
            self.record_3.subject,
        }
        self.assertEqual(expected, subjects)

    def test_filter_by_tags_and(self):
        """Show only commrec with correct tags in 'and' configuration."""
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(tags=AndGroupFilter([
                OrGroupFilter([MatchFilter('EaSt')]),
                OrGroupFilter([MatchFilter('wEsT')])])),
            [])
        subjects = {r['subject'] for r in recs}
        expected = set()
        self.assertEqual(expected, subjects)

        # Now try adding another tag.
        self.record_1.tags.add(self.west_tag)
        self.record_1.save()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(tags=AndGroupFilter([
                OrGroupFilter([MatchFilter('EaSt')]),
                OrGroupFilter([MatchFilter('wEsT')])])),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_communication_type(self):
        """Check communication_type filter works at all."""
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(communication_type=OrGroupFilter([
                MatchFilter('email')])),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_partner(self):
        """
        Check partner filter works at all.

        """
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(
                partner=OrGroupFilter([MatchFilter(self.partner_a.pk)])),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_1.subject, self.record_2.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_contact(self):
        """
        Check partner filter works at all.

        """
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(
                contact=OrGroupFilter([MatchFilter(self.sue.pk)])),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_contact_tags(self):
        """
        Test that we can filter by contact tags.

        """
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(
                contact_tags=AndGroupFilter([
                    OrGroupFilter([MatchFilter('sOuTh')])])),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_contact_tags_untagged(self):
        """
        Check that we can find a record attached to an untagged contact.

        """
        self.sue.tags.clear()
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(contact_tags=UnlinkedFilter()),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)

    def test_filter_by_partner_tags(self):
        """
        Test that we can filter by partner tags.

        """
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(
                partner_tags=AndGroupFilter([
                    OrGroupFilter([MatchFilter('rigHt')])])),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        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 = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(partner_tags=UnlinkedFilter()),
            [])
        subjects = {r['subject'] for r in recs}
        expected = {self.record_3.subject}
        self.assertEqual(expected, subjects)

    def test_help_city(self):
        """
        Check city help works and ignores current city filter.

        """
        ds = CommRecordsDataSource()
        recs = ds.help_city(
            self.company,
            CommRecordsFilter(
                locations=CompositeAndFilter({
                    'city': MatchFilter("zz")})),
            "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 = CommRecordsDataSource()
        recs = ds.help_state(
            self.company,
            CommRecordsFilter(
                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 = CommRecordsDataSource()
        recs = ds.help_tags(self.company, CommRecordsFilter(), "E")
        actual = {r['value'] for r in recs}
        self.assertEqual({'east', 'west'}, actual)

    def test_help_contact_tags(self):
        """
        Check contact tags help works at all.

        """
        ds = CommRecordsDataSource()
        recs = ds.help_contact_tags(self.company, CommRecordsFilter(), "O")
        actual = {r['value'] for r in recs}
        self.assertEqual({'north', 'south'}, actual)

    def test_help_partner_tags(self):
        """
        Check partner tags help works at all.

        """
        ds = CommRecordsDataSource()
        recs = ds.help_partner_tags(self.company, CommRecordsFilter(), "t")
        actual = {r['value'] for r in recs}
        self.assertEqual({'left', 'right'}, actual)

    def test_help_tags_colors(self):
        """
        Tags should have colors

        """
        ds = CommRecordsDataSource()
        recs = ds.help_tags(self.company, CommRecordsFilter(), "east")
        self.assertEqual("aaaaaa", recs[0]['hexColor'])

    def test_help_communication_types(self):
        """
        Check communication_types help works at all.

        """
        ds = CommRecordsDataSource()
        recs = ds.help_communication_type(
            self.company, CommRecordsFilter(), "ph")
        actual = {r['value'] for r in recs}
        expected = {'phone', 'job', 'meetingorevent', 'email', 'pssemail'}
        self.assertEqual(expected, actual)

    def test_help_partner(self):
        """
        Check partner help works at all.

        """
        ds = CommRecordsDataSource()
        recs = ds.help_partner(self.company, CommRecordsFilter(), "A")
        self.assertEqual(
            [{'value': self.partner_a.pk, 'display': self.partner_a.name}],
            recs)

    def test_help_contact(self):
        """
        Check contact help works at all.

        """
        ds = CommRecordsDataSource()
        recs = ds.help_contact(self.company, CommRecordsFilter(), "U")
        self.assertEqual(
            [{'value': self.sue.pk, 'display': self.sue.name}],
            recs)

    def test_values(self):
        """
        Check limiting values works at all

        """
        self.maxDiff = 10000
        ds = CommRecordsDataSource()
        recs = ds.run_unaggregated(
            self.company,
            CommRecordsFilter(),
            ["partner", "subject"])
        expected = [
            {'partner': u'aaa', 'subject': u'record 1'},
            {'partner': u'aaa', 'subject': u'record 2'},
            {'partner': u'bbb', 'subject': u'record 3'},
        ]
        self.assertEqual(expected, recs)

    def test_adorn_filter(self):
        self.maxDiff = 10000
        found_filter_items = {
            'tags': ['east', 'west'],
            'communication_type': ['Email'],
            'partner': [str(self.partner_a.pk)],
            'contact': [str(self.sue.pk)],
            'contact_tags': ['nOrth', 'south'],
            'partner_tags': ['lEft', 'riGht'],
        }

        expected = {
            u'partner': {
                self.partner_a.pk:
                    {'value': self.partner_a.pk, 'display': u'aaa'},
            },
            u'contact': {
                self.sue.pk:
                    {'value': self.sue.pk, 'display': u'Sue Baxter'},
            },
            u'tags': {
                u'east': {
                    'value': u'east',
                    'display': u'east',
                    'hexColor': u'aaaaaa',
                },
                u'west': {
                    'value': u'west',
                    'display': u'west',
                    'hexColor': u'bbbbbb',
                },
            },
            u'communication_type': {
                'email': {'value': 'email', 'display': 'Email'}
            },
            u'contact_tags': {
                u'north': {
                    'value': u'north',
                    'display': u'north',
                    'hexColor': u'cccccc',
                },
                u'south': {
                    'value': u'south',
                    'display': u'south',
                    'hexColor': u'dddddd',
                },
            },
            u'partner_tags': {
                u'left': {
                    'value': u'left',
                    'display': u'left',
                    'hexColor': u'eeeeee',
                },
                u'right': {
                    'value': u'right',
                    'display': u'right',
                    'hexColor': u'ffffff',
                },
            },
        }

        ds = CommRecordsDataSource()
        result = ds.adorn_filter_items(self.company, found_filter_items)
        self.assertEqual(expected, result)

    def test_default_filter(self):
        """
        should produce a populated filter object.

        """
        ds = CommRecordsDataSource()
        default_filter = ds.get_default_filter(None, self.company)
        self.assertEquals(
            datetime.now().year,
            default_filter.date_time.dates[1].year)
        # Take out value dated today. Too hard to run through assertEquals.
        default_filter.date_time.dates[1] = None
        expected = CommRecordsFilter(
            date_time=DateRangeFilter([datetime(2014, 1, 1), None]))
        self.assertEquals(expected, default_filter)
예제 #13
0
class TestPartnersDataSource(MyJobsBase):
    def setUp(self):
        super(TestPartnersDataSource, 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_a = PartnerFactory(owner=self.company,
                                        last_action_time='2015-09-30 13:23',
                                        uri='http://www.example.com/',
                                        data_source="zap",
                                        name="aaa")
        self.partner_b = PartnerFactory(owner=self.company,
                                        last_action_time='2015-10-03',
                                        uri='http://www.asdf.com/',
                                        data_source="bcd",
                                        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.bad_tag = TagFactory.create(company=self.company,
                                         name='bad',
                                         hex_color="cccccc")

        self.partner_a.tags.add(self.east_tag)
        self.partner_b.tags.add(self.west_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.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.partner_a.primary_contact = self.john
        self.partner_b.primary_contact = self.sue

        self.partner_a.save()
        self.partner_b.save()

        # Archive archived data here. Doing this earlier in the set up results
        # in odd exceptions.
        self.partner_archived.archive()

    def test_run_unfiltered(self):
        """Make sure we only get data for this user."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(self.company, PartnersFilter(), [])
        names = {r['name'] for r in recs}
        expected = {self.partner_a.name, self.partner_b.name}
        self.assertEqual(expected, names)
        expected_tags = {
            self.partner_a.pk: {'east'},
            self.partner_b.pk: {'west'},
        }

        def tags_by_pk(rec):
            return (rec['partner_id'], set(t['name'] for t in rec['tags']))

        found_tags = dict(tags_by_pk(r) for r in recs)

        self.assertEqual(expected_tags, found_tags)

    def test_run_count_comm_rec_per_month(self):
        """Make sure we only get data for this user."""
        for (subject, itx) in enumerate(['a', 'b', 'c']):
            for month in [2, 3, 4]:
                self.sue.contactrecord_set.add(
                    ContactRecordFactory(subject=subject,
                                         date_time=datetime(2015, month, 1)))

        ds = PartnersDataSource()
        recs = ds.run_count_comm_rec_per_month(self.company, PartnersFilter(),
                                               [])
        data = [(r['name'], r['year'], r['month'], r['comm_rec_count'])
                for r in recs]
        expected = [
            (self.partner_a.name, 2015, 1, 0),
            (self.partner_a.name, 2015, 2, 0),
            (self.partner_a.name, 2015, 3, 0),
            (self.partner_a.name, 2015, 4, 0),
            (self.partner_a.name, 2015, 5, 0),
            (self.partner_a.name, 2015, 6, 0),
            (self.partner_a.name, 2015, 7, 0),
            (self.partner_a.name, 2015, 8, 0),
            (self.partner_a.name, 2015, 9, 0),
            (self.partner_a.name, 2015, 10, 0),
            (self.partner_a.name, 2015, 11, 0),
            (self.partner_a.name, 2015, 12, 0),
            (self.partner_b.name, 2015, 1, 0),
            (self.partner_b.name, 2015, 2, 3),
            (self.partner_b.name, 2015, 3, 3),
            (self.partner_b.name, 2015, 4, 3),
            (self.partner_b.name, 2015, 5, 0),
            (self.partner_b.name, 2015, 6, 0),
            (self.partner_b.name, 2015, 7, 0),
            (self.partner_b.name, 2015, 8, 0),
            (self.partner_b.name, 2015, 9, 0),
            (self.partner_b.name, 2015, 10, 0),
            (self.partner_b.name, 2015, 11, 0),
            (self.partner_b.name, 2015, 12, 0),
        ]
        self.assertEqual(expected, data)

    def test_run_count_comm_rec_per_month_one_partner(self):
        """Trip over a bug in the mysql client driver."""
        for (subject, itx) in enumerate(['a', 'b', 'c']):
            for year in [2013, 2015, 2014]:
                for month in [2, 3, 4]:
                    self.sue.contactrecord_set.add(
                        ContactRecordFactory(subject=subject,
                                             date_time=datetime(
                                                 year, month, 1)))

        ds = PartnersDataSource()
        partners_filter = PartnersFilter(
            tags=AndGroupFilter([OrGroupFilter([MatchFilter('west')])]))
        recs = ds.run_count_comm_rec_per_month(self.company, partners_filter,
                                               ['name', 'year', '-month'])
        data = [(r['name'], r['year'], r['month'], r['comm_rec_count'])
                for r in recs]
        self.assertEqual(36, len(data))

    def test_run_count_comm_rec_per_month_no_partners(self):
        """Trip over a bug in the mysql client driver."""
        for (subject, itx) in enumerate(['a', 'b', 'c']):
            for month in [2, 3, 4]:
                self.sue.contactrecord_set.add(
                    ContactRecordFactory(subject=subject,
                                         date_time=datetime(2015, month, 1)))

        ds = PartnersDataSource()
        partners_filter = PartnersFilter(
            tags=AndGroupFilter([OrGroupFilter([MatchFilter('zzz')])]))
        recs = ds.run_count_comm_rec_per_month(self.company, partners_filter,
                                               ['name', 'year', '-month'])
        self.assertEqual(0, len(recs))

    def test_run_count_comm_rec_per_month_empty_partner(self):
        """One partner, no communication records."""
        ds = PartnersDataSource()
        partners_filter = PartnersFilter(
            tags=AndGroupFilter([OrGroupFilter([MatchFilter('east')])]))
        recs = ds.run_count_comm_rec_per_month(self.company, partners_filter,
                                               ['name', 'year', '-month'])
        data = [(r['name'], r['year'], r['month'], r['comm_rec_count'])
                for r in recs]
        self.assertEqual(12, len(data))
        default_year = datetime.now().year
        for item in data:
            self.assertEqual(default_year, item[1])
            self.assertEqual(0, item[3])

    def test_filter_by_date_range(self):
        """Should show only partner with last_action_time in range."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(date=DateRangeFilter(
                [datetime(2015, 9, 1),
                 datetime(2015, 9, 30)])), [])
        names = {r['name'] for r in recs}
        expected = {self.partner_a.name}
        self.assertEqual(expected, names)

    def test_filter_by_date_before(self):
        """Should show only partner with last_action_time before date."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(
                date=DateRangeFilter([None, datetime(2015, 9, 30)])), [])
        names = {r['name'] for r in recs}
        expected = {self.partner_a.name}
        self.assertEqual(expected, names)

    def test_filter_by_date_after(self):
        """Should show only partner with last_action_time after date."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(
                date=DateRangeFilter([datetime(2015, 10, 1), None])), [])
        names = {r['name'] for r in recs}
        expected = {self.partner_b.name}
        self.assertEqual(expected, names)

    def test_filter_by_state(self):
        """Should show only partners with correct state."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(
                locations=CompositeAndFilter({
                    'state': MatchFilter('CA'),
                })), [])
        names = [r['name'] for r in recs]
        expected = [self.partner_b.name]
        self.assertEqual(expected, names)

    def test_filter_by_city(self):
        """Should show only partners with correct city."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(locations=CompositeAndFilter({
                'city':
                MatchFilter('Los Angeles'),
            })), [])
        names = [r['name'] for r in recs]
        expected = [self.partner_b.name]
        self.assertEqual(expected, names)

    def test_filter_by_tags(self):
        """Show only partner with correct tags."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(
                tags=AndGroupFilter([OrGroupFilter([MatchFilter('EaSt')])])),
            [])
        names = {r['name'] for r in recs}
        expected = {self.partner_a.name}
        self.assertEqual(expected, names)

    def test_filter_by_tags_or(self):
        """Show only partner with correct tags in 'or' configuration."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(tags=AndGroupFilter(
                [OrGroupFilter([MatchFilter('EaSt'),
                                MatchFilter('wEsT')])])), [])
        names = {r['name'] for r in recs}
        expected = {self.partner_a.name, self.partner_b.name}
        self.assertEqual(expected, names)

    def test_filter_by_tags_and(self):
        """Show only partner with correct tags in 'and' configuration."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(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.partner_a.tags.add(self.west_tag)
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(tags=AndGroupFilter([
                OrGroupFilter([MatchFilter('EaSt')]),
                OrGroupFilter([MatchFilter('wEsT')])
            ])), [])
        names = {r['name'] for r in recs}
        expected = {self.partner_a.name}
        self.assertEqual(expected, names)

    def test_filter_by_data_source(self):
        """Check datasource filter works at all."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company, PartnersFilter(data_source=MatchFilter("zap")), [])
        names = {r['name'] for r in recs}
        expected = {self.partner_a.name}
        self.assertEqual(expected, names)

    def test_filter_by_uri(self):
        """Check uri filter works at all."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(uri=MatchFilter("http://www.asdf.com/")), [])
        names = {r['name'] for r in recs}
        expected = {self.partner_b.name}
        self.assertEqual(expected, names)

    def test_help_city(self):
        """Check city help works and ignores current city filter."""
        ds = PartnersDataSource()
        recs = ds.help_city(
            self.company,
            PartnersFilter(
                locations=CompositeAndFilter({'city': MatchFilter("zz")})),
            "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 = PartnersDataSource()
        recs = ds.help_state(
            self.company,
            PartnersFilter(
                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 = PartnersDataSource()
        recs = ds.help_tags(self.company, PartnersFilter(), "E")
        actual = {r['value'] for r in recs}
        self.assertEqual({'east', 'west'}, actual)

    def test_help_tags_colors(self):
        """Tags should have colors"""
        ds = PartnersDataSource()
        recs = ds.help_tags(self.company, PartnersFilter(), "east")
        self.assertEqual("aaaaaa", recs[0]['hexColor'])

    def test_help_uri(self):
        """Check uri help works at all."""
        ds = PartnersDataSource()
        recs = ds.help_uri(self.company, PartnersFilter(), "ex")
        actual = {r['value'] for r in recs}
        self.assertEqual({'http://www.example.com/'}, actual)

    def test_help_data_source(self):
        """Check data_source help works at all."""
        ds = PartnersDataSource()
        recs = ds.help_data_source(self.company, PartnersFilter(), "z")
        actual = {r['value'] for r in recs}
        self.assertEqual({'zap'}, actual)

    def test_values(self):
        """Check limiting values works at all."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(self.company, PartnersFilter(),
                                   ["name", "uri"])
        expected = [
            {
                'name': self.partner_a.name,
                'uri': 'http://www.example.com/'
            },
            {
                'name': self.partner_b.name,
                'uri': 'http://www.asdf.com/'
            },
        ]
        self.assertEqual(expected, recs)

    def test_adorn_filter_items(self):
        found_filter_items = {
            'tags': ['east', 'west'],
            'uri': 'http://www.example.com/',
        }
        expected = {
            u'tags': {
                'east': {
                    'value': u'east',
                    'display': u'east',
                    'hexColor': u'aaaaaa',
                },
                'west': {
                    'value': u'west',
                    'display': u'west',
                    'hexColor': u'bbbbbb',
                },
            },
        }

        ds = PartnersDataSource()
        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 = PartnersDataSource()
        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 = PartnersFilter(
            date=DateRangeFilter([datetime(2014, 1, 1), None]))
        self.assertEquals(expected, default_filter)
class TestPartnersDataSource(MyJobsBase):
    def setUp(self):
        super(TestPartnersDataSource, 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_a = PartnerFactory(
            owner=self.company,
            last_action_time='2015-09-30 13:23',
            uri='http://www.example.com/',
            data_source="zap",
            name="aaa")
        self.partner_b = PartnerFactory(
            owner=self.company,
            last_action_time='2015-10-03',
            uri='http://www.asdf.com/',
            data_source="bcd",
            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.bad_tag = TagFactory.create(
            company=self.company, name='bad', hex_color="cccccc")

        self.partner_a.tags.add(self.east_tag)
        self.partner_b.tags.add(self.west_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.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.partner_a.primary_contact = self.john
        self.partner_b.primary_contact = self.sue

        self.partner_a.save()
        self.partner_b.save()

        # Archive archived data here. Doing this earlier in the set up results
        # in odd exceptions.
        self.partner_archived.archive()

    def test_run_unfiltered(self):
        """Make sure we only get data for this user."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(self.company, PartnersFilter(), [])
        names = {r['name'] for r in recs}
        expected = {self.partner_a.name, self.partner_b.name}
        self.assertEqual(expected, names)
        expected_tags = {
            self.partner_a.pk: {'east'},
            self.partner_b.pk: {'west'},
        }

        def tags_by_pk(rec):
            return (rec['partner_id'], set(t['name'] for t in rec['tags']))

        found_tags = dict(tags_by_pk(r) for r in recs)

        self.assertEqual(expected_tags, found_tags)

    def test_run_count_comm_rec_per_month(self):
        """Make sure we only get data for this user."""
        for (subject, itx) in enumerate(['a', 'b', 'c']):
            for month in [2, 3, 4]:
                self.sue.contactrecord_set.add(
                    ContactRecordFactory(
                        subject=subject,
                        date_time=datetime(2015, month, 1)))

        ds = PartnersDataSource()
        recs = ds.run_count_comm_rec_per_month(
            self.company, PartnersFilter(), [])
        data = [
            (r['name'], r['year'], r['month'], r['comm_rec_count'])
            for r in recs
        ]
        expected = [
            (self.partner_a.name, 2015, 1, 0),
            (self.partner_a.name, 2015, 2, 0),
            (self.partner_a.name, 2015, 3, 0),
            (self.partner_a.name, 2015, 4, 0),
            (self.partner_a.name, 2015, 5, 0),
            (self.partner_a.name, 2015, 6, 0),
            (self.partner_a.name, 2015, 7, 0),
            (self.partner_a.name, 2015, 8, 0),
            (self.partner_a.name, 2015, 9, 0),
            (self.partner_a.name, 2015, 10, 0),
            (self.partner_a.name, 2015, 11, 0),
            (self.partner_a.name, 2015, 12, 0),
            (self.partner_b.name, 2015, 1, 0),
            (self.partner_b.name, 2015, 2, 3),
            (self.partner_b.name, 2015, 3, 3),
            (self.partner_b.name, 2015, 4, 3),
            (self.partner_b.name, 2015, 5, 0),
            (self.partner_b.name, 2015, 6, 0),
            (self.partner_b.name, 2015, 7, 0),
            (self.partner_b.name, 2015, 8, 0),
            (self.partner_b.name, 2015, 9, 0),
            (self.partner_b.name, 2015, 10, 0),
            (self.partner_b.name, 2015, 11, 0),
            (self.partner_b.name, 2015, 12, 0),
        ]
        self.assertEqual(expected, data)

    def test_run_count_comm_rec_per_month_one_partner(self):
        """Trip over a bug in the mysql client driver."""
        for (subject, itx) in enumerate(['a', 'b', 'c']):
            for year in [2013, 2015, 2014]:
                for month in [2, 3, 4]:
                    self.sue.contactrecord_set.add(
                        ContactRecordFactory(
                            subject=subject,
                            date_time=datetime(year, month, 1)))

        ds = PartnersDataSource()
        partners_filter = PartnersFilter(tags=AndGroupFilter([
            OrGroupFilter([MatchFilter('west')])]))
        recs = ds.run_count_comm_rec_per_month(
            self.company, partners_filter, ['name', 'year', '-month'])
        data = [
            (r['name'], r['year'], r['month'], r['comm_rec_count'])
            for r in recs
        ]
        self.assertEqual(36, len(data))

    def test_run_count_comm_rec_per_month_no_partners(self):
        """Trip over a bug in the mysql client driver."""
        for (subject, itx) in enumerate(['a', 'b', 'c']):
            for month in [2, 3, 4]:
                self.sue.contactrecord_set.add(
                    ContactRecordFactory(
                        subject=subject,
                        date_time=datetime(2015, month, 1)))

        ds = PartnersDataSource()
        partners_filter = PartnersFilter(tags=AndGroupFilter([
            OrGroupFilter([MatchFilter('zzz')])]))
        recs = ds.run_count_comm_rec_per_month(
            self.company, partners_filter, ['name', 'year', '-month'])
        self.assertEqual(0, len(recs))

    def test_run_count_comm_rec_per_month_empty_partner(self):
        """One partner, no communication records."""
        ds = PartnersDataSource()
        partners_filter = PartnersFilter(tags=AndGroupFilter([
            OrGroupFilter([MatchFilter('east')])]))
        recs = ds.run_count_comm_rec_per_month(
            self.company, partners_filter, ['name', 'year', '-month'])
        data = [
            (r['name'], r['year'], r['month'], r['comm_rec_count'])
            for r in recs
        ]
        self.assertEqual(12, len(data))
        default_year = datetime.now().year
        for item in data:
            self.assertEqual(default_year, item[1])
            self.assertEqual(0, item[3])

    def test_filter_by_date_range(self):
        """Should show only partner with last_action_time in range."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(
                date=DateRangeFilter(
                    [datetime(2015, 9, 1), datetime(2015, 9, 30)])),
            [])
        names = {r['name'] for r in recs}
        expected = {self.partner_a.name}
        self.assertEqual(expected, names)

    def test_filter_by_date_before(self):
        """Should show only partner with last_action_time before date."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(
                date=DateRangeFilter([None, datetime(2015, 9, 30)])),
            [])
        names = {r['name'] for r in recs}
        expected = {self.partner_a.name}
        self.assertEqual(expected, names)

    def test_filter_by_date_after(self):
        """Should show only partner with last_action_time after date."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(
                date=DateRangeFilter([datetime(2015, 10, 1), None])),
            [])
        names = {r['name'] for r in recs}
        expected = {self.partner_b.name}
        self.assertEqual(expected, names)

    def test_filter_by_state(self):
        """Should show only partners with correct state."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(
                locations=CompositeAndFilter({
                    'state': MatchFilter('CA'),
                })),
            [])
        names = [r['name'] for r in recs]
        expected = [self.partner_b.name]
        self.assertEqual(expected, names)

    def test_filter_by_city(self):
        """Should show only partners with correct city."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(
                locations=CompositeAndFilter({
                    'city': MatchFilter('Los Angeles'),
                })),
            [])
        names = [r['name'] for r in recs]
        expected = [self.partner_b.name]
        self.assertEqual(expected, names)

    def test_filter_by_tags(self):
        """Show only partner with correct tags."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(tags=AndGroupFilter([
                OrGroupFilter([MatchFilter('EaSt')])])),
            [])
        names = {r['name'] for r in recs}
        expected = {self.partner_a.name}
        self.assertEqual(expected, names)

    def test_filter_by_tags_or(self):
        """Show only partner with correct tags in 'or' configuration."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(tags=AndGroupFilter([
                OrGroupFilter([MatchFilter('EaSt'), MatchFilter('wEsT')])])),
            [])
        names = {r['name'] for r in recs}
        expected = {self.partner_a.name, self.partner_b.name}
        self.assertEqual(expected, names)

    def test_filter_by_tags_and(self):
        """Show only partner with correct tags in 'and' configuration."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(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.partner_a.tags.add(self.west_tag)
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(tags=AndGroupFilter([
                OrGroupFilter([MatchFilter('EaSt')]),
                OrGroupFilter([MatchFilter('wEsT')])])),
            [])
        names = {r['name'] for r in recs}
        expected = {self.partner_a.name}
        self.assertEqual(expected, names)

    def test_filter_by_data_source(self):
        """Check datasource filter works at all."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(data_source=MatchFilter("zap")),
            [])
        names = {r['name'] for r in recs}
        expected = {self.partner_a.name}
        self.assertEqual(expected, names)

    def test_filter_by_uri(self):
        """Check uri filter works at all."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(uri=MatchFilter("http://www.asdf.com/")),
            [])
        names = {r['name'] for r in recs}
        expected = {self.partner_b.name}
        self.assertEqual(expected, names)

    def test_help_city(self):
        """Check city help works and ignores current city filter."""
        ds = PartnersDataSource()
        recs = ds.help_city(
            self.company,
            PartnersFilter(locations=CompositeAndFilter({
                'city': MatchFilter("zz")})),
            "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 = PartnersDataSource()
        recs = ds.help_state(
            self.company,
            PartnersFilter(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 = PartnersDataSource()
        recs = ds.help_tags(self.company, PartnersFilter(), "E")
        actual = {r['value'] for r in recs}
        self.assertEqual({'east', 'west'}, actual)

    def test_help_tags_colors(self):
        """Tags should have colors"""
        ds = PartnersDataSource()
        recs = ds.help_tags(self.company, PartnersFilter(), "east")
        self.assertEqual("aaaaaa", recs[0]['hexColor'])

    def test_help_uri(self):
        """Check uri help works at all."""
        ds = PartnersDataSource()
        recs = ds.help_uri(
            self.company,
            PartnersFilter(),
            "ex")
        actual = {r['value'] for r in recs}
        self.assertEqual({'http://www.example.com/'}, actual)

    def test_help_data_source(self):
        """Check data_source help works at all."""
        ds = PartnersDataSource()
        recs = ds.help_data_source(
            self.company,
            PartnersFilter(),
            "z")
        actual = {r['value'] for r in recs}
        self.assertEqual({'zap'}, actual)

    def test_values(self):
        """Check limiting values works at all."""
        ds = PartnersDataSource()
        recs = ds.run_unaggregated(
            self.company,
            PartnersFilter(),
            ["name", "uri"])
        expected = [
            {'name': self.partner_a.name, 'uri': 'http://www.example.com/'},
            {'name': self.partner_b.name, 'uri': 'http://www.asdf.com/'},
        ]
        self.assertEqual(expected, recs)

    def test_adorn_filter_items(self):
        found_filter_items = {
            'tags': ['east', 'west'],
            'uri': 'http://www.example.com/',
        }
        expected = {
            u'tags': {
                'east': {
                    'value': u'east',
                    'display': u'east',
                    'hexColor': u'aaaaaa',
                },
                'west': {
                    'value': u'west',
                    'display': u'west',
                    'hexColor': u'bbbbbb',
                },
            },
        }

        ds = PartnersDataSource()
        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 = PartnersDataSource()
        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 = PartnersFilter(
            date=DateRangeFilter([datetime(2014, 1, 1), None]))
        self.assertEquals(expected, default_filter)