Exemplo n.º 1
0
    def test_send_pss_fails(self, mock_send_email):
        """
        When a partner saved search fails to send, we should not imply
        that it was successful.
        """
        company = CompanyFactory()
        partner = PartnerFactory(owner=company)
        search = PartnerSavedSearchFactory(user=self.user,
                                           created_by=self.user,
                                           provider=company,
                                           partner=partner)

        e = SMTPAuthenticationError(418, 'Toot toot')
        mock_send_email.side_effect = e

        self.assertEqual(ContactRecord.objects.count(), 0)
        self.assertEqual(SavedSearchLog.objects.count(), 0)
        search.send_email()

        record = ContactRecord.objects.get()
        log = SavedSearchLog.objects.get()
        self.assertFalse(log.was_sent)
        self.assertEqual(log.reason, "Toot toot")
        self.assertTrue(record.notes.startswith(log.reason))
        self.assertFalse(record.contactlogentry.successful)
Exemplo n.º 2
0
    def setUp(self):
        super(PartnerSavedSearchTests, self).setUp()
        self.digest = SavedSearchDigestFactory(user=self.user)
        self.company = CompanyFactory()
        self.partner = PartnerFactory(owner=self.company)
        self.contact = ContactFactory(user=self.user, partner=self.partner)
        self.partner_search = PartnerSavedSearchFactory(user=self.user,
                                                        created_by=self.user,
                                                        provider=self.company,
                                                        partner=self.partner)
        # Partner searches are normally created with a form, which creates
        # invitations as a side effect. We're not testing the form, so we
        # can fake an invitation here.
        invitation = Invitation.objects.create(
            invitee_email=self.partner_search.email,
            invitee=self.partner_search.user,
            inviting_user=self.partner_search.created_by,
            inviting_company=self.partner_search.partner.owner,
            added_saved_search=self.partner_search)
        invitation.send(self.partner_search)

        self.num_occurrences = lambda text, search_str: [
            match.start() for match in re.finditer(search_str, text)
        ]
        # classes and ids may get stripped out when pynliner inlines css.
        # all jobs contain a default (blank) icon, so we can search for that if
        # we want a job count
        self.job_icon = 'http://png.nlx.org/100x50/logo.gif'
Exemplo n.º 3
0
    def test_send_pss_after_10(self):
        """
        Ensures that partner saved searches that are created and scheduled for
        today are sent immediately if they are saved after the batch sending
        process begins.
        """
        company = CompanyFactory()
        partner = PartnerFactory(owner=company)

        communication_records = ContactRecord.objects.count()

        # The act of creating a daily partner saved search after 10 AM should
        # send the saved search being created.
        PartnerSavedSearchFactory(user=self.user,
                                  created_by=self.user,
                                  provider=company,
                                  partner=partner,
                                  frequency='D')

        self.assertEqual(ContactRecord.objects.count(),
                         communication_records + 1,
                         msg=("No communication record after "
                              "daily search creation"))

        today = datetime.date.today()

        # Creating a weekly partner saved search with a day_of_week of today
        # should send the saved search on save.
        PartnerSavedSearchFactory(user=self.user,
                                  created_by=self.user,
                                  provider=company,
                                  partner=partner,
                                  frequency='W',
                                  day_of_week=today.isoweekday())

        self.assertEqual(ContactRecord.objects.count(),
                         communication_records + 2,
                         msg=("No communication record after "
                              "weekly search creation"))

        PartnerSavedSearchFactory(user=self.user,
                                  created_by=self.user,
                                  provider=company,
                                  partner=partner,
                                  frequency='M',
                                  day_of_month=today.day)

        self.assertEqual(ContactRecord.objects.count(),
                         communication_records + 3,
                         msg=("No communication record after "
                              "monthly search creation"))
Exemplo n.º 4
0
 def setUp(self):
     super(SavedSearchSendingTests, self).setUp()
     self.feed = 'http://rushenterprises-veterans.jobs/alabama/usa/jobs/feed/rss'
     self.saved_search = SavedSearchFactory(user=self.user,
                                            feed=self.feed,
                                            frequency='D')
     self.company = CompanyFactory()
     self.partner = PartnerFactory(owner=self.company)
     self.contact = ContactFactory(user=self.user, partner=self.partner)
     self.partner_search = PartnerSavedSearchFactory(user=self.user,
                                                     feed=self.feed,
                                                     frequency='D',
                                                     created_by=self.user,
                                                     provider=self.company,
                                                     partner=self.partner)
     mail.outbox = []
