def _send_wecom_prepare_values(self, partner=None):
        """
        根据合作伙伴返回有关特定电子邮件值的字典,或者对整个邮件都是通用的。对于特定电子邮件值取决于对伙伴的字典,或者对mail.email_to给出的整个收件人来说都是通用的。

        :param Model partner: 具体的收件人合作伙伴
        """
        self.ensure_one()
        body_html = self._send_prepare_body_html()
        body_json = self._send_prepare_body_json()
        body_markdown = self._send_prepare_body_markdown()
        # body_alternative = tools.html2plaintext(body_html)
        if partner:
            email_to = [
                tools.formataddr((partner.name or "False", partner.email or "False"))
            ]
            message_to_user = [
                tools.formataddr(
                    (partner.name or "False", partner.wecom_userid or "False")
                )
            ]
        else:
            email_to = tools.email_split_and_format(self.email_to)
            message_to_user = self.message_to_user
        res = {
            # "message_body_text": message_body_text,
            # "message_body_html": message_body_html,
            "email_to": email_to,
            "message_to_user": message_to_user,
            "body_json": body_json,
            "body_html": body_html,
            "body_markdown": body_markdown,
        }

        return res
Esempio n. 2
0
    def test_channel_mailing_list_recipients(self):
        """ Posting a message on a mailing list should send one email to all recipients """
        self.env['ir.config_parameter'].set_param('mail.catchall.domain',
                                                  'schlouby.fr')
        self.test_channel.write({'email_send': True})

        # Subscribe an user without email. We shouldn't try to send email to them.
        nomail = self.env['res.users'].create({
            "login": "******",
            "name": "No Mail",
            "email": False,
            "notification_type": "email",
        })
        self._join_channel(
            self.test_channel, self.user_employee.partner_id
            | self.test_partner | nomail.partner_id)
        self.test_channel.message_post(body="Test",
                                       message_type='comment',
                                       subtype='mt_comment')

        self.assertEqual(len(self._mails), 1)
        for email in self._mails:
            self.assertEqual(
                set(email['email_to']),
                set([
                    formataddr(
                        (self.user_employee.name, self.user_employee.email)),
                    formataddr(
                        (self.test_partner.name, self.test_partner.email))
                ]))
Esempio n. 3
0
    def test_message_process_model_res_id(self):
        """ Incoming email with ref holding model / res_id but that does not match any message in the thread: must raise since OpenERP saas-3 """
        self.assertRaises(ValueError,
                          self.format_and_process, MAIL_TEMPLATE,
                          email_from=formataddr((self.partner_1.name, self.partner_1.email)),
                          to='*****@*****.**', subject='spam',
                          extra='In-Reply-To: <12321321-openerp-%d-mail.test.simple@%s>' % (self.test_record.id, socket.gethostname()),
                          msg_id='<*****@*****.**>')

        # when 6.1 messages are present, compat mode is available
        # Odoo 10 update: compat mode has been removed and should not work anymore
        self.fake_email.write({'message_id': False})
        # Do: compat mode accepts partial-matching emails
        self.assertRaises(
            ValueError,
            self.format_and_process,
            MAIL_TEMPLATE, email_from=formataddr((self.partner_1.name, self.partner_1.email)),
            msg_id='<*****@*****.**>',
            to='*****@*****.**>', subject='spam',
            extra='In-Reply-To: <12321321-openerp-%d-mail.test.simple@%s>' % (self.test_record.id, socket.gethostname()))

        # 3''. 6.1 compat mode should not work if hostname does not match!
        # Odoo 10 update: compat mode has been removed and should not work anymore and does not depend from hostname
        self.assertRaises(ValueError,
                          self.format_and_process,
                          MAIL_TEMPLATE, email_from=formataddr((self.partner_1.name, self.partner_1.email)),
                          msg_id='<*****@*****.**>',
                          to='*****@*****.**>', subject='spam',
                          extra='In-Reply-To: <*****@*****.**>' % self.test_record.id)

        # Test created messages
        self.assertEqual(len(self.test_record.message_ids), 1)
        self.assertEqual(len(self.test_record.message_ids[0].child_ids), 0)
