290 lines
8.3 KiB
ReStructuredText
290 lines
8.3 KiB
ReStructuredText
Marketing Automation Scenario
|
|
=============================
|
|
|
|
Imports::
|
|
|
|
>>> import datetime
|
|
>>> import re
|
|
>>> from unittest.mock import patch
|
|
|
|
>>> from proteus import Model
|
|
>>> from trytond.modules.marketing_automation import marketing_automation
|
|
>>> from trytond.pyson import Eval, PYSONEncoder
|
|
>>> from trytond.tests.tools import (
|
|
... activate_modules, assertEqual, assertIn, assertTrue)
|
|
>>> from trytond.tools import file_open
|
|
|
|
Patch send_message_transactional::
|
|
|
|
>>> smtp_calls = patch.object(
|
|
... marketing_automation, 'send_message_transactional').start()
|
|
>>> manager = patch.object(
|
|
... marketing_automation, 'SMTPDataManager').start()
|
|
|
|
Activate modules::
|
|
|
|
>>> config = activate_modules('marketing_automation')
|
|
|
|
>>> Email = Model.get('ir.email')
|
|
>>> ReportingScenario = Model.get('marketing.automation.reporting.scenario')
|
|
>>> ReportingActivity = Model.get('marketing.automation.reporting.activity')
|
|
|
|
Create a party::
|
|
|
|
>>> Party = Model.get('party.party')
|
|
>>> party = Party()
|
|
>>> party.name = "Michael Scott"
|
|
>>> contact = party.contact_mechanisms.new()
|
|
>>> contact.type = 'email'
|
|
>>> contact.value = 'michael@example.com'
|
|
>>> party.save()
|
|
|
|
Create the running scenario::
|
|
|
|
>>> Scenario = Model.get('marketing.automation.scenario')
|
|
>>> Activity = Model.get('marketing.automation.activity')
|
|
>>> scenario = Scenario()
|
|
>>> scenario.name = "Party Scenario"
|
|
>>> scenario.model = 'party.party'
|
|
>>> scenario.domain = '[["contact_mechanisms", "!=", null]]'
|
|
>>> scenario.save()
|
|
|
|
>>> root_activity = Activity()
|
|
>>> root_activity.name = "First email"
|
|
>>> root_activity.parent = scenario
|
|
>>> root_activity.action = 'send_email'
|
|
>>> root_activity.email_title = "Hello"
|
|
>>> root_activity.condition = PYSONEncoder().encode(
|
|
... Eval('self', {}).get('active'))
|
|
>>> with file_open('marketing_automation/tests/email.html', mode='r') as fp:
|
|
... root_activity.email_template = fp.read()
|
|
>>> root_activity.save()
|
|
|
|
>>> email_opened = Activity()
|
|
>>> email_opened.name = "Email Opened"
|
|
>>> email_opened.parent = root_activity
|
|
>>> email_opened.on = 'email_opened'
|
|
>>> email_opened.save()
|
|
|
|
>>> email_clicked = Activity()
|
|
>>> email_clicked.name = "Email Clicked"
|
|
>>> email_clicked.parent = root_activity
|
|
>>> email_clicked.on = 'email_clicked'
|
|
>>> email_clicked.save()
|
|
|
|
>>> email_not_clicked = Activity()
|
|
>>> email_not_clicked.name = "Email no clicked"
|
|
>>> email_not_clicked.parent = root_activity
|
|
>>> email_not_clicked.on = 'email_clicked_not'
|
|
>>> email_not_clicked.delay = datetime.timedelta(days=2)
|
|
>>> email_not_clicked.save()
|
|
|
|
>>> email_reminder = Activity()
|
|
>>> email_reminder.name = "Email Reminder"
|
|
>>> email_reminder.parent = root_activity
|
|
>>> email_reminder.action = 'send_email'
|
|
>>> email_reminder.email_title = "Reminder"
|
|
>>> email_reminder.delay = datetime.timedelta()
|
|
>>> with file_open('marketing_automation/tests/reminder.html', mode='r') as fp:
|
|
... email_reminder.email_template = fp.read()
|
|
>>> email_reminder.save()
|
|
|
|
>>> scenario.record_count
|
|
1
|
|
|
|
>>> scenario.click('run')
|
|
|
|
Trigger scenario::
|
|
|
|
>>> Cron = Model.get('ir.cron')
|
|
>>> cron_trigger, = Cron.find([
|
|
... ('method', '=', 'marketing.automation.scenario|trigger'),
|
|
... ])
|
|
>>> cron_process, = Cron.find([
|
|
... ('method', '=', 'marketing.automation.record.activity|process'),
|
|
... ])
|
|
>>> cron_trigger.click('run_once')
|
|
>>> cron_process.click('run_once')
|
|
|
|
>>> Record = Model.get('marketing.automation.record')
|
|
>>> record, = Record.find([])
|
|
>>> assertEqual(record.record, party)
|
|
>>> scenario.record_count
|
|
1
|
|
>>> scenario.record_count_blocked
|
|
0
|
|
>>> scenario.block_rate
|
|
0.0
|
|
>>> bool(scenario.block_rate_trend)
|
|
True
|
|
|
|
>>> reporting, = ReportingScenario.find([])
|
|
>>> reporting.record_count
|
|
1
|
|
>>> reporting.record_count_blocked
|
|
0
|
|
>>> reporting.block_rate
|
|
0.0
|
|
|
|
Check email sent::
|
|
|
|
>>> ShortenedURL = Model.get('web.shortened_url')
|
|
>>> open_url, = ShortenedURL.find([
|
|
... ('redirect_url', 'like', '%/m/empty.gif'),
|
|
... ])
|
|
>>> click_url, = ShortenedURL.find([
|
|
... ('redirect_url', '=', 'http://example.com/action'),
|
|
... ])
|
|
|
|
>>> RecordActivity = Model.get('marketing.automation.record.activity')
|
|
>>> record_activity, = RecordActivity.find([
|
|
... ('record', '=', record.id),
|
|
... ('activity', '=', root_activity.id),
|
|
... ])
|
|
>>> record_activity.state
|
|
'done'
|
|
>>> root_activity.reload()
|
|
>>> root_activity.record_count
|
|
1
|
|
|
|
>>> smtp_calls.call_count
|
|
1
|
|
>>> msg, = smtp_calls.call_args[0]
|
|
>>> smtp_calls.reset_mock()
|
|
>>> msg = msg.get_body().get_content()
|
|
>>> assertEqual(re.search(r'Hello, (.*)!', msg).group(1), party.name)
|
|
>>> open_url.shortened_url in msg
|
|
True
|
|
>>> assertEqual(open_url.record, record_activity)
|
|
>>> open_url.method
|
|
'marketing.automation.record.activity|on_email_opened'
|
|
>>> click_url.shortened_url in msg
|
|
True
|
|
>>> assertEqual(click_url.record, record_activity)
|
|
>>> click_url.method
|
|
'marketing.automation.record.activity|on_email_clicked'
|
|
>>> assertIn(record.uuid, msg)
|
|
|
|
>>> email, = Email.find([])
|
|
>>> email.recipients
|
|
'Michael Scott <michael@example.com>'
|
|
>>> email.subject
|
|
'Hello'
|
|
>>> email.resource == party
|
|
True
|
|
>>> assertEqual(email.marketing_automation_activity, root_activity)
|
|
>>> assertTrue(email.marketing_automation_record)
|
|
|
|
Trigger open email and reminder after delay::
|
|
|
|
>>> record_activity.click('on_email_opened')
|
|
|
|
>>> open_activity, = RecordActivity.find([
|
|
... ('record', '=', record.id),
|
|
... ('activity', '=', email_opened.id),
|
|
... ])
|
|
>>> bool(open_activity.at)
|
|
True
|
|
>>> open_activity.state
|
|
'waiting'
|
|
|
|
>>> cron_process.click('run_once')
|
|
|
|
>>> open_activity.reload()
|
|
>>> open_activity.state
|
|
'done'
|
|
>>> root_activity.reload()
|
|
>>> root_activity.email_opened
|
|
1
|
|
>>> root_activity.email_opened
|
|
1
|
|
>>> root_activity.email_clicked
|
|
0
|
|
>>> root_activity.email_open_rate
|
|
1.0
|
|
>>> bool(root_activity.email_open_rate_trend)
|
|
True
|
|
>>> root_activity.email_click_rate
|
|
0.0
|
|
>>> bool(root_activity.email_click_rate_trend)
|
|
True
|
|
>>> root_activity.email_click_through_rate
|
|
0.0
|
|
>>> bool(root_activity.email_click_through_rate_trend)
|
|
True
|
|
|
|
>>> reporting, = ReportingActivity.find([
|
|
... ('activity', '=', root_activity.id),
|
|
... ])
|
|
>>> reporting.activity_action
|
|
'send_email'
|
|
>>> reporting.record_count
|
|
1
|
|
>>> reporting.email_opened
|
|
1
|
|
>>> reporting.email_clicked
|
|
0
|
|
>>> reporting.email_open_rate
|
|
1.0
|
|
>>> reporting.email_click_rate
|
|
0.0
|
|
>>> reporting.email_click_through_rate
|
|
0.0
|
|
|
|
>>> email_reminder, = RecordActivity.find([
|
|
... ('record', '=', record.id),
|
|
... ('activity', '=', email_reminder.id),
|
|
... ])
|
|
>>> email_reminder.state
|
|
'done'
|
|
|
|
>>> smtp_calls.call_count
|
|
1
|
|
>>> smtp_calls.reset_mock()
|
|
|
|
Trigger click email::
|
|
|
|
>>> record_activity.click('on_email_clicked')
|
|
>>> cron_process.click('run_once')
|
|
|
|
>>> clicked_activity, = RecordActivity.find([
|
|
... ('record', '=', record.id),
|
|
... ('activity', '=', email_clicked.id),
|
|
... ])
|
|
>>> clicked_activity.state
|
|
'done'
|
|
>>> root_activity.reload()
|
|
>>> root_activity.record_count
|
|
1
|
|
>>> root_activity.email_opened
|
|
1
|
|
>>> root_activity.email_clicked
|
|
1
|
|
>>> root_activity.email_open_rate
|
|
1.0
|
|
>>> root_activity.email_click_rate
|
|
1.0
|
|
>>> root_activity.email_click_through_rate
|
|
1.0
|
|
|
|
>>> reporting.reload()
|
|
>>> reporting.record_count
|
|
1
|
|
>>> reporting.email_opened
|
|
1
|
|
>>> reporting.email_clicked
|
|
1
|
|
>>> reporting.email_open_rate
|
|
1.0
|
|
>>> reporting.email_click_rate
|
|
1.0
|
|
>>> reporting.email_click_through_rate
|
|
1.0
|
|
|
|
>>> not_clicked_activity, = RecordActivity.find([
|
|
... ('record', '=', record.id),
|
|
... ('activity', '=', email_not_clicked.id),
|
|
... ])
|
|
>>> not_clicked_activity.state
|
|
'cancelled'
|