Exemplo n.º 5
0
    def test_send_link_appearance(self):
        """
        The button to manually send a saved search should not be displayed
        when DEBUG=False. If the url is guessed, nothing bad should happen.
        """
        self.user.is_superuser = True
        self.user.save()
        saved_search = SavedSearchFactory(user=self.user)
        partner_search = PartnerSavedSearchFactory(user=self.user,
                                                   created_by=self.user)
        ContactFactory(partner=partner_search.partner, user=self.user)

        for search in [saved_search, partner_search]:
            full_feed = reverse('view_full_feed') + '?id=%s' % search.id
            send_url = reverse('send_saved_search') + '?id=%s' % search.id
            if hasattr(search, 'partnersavedsearch'):
                send_url += '&is_pss=True'

            self.client.login_user(self.user)
            response = self.client.get(full_feed)
            self.assertNotIn('>Send</a>', response.content)
            send = self.client.get(send_url)
            self.assertEqual(send.status_code, 404)
            self.assertEqual(len(mail.outbox), 0)

            settings.DEBUG = True
            self.client.login_user(self.user)
            response = self.client.get(full_feed)
            self.assertIn('>Send</a>', response.content)
            send = self.client.get(send_url)
            self.assertEqual(send.status_code, 302)
            self.assertEqual(len(mail.outbox), 1)
            mail.outbox = []

            settings.DEBUG = False
Exemplo n.º 6
0
    def setUp(self):
        super(PartnerSavedSearchTests, self).setUp()
        self.user = UserFactory()
        self.digest = SavedSearchDigestFactory(user=self.user)
        self.company = CompanyFactory()
        self.partner = PartnerFactory(owner=self.company)
        self.contact = ContactFactory(user=self.user,
                                      partner=self.partner)
        self.partner_search = PartnerSavedSearchFactory(user=self.user,
                                                        created_by=self.user,
                                                        provider=self.company,
                                                        partner=self.partner)
        # Partner searches are normally created with a form, which creates
        # invitations as a side effect. We're not testing the form, so we
        # can fake an invitation here.
        Invitation(invitee_email=self.partner_search.email,
                   invitee=self.partner_search.user,
                   inviting_user=self.partner_search.created_by,
                   inviting_company=self.partner_search.partner.owner,
                   added_saved_search=self.partner_search).save()

        self.patcher = patch('urllib2.urlopen', return_file())
        self.mock_urlopen = self.patcher.start()
        self.num_occurrences = lambda text, search_str: [match.start()
                                                         for match
                                                         in re.finditer(
                                                             search_str, text)]
        # classes and ids may get stripped out when pynliner inlines css.
        # all jobs contain a default (blank) icon, so we can search for that if
        # we want a job count
        self.job_icon = 'http://png.nlx.org/100x50/logo.gif'
Exemplo n.º 7
0
    def test_partner_saved_search_digest_no_jobs(self):
        self.digest.is_active = True
        self.digest.save()

        self.partner_search.feed = 'http://google.com'
        self.partner_search.save()
        self.partner_search.send_email()

        for x in range(1, 5):
            PartnerSavedSearchFactory(user=self.user,
                                      created_by=self.user,
                                      provider=self.company,
                                      feed='http://google.com',
                                      partner=self.partner)

        self.digest.send_email()

        email = mail.outbox.pop()
        self.assertEqual(email.body.count('There are no results for today!'),
                         5)

        # Confirm last_sent was updated on all searches even though there were
        # no jobs.
        kwargs = {
            'user': self.user,
            'last_sent__isnull': True,
        }
        self.assertEqual(SavedSearch.objects.filter(**kwargs).count(), 0)
Exemplo n.º 8
0
    def test_pss_contact_record_tagged(self):
        """
        When a contact record is created from a saved search being sent, that
        record should have the saved search's tag.
        """

        company = CompanyFactory()
        partner = PartnerFactory(owner=company)
        tag = TagFactory(name="Test Tag")
        search = PartnerSavedSearchFactory(
            user=self.user, created_by=self.user, provider=company,
            partner=partner)
        search.tags.add(tag)

        search.send_email()
        record = ContactRecord.objects.get(tags__name=tag.name)
        self.assertTrue(record.contactlogentry.successful)
Exemplo n.º 9
0
    def test_pss_contact_record_tagged(self):
        """
        When a contact record is created from a saved search being sent, that
        record should have the saved search's tag.
        """

        company = CompanyFactory()
        partner = PartnerFactory(owner=company)
        tag = TagFactory(name="Test Tag")
        search = PartnerSavedSearchFactory(user=self.user,
                                           created_by=self.user,
                                           provider=company,
                                           partner=partner)
        search.tags.add(tag)

        search.send_email()
        record = ContactRecord.objects.get(tags__name=tag.name)
        self.assertTrue(record.contactlogentry.successful)
Exemplo n.º 10
0
 def test_partner_saved_search_form_from_instance(self):
     user = UserFactory(email='*****@*****.**')
     ContactFactory(user=user, partner=self.partner)
     partner_saved_search = PartnerSavedSearchFactory(
         created_by=self.staff_user,
         provider=self.company,
         partner=self.partner,
         user=user,
         notes='')
     response = self.client.get(
         reverse('partner_edit_search') + '?partner=%s&id=%s' %
         (self.partner.pk, partner_saved_search.pk))
     self.assertTrue(partner_saved_search.feed in response.content)