Esempio n. 4
0
    def _notify_get_reply_to_formatted_email(self, record_email, record_name):
        """ Compute formatted email for reply_to and try to avoid refold issue
        with python that splits the reply-to over multiple lines. It is due to
        a bad management of quotes (missing quotes after refold). This appears
        therefore only when having quotes (aka not simple names, and not when
        being unicode encoded).

        To avoid that issue when formataddr would return more than 78 chars we
        return a simplified name/email to try to stay under 78 chars. If not
        possible we return only the email and skip the formataddr which causes
        the issue in python. We do not use hacks like crop the name part as
        encoding and quoting would be error prone.
        """
        # address itself is too long for 78 chars limit: return only email
        if len(record_email) >= 78:
            return record_email

        company_name = self.env.company.name

        # try company_name + record_name, or record_name alone (or company_name alone)
        name = f"{company_name} {record_name}" if record_name else company_name

        formatted_email = tools.formataddr((name, record_email))
        if len(formatted_email) > 78:
            formatted_email = tools.formataddr((record_name
                                                or company_name, record_email))
        if len(formatted_email) > 78:
            formatted_email = record_email
        return formatted_email
    def test_notify_reply_to_computation_mc(self):
        """ Test reply-to computation in multi company mode. Add notably tests
        depending on user company_id / company_ids. """
        # Test1: no company_id field
        test_record = self.env['mail.test.gateway'].browse(
            self.test_record.ids)
        res = test_record._notify_get_reply_to()
        self.assertEqual(
            res[test_record.id],
            formataddr(
                ("%s %s" %
                 (self.user_employee_c2.company_id.name, test_record.name),
                 "%s@%s" % (self.alias_catchall, self.alias_domain))))

        # Test2: company_id field, MC environment
        self.user_employee_c2.write(
            {'company_ids': [(4, self.user_employee.company_id.id)]})
        test_records = self.env['mail.test.multi.company'].create([
            {
                'name': 'Test',
                'company_id': self.user_employee.company_id.id
            },
            {
                'name': 'Test',
                'company_id': self.user_employee_c2.company_id.id
            },
        ])
        res = test_records._notify_get_reply_to()
        for test_record in test_records:
            self.assertEqual(
                res[test_record.id],
                formataddr(
                    ("%s %s" %
                     (self.user_employee_c2.company_id.name, test_record.name),
                     "%s@%s" % (self.alias_catchall, self.alias_domain))))
Esempio n. 6
0
    def test_mail_message_values_document_manual_alias(self):
        test_record = self.env['mail.test.simple'].create({
            'name':
            'Test',
            'email_from':
            '*****@*****.**'
        })
        alias = self.env['mail.alias'].create({
            'alias_name':
            'MegaLias',
            'alias_user_id':
            False,
            'alias_model_id':
            self.env['ir.model']._get('mail.test.simple').id,
            'alias_parent_model_id':
            self.env['ir.model']._get('mail.test.simple').id,
            'alias_parent_thread_id':
            test_record.id,
        })

        msg = self.Message.create({
            'model': 'mail.test.simple',
            'res_id': test_record.id
        })

        self.assertIn('-openerp-%d-mail.test.simple' % test_record.id,
                      msg.message_id.split('@')[0])
        reply_to_name = '%s %s' % (self.env.user.company_id.name,
                                   test_record.name)
        reply_to_email = '%s@%s' % (alias.alias_name, self.alias_domain)
        self.assertEqual(msg.reply_to,
                         formataddr((reply_to_name, reply_to_email)))
        self.assertEqual(
            msg.email_from,
            formataddr((self.user_employee.name, self.user_employee.email)))
Esempio n. 7
0
    def test_channel_blacklisted_recipients(self):
        """ Posting a message on a channel should send one email to all recipients, except the blacklisted ones """
        test_channel = self.env['mail.channel'].create({
            'name': 'Test',
            'description': 'Description',
            'alias_name': 'test',
            'public': 'public',
            'email_send': True,
        })
        test_partner = self.env['res.partner'].create({
            'name': 'Test Partner',
            'email': '*****@*****.**',
        })

        blacklisted_partner = self.env['res.partner'].create({
            'name': 'Blacklisted Partner',
            'email': '*****@*****.**',
        })

        # Set Blacklist
        self.env['mail.blacklist'].create({
            'email': '*****@*****.**',
        })

        test_channel._action_add_members(test_partner + blacklisted_partner)
        with self.mock_mail_gateway():
            test_channel.message_post(body="Test", message_type='comment', subtype_xmlid='mail.mt_comment')

        self.assertEqual(len(self._mails), 1, 'Number of mail incorrect. Should be equal to 1.')
        for email in self._mails:
            self.assertEqual(
                set(email['email_to']),
                set([formataddr((test_partner.name, test_partner.email))]),
                'email_to incorrect. Should be equal to "%s"' % (
                    formataddr((test_partner.name, test_partner.email))))
Esempio n. 8
0
    def test_message_process_email_author(self):
        """ Incoming email: recognized author: email_from, author_id, added as follower """
        record = self.format_and_process(MAIL_TEMPLATE, email_from=formataddr((self.partner_1.name, self.partner_1.email)))

        self.assertEqual(record.message_ids[0].author_id, self.partner_1,
                         'message_process: recognized email -> author_id')
        self.assertEqual(record.message_ids[0].email_from, formataddr((self.partner_1.name, self.partner_1.email)))
        self.assertEqual(len(self._mails), 0, 'No notification / bounce should be sent')
