Esempio n. 1
0
    def test_open_tracking(self):
        campaign = Campaign.objects.create(message_content_html=HTML_MESSAGE,
                                           message_content_text="Test")
        subscriber = Subscriber.objects.get(email="*****@*****.**")
        event = campaign.get_event_for_subscriber(subscriber)
        message = message_for_event(event)

        tracking_id = event.tracking_id
        tracking_url = reverse("nuntius_track_open",
                               kwargs={"tracking_id": tracking_id})

        self.assertIn(
            '<img src="{}" width="1" height="1" alt="nt">'.format(
                IMAGES_URL + tracking_url),
            str(message.message()),
        )

        for i in range(2):
            self.client.get(tracking_url)

        self.assertEqual(
            2,
            CampaignSentEvent.objects.get(email="*****@*****.**").open_count,
            campaign.get_open_count(),
        )
        self.assertEqual(1, campaign.get_unique_open_count())
Esempio n. 2
0
def email_campaign_manager_process(
    *, campaign: Campaign, queue: mp.Queue, quit_event: mp.Event
):
    """
    Main function of the process responsible for scheduling the sending of campaigns

    :param campaign: the campaign for which messages must be sent
    :type campaign: :class:`nuntius.models.Campaign`

    :param queue: the work queue on which email messages are put
    :type queue: : class:`multiprocessing.Queue`

    :param quit_event: an event that may be used by the main process to tell the manager it needs to quit
    :type quit_event: class:`multiprocessing.Event`
    """
    queryset = campaign.get_subscribers_queryset()
    # eliminate people who already received the message
    queryset = queryset.annotate(
        already_sent=Exists(
            CampaignSentEvent.objects.filter(
                subscriber_id=OuterRef("pk"), campaign_id=campaign.id
            ).exclude(result=CampaignSentStatusType.PENDING)
        )
    ).filter(already_sent=False)

    campaign_finished = False

    for subscriber in queryset.iterator():
        if quit_event.is_set():
            break

        if subscriber.get_subscriber_status() != AbstractSubscriber.STATUS_SUBSCRIBED:
            continue

        sent_event = campaign.get_event_for_subscriber(subscriber)

        # just in case there is another nuntius_worker started, but this should not happen
        if sent_event.result != CampaignSentStatusType.PENDING:
            continue

        message = message_for_event(sent_event)

        try:
            put_in_queue_or_quit(
                queue,
                (message, sent_event.id),
                event=quit_event,
                polling_period=app_settings.POLLING_INTERVAL,
            )
        except GracefulExit:
            break
    else:
        campaign_finished = True

    queue.close()
    queue.join_thread()
    # everything has been scheduled for sending:
    if campaign_finished:
        campaign.status = Campaign.STATUS_SENT
        campaign.save()
Esempio n. 3
0
    def test_send_emails(self):
        segment = Segment.objects.get(id="subscribed")
        campaign = Campaign.objects.create(
            segment=segment,
            message_from_email="*****@*****.**",
            message_from_name="Test sender",
            message_subject="Subject",
            message_content_text="test {{email}} test",
        )
        subscribers = segment.get_subscribers_queryset()
        events = [campaign.get_event_for_subscriber(s) for s in subscribers]
        messages = [message_for_event(e) for e in events]

        run_sender_process_sync(zip(messages, (e.id for e in events)))

        self.assertEqual(len(events), len(mail.outbox))
        self.assertEqual(len(events), campaign.get_sent_count())
Esempio n. 4
0
    def test_correctly_generate_text_only_message_from_subscriber(self):
        campaign = Campaign.objects.create(
            message_from_email="*****@*****.**",
            message_subject="Nice campaign",
            message_content_text="Here's some text for you {{ email }} !",
        )

        subscriber = Subscriber.objects.get(email="*****@*****.**")
        event = campaign.get_event_for_subscriber(subscriber)
        message = message_for_event(event)

        self.assertIsInstance(message, EmailMessage)
        self.assertEqual(message.subject, "Nice campaign")
        self.assertEqual(message.from_email, "*****@*****.**")
        self.assertEqual(message.to, [subscriber.email])
        self.assertEqual(message.body,
                         "Here's some text for you [email protected] !")
        self.assertEqual(message.content_subtype, "plain")
Esempio n. 5
0
    def test_link_tracking(self):
        campaign = Campaign.objects.create(
            message_content_html=HTML_MESSAGE,
            message_content_text="Test",
            utm_name="tracked_campaign",
        )
        subscriber = Subscriber.objects.get(email="*****@*****.**")
        event = campaign.get_event_for_subscriber(subscriber)
        message = message_for_event(event)

        tracking_id = event.tracking_id
        encoded_tracking_query = "?utm_content=link-0&utm_term="
        tracking_url = reverse(
            "nuntius_track_click",
            kwargs={
                "tracking_id":
                tracking_id,
                "signature":
                sign_url(campaign, EXTERNAL_LINK + encoded_tracking_query),
                "link":
                url_quote(EXTERNAL_LINK + encoded_tracking_query, safe=""),
            },
        )

        self.assertIn(
            '<a href="{}">Link</a>'.format(LINKS_URL + tracking_url),
            str(message.message()),
        )

        for i in range(2):
            res = self.client.get(tracking_url)

        self.assertRedirects(
            res,
            EXTERNAL_LINK +
            "?utm_campaign=tracked_campaign&utm_content=link-0&utm_source=nuntius&utm_medium=email",
            fetch_redirect_response=False,
        )
        self.assertEqual(
            2,
            CampaignSentEvent.objects.get(email="*****@*****.**").click_count,
            campaign.get_click_count(),
        )