Exemplo n.º 11
0
    def test_deleting_user_does_not_cascade(self):
        """
        Deleting a user shouldn't delete related objects such as partner saved
        searches and reports.
        """

        user = UserFactory(email="*****@*****.**")
        company = CompanyFactory()
        pss = PartnerSavedSearchFactory(user=self.user, created_by=user)
        report = Report.objects.create(created_by=user, owner=company)

        user.delete()
        self.assertIn(pss, PartnerSavedSearch.objects.all())
        self.assertIn(report, Report.objects.all())
Exemplo n.º 12
0
    def test_send_pss_fails(self, mock_send_email):
        """
        When a partner saved search fails to send, we should not imply
        that it was successful.
        """
        company = CompanyFactory()
        partner = PartnerFactory(owner=company)
        search = PartnerSavedSearchFactory(user=self.user, created_by=self.user,
                                           provider=company, partner=partner)

        e = SMTPAuthenticationError(418, 'Toot toot')
        mock_send_email.side_effect = e

        self.assertEqual(ContactRecord.objects.count(), 0)
        self.assertEqual(SavedSearchLog.objects.count(), 0)
        search.send_email()

        record = ContactRecord.objects.get()
        log = SavedSearchLog.objects.get()
        self.assertFalse(log.was_sent)
        self.assertEqual(log.reason, "Toot toot")
        self.assertTrue(record.notes.startswith(log.reason))
        self.assertFalse(record.contactlogentry.successful)
Exemplo n.º 13
0
    def test_widget_with_partner_saved_search(self):
        company = CompanyFactory()
        partner = PartnerFactory(owner=company)
        ContactFactory(user=self.user, partner=partner)
        search = PartnerSavedSearchFactory(user=self.user,
                                           created_by=self.user,
                                           provider=company,
                                           partner=partner)

        response = self.client.get(reverse('saved_search_widget') +
                                   '?url=%s&callback=callback' % (
                                       search.url, ))
        edit_url = '\\"https://secure.my.jobs%s?id=%s&pss=True\\"' % (
            reverse('edit_search'), search.pk)
        self.assertTrue(edit_url in response.content)
Exemplo n.º 14
0
 def setUp(self):
     super(SavedSearchSendingTests, self).setUp()
     self.feed = 'http://rushenterprises-veterans.jobs/alabama/usa/jobs/feed/rss'
     self.saved_search = SavedSearchFactory(user=self.user, feed=self.feed,
                                            frequency='D')
     self.company = CompanyFactory()
     self.partner = PartnerFactory(owner=self.company)
     self.contact = ContactFactory(user=self.user,
                                   partner=self.partner)
     self.partner_search = PartnerSavedSearchFactory(user=self.user,
                                                     feed=self.feed,
                                                     frequency='D',
                                                     created_by=self.user,
                                                     provider=self.company,
                                                     partner=self.partner)
     mail.outbox = []
Exemplo n.º 15
0
    def test_partner_saved_search_delete_contact(self):
        """
        When a contact gets deleted, we should log it and disable any partner
        saved searches for that contact
        """
        user = UserFactory(email='*****@*****.**')
        self.contact.user = user
        self.contact.save()
        self.contact = Contact.objects.get(pk=self.contact.pk)
        owner = UserFactory(email='*****@*****.**')

        partner_saved_search = PartnerSavedSearchFactory(created_by=owner,
                                                         provider=self.company,
                                                         partner=self.partner,
                                                         user=user,
                                                         notes='')
        self.assertTrue(partner_saved_search.is_active)
        self.contact.delete()
        partner_saved_search = PartnerSavedSearch.objects.get(
            pk=partner_saved_search.pk)
        self.assertFalse(partner_saved_search.is_active)
        self.assertTrue(self.contact.name in partner_saved_search.notes)
Exemplo n.º 16
0
    def test_delete_all_searches(self):
        """
        Deleting all searches should only remove regular saved searches if the
        partner saved searches weren't created by the user trying to use it.
        """

        user = UserFactory(email='*****@*****.**')
        company = CompanyFactory(id=2423, name="Bacon Factory",
                                 user_created=False)
        SavedSearchFactory(user=self.user)
        pss = PartnerSavedSearchFactory(user=self.user, created_by=user,
                                        provider=company)

        response = self.client.get(reverse('delete_saved_search') +
            '?id=ALL')

        self.assertEqual(response.status_code, 302)
        # partner saved search should still exist...
        self.assertTrue(models.PartnerSavedSearch.objects.filter(
            pk=pss.pk).exists())
        # ... but the regular saved search shouldn't
        self.assertFalse(models.SavedSearch.objects.filter(
            partnersavedsearch__isnull=True).exists())