Esempio n. 9
0
    def test_mail_message_values_document_alias(self):
        msg = self.Message.create({
            'model': 'mail.test',
            'res_id': self.alias_record.id
        })
        self.assertIn('-openerp-%d-mail.test' % self.alias_record.id,
                      msg.message_id.split('@')[0])
        reply_to_name = '%s %s' % (self.env.user.company_id.name,
                                   self.alias_record.name)
        reply_to_email = '%s@%s' % (self.alias_record.alias_name,
                                    self.alias_domain)
        self.assertEqual(msg.reply_to,
                         formataddr((reply_to_name, reply_to_email)))
        self.assertEqual(
            msg.email_from,
            '"%s" <%s>' % (self.user_employee.name, self.user_employee.email))

        # no alias domain -> author
        self.env['ir.config_parameter'].search([
            ('key', '=', 'mail.catchall.domain')
        ]).unlink()

        msg = self.Message.create({
            'model': 'mail.test',
            'res_id': self.alias_record.id
        })
        self.assertIn('-openerp-%d-mail.test' % self.alias_record.id,
                      msg.message_id.split('@')[0])
        self.assertEqual(
            msg.reply_to,
            formataddr((self.user_employee.name, self.user_employee.email)))
        self.assertEqual(
            msg.email_from,
            formataddr((self.user_employee.name, self.user_employee.email)))

        # no catchall -> don't care, alias
        self.env['ir.config_parameter'].set_param('mail.catchall.domain',
                                                  self.alias_domain)
        self.env['ir.config_parameter'].search([
            ('key', '=', 'mail.catchall.alias')
        ]).unlink()

        msg = self.Message.create({
            'model': 'mail.test',
            'res_id': self.alias_record.id
        })
        self.assertIn('-openerp-%d-mail.test' % self.alias_record.id,
                      msg.message_id.split('@')[0])
        reply_to_name = '%s %s' % (self.env.company.name,
                                   self.alias_record.name)
        reply_to_email = '%s@%s' % (self.alias_record.alias_name,
                                    self.alias_domain)
        self.assertEqual(msg.reply_to,
                         formataddr((reply_to_name, reply_to_email)))
        self.assertEqual(
            msg.email_from,
            formataddr((self.user_employee.name, self.user_employee.email)))
Esempio n. 10
0
    def test_mail_message_values_fromto_long_name(self):
        """ Long headers may break in python if above 78 chars as folding is not
        done correctly (see ``_notify_get_reply_to_formatted_email`` docstring
        + commit linked to this test). """
        # name would make it blow up: keep only email
        test_record = self.env['mail.test.container'].browse(self.alias_record.ids)
        test_record.write({
            'name': 'Super Long Name That People May Enter "Even with an internal quoting of stuff"'
        })
        msg = self.env['mail.message'].create({
            'model': test_record._name,
            'res_id': test_record.id
        })
        reply_to_email = f"{test_record.alias_name}@{self.alias_domain}"
        self.assertEqual(msg.reply_to, reply_to_email,
                         'Reply-To: use only email when formataddr > 78 chars')

        # name + company_name would make it blow up: keep record_name in formatting
        test_record.write({'name': 'Name that would be more than 78 with company name'})
        msg = self.env['mail.message'].create({
            'model': test_record._name,
            'res_id': test_record.id
        })
        self.assertEqual(msg.reply_to, formataddr((test_record.name, reply_to_email)),
                         'Reply-To: use recordname as name in format if recordname + company > 78 chars')

        # no record_name: keep company_name in formatting if ok
        test_record.write({'name': ''})
        msg = self.env['mail.message'].create({
            'model': test_record._name,
            'res_id': test_record.id
        })
        self.assertEqual(msg.reply_to, formataddr((self.env.user.company_id.name, reply_to_email)),
                         'Reply-To: use company as name in format when no record name and still < 78 chars')

        # no record_name and company_name make it blow up: keep only email
        self.env.user.company_id.write({'name': 'Super Long Name That People May Enter "Even with an internal quoting of stuff"'})
        msg = self.env['mail.message'].create({
            'model': test_record._name,
            'res_id': test_record.id
        })
        self.assertEqual(msg.reply_to, reply_to_email,
                         'Reply-To: use only email when formataddr > 78 chars')

        # whatever the record and company names, email is too long: keep only email
        test_record.write({
            'alias_name': 'Waaaay too long alias name that should make any reply-to blow the 78 characters limit',
            'name': 'Short',
        })
        self.env.user.company_id.write({'name': 'Comp'})
        sanitized_alias_name = 'waaaay-too-long-alias-name-that-should-make-any-reply-to-blow-the-78-characters-limit'
        msg = self.env['mail.message'].create({
            'model': test_record._name,
            'res_id': test_record.id
        })
        self.assertEqual(msg.reply_to, f"{sanitized_alias_name}@{self.alias_domain}",
                         'Reply-To: even a long email is ok as only formataddr is problematic')
