mirror of https://github.com/OCA/social.git
[MIG] mail_tracking
* Improve tests * Show trackings even if partner removed * Disable CSRF protection to webhooks controllerspull/269/head
parent
6585c28029
commit
2a16997c1c
|
@ -63,7 +63,7 @@ These are all available status icons:
|
||||||
|
|
||||||
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
.. image:: https://odoo-community.org/website/image/ir.attachment/5784_f2813bd/datas
|
||||||
:alt: Try me on Runbot
|
:alt: Try me on Runbot
|
||||||
:target: https://runbot.odoo-community.org/runbot/205/8.0
|
:target: https://runbot.odoo-community.org/runbot/205/9.0
|
||||||
|
|
||||||
If you want to see all tracking emails and events you can go to
|
If you want to see all tracking emails and events you can go to
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
{
|
{
|
||||||
"name": "Email tracking",
|
"name": "Email tracking",
|
||||||
"summary": "Email tracking system for all mails sent",
|
"summary": "Email tracking system for all mails sent",
|
||||||
"version": "8.0.2.0.1",
|
"version": "9.0.1.0.0",
|
||||||
"category": "Social Network",
|
"category": "Social Network",
|
||||||
"website": "http://www.tecnativa.com",
|
"website": "http://www.tecnativa.com",
|
||||||
"author": "Tecnativa, "
|
"author": "Tecnativa, "
|
||||||
|
|
|
@ -36,7 +36,7 @@ class MailTrackingController(http.Controller):
|
||||||
}
|
}
|
||||||
|
|
||||||
@http.route('/mail/tracking/all/<string:db>',
|
@http.route('/mail/tracking/all/<string:db>',
|
||||||
type='http', auth='none')
|
type='http', auth='none', csrf=False)
|
||||||
def mail_tracking_all(self, db, **kw):
|
def mail_tracking_all(self, db, **kw):
|
||||||
env = _env_get(db)
|
env = _env_get(db)
|
||||||
if not env:
|
if not env:
|
||||||
|
@ -49,7 +49,7 @@ class MailTrackingController(http.Controller):
|
||||||
return response
|
return response
|
||||||
|
|
||||||
@http.route('/mail/tracking/event/<string:db>/<string:event_type>',
|
@http.route('/mail/tracking/event/<string:db>/<string:event_type>',
|
||||||
type='http', auth='none')
|
type='http', auth='none', csrf=False)
|
||||||
def mail_tracking_event(self, db, event_type, **kw):
|
def mail_tracking_event(self, db, event_type, **kw):
|
||||||
env = _env_get(db)
|
env = _env_get(db)
|
||||||
if not env:
|
if not env:
|
||||||
|
|
|
@ -12,8 +12,7 @@ from openerp import models, api, fields
|
||||||
class MailMail(models.Model):
|
class MailMail(models.Model):
|
||||||
_inherit = 'mail.mail'
|
_inherit = 'mail.mail'
|
||||||
|
|
||||||
@api.model
|
def _tracking_email_prepare(self, partner, email):
|
||||||
def _tracking_email_prepare(self, mail, partner, email):
|
|
||||||
ts = time.time()
|
ts = time.time()
|
||||||
dt = datetime.utcfromtimestamp(ts)
|
dt = datetime.utcfromtimestamp(ts)
|
||||||
email_to_list = email.get('email_to', [])
|
email_to_list = email.get('email_to', [])
|
||||||
|
@ -22,22 +21,16 @@ class MailMail(models.Model):
|
||||||
'name': email.get('subject', False),
|
'name': email.get('subject', False),
|
||||||
'timestamp': '%.6f' % ts,
|
'timestamp': '%.6f' % ts,
|
||||||
'time': fields.Datetime.to_string(dt),
|
'time': fields.Datetime.to_string(dt),
|
||||||
'mail_id': mail.id if mail else False,
|
'mail_id': self.id,
|
||||||
'mail_message_id': mail.mail_message_id.id if mail else False,
|
'mail_message_id': self.mail_message_id.id,
|
||||||
'partner_id': partner.id if partner else False,
|
'partner_id': partner.id if partner else False,
|
||||||
'recipient': email_to,
|
'recipient': email_to,
|
||||||
'sender': mail.email_from,
|
'sender': self.email_from,
|
||||||
}
|
}
|
||||||
|
|
||||||
@api.model
|
@api.multi
|
||||||
def send_get_email_dict(self, mail, partner=None):
|
def send_get_email_dict(self, partner=None):
|
||||||
email = super(MailMail, self).send_get_email_dict(
|
email = super(MailMail, self).send_get_email_dict(partner=partner)
|
||||||
mail, partner=partner)
|
vals = self._tracking_email_prepare(partner, email)
|
||||||
m_tracking = self.env['mail.tracking.email']
|
tracking_email = self.env['mail.tracking.email'].sudo().create(vals)
|
||||||
tracking_email = False
|
return tracking_email.tracking_img_add(email)
|
||||||
if mail:
|
|
||||||
vals = self._tracking_email_prepare(mail, partner, email)
|
|
||||||
tracking_email = m_tracking.sudo().create(vals)
|
|
||||||
if tracking_email:
|
|
||||||
email = tracking_email.tracking_img_add(email)
|
|
||||||
return email
|
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
|
||||||
|
|
||||||
from openerp import models, api
|
from openerp import models, api
|
||||||
import logging
|
|
||||||
_logger = logging.getLogger(__name__)
|
|
||||||
|
|
||||||
|
|
||||||
class MailMessage(models.Model):
|
class MailMessage(models.Model):
|
||||||
|
@ -33,22 +31,49 @@ class MailMessage(models.Model):
|
||||||
status = tracking_status_map.get(tracking_email_status, 'unknown')
|
status = tracking_status_map.get(tracking_email_status, 'unknown')
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
@api.multi
|
||||||
|
def tracking_status(self):
|
||||||
|
res = {}
|
||||||
|
for message in self:
|
||||||
|
partner_trackings = []
|
||||||
|
partners_already = self.env['res.partner']
|
||||||
|
partners = self.env['res.partner']
|
||||||
|
trackings = self.env['mail.tracking.email'].search([
|
||||||
|
('mail_message_id', '=', message.id),
|
||||||
|
])
|
||||||
|
# Search all trackings for this message
|
||||||
|
for tracking in trackings:
|
||||||
|
status = self._partner_tracking_status_get(tracking)
|
||||||
|
recipient = (
|
||||||
|
tracking.partner_id.display_name or tracking.recipient)
|
||||||
|
partner_trackings.append((
|
||||||
|
status, tracking.id, recipient, tracking.partner_id.id))
|
||||||
|
if tracking.partner_id:
|
||||||
|
partners_already |= tracking.partner_id
|
||||||
|
# Search all recipients for this message
|
||||||
|
if message.partner_ids:
|
||||||
|
partners |= message.partner_ids
|
||||||
|
if message.needaction_partner_ids:
|
||||||
|
partners |= message.needaction_partner_ids
|
||||||
|
# Remove recipients already included
|
||||||
|
partners -= partners_already
|
||||||
|
for partner in partners:
|
||||||
|
# If there is partners not included, then status is 'unknown'
|
||||||
|
partner_trackings.append((
|
||||||
|
'unknown', False, partner.display_name, partner.id))
|
||||||
|
res[message.id] = partner_trackings
|
||||||
|
return res
|
||||||
|
|
||||||
@api.model
|
@api.model
|
||||||
def _message_read_dict_postprocess(self, messages, message_tree):
|
def _message_read_dict_postprocess(self, messages, message_tree):
|
||||||
res = super(MailMessage, self)._message_read_dict_postprocess(
|
res = super(MailMessage, self)._message_read_dict_postprocess(
|
||||||
messages, message_tree)
|
messages, message_tree)
|
||||||
|
mail_message_ids = {m.get('id') for m in messages if m.get('id')}
|
||||||
|
mail_messages = self.browse(mail_message_ids)
|
||||||
|
partner_trackings = mail_messages.tracking_status()
|
||||||
for message_dict in messages:
|
for message_dict in messages:
|
||||||
mail_message_id = message_dict.get('id', False)
|
mail_message_id = message_dict.get('id', False)
|
||||||
if mail_message_id:
|
if mail_message_id:
|
||||||
partner_trackings = {}
|
message_dict['partner_trackings'] = \
|
||||||
for partner in message_dict.get('partner_ids', []):
|
partner_trackings[mail_message_id]
|
||||||
partner_id = partner[0]
|
|
||||||
tracking_email = self.env['mail.tracking.email'].search([
|
|
||||||
('mail_message_id', '=', mail_message_id),
|
|
||||||
('partner_id', '=', partner_id),
|
|
||||||
], limit=1)
|
|
||||||
status = self._partner_tracking_status_get(tracking_email)
|
|
||||||
partner_trackings[str(partner_id)] = (
|
|
||||||
status, tracking_email.id)
|
|
||||||
message_dict['partner_trackings'] = partner_trackings
|
|
||||||
return res
|
return res
|
||||||
|
|
|
@ -167,7 +167,7 @@ class MailTrackingEmail(models.Model):
|
||||||
@api.depends('name', 'recipient')
|
@api.depends('name', 'recipient')
|
||||||
def _compute_display_name(self):
|
def _compute_display_name(self):
|
||||||
for email in self:
|
for email in self:
|
||||||
parts = [email.name]
|
parts = [email.name or '']
|
||||||
if email.recipient:
|
if email.recipient:
|
||||||
parts.append(email.recipient)
|
parts.append(email.recipient)
|
||||||
email.display_name = ' - '.join(parts)
|
email.display_name = ' - '.join(parts)
|
||||||
|
@ -225,13 +225,14 @@ class MailTrackingEmail(models.Model):
|
||||||
|
|
||||||
def _message_partners_check(self, message, message_id):
|
def _message_partners_check(self, message, message_id):
|
||||||
mail_message = self.mail_message_id
|
mail_message = self.mail_message_id
|
||||||
partners = mail_message.notified_partner_ids | mail_message.partner_ids
|
partners = (
|
||||||
|
mail_message.needaction_partner_ids | mail_message.partner_ids)
|
||||||
if (self.partner_id and self.partner_id not in partners):
|
if (self.partner_id and self.partner_id not in partners):
|
||||||
# If mail_message haven't tracking partner, then
|
# If mail_message haven't tracking partner, then
|
||||||
# add it in order to see his trackking status in chatter
|
# add it in order to see his tracking status in chatter
|
||||||
if mail_message.subtype_id:
|
if mail_message.subtype_id:
|
||||||
mail_message.sudo().write({
|
mail_message.sudo().write({
|
||||||
'notified_partner_ids': [(4, self.partner_id.id)],
|
'needaction_partner_ids': [(4, self.partner_id.id)],
|
||||||
})
|
})
|
||||||
else:
|
else:
|
||||||
mail_message.sudo().write({
|
mail_message.sudo().write({
|
||||||
|
|
|
@ -11,3 +11,11 @@
|
||||||
.mail_tracking span.mail_tracking_opened {
|
.mail_tracking span.mail_tracking_opened {
|
||||||
color: #a34a8b;
|
color: #a34a8b;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.o_mail_thread .o_thread_message .o_thread_message_core .o_mail_info {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.o_mail_thread .o_thread_message .o_thread_message_core .o_mail_tracking {
|
||||||
|
margin: 0 0 2px 0;
|
||||||
|
}
|
||||||
|
|
|
@ -1,36 +1,59 @@
|
||||||
/* © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
/* © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). */
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). */
|
||||||
|
|
||||||
(function ($, window, document) {
|
odoo.define('mail_tracking.partner_tracking', function(require){
|
||||||
'use strict';
|
"use strict";
|
||||||
|
|
||||||
openerp.mail_tracking = function (instance) {
|
var $ = require('$');
|
||||||
var _t = instance.web._t,
|
var core = require('web.core');
|
||||||
_lt = instance.web._lt;
|
var session = require('web.session');
|
||||||
var QWeb = instance.web.qweb;
|
var Model = require('web.Model');
|
||||||
var mail_orig = instance.mail;
|
var ActionManager = require('web.ActionManager');
|
||||||
var mail_inherit = function() {
|
var chat_manager = require('mail.chat_manager');
|
||||||
instance.mail.MessageCommon.include({
|
var ChatThread = require('mail.ChatThread');
|
||||||
init: function (parent, datasets, options) {
|
var Chatter = require('mail.Chatter');
|
||||||
this._super(parent, datasets, options);
|
|
||||||
this.partner_trackings = datasets.partner_trackings || [];
|
var _t = core._t;
|
||||||
}
|
var MessageModel = new Model('mail.message', session.context);
|
||||||
});
|
|
||||||
instance.mail.ThreadMessage.include({
|
// chat_manager is a simple dictionary, not an OdooClass
|
||||||
bind_events: function () {
|
chat_manager._make_message_super = chat_manager.make_message;
|
||||||
this._super();
|
chat_manager.make_message = function(data) {
|
||||||
this.$('.oe_mail_action_tracking').on('click', this.on_tracking_status_clicked);
|
var msg = this._make_message_super(data);
|
||||||
},
|
msg.partner_trackings = data.partner_trackings || [];
|
||||||
on_tracking_status_clicked: function (event) {
|
return msg;
|
||||||
|
};
|
||||||
|
|
||||||
|
ChatThread.include({
|
||||||
|
on_tracking_partner_click: function (event) {
|
||||||
|
var partner_id = $(event.currentTarget).data('partner');
|
||||||
|
var state = {
|
||||||
|
'model': 'res.partner',
|
||||||
|
'id': partner_id,
|
||||||
|
'title': _t("Tracking partner"),
|
||||||
|
};
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
var tracking_email_id = $(event.delegateTarget).data('tracking');
|
this.action_manager.do_push_state(state);
|
||||||
|
var action = {
|
||||||
|
type:'ir.actions.act_window',
|
||||||
|
view_type: 'form',
|
||||||
|
view_mode: 'form',
|
||||||
|
res_model: 'res.partner',
|
||||||
|
views: [[false, 'form']],
|
||||||
|
target: 'current',
|
||||||
|
res_id: partner_id,
|
||||||
|
};
|
||||||
|
this.do_action(action);
|
||||||
|
},
|
||||||
|
on_tracking_status_click: function (event) {
|
||||||
|
var tracking_email_id = $(event.currentTarget).data('tracking');
|
||||||
var state = {
|
var state = {
|
||||||
'model': 'mail.tracking.email',
|
'model': 'mail.tracking.email',
|
||||||
'id': tracking_email_id,
|
'id': tracking_email_id,
|
||||||
'title': _t("Message tracking"),
|
'title': _t("Message tracking"),
|
||||||
};
|
};
|
||||||
instance.webclient.action_manager.do_push_state(state);
|
event.preventDefault();
|
||||||
console.log('tracking_email_id = ' + tracking_email_id);
|
this.action_manager.do_push_state(state);
|
||||||
var action = {
|
var action = {
|
||||||
type:'ir.actions.act_window',
|
type:'ir.actions.act_window',
|
||||||
view_type: 'form',
|
view_type: 'form',
|
||||||
|
@ -41,23 +64,40 @@
|
||||||
res_id: tracking_email_id,
|
res_id: tracking_email_id,
|
||||||
};
|
};
|
||||||
this.do_action(action);
|
this.do_action(action);
|
||||||
}
|
},
|
||||||
|
bind_events: function () {
|
||||||
|
this.$el.on('click', '.o_mail_action_tracking_partner',
|
||||||
|
this.on_tracking_partner_click);
|
||||||
|
this.$el.on('click', '.o_mail_action_tracking_status',
|
||||||
|
this.on_tracking_status_click);
|
||||||
|
},
|
||||||
|
init: function (parent, options) {
|
||||||
|
this._super.apply(this, arguments);
|
||||||
|
this.action_manager = this.findAncestor(function(ancestor){
|
||||||
|
return ancestor instanceof ActionManager;
|
||||||
});
|
});
|
||||||
};
|
},
|
||||||
|
start: function () {
|
||||||
|
this._super();
|
||||||
|
this.bind_events();
|
||||||
|
},
|
||||||
|
render: function(messages, options) {
|
||||||
|
var self = this, render_super = this._super,
|
||||||
|
msgs = {},
|
||||||
|
msg_ids = [];
|
||||||
|
// Update trackings (async) each time we re-render thread
|
||||||
|
_.each(messages, function (message) {
|
||||||
|
msgs[message.id] = message;
|
||||||
|
msg_ids.push(message.id);
|
||||||
|
});
|
||||||
|
MessageModel.call('tracking_status', [msg_ids]).then(function (trackings) {
|
||||||
|
_.each(trackings, function (tracking, id) {
|
||||||
|
msgs[id].partner_trackings = tracking;
|
||||||
|
});
|
||||||
|
render_super.apply(self, [messages, options]);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
// Tricky way to guarantee that this module is loaded always
|
});
|
||||||
// after mail module.
|
|
||||||
// When --load=web,mail_tracking is specified in init script, then
|
|
||||||
// web and mail_tracking are the first modules to load in JS
|
|
||||||
if (instance.mail.MessageCommon === undefined) {
|
|
||||||
instance.mail = function(instance) {
|
|
||||||
instance.mail = mail_orig;
|
|
||||||
instance.mail(instance, instance.mail);
|
|
||||||
mail_inherit();
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
mail_inherit();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}(window.jQuery, window, document));
|
}); // odoo.define
|
||||||
|
|
|
@ -40,21 +40,33 @@
|
||||||
</t>
|
</t>
|
||||||
</t>
|
</t>
|
||||||
|
|
||||||
<t t-extend="mail.thread.message">
|
<t t-extend="mail.ChatThread.Message">
|
||||||
<t t-jquery="span[t-attf-class='oe_partner_follower']" t-operation="append">
|
<t t-jquery="p[class='o_mail_info']" t-operation="after">
|
||||||
<t t-set='tracking' t-value='widget.partner_trackings[partner[0]]'/>
|
<p class="o_mail_tracking">
|
||||||
<t t-if="tracking[1]">
|
<strong>To:</strong>
|
||||||
<span class="mail_tracking oe_mail_action_tracking"
|
<t t-set="first_tracking" t-value="true"/>
|
||||||
|
<t t-foreach="message.partner_trackings" t-as="tracking">
|
||||||
|
<t t-if="!first_tracking">
|
||||||
|
-
|
||||||
|
</t>
|
||||||
|
<t t-if="tracking[3]">
|
||||||
|
<a class="o_mail_action_tracking_partner"
|
||||||
|
t-att-data-partner="tracking[3]"
|
||||||
|
t-attf-href="#model=res.partner&id=#{tracking[3]}">
|
||||||
|
<t t-esc="tracking[2]"/>
|
||||||
|
</a>
|
||||||
|
</t>
|
||||||
|
<t t-if="!tracking[3]">
|
||||||
|
<span><t t-esc="tracking[2]"/></span>
|
||||||
|
</t>
|
||||||
|
<span class="mail_tracking o_mail_action_tracking_status"
|
||||||
t-att-data-tracking="tracking[1]"
|
t-att-data-tracking="tracking[1]"
|
||||||
t-attf-title="Status: #{tracking[0]}">
|
t-attf-title="Status: #{tracking[0]}">
|
||||||
<t t-call="mail.tracking.status"/>
|
<t t-call="mail.tracking.status"/>
|
||||||
</span>
|
</span>
|
||||||
|
<t t-set="first_tracking" t-value="false"/>
|
||||||
</t>
|
</t>
|
||||||
<t t-if="!tracking[1]">
|
</p>
|
||||||
<span class="mail_tracking" t-attf-title="Status: #{tracking[0]}">
|
|
||||||
<t t-call="mail.tracking.status"/>
|
|
||||||
</span>
|
|
||||||
</t>
|
|
||||||
</t>
|
</t>
|
||||||
</t>
|
</t>
|
||||||
|
|
||||||
|
|
|
@ -65,19 +65,20 @@ class TestMailTracking(TransactionCase):
|
||||||
self.assertTrue(tracking_email)
|
self.assertTrue(tracking_email)
|
||||||
self.assertEqual(tracking_email.state, 'sent')
|
self.assertEqual(tracking_email.state, 'sent')
|
||||||
# message_dict read by web interface
|
# message_dict read by web interface
|
||||||
message_dict = self.env['mail.message'].message_read(message.id)
|
message_dict = message.message_read()
|
||||||
# First item is message content
|
# First item in threads is message content
|
||||||
self.assertTrue(len(message_dict) > 0)
|
message_dict = message_dict['threads'][0][0]
|
||||||
message_dict = message_dict[0]
|
|
||||||
self.assertTrue(len(message_dict['partner_ids']) > 0)
|
self.assertTrue(len(message_dict['partner_ids']) > 0)
|
||||||
# First partner is recipient
|
# First partner is recipient
|
||||||
partner_id = message_dict['partner_ids'][0][0]
|
partner_id = message_dict['partner_ids'][0][0]
|
||||||
self.assertEqual(partner_id, self.recipient.id)
|
self.assertEqual(partner_id, self.recipient.id)
|
||||||
status = message_dict['partner_trackings'][str(partner_id)]
|
status = message_dict['partner_trackings'][0]
|
||||||
# Tracking status must be sent and
|
# Tracking status must be sent and
|
||||||
# mail tracking must be the one search before
|
# mail tracking must be the one search before
|
||||||
self.assertEqual(status[0], 'sent')
|
self.assertEqual(status[0], 'sent')
|
||||||
self.assertEqual(status[1], tracking_email.id)
|
self.assertEqual(status[1], tracking_email.id)
|
||||||
|
self.assertEqual(status[2], self.recipient.display_name)
|
||||||
|
self.assertEqual(status[3], self.recipient.id)
|
||||||
# And now open the email
|
# And now open the email
|
||||||
metadata = {
|
metadata = {
|
||||||
'ip': '127.0.0.1',
|
'ip': '127.0.0.1',
|
||||||
|
@ -88,11 +89,11 @@ class TestMailTracking(TransactionCase):
|
||||||
tracking_email.event_create('open', metadata)
|
tracking_email.event_create('open', metadata)
|
||||||
self.assertEqual(tracking_email.state, 'opened')
|
self.assertEqual(tracking_email.state, 'opened')
|
||||||
|
|
||||||
def mail_send(self):
|
def mail_send(self, recipient):
|
||||||
mail = self.env['mail.mail'].create({
|
mail = self.env['mail.mail'].create({
|
||||||
'subject': 'Test subject',
|
'subject': 'Test subject',
|
||||||
'email_from': 'from@domain.com',
|
'email_from': 'from@domain.com',
|
||||||
'email_to': 'to@domain.com',
|
'email_to': recipient,
|
||||||
'body_html': '<p>This is a test message</p>',
|
'body_html': '<p>This is a test message</p>',
|
||||||
})
|
})
|
||||||
mail.send()
|
mail.send()
|
||||||
|
@ -106,7 +107,7 @@ class TestMailTracking(TransactionCase):
|
||||||
controller = MailTrackingController()
|
controller = MailTrackingController()
|
||||||
db = self.env.cr.dbname
|
db = self.env.cr.dbname
|
||||||
image = base64.decodestring(BLANK)
|
image = base64.decodestring(BLANK)
|
||||||
mail, tracking = self.mail_send()
|
mail, tracking = self.mail_send(self.recipient.email)
|
||||||
self.assertEqual(mail.email_to, tracking.recipient)
|
self.assertEqual(mail.email_to, tracking.recipient)
|
||||||
self.assertEqual(mail.email_from, tracking.sender)
|
self.assertEqual(mail.email_from, tracking.sender)
|
||||||
with mock.patch(mock_request) as mock_func:
|
with mock.patch(mock_request) as mock_func:
|
||||||
|
@ -115,7 +116,7 @@ class TestMailTracking(TransactionCase):
|
||||||
self.assertEqual(image, res.response[0])
|
self.assertEqual(image, res.response[0])
|
||||||
|
|
||||||
def test_concurrent_open(self):
|
def test_concurrent_open(self):
|
||||||
mail, tracking = self.mail_send()
|
mail, tracking = self.mail_send(self.recipient.email)
|
||||||
ts = time.time()
|
ts = time.time()
|
||||||
metadata = {
|
metadata = {
|
||||||
'ip': '127.0.0.1',
|
'ip': '127.0.0.1',
|
||||||
|
@ -146,7 +147,7 @@ class TestMailTracking(TransactionCase):
|
||||||
self.assertEqual(len(opens), 2)
|
self.assertEqual(len(opens), 2)
|
||||||
|
|
||||||
def test_concurrent_click(self):
|
def test_concurrent_click(self):
|
||||||
mail, tracking = self.mail_send()
|
mail, tracking = self.mail_send(self.recipient.email)
|
||||||
ts = time.time()
|
ts = time.time()
|
||||||
metadata = {
|
metadata = {
|
||||||
'ip': '127.0.0.1',
|
'ip': '127.0.0.1',
|
||||||
|
@ -188,11 +189,66 @@ class TestMailTracking(TransactionCase):
|
||||||
def test_smtp_error(self):
|
def test_smtp_error(self):
|
||||||
with mock.patch(mock_send_email) as mock_func:
|
with mock.patch(mock_send_email) as mock_func:
|
||||||
mock_func.side_effect = Warning('Test error')
|
mock_func.side_effect = Warning('Test error')
|
||||||
mail, tracking = self.mail_send()
|
mail, tracking = self.mail_send(self.recipient.email)
|
||||||
self.assertEqual('error', tracking.state)
|
self.assertEqual('error', tracking.state)
|
||||||
self.assertEqual('Warning', tracking.error_type)
|
self.assertEqual('Warning', tracking.error_type)
|
||||||
self.assertEqual('Test error', tracking.error_description)
|
self.assertEqual('Test error', tracking.error_description)
|
||||||
|
|
||||||
|
def test_partner_email_change(self):
|
||||||
|
mail, tracking = self.mail_send(self.recipient.email)
|
||||||
|
tracking.event_create('open', {})
|
||||||
|
orig_score = self.recipient.email_score
|
||||||
|
orig_email = self.recipient.email
|
||||||
|
self.recipient.email = orig_email + '2'
|
||||||
|
self.assertEqual(50.0, self.recipient.email_score)
|
||||||
|
self.recipient.email = orig_email
|
||||||
|
self.assertEqual(orig_score, self.recipient.email_score)
|
||||||
|
|
||||||
|
def test_process_hard_bounce(self):
|
||||||
|
mail, tracking = self.mail_send(self.recipient.email)
|
||||||
|
tracking.event_create('hard_bounce', {})
|
||||||
|
self.assertEqual('bounced', tracking.state)
|
||||||
|
|
||||||
|
def test_process_soft_bounce(self):
|
||||||
|
mail, tracking = self.mail_send(self.recipient.email)
|
||||||
|
tracking.event_create('soft_bounce', {})
|
||||||
|
self.assertEqual('soft-bounced', tracking.state)
|
||||||
|
|
||||||
|
def test_process_delivered(self):
|
||||||
|
mail, tracking = self.mail_send(self.recipient.email)
|
||||||
|
tracking.event_create('delivered', {})
|
||||||
|
self.assertEqual('delivered', tracking.state)
|
||||||
|
|
||||||
|
def test_process_deferral(self):
|
||||||
|
mail, tracking = self.mail_send(self.recipient.email)
|
||||||
|
tracking.event_create('deferral', {})
|
||||||
|
self.assertEqual('deferred', tracking.state)
|
||||||
|
|
||||||
|
def test_process_spam(self):
|
||||||
|
mail, tracking = self.mail_send(self.recipient.email)
|
||||||
|
tracking.event_create('spam', {})
|
||||||
|
self.assertEqual('spam', tracking.state)
|
||||||
|
|
||||||
|
def test_process_unsub(self):
|
||||||
|
mail, tracking = self.mail_send(self.recipient.email)
|
||||||
|
tracking.event_create('unsub', {})
|
||||||
|
self.assertEqual('unsub', tracking.state)
|
||||||
|
|
||||||
|
def test_process_reject(self):
|
||||||
|
mail, tracking = self.mail_send(self.recipient.email)
|
||||||
|
tracking.event_create('reject', {})
|
||||||
|
self.assertEqual('rejected', tracking.state)
|
||||||
|
|
||||||
|
def test_process_open(self):
|
||||||
|
mail, tracking = self.mail_send(self.recipient.email)
|
||||||
|
tracking.event_create('open', {})
|
||||||
|
self.assertEqual('opened', tracking.state)
|
||||||
|
|
||||||
|
def test_process_click(self):
|
||||||
|
mail, tracking = self.mail_send(self.recipient.email)
|
||||||
|
tracking.event_create('click', {})
|
||||||
|
self.assertEqual('opened', tracking.state)
|
||||||
|
|
||||||
def test_db(self):
|
def test_db(self):
|
||||||
db = self.env.cr.dbname
|
db = self.env.cr.dbname
|
||||||
controller = MailTrackingController()
|
controller = MailTrackingController()
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||||
<openerp>
|
<odoo>
|
||||||
<data>
|
|
||||||
|
|
||||||
<template id="assets_backend"
|
<template id="assets_backend"
|
||||||
name="mail_tracking assets"
|
name="mail_tracking assets"
|
||||||
|
@ -15,5 +14,4 @@
|
||||||
</xpath>
|
</xpath>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
</data>
|
</odoo>
|
||||||
</openerp>
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||||
<openerp>
|
<odoo>
|
||||||
<data>
|
|
||||||
|
|
||||||
<record model="ir.ui.view" id="view_mail_tracking_email_form">
|
<record model="ir.ui.view" id="view_mail_tracking_email_form">
|
||||||
<field name="name">mail.tracking.email.form</field>
|
<field name="name">mail.tracking.email.form</field>
|
||||||
|
@ -118,5 +117,4 @@
|
||||||
parent="base.menu_email"
|
parent="base.menu_email"
|
||||||
action="action_view_mail_tracking_email"/>
|
action="action_view_mail_tracking_email"/>
|
||||||
|
|
||||||
</data>
|
</odoo>
|
||||||
</openerp>
|
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||||
<openerp>
|
<odoo>
|
||||||
<data>
|
|
||||||
|
|
||||||
<record model="ir.ui.view" id="view_mail_tracking_event_form">
|
<record model="ir.ui.view" id="view_mail_tracking_event_form">
|
||||||
<field name="name">mail.tracking.event.form</field>
|
<field name="name">mail.tracking.event.form</field>
|
||||||
|
@ -121,5 +120,4 @@
|
||||||
action="action_view_mail_tracking_event"/>
|
action="action_view_mail_tracking_event"/>
|
||||||
|
|
||||||
|
|
||||||
</data>
|
</odoo>
|
||||||
</openerp>
|
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
<!-- © 2016 Antonio Espinosa - <antonio.espinosa@tecnativa.com>
|
||||||
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). -->
|
||||||
<openerp>
|
<odoo>
|
||||||
<data>
|
|
||||||
|
|
||||||
<record model="ir.ui.view" id="view_partner_form">
|
<record model="ir.ui.view" id="view_partner_form">
|
||||||
<field name="name">Partner Form with tracking emails</field>
|
<field name="name">Partner Form with tracking emails</field>
|
||||||
<field name="model">res.partner</field>
|
<field name="model">res.partner</field>
|
||||||
<field name="inherit_id" ref="base.view_partner_form"/>
|
<field name="inherit_id" ref="base.view_partner_form"/>
|
||||||
<field name="arch" type="xml">
|
<field name="arch" type="xml">
|
||||||
<div class="oe_right oe_button_box" position="inside">
|
<div name="button_box" position="inside">
|
||||||
<button name="%(mail_tracking.action_view_mail_tracking_email)d"
|
<button name="%(mail_tracking.action_view_mail_tracking_email)d"
|
||||||
context="{'search_default_recipient': email,
|
context="{'search_default_recipient': email,
|
||||||
'default_recipient': email}"
|
'default_recipient': email}"
|
||||||
|
@ -29,5 +28,4 @@
|
||||||
</field>
|
</field>
|
||||||
</record>
|
</record>
|
||||||
|
|
||||||
</data>
|
</odoo>
|
||||||
</openerp>
|
|
||||||
|
|
Loading…
Reference in New Issue