Exemplo n.º 17
0
class SavedSearchSendingTests(MyJobsBase):
    def setUp(self):
        super(SavedSearchSendingTests, self).setUp()
        self.feed = 'http://rushenterprises-veterans.jobs/alabama/usa/jobs/feed/rss'
        self.user = UserFactory()
        self.saved_search = SavedSearchFactory(user=self.user, feed=self.feed,
                                               frequency='D')
        self.company = CompanyFactory()
        self.partner = PartnerFactory(owner=self.company)
        self.contact = ContactFactory(user=self.user,
                                      partner=self.partner)
        self.partner_search = PartnerSavedSearchFactory(user=self.user,
                                                        feed=self.feed,
                                                        frequency='D',
                                                        created_by=self.user,
                                                        provider=self.company,
                                                        partner=self.partner)
        mail.outbox = []

    @patch('urllib2.urlopen')
    def test_all_jobs_new(self, urlopen_mock):
        mock_obj = Mock()
        mock_obj.read.side_effect = [jobs, jobs, jobs]
        urlopen_mock.return_value = mock_obj

        three_days_ago = datetime.datetime.now() - datetime.timedelta(days=365)
        self.partner_search.last_sent = three_days_ago
        self.saved_search.last_sent = three_days_ago
        self.partner_search.save()
        self.saved_search.save()

        # All of the jobs were sent within the past year, so if we set
        # last_sent to one year ago all of the jobs should be old.
        self.saved_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top 3 jobs', email.body)

        self.partner_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top 3 jobs', email.body)

    @patch('urllib2.urlopen')
    def test_some_jobs_new(self, urlopen_mock):
        mock_obj = Mock()
        mock_obj.read.side_effect = [jobs, jobs, jobs]
        urlopen_mock.return_value = mock_obj

        three_days_ago = datetime.datetime.now() - datetime.timedelta(days=3)
        self.partner_search.last_sent = three_days_ago
        self.saved_search.last_sent = three_days_ago
        self.partner_search.save()
        self.saved_search.save()

        # One job was sent within the past 3 days, so if we set last_sent to
        # three days ago one of the jobs should be old.
        self.saved_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top job', email.body)

        self.partner_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top 3 jobs', email.body)

    @patch('urllib2.urlopen')
    def test_no_jobs_new(self, urlopen_mock):
        mock_obj = Mock()
        mock_obj.read.side_effect = [jobs, jobs, jobs]
        urlopen_mock.return_value = mock_obj

        self.partner_search.last_sent = datetime.datetime.now()
        self.saved_search.last_sent = datetime.datetime.now()
        self.partner_search.save()
        self.saved_search.save()

        # All jobs were sent over 2 days ago, so if we set last_sent to
        # today none of the jobs should be old.
        self.saved_search.send_email()
        self.assertEqual(len(mail.outbox), 0)

        self.partner_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top 3 jobs', email.body)

    @patch('urllib2.urlopen')
    def test_partner_saved_search_backfill(self, urlopen_mock):
        mock_obj = Mock()
        mock_obj.read.side_effect = [jobs, jobs, jobs, jobs, jobs, jobs]
        urlopen_mock.return_value = mock_obj

        # Make it so there should be no new jobs.
        self.partner_search.last_sent = datetime.datetime.now()
        self.partner_search.save()

        # jobs_per_email is default, so all 3 should get sent.
        self.partner_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top 3 jobs', email.body)

        self.partner_search.jobs_per_email = 2
        self.partner_search.save()
        self.partner_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top 2 jobs', email.body)

        self.partner_search.jobs_per_email = 1
        self.partner_search.save()
        self.partner_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top job', email.body)

    @patch('urllib2.urlopen')
    def test_no_jobs(self, urlopen_mock):
        mock_obj = Mock()
        mock_obj.read.side_effect = [no_jobs, no_jobs, no_jobs]
        urlopen_mock.return_value = mock_obj

        self.saved_search.send_email()
        self.assertEqual(len(mail.outbox), 0)

        self.partner_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('There are no results for today!', email.body)