Esempio n. 11
0
    def assertSentEmail(self, author, recipients, **values):
        """ Tool method to ease the check of send emails.

        :param author: email author, either a string (email), either a partner
          record;
        :param recipients: list of recipients, each being either a string (email),
          either a partner record;
        :param values: dictionary of additional values to check email content;
        """
        base_expected = {}
        for fname in ['reply_to', 'subject', 'attachments', 'body', 'references',
                      'body_content', 'body_alternative_content', 'references_content']:
            if fname in values:
                base_expected[fname] = values[fname]

        expected = dict(base_expected)
        if isinstance(author, self.env['res.partner'].__class__):
            expected['email_from'] = formataddr((author.name, author.email))
        else:
            expected['email_from'] = author

        email_to_list = []
        for email_to in recipients:
            if isinstance(email_to, self.env['res.partner'].__class__):
                email_to_list.append(formataddr((email_to.name, email_to.email)))
            else:
                email_to_list.append(email_to)
        expected['email_to'] = email_to_list

        sent_mail = next(
            (mail for mail in self._mails
             if set(mail['email_to']) == set(expected['email_to']) and mail['email_from'] == expected['email_from']
             ), False)
        debug_info = '-'.join('From: %s-To: %s' % (mail['email_from'], mail['email_to']) for mail in self._mails) if not bool(sent_mail) else ''
        self.assertTrue(bool(sent_mail), 'Expected mail from %s to %s not found in %s' % (expected['email_from'], expected['email_to'], debug_info))

        for val in ['reply_to', 'subject', 'references', 'attachments']:
            if val in expected:
                self.assertEqual(expected[val], sent_mail[val], 'Value for %s: expected %s, received %s' % (val, expected[val], sent_mail[val]))
        if 'attachments_info' in values:
            attachments = sent_mail['attachments']
            for attachment_info in values['attachments_info']:
                attachment = next(attach for attach in attachments if attach[0] == attachment_info['name'])
                if attachment_info.get('raw'):
                    self.assertEqual(attachment[1], attachment_info['raw'])
                if attachment_info.get('type'):
                    self.assertEqual(attachment[2], attachment_info['type'])
            self.assertEqual(len(values['attachments_info']), len(attachments))
        for val in ['body']:
            if val in expected:
                self.assertHtmlEqual(expected[val], sent_mail[val], 'Value for %s: expected %s, received %s' % (val, expected[val], sent_mail[val]))
        for val in ['body_content', 'body_alternative', 'references_content']:
            if val in expected:
                self.assertIn(expected[val], sent_mail[val[:-8]], 'Value for %s: %s does not contain %s' % (val, sent_mail[val[:-8]], expected[val]))
Esempio n. 12
0
    def test_channel_classic_recipients(self):
        """ Posting a message on a classic channel should work like classic post """
        self.test_channel.write({'alias_name': False})
        self.test_channel.message_subscribe([self.user_employee.partner_id.id, self.test_partner.id])
        self.test_channel.message_post(body="Test", message_type='comment', subtype='mt_comment')

        sent_emails = self._mails
        self.assertEqual(len(sent_emails), 2)
        for email in sent_emails:
            self.assertIn(
                email['email_to'][0],
                [formataddr((self.user_employee.name, self.user_employee.email)), formataddr((self.test_partner.name, self.test_partner.email))])
    def test_mail_group_notification_recipients_separated(self):
        # Remove alias, should trigger classic behavior of mail group
        self.group_private.write({'alias_name': False})
        self.group_private.message_subscribe_users([self.user_employee.id, self.user_portal.id])

        self.group_private.message_post(body="Test", message_type='comment', subtype='mt_comment')
        sent_emails = self._mails
        self.assertEqual(len(sent_emails), 2)
        for email in sent_emails:
            self.assertIn(
                email['email_to'][0],
                [formataddr((self.user_employee.name, self.user_employee.email)), formataddr((self.user_portal.name, self.user_portal.email))])