Exemplo n.º 18
0
class PartnerSavedSearchTests(MyJobsBase):
    def setUp(self):
        super(PartnerSavedSearchTests, self).setUp()
        self.user = UserFactory()
        self.digest = SavedSearchDigestFactory(user=self.user)
        self.company = CompanyFactory()
        self.partner = PartnerFactory(owner=self.company)
        self.contact = ContactFactory(user=self.user,
                                      partner=self.partner)
        self.partner_search = PartnerSavedSearchFactory(user=self.user,
                                                        created_by=self.user,
                                                        provider=self.company,
                                                        partner=self.partner)
        # Partner searches are normally created with a form, which creates
        # invitations as a side effect. We're not testing the form, so we
        # can fake an invitation here.
        Invitation(invitee_email=self.partner_search.email,
                   invitee=self.partner_search.user,
                   inviting_user=self.partner_search.created_by,
                   inviting_company=self.partner_search.partner.owner,
                   added_saved_search=self.partner_search).save()

        self.patcher = patch('urllib2.urlopen', return_file())
        self.mock_urlopen = self.patcher.start()
        self.num_occurrences = lambda text, search_str: [match.start()
                                                         for match
                                                         in re.finditer(
                                                             search_str, text)]
        # classes and ids may get stripped out when pynliner inlines css.
        # all jobs contain a default (blank) icon, so we can search for that if
        # we want a job count
        self.job_icon = 'http://png.nlx.org/100x50/logo.gif'

    def tearDown(self):
        super(PartnerSavedSearchTests, self).tearDown()
        try:
            self.patcher.stop()
        except RuntimeError:
            # patcher was stopped in a test
            pass

    def test_send_partner_saved_search_as_saved_search(self):
        """
        When we send saved searches, we assume they are instances of SavedSearch
        and disregard any subclasses. Ensure that partner saved searches are
        correctly recorded as sent when this happens.
        """
        search = SavedSearch.objects.get(pk=self.partner_search.pk)
        mail.outbox = []
        self.assertEqual(ContactRecord.objects.count(), 1)
        self.partner_search.send_email()
        self.assertEqual(SavedSearchLog.objects.count(), 2)
        self.assertEqual(ContactRecord.objects.count(), 2)
        partner_record = ContactRecord.objects.all()[1]
        partner_email = mail.outbox.pop()

        search.send_email()
        self.assertEqual(SavedSearchLog.objects.count(), 3)
        self.assertEqual(ContactRecord.objects.count(), 3)
        search_record = ContactRecord.objects.all()[2]
        search_email = mail.outbox.pop()

        self.assertEqual(partner_record.notes, search_record.notes)
        self.assertEqual(partner_email.body, search_email.body)
        self.assertEqual(partner_record.notes, partner_email.body)
        self.assertFalse("Your resume is %s%% complete" %
                         self.user.profile_completion in partner_email.body)
        logs = SavedSearchLog.objects.all()[1:]
        for log in logs:
            self.assertTrue(log.was_sent)
            self.assertIsNotNone(log.contact_record)
        # These are separate contact records (different pks), but the notes
        # attached to each are identical.
        self.assertEqual(logs[0].contact_record.notes,
                         logs[1].contact_record.notes)

    def test_send_partner_saved_search_in_digest(self):
        """
        Saved search digests bypass the SavedSearch.send_email method. Ensure
        that partner saved searches are recorded when sent in a digest.
        """
        SavedSearchFactory(user=self.user)
        self.assertEqual(ContactRecord.objects.count(), 1)
        self.digest.send_email()
        self.assertEqual(SavedSearchLog.objects.count(), 2)
        self.assertEqual(ContactRecord.objects.count(), 2)
        email = mail.outbox[0]
        self.assertFalse("Your resume is %s%% complete" %
                         self.user.profile_completion in email.body)
        log = SavedSearchLog.objects.last()
        self.assertTrue(log.was_sent)

    def test_send_partner_saved_search_with_inactive_user(self):
        self.user.is_active = False
        self.user.save()
        mail.outbox = []
        self.partner_search.initial_email()
        email = mail.outbox.pop()
        self.assertTrue('Your account is not currently active.' in email.body)

        verify_url = get_activation_link(self.user)
        profile = ActivationProfile.objects.get(user=self.user,
                                                email=self.user.email)
        self.assertTrue(profile.activation_key in verify_url)
        self.assertTrue(self.user.user_guid in verify_url)
        self.assertTrue('https://secure.my.jobs%s' % verify_url
                        in email.body)

    def test_contact_record_created_by(self):
        ContactRecord.objects.all().delete()
        self.partner_search.initial_email()
        record = ContactRecord.objects.get()
        self.assertEqual(record.created_by, self.partner_search.created_by)

    def test_num_occurrences_instance_method(self):
        # quick sanity checks; searching for a string that doesn't exist
        # returns an empty list
        not_found = self.num_occurrences(
            'this is not the string you are looking for',
            self.job_icon)
        self.assertEqual(not_found, [])
        # searching for a string that does exist returns all starting indices
        # for the string
        found = self.num_occurrences(self.job_icon, self.job_icon)
        self.assertEqual(found, [0])

    def test_partner_saved_search_pads_results(self):
        """
        If a partner saved search results in less than the desired number of
        results, it should be padded with additional older results.
        """

        self.partner_search.send_email()
        partner_search_email = mail.outbox.pop()
        job_count = self.num_occurrences(partner_search_email.body,
                                         self.job_icon)
        self.assertEqual(len(job_count), 2)
        log = SavedSearchLog.objects.last()
        self.assertEqual(log.new_jobs, 1)
        self.assertEqual(log.backfill_jobs, 1)

    def test_saved_search_new_job_indicator(self):
        """
        Partner saved searches should include indicators for unseen jobs, while
        job seeker saved searches should not.
        """
        new_job_indicator = '>New! <'
        search = SavedSearchFactory(user=self.user)
        search.send_email()
        search_email = mail.outbox.pop()
        new_jobs = self.num_occurrences(search_email.body,
                                        new_job_indicator)
        self.assertEqual(len(new_jobs), 0)

        self.partner_search.send_email()
        partner_search_email = mail.outbox.pop()
        new_jobs = self.num_occurrences(partner_search_email.body,
                                        new_job_indicator)
        self.assertEqual(len(new_jobs), 1)

    def test_partner_saved_search_no_jobs(self):
        self.partner_search.feed = 'http://google.com'
        self.partner_search.save()
        self.partner_search.send_email()

        email = mail.outbox.pop()
        self.assertIn('There are no results for today!', email.body)

        # Confirm last_sent was updated even though there were no jobs.
        updated_search = SavedSearch.objects.get(pk=self.partner_search.pk)
        new_last_sent = updated_search.last_sent.replace(tzinfo=None)
        self.assertNotEqual(self.partner_search.last_sent, new_last_sent)

    def test_partner_saved_search_digest_no_jobs(self):
        self.digest.is_active = True
        self.digest.save()

        self.partner_search.feed = 'http://google.com'
        self.partner_search.save()
        self.partner_search.send_email()

        for x in range(1, 5):
            PartnerSavedSearchFactory(user=self.user, created_by=self.user,
                                      provider=self.company,
                                      feed='http://google.com',
                                      partner=self.partner)

        self.digest.send_email()

        email = mail.outbox.pop()
        self.assertEqual(email.body.count('There are no results for today!'), 5)

        # Confirm last_sent was updated on all searches even though there were
        # no jobs.
        kwargs = {
            'user': self.user,
            'last_sent__isnull': True,
        }
        self.assertEqual(SavedSearch.objects.filter(**kwargs).count(), 0)