Esempio n. 14
0
    def test_mail_message_values_document_no_alias(self):
        test_record = self.env['mail.test.simple'].create({'name': 'Test', 'email_from': '*****@*****.**'})

        msg = self.Message.create({
            'model': 'mail.test.simple',
            'res_id': test_record.id
        })
        self.assertIn('-openerp-%d-mail.test.simple' % test_record.id, msg.message_id.split('@')[0])
        reply_to_name = '%s %s' % (self.env.user.company_id.name, test_record.name)
        reply_to_email = '%s@%s' % (self.alias_catchall, self.alias_domain)
        self.assertEqual(msg.reply_to, formataddr((reply_to_name, reply_to_email)))
        self.assertEqual(msg.email_from, formataddr((self.user_employee.name, self.user_employee.email)))
Esempio n. 15
0
 def _compute_email_formatted(self):
     for partner in self:
         if partner.email:
             partner.email_formatted = tools.formataddr(
                 (partner.name or u"False", partner.email or u"False"))
         else:
             partner.email_formatted = ''
Esempio n. 16
0
    def test_post_notify(self):
        self.user_employee.write({'notification_type': 'inbox'})

        with self.mock_mail_gateway():
            new_notification = self.test_record.message_notify(
                subject='This should be a subject',
                body='<p>You have received a notification</p>',
                partner_ids=[self.partner_1.id, self.partner_admin.id, self.user_employee.partner_id.id],
            )

        self.assertEqual(new_notification.subtype_id, self.env.ref('mail.mt_note'))
        self.assertEqual(new_notification.message_type, 'user_notification')
        self.assertEqual(new_notification.body, '<p>You have received a notification</p>')
        self.assertEqual(new_notification.author_id, self.env.user.partner_id)
        self.assertEqual(new_notification.email_from, formataddr((self.env.user.name, self.env.user.email)))
        self.assertEqual(new_notification.notified_partner_ids, self.partner_1 | self.user_employee.partner_id | self.partner_admin)
        self.assertNotIn(new_notification, self.test_record.message_ids)

        admin_mails = [x for x in self._mails if self.partner_admin.name in x.get('email_to')[0]]
        self.assertEqual(len(admin_mails), 1, 'There should be exactly one email sent to admin')
        admin_mail = admin_mails[0].get('body')
        admin_access_link = admin_mail[admin_mail.index('model='):admin_mail.index('/>') - 1] if 'model=' in admin_mail else None
  
        self.assertIsNotNone(admin_access_link, 'The email sent to admin should contain an access link')
        self.assertIn('model=%s' % self.test_record._name, admin_access_link, 'The access link should contain a valid model argument')
        self.assertIn('res_id=%d' % self.test_record.id, admin_access_link, 'The access link should contain a valid res_id argument')

        partner_mails = [x for x in self._mails if self.partner_1.name in x.get('email_to')[0]]
        self.assertEqual(len(partner_mails), 1, 'There should be exactly one email sent to partner')
        partner_mail = partner_mails[0].get('body')
        self.assertNotIn('/mail/view?model=', partner_mail, 'The email sent to admin should not contain an access link')
Esempio n. 17
0
    def test_email_formataddr(self):
        email = '*****@*****.**'
        cases = [
            # (name, address),          charsets            expected
            (('', email), ['ascii', 'utf-8'], '*****@*****.**'),
            (('joe', email), ['ascii', 'utf-8'], '"joe" <*****@*****.**>'),
            (('joe doe', email), ['ascii',
                                  'utf-8'], '"joe doe" <*****@*****.**>'),
            (('joe"doe', email), ['ascii',
                                  'utf-8'], '"joe\\"doe" <*****@*****.**>'),
            (('joé', email), ['ascii'],
             '=?utf-8?b?am/DqQ==?= <*****@*****.**>'),
            (('joé', email), ['utf-8'], '"joé" <*****@*****.**>'),
            (('', 'joé@example.com'), ['ascii', 'utf-8'],
             UnicodeEncodeError),  # need SMTPUTF8 support
            (('', 'joe@examplé.com'), ['ascii', 'utf-8'],
             UnicodeEncodeError),  # need IDNA support
        ]

        for pair, charsets, expected in cases:
            for charset in charsets:
                with self.subTest(pair=pair, charset=charset):
                    if isinstance(expected, str):
                        self.assertEqual(formataddr(pair, charset), expected)
                    else:
                        self.assertRaises(expected, formataddr, pair, charset)
Esempio n. 18
0
    def test_complex_mail_mail_send(self):
        message = self.env['mail.message'].sudo().create({
            'subject':
            'Test',
            'body':
            '<p>Test</p>',
            'author_id':
            self.env.user.partner_id.id,
            'email_from':
            self.env.user.partner_id.email,
            'model':
            'mail.test.container',
            'res_id':
            self.container.id,
        })
        mail = self.env['mail.mail'].sudo().create({
            'body_html':
            '<p>Test</p>',
            'mail_message_id':
            message.id,
            'recipient_ids': [(4, pid) for pid in self.partners.ids],
        })
        mail_ids = mail.ids
        with self.assertQueryCount(__system__=7, emp=7):
            self.env['mail.mail'].sudo().browse(mail_ids).send()

        self.assertEqual(mail.body_html, '<p>Test</p>')
        self.assertEqual(
            mail.reply_to,
            formataddr(('%s %s' % (self.env.company.name, self.container.name),
                        '*****@*****.**')))