Exemplo n.º 19
0
 def setUp(self):
     super(SavedSearchDeletionTests, self).setUp()
     self.creator = UserFactory(email='*****@*****.**')
     self.search = SavedSearchFactory(user=self.user)
     self.partner_search = PartnerSavedSearchFactory(
         user=self.user, created_by=self.creator)
Exemplo n.º 20
0
class PartnerSavedSearchTests(MyJobsBase):
    def setUp(self):
        super(PartnerSavedSearchTests, self).setUp()
        self.digest = SavedSearchDigestFactory(user=self.user)
        self.company = CompanyFactory()
        self.partner = PartnerFactory(owner=self.company)
        self.contact = ContactFactory(user=self.user, partner=self.partner)
        self.partner_search = PartnerSavedSearchFactory(user=self.user,
                                                        created_by=self.user,
                                                        provider=self.company,
                                                        partner=self.partner)
        # Partner searches are normally created with a form, which creates
        # invitations as a side effect. We're not testing the form, so we
        # can fake an invitation here.
        invitation = Invitation.objects.create(
            invitee_email=self.partner_search.email,
            invitee=self.partner_search.user,
            inviting_user=self.partner_search.created_by,
            inviting_company=self.partner_search.partner.owner,
            added_saved_search=self.partner_search)
        invitation.send(self.partner_search)

        self.num_occurrences = lambda text, search_str: [
            match.start() for match in re.finditer(search_str, text)
        ]
        # classes and ids may get stripped out when pynliner inlines css.
        # all jobs contain a default (blank) icon, so we can search for that if
        # we want a job count
        self.job_icon = 'http://png.nlx.org/100x50/logo.gif'

    def test_send_partner_saved_search_as_saved_search(self):
        """
        When we send saved searches, we assume they are instances of SavedSearch
        and disregard any subclasses. Ensure that partner saved searches are
        correctly recorded as sent when this happens.
        """
        search = SavedSearch.objects.get(pk=self.partner_search.pk)
        mail.outbox = []
        self.assertEqual(ContactRecord.objects.count(), 1)
        self.partner_search.send_email()
        self.assertEqual(SavedSearchLog.objects.count(), 2)
        self.assertEqual(ContactRecord.objects.count(), 2)
        partner_record = ContactRecord.objects.all()[1]
        partner_email = mail.outbox.pop()

        search.send_email()
        self.assertEqual(SavedSearchLog.objects.count(), 3)
        self.assertEqual(ContactRecord.objects.count(), 3)
        search_record = ContactRecord.objects.all()[2]
        search_email = mail.outbox.pop()

        self.assertEqual(partner_record.notes, search_record.notes)
        self.assertEqual(partner_email.body, search_email.body)
        self.assertEqual(partner_record.notes, partner_email.body)
        self.assertFalse("Your profile is %s%% complete" %
                         self.user.profile_completion in partner_email.body)
        logs = SavedSearchLog.objects.all()[1:]
        for log in logs:
            self.assertTrue(log.was_sent)
            self.assertIsNotNone(log.contact_record)
        # These are separate contact records (different pks), but the notes
        # attached to each are identical.
        self.assertEqual(logs[0].contact_record.notes,
                         logs[1].contact_record.notes)

    def test_send_partner_saved_search_in_digest(self):
        """
        Saved search digests bypass the SavedSearch.send_email method. Ensure
        that partner saved searches are recorded when sent in a digest.
        """
        SavedSearchFactory(user=self.user)
        self.assertEqual(ContactRecord.objects.count(), 1)
        self.digest.send_email()
        self.assertEqual(SavedSearchLog.objects.count(), 2)
        self.assertEqual(ContactRecord.objects.count(), 2)
        email = mail.outbox[0]
        self.assertFalse("Your profile is %s%% complete" %
                         self.user.profile_completion in email.body)
        log = SavedSearchLog.objects.last()
        self.assertTrue(log.was_sent)

    def test_send_partner_saved_search_with_inactive_user(self):
        self.user.is_active = False
        self.user.save()
        mail.outbox = []
        self.partner_search.initial_email()
        email = mail.outbox.pop()
        self.assertTrue('Your account is not currently active.' in email.body)

        verify_url = get_activation_link(self.user)
        profile = ActivationProfile.objects.get(user=self.user,
                                                email=self.user.email)
        self.assertTrue(profile.activation_key in verify_url)
        self.assertTrue(self.user.user_guid in verify_url)
        self.assertTrue('https://secure.my.jobs%s' % verify_url in email.body)

    def test_contact_record_created_by(self):
        ContactRecord.objects.all().delete()
        self.partner_search.initial_email()
        record = ContactRecord.objects.get()
        self.assertEqual(record.created_by, self.partner_search.created_by)

    def test_num_occurrences_instance_method(self):
        # quick sanity checks; searching for a string that doesn't exist
        # returns an empty list
        not_found = self.num_occurrences(
            'this is not the string you are looking for', self.job_icon)
        self.assertEqual(not_found, [])
        # searching for a string that does exist returns all starting indices
        # for the string
        found = self.num_occurrences(self.job_icon, self.job_icon)
        self.assertEqual(found, [0])

    def test_partner_saved_search_pads_results(self):
        """
        If a partner saved search results in less than the desired number of
        results, it should be padded with additional older results.
        """

        self.partner_search.send_email()
        partner_search_email = mail.outbox.pop()
        job_count = self.num_occurrences(partner_search_email.body,
                                         self.job_icon)
        self.assertEqual(len(job_count), 2)
        log = SavedSearchLog.objects.last()
        self.assertEqual(log.new_jobs, 1)
        self.assertEqual(log.backfill_jobs, 1)

    def test_saved_search_new_job_indicator(self):
        """
        Partner saved searches should include indicators for unseen jobs, while
        job seeker saved searches should not.
        """
        new_job_indicator = '>New! <'
        search = SavedSearchFactory(user=self.user)
        search.send_email()
        search_email = mail.outbox.pop()
        new_jobs = self.num_occurrences(search_email.body, new_job_indicator)
        self.assertEqual(len(new_jobs), 0)

        self.partner_search.send_email()
        partner_search_email = mail.outbox.pop()
        new_jobs = self.num_occurrences(partner_search_email.body,
                                        new_job_indicator)
        self.assertEqual(len(new_jobs), 1)

    def test_partner_saved_search_no_jobs(self):
        self.partner_search.feed = 'http://google.com'
        self.partner_search.save()
        self.partner_search.send_email()

        email = mail.outbox.pop()
        self.assertIn('There are no results for today!', email.body)

        # Confirm last_sent was updated even though there were no jobs.
        updated_search = SavedSearch.objects.get(pk=self.partner_search.pk)
        new_last_sent = updated_search.last_sent.replace(tzinfo=None)
        self.assertNotEqual(self.partner_search.last_sent, new_last_sent)

    def test_partner_saved_search_digest_no_jobs(self):
        self.digest.is_active = True
        self.digest.save()

        self.partner_search.feed = 'http://google.com'
        self.partner_search.save()
        self.partner_search.send_email()

        for x in range(1, 5):
            PartnerSavedSearchFactory(user=self.user,
                                      created_by=self.user,
                                      provider=self.company,
                                      feed='http://google.com',
                                      partner=self.partner)

        self.digest.send_email()

        email = mail.outbox.pop()
        self.assertEqual(email.body.count('There are no results for today!'),
                         5)

        # Confirm last_sent was updated on all searches even though there were
        # no jobs.
        kwargs = {
            'user': self.user,
            'last_sent__isnull': True,
        }
        self.assertEqual(SavedSearch.objects.filter(**kwargs).count(), 0)

    @freeze_time("2016-10-01 10:01:00")
    def test_send_pss_after_10(self):
        """
        Ensures that partner saved searches that are created and scheduled for
        today are sent immediately if they are saved after the batch sending
        process begins.
        """
        company = CompanyFactory()
        partner = PartnerFactory(owner=company)

        communication_records = ContactRecord.objects.count()

        # The act of creating a daily partner saved search after 10 AM should
        # send the saved search being created.
        PartnerSavedSearchFactory(user=self.user,
                                  created_by=self.user,
                                  provider=company,
                                  partner=partner,
                                  frequency='D')

        self.assertEqual(ContactRecord.objects.count(),
                         communication_records + 1,
                         msg=("No communication record after "
                              "daily search creation"))

        today = datetime.date.today()

        # Creating a weekly partner saved search with a day_of_week of today
        # should send the saved search on save.
        PartnerSavedSearchFactory(user=self.user,
                                  created_by=self.user,
                                  provider=company,
                                  partner=partner,
                                  frequency='W',
                                  day_of_week=today.isoweekday())

        self.assertEqual(ContactRecord.objects.count(),
                         communication_records + 2,
                         msg=("No communication record after "
                              "weekly search creation"))

        PartnerSavedSearchFactory(user=self.user,
                                  created_by=self.user,
                                  provider=company,
                                  partner=partner,
                                  frequency='M',
                                  day_of_month=today.day)

        self.assertEqual(ContactRecord.objects.count(),
                         communication_records + 3,
                         msg=("No communication record after "
                              "monthly search creation"))
Exemplo n.º 21
0
class SavedSearchSendingTests(MyJobsBase):
    def setUp(self):
        super(SavedSearchSendingTests, self).setUp()
        self.feed = 'http://rushenterprises-veterans.jobs/alabama/usa/jobs/feed/rss'
        self.saved_search = SavedSearchFactory(user=self.user,
                                               feed=self.feed,
                                               frequency='D')
        self.company = CompanyFactory()
        self.partner = PartnerFactory(owner=self.company)
        self.contact = ContactFactory(user=self.user, partner=self.partner)
        self.partner_search = PartnerSavedSearchFactory(user=self.user,
                                                        feed=self.feed,
                                                        frequency='D',
                                                        created_by=self.user,
                                                        provider=self.company,
                                                        partner=self.partner)
        mail.outbox = []

    @patch('urllib2.urlopen')
    def test_all_jobs_new(self, urlopen_mock):
        mock_obj = Mock()
        mock_obj.read.side_effect = [jobs, jobs, jobs]
        urlopen_mock.return_value = mock_obj

        three_days_ago = datetime.datetime.now() - datetime.timedelta(days=365)
        self.partner_search.last_sent = three_days_ago
        self.saved_search.last_sent = three_days_ago
        self.partner_search.save()
        self.saved_search.save()

        # All of the jobs were sent within the past year, so if we set
        # last_sent to one year ago all of the jobs should be old.
        self.saved_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top 3 jobs', email.body)

        self.partner_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top 3 jobs', email.body)

    @patch('urllib2.urlopen')
    def test_some_jobs_new(self, urlopen_mock):
        mock_obj = Mock()
        mock_obj.read.side_effect = [jobs, jobs, jobs]
        urlopen_mock.return_value = mock_obj

        three_days_ago = datetime.datetime.now() - datetime.timedelta(days=3)
        self.partner_search.last_sent = three_days_ago
        self.saved_search.last_sent = three_days_ago
        self.partner_search.save()
        self.saved_search.save()

        # One job was sent within the past 3 days, so if we set last_sent to
        # three days ago one of the jobs should be old.
        self.saved_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top job', email.body)

        self.partner_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top 3 jobs', email.body)

    @patch('urllib2.urlopen')
    def test_no_jobs_new(self, urlopen_mock):
        mock_obj = Mock()
        mock_obj.read.side_effect = [jobs, jobs, jobs]
        urlopen_mock.return_value = mock_obj

        self.partner_search.last_sent = datetime.datetime.now()
        self.saved_search.last_sent = datetime.datetime.now()
        self.partner_search.save()
        self.saved_search.save()

        # All jobs were sent over 2 days ago, so if we set last_sent to
        # today none of the jobs should be old.
        self.saved_search.send_email()
        self.assertEqual(len(mail.outbox), 0)

        self.partner_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top 3 jobs', email.body)

    @patch('urllib2.urlopen')
    def test_partner_saved_search_backfill(self, urlopen_mock):
        mock_obj = Mock()
        mock_obj.read.side_effect = [jobs, jobs, jobs, jobs, jobs, jobs]
        urlopen_mock.return_value = mock_obj

        # Make it so there should be no new jobs.
        self.partner_search.last_sent = datetime.datetime.now()
        self.partner_search.save()

        # jobs_per_email is default, so all 3 should get sent.
        self.partner_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top 3 jobs', email.body)

        self.partner_search.jobs_per_email = 2
        self.partner_search.save()
        self.partner_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top 2 jobs', email.body)

        self.partner_search.jobs_per_email = 1
        self.partner_search.save()
        self.partner_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('Showing the top job', email.body)

    @patch('urllib2.urlopen')
    def test_no_jobs(self, urlopen_mock):
        mock_obj = Mock()
        mock_obj.read.side_effect = [no_jobs, no_jobs, no_jobs]
        urlopen_mock.return_value = mock_obj

        self.saved_search.send_email()
        self.assertEqual(len(mail.outbox), 0)

        self.partner_search.send_email()
        email = mail.outbox.pop()
        self.assertIn('There are no results for today!', email.body)