Esempio n. 19
0
    def _compose_default_from(self, email=False):
        """
        Compose email based on company setting and
        :param email: Char email address
        :return: formatted email (e.g. "Bob Doe via MyCompany <*****@*****.**>")
        """

        # Check settings.
        # If not using company email fallback to original function
        if not email:
            return False
        user = self.env.user
        company = user.company_id

        if company.add_company_from:
            if company.add_company_mode == 'r':
                name_from = company.name
            else:
                if company.email_joint:
                    name_from = '%s %s %s' % (user.name, company.email_joint,
                                              company.name)
                else:
                    name_from = '%s %s' % (user.name, company.name)
        else:
            name_from = user.name

        return formataddr((name_from, email))
Esempio n. 20
0
    def _create_leads_batch(self, lead_type='lead', count=10, partner_ids=None, user_ids=None):
        """ Helper tool method creating a batch of leads, useful when dealing
        with batch processes. Please update me.

        :param string type: 'lead', 'opportunity', 'mixed' (lead then opp),
          None (depends on configuration);
        """
        types = ['lead', 'opportunity']
        leads_data = [{
            'name': 'TestLead_%02d' % (x),
            'type': lead_type if lead_type else types[x % 2],
            'priority': '%s' % (x % 3),
        } for x in range(count)]

        # customer information
        if partner_ids:
            for idx, lead_data in enumerate(leads_data):
                lead_data['partner_id'] = partner_ids[idx % len(partner_ids)]
        else:
            for idx, lead_data in enumerate(leads_data):
                lead_data['email_from'] = tools.formataddr((
                    'TestCustomer_%02d' % (idx),
                    '*****@*****.**' % (idx)
                ))

        # salesteam information
        if user_ids:
            for idx, lead_data in enumerate(leads_data):
                lead_data['user_id'] = user_ids[idx % len(user_ids)]

        return self.env['crm.lead'].create(leads_data)
Esempio n. 21
0
    def test_message_process_alias_followers_bounce(self):
        """ Incoming email from unknown partner / not follower partner on a Followers only alias -> bounce """
        self.alias.write({
            'alias_contact':
            'followers',
            'alias_parent_model_id':
            self.env['ir.model']._get('mail.test.simple').id,
            'alias_parent_thread_id':
            self.test_record.id,
        })

        # Test: unknown on followers alias -> bounce
        record = self.format_and_process(
            MAIL_TEMPLATE, to='[email protected], [email protected]')
        self.assertEqual(len(record), 0,
                         'message_process: should have bounced')
        self.assertEqual(
            len(self._mails), 1,
            'message_process: incoming email on Followers alias should send a bounce email'
        )

        # Test: partner on followers alias -> bounce
        self._init_mock_build_email()
        record = self.format_and_process(MAIL_TEMPLATE,
                                         email_from=formataddr(
                                             (self.partner_1.name,
                                              self.partner_1.email)))
        self.assertTrue(
            len(record) == 0, 'message_process: should have bounced')
        self.assertEqual(
            len(self._mails), 1,
            'message_process: incoming email on Followers alias should send a bounce email'
        )
Esempio n. 22
0
    def test_move_composer_multi_form(self):
        with self.assertQueryCount(user_account=17):  # acc: 15 / com 15
            account_moves = self.env['account.move'].browse(self.test_account_moves.ids)
            default_ctx = account_moves.action_send_and_print()['context']
            composer_form = Form(self.env['account.invoice.send'].with_context(default_ctx))

        with self.mock_mail_gateway(mail_unlink_sent=True), \
             self.mock_mail_app(), \
             self.assertQueryCount(user_account=510):  # acc: 509 / com 489
            composer = composer_form.save()
            composer.send_and_print_action()

        self.assertEqual(len(self._new_mails), 10)
        for index, move in enumerate(self.test_account_moves):
            if move.partner_id.lang == 'es_ES':
                _exp_subject = 'SpanishSubject for %s' % move.name
                _exp_body_tip = '<p>SpanishBody for %s</p>' % move.name
            else:
                _exp_subject = '%s Invoice (Ref %s)' % (self.env.user.company_id.name, move.name)
                _exp_body_tip = 'Please remit payment at your earliest convenience'

            self.assertEqual(move.partner_id, self.test_customers[index])
            self.assertSentEmail(self.user_account_other.email_formatted,
                                 move.partner_id,
                                 body_content=_exp_body_tip,
                                 subject=_exp_subject,
                                 reply_to=formataddr(
                                    ('%s %s' % (move.company_id.name, move.display_name),
                                     '%s@%s' % (self.alias_catchall, self.alias_domain))
                                 ),
                                )
Esempio n. 23
0
    def test_email_formataddr(self):
        email = '*****@*****.**'
        email_idna = 'joe@examplé.com'
        cases = [
            # (name, address),          charsets            expected
            (('', email), ['ascii', 'utf-8'], '*****@*****.**'),
            (('joe', email), ['ascii', 'utf-8'], '"joe" <*****@*****.**>'),
            (('joe doe', email), ['ascii',
                                  'utf-8'], '"joe doe" <*****@*****.**>'),
            (('joe"doe', email), ['ascii',
                                  'utf-8'], '"joe\\"doe" <*****@*****.**>'),
            (('joé', email), ['ascii'],
             '=?utf-8?b?am/DqQ==?= <*****@*****.**>'),
            (('joé', email), ['utf-8'], '"joé" <*****@*****.**>'),
            (('', email_idna), ['ascii'], '*****@*****.**'),
            (('', email_idna), ['utf-8'], 'joe@examplé.com'),
            (('joé', email_idna), ['ascii'],
             '=?utf-8?b?am/DqQ==?= <*****@*****.**>'),
            (('joé', email_idna), ['utf-8'], '"joé" <joe@examplé.com>'),
            (('', 'joé@example.com'), ['ascii', 'utf-8'], 'joé@example.com'),
        ]

        for pair, charsets, expected in cases:
            for charset in charsets:
                with self.subTest(pair=pair, charset=charset):
                    self.assertEqual(formataddr(pair, charset), expected)
    def test_message_track_template(self):
        """ Update some tracked fields linked to some template -> message with onchange """
        self.record.write({'mail_template': self.env.ref('test_mail.mail_test_full_tracking_tpl').id})
        self.assertEqual(self.record.message_ids, self.env['mail.message'])

        self.record.write({
            'name': 'Test2',
            'customer_id': self.user_admin.partner_id.id,
        })

        self.assertEqual(len(self.record.message_ids), 2, 'should have 2 new messages: one for tracking, one for template')

        # one new message containing the template linked to tracking
        self.assertEqual(self.record.message_ids[0].subject, 'Test Template')
        self.assertEqual(self.record.message_ids[0].body, '<p>Hello Test2</p>')

        # one email send due to template
        self.assertEqual(len(self._mails), 1)
        self.assertEqual(set(self._mails[0]['email_to']), set([formataddr((self.user_admin.name, self.user_admin.email))]))
        self.assertHtmlEqual(self._mails[0]['body'], '<p>Hello Test2</p>')

        # one new message containing tracking; without subtype linked to tracking
        self.assertEqual(self.record.message_ids[1].subtype_id, self.env.ref('mail.mt_note'))
        self.assertTracking(
            self.record.message_ids[1],
            [('customer_id', 'many2one', False, self.user_admin.partner_id)  # onchange tracked field
             ])
Esempio n. 25
0
    def test_notify_from_user_id(self):
        """ Test notify coming from user_id assignment. """
        test_record = self.env['mail.test.track'].create({
            'company_id': self.env.user.company_id.id,
            'email_from': self.env.user.email_formatted,
            'name': 'Test UserId Track',
            'user_id': False,
        })
        self.flush_tracking()

        with self.mock_mail_gateway(), self.mock_mail_app():
            test_record.write({'user_id': self.user_employee_2.id})
            self.flush_tracking()

        self.assertEqual(len(self._new_msgs), 2, 'Should have 2 messages: tracking and assignment')
        assign_notif = self._new_msgs.filtered(lambda msg: msg.message_type == 'user_notification')
        self.assertTrue(assign_notif)
        self.assertMessageFields(
            assign_notif,
            {'author_id': self.partner_employee,
             'email_from': formataddr((self.partner_employee.name, self.partner_employee.email_normalized)),
             'model': test_record._name,
             'notified_partner_ids': self.partner_employee_2,
             'res_id': test_record.id,
             'subtype_id': self.env.ref('mail.mt_note'),
            }
        )
        self.assertIn('Dear %s' % self.partner_employee_2.name, assign_notif.body)
Esempio n. 26
0
    def test_notify_from_user_id_batch(self):
        """ Test notify coming from user_id assignment. """
        test_records, _ = self._create_records_for_batch(
            'mail.test.track', 10, {
                'company_id': self.env.user.company_id.id,
                'email_from': self.env.user.email_formatted,
                'user_id': False,
            }
        )
        test_records = self.env['mail.test.track'].browse(test_records.ids)
        self.flush_tracking()

        with self.mock_mail_gateway(), self.mock_mail_app():
            test_records.write({'user_id': self.user_employee_2.id})
            self.flush_tracking()

        self.assertEqual(len(self._new_msgs), 20, 'Should have 20 messages: 10 tracking and 10 assignments')
        for test_record in test_records:
            assign_notif = self._new_msgs.filtered(lambda msg: msg.message_type == 'user_notification' and msg.res_id == test_record.id)
            self.assertTrue(assign_notif)
            self.assertMessageFields(
                assign_notif,
                {'author_id': self.partner_employee,
                 'email_from': formataddr((self.partner_employee.name, self.partner_employee.email_normalized)),
                 'model': test_record._name,
                 'notified_partner_ids': self.partner_employee_2,
                 'res_id': test_record.id,
                 'subtype_id': self.env.ref('mail.mt_note'),
                }
            )
Esempio n. 27
0
    def _get_default_from(self):
        """
        Check settings and use company's email if forced.
        Make 'From:' look like 'John Smith via Your Company <*****@*****.**>
        """

        # Check settings.
        # If not using company email fallback to original function
        user = self.env.user
        company = user.company_id

        if not company.use_company_email:
            if user.email:
                return formataddr((user.name, user.email))
            raise UserError(
                _("Unable to send email, please configure the sender's email address."
                  ))

        if company.email:
            res = self._compose_default_from(company.email)
            if res:
                return res

        raise UserError(
            _("Unable to send email, please configure company email address."))
Esempio n. 28
0
    def test_post_flow(self):
        channel = self.env['mail.channel'].browse(self.channel.ids)

        msg_admin = channel.message_post(message_type='email',
                                         subtype_xmlid='mail.mt_comment',
                                         author_id=self.partner_admin.id)
        msg_moderator = channel.message_post(
            message_type='comment',
            subtype_xmlid='mail.mt_comment',
            author_id=self.partner_employee.id)
        msg_email1 = channel.message_post(message_type='comment',
                                          subtype_xmlid='mail.mt_comment',
                                          email_from=formataddr(
                                              ("MyName", "*****@*****.**")))
        msg_email2 = channel.message_post(message_type='email',
                                          subtype_xmlid='mail.mt_comment',
                                          email_from="*****@*****.**")
        msg_notif = channel.message_post()

        messages = self.env['mail.message'].search([
            ('model', '=', 'mail.channel'), ('res_id', '=', channel.id)
        ])
        pending_messages = messages.filtered(
            lambda m: m.moderation_status == 'pending_moderation')
        accepted_messages = messages.filtered(
            lambda m: m.moderation_status == 'accepted')

        self.assertFalse(msg_email1)
        self.assertEqual(msg_admin, pending_messages)
        self.assertEqual(accepted_messages,
                         msg_moderator | msg_email2 | msg_notif)
        self.assertFalse(msg_admin.channel_ids)
        self.assertEqual(msg_email2.channel_ids, channel)
Esempio n. 29
0
 def _create_new_message(self,
                         channel_id,
                         status='pending_moderation',
                         author=None,
                         body='',
                         message_type="email"):
     author = author if author else self.env.user.partner_id
     message = self.env['mail.message'].create({
         'model':
         'mail.channel',
         'res_id':
         channel_id,
         'message_type':
         'email',
         'body':
         body,
         'moderation_status':
         status,
         'author_id':
         author.id,
         'email_from':
         formataddr((author.name, author.email)),
         'subtype_id':
         self.env['mail.message.subtype'].search([('name', '=',
                                                   'Discussions')]).id
     })
     return message
Esempio n. 30
0
    def test_message_process_alias_update(self):
        """ Incoming email update discussion + notification email """
        self.alias.write({'alias_force_thread_id': self.test_record.id})

        self.test_record.message_subscribe(partner_ids=[self.partner_1.id])
        record = self.format_and_process(
            MAIL_TEMPLATE,
            email_from='*****@*****.**',
            msg_id=
            '<*****@*****.**>',
            to='*****@*****.**>',
            subject='Re: cats')

        # Test: no new group + new message
        self.assertEqual(
            len(record), 0,
            'message_process: alias update should not create new records')
        self.assertEqual(len(self.test_record.message_ids), 2)
        # Test: sent emails: 1 (Sylvie copy of the incoming email)
        self.assertEqual(
            len(self._mails), 1,
            'message_process: one email should have been generated')
        self.assertEqual(
            formataddr((self.partner_1.name, self.partner_1.email)),
            self._mails[0].get('email_to')[0],
            'message_process: email should be sent to Sylvie')