[MIG] test_new_api: convert tests and remove old-API specific ones
This commit is contained in:
@@ -26,8 +26,6 @@
|
||||
<field name="discussion" ref="discussion_0"/>
|
||||
<field name="body">This is a much longer message</field>
|
||||
</record>
|
||||
<record id="c1" model="test_old_api.function_counter">
|
||||
</record>
|
||||
|
||||
<record id="bool_1" model="domain.bool">
|
||||
<field name="bool_true" eval="True"/>
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
"id","name","model_id:id","group_id:id","perm_read","perm_write","perm_create","perm_unlink"
|
||||
access_test_new_api_alpha,access_test_new_api_alpha,model_test_new_api_alpha,,1,0,0,0
|
||||
access_test_new_api_bravo,access_test_new_api_bravo,model_test_new_api_bravo,,1,0,0,0
|
||||
access_category,test_new_api_category,test_new_api.model_test_new_api_category,,1,1,1,1
|
||||
access_discussion,test_new_api_discussion,test_new_api.model_test_new_api_discussion,,1,1,1,1
|
||||
access_message,test_new_api_message,test_new_api.model_test_new_api_message,,1,1,1,1
|
||||
@@ -8,8 +6,8 @@ access_emailmessage,test_new_api_emailmessage,test_new_api.model_test_new_api_em
|
||||
access_multi,test_new_api_multi,test_new_api.model_test_new_api_multi,,1,1,1,1
|
||||
access_multi_line,test_new_api_multi_line,test_new_api.model_test_new_api_multi_line,,1,1,1,1
|
||||
access_mixed,test_new_api_mixed,test_new_api.model_test_new_api_mixed,,1,1,1,1
|
||||
access_test_function_noinfiniterecursion,access_test_function_noinfiniterecursion,model_test_old_api_function_noinfiniterecursion,,1,1,1,1
|
||||
access_test_function_counter,access_test_function_counter,model_test_old_api_function_counter,,1,1,1,1
|
||||
access_domain_bool,access_domain_bool,model_domain_bool,,1,1,1,1
|
||||
access_test_new_api_foo,access_test_new_api_foo,model_test_new_api_foo,,1,1,1,1
|
||||
access_test_new_api_bar,access_test_new_api_bar,model_test_new_api_bar,,1,1,1,1
|
||||
access_test_new_api_related,access_test_new_api_related,model_test_new_api_related,,1,1,1,1
|
||||
access_test_new_api_company,access_test_new_api_company,model_test_new_api_company,,1,1,1,1
|
||||
|
||||
|
@@ -2,78 +2,9 @@
|
||||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import datetime
|
||||
from openerp.exceptions import AccessError
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# OLD API
|
||||
#
|
||||
##############################################################################
|
||||
from openerp.osv import osv, fields
|
||||
|
||||
|
||||
class Alpha(osv.Model):
|
||||
_name = 'test_new_api.alpha'
|
||||
_columns = {
|
||||
'name': fields.char(),
|
||||
}
|
||||
|
||||
class Bravo(osv.Model):
|
||||
_name = 'test_new_api.bravo'
|
||||
_columns = {
|
||||
'alpha_id': fields.many2one('test_new_api.alpha'),
|
||||
# a related field with a non-trivial path
|
||||
'alpha_name': fields.related('alpha_id', 'name', type='char'),
|
||||
# a related field with a single field
|
||||
'related_alpha_id': fields.related('alpha_id', type='many2one', obj='test_new_api.alpha'),
|
||||
# a related field with a single field that is also a related field!
|
||||
'related_related_alpha_id': fields.related('related_alpha_id', type='many2one', obj='test_new_api.alpha'),
|
||||
}
|
||||
|
||||
|
||||
class TestFunctionCounter(osv.Model):
|
||||
_name = 'test_old_api.function_counter'
|
||||
|
||||
def _compute_cnt(self, cr, uid, ids, fname, arg, context=None):
|
||||
res = {}
|
||||
for cnt in self.browse(cr, uid, ids, context=context):
|
||||
res[cnt.id] = cnt.access and cnt.cnt + 1 or 0
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'access': fields.datetime('Datetime Field'),
|
||||
'cnt': fields.function(
|
||||
_compute_cnt, type='integer', string='Function Field', store=True),
|
||||
}
|
||||
|
||||
|
||||
class TestFunctionNoInfiniteRecursion(osv.Model):
|
||||
_name = 'test_old_api.function_noinfiniterecursion'
|
||||
|
||||
def _compute_f1(self, cr, uid, ids, fname, arg, context=None):
|
||||
res = {}
|
||||
for tf in self.browse(cr, uid, ids, context=context):
|
||||
res[tf.id] = 'create' in tf.f0 and 'create' or 'write'
|
||||
cntobj = self.pool['test_old_api.function_counter']
|
||||
cnt_id = self.pool['ir.model.data'].xmlid_to_res_id(
|
||||
cr, uid, 'test_new_api.c1')
|
||||
cntobj.write(
|
||||
cr, uid, cnt_id, {'access': datetime.datetime.now()},
|
||||
context=context)
|
||||
return res
|
||||
|
||||
_columns = {
|
||||
'f0': fields.char('Char Field'),
|
||||
'f1': fields.function(
|
||||
_compute_f1, type='char', string='Function Field', store=True),
|
||||
}
|
||||
|
||||
##############################################################################
|
||||
#
|
||||
# NEW API
|
||||
#
|
||||
##############################################################################
|
||||
from openerp import models, fields, api, _
|
||||
from openerp.exceptions import AccessError
|
||||
|
||||
|
||||
class Category(models.Model):
|
||||
@@ -117,6 +48,7 @@ class Category(models.Model):
|
||||
raise AccessError('Sorry')
|
||||
return super(Category, self).read(fields=fields, load=load)
|
||||
|
||||
|
||||
class Discussion(models.Model):
|
||||
_name = 'test_new_api.discussion'
|
||||
|
||||
@@ -221,6 +153,7 @@ class EmailMessage(models.Model):
|
||||
required=True, ondelete='cascade')
|
||||
email_to = fields.Char('To')
|
||||
|
||||
|
||||
class Multi(models.Model):
|
||||
""" Model for testing multiple onchange methods in cascade that modify a
|
||||
one2many field several times.
|
||||
@@ -314,6 +247,15 @@ class Bar(models.Model):
|
||||
bar.foo = self.env['test_new_api.foo'].search([('name', '=', bar.name)], limit=1)
|
||||
|
||||
|
||||
class Related(models.Model):
|
||||
_name = 'test_new_api.related'
|
||||
|
||||
name = fields.Char()
|
||||
# related fields with a single field
|
||||
related_name = fields.Char(related='name')
|
||||
related_related_name = fields.Char(related='related_name')
|
||||
|
||||
|
||||
class ComputeInverse(models.Model):
|
||||
_name = 'test_new_api.compute.inverse'
|
||||
|
||||
@@ -332,3 +274,9 @@ class ComputeInverse(models.Model):
|
||||
self.counts['inverse'] += 1
|
||||
for record in self:
|
||||
record.foo = record.bar
|
||||
|
||||
|
||||
class CompanyDependent(models.Model):
|
||||
_name = 'test_new_api.company'
|
||||
|
||||
foo = fields.Char(company_dependent=True)
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from . import test_related
|
||||
from . import test_new_fields
|
||||
from . import test_onchange
|
||||
from . import test_field_conversions
|
||||
from . import test_attributes
|
||||
from . import test_ui
|
||||
from . import test_no_infinite_recursion
|
||||
from . import test_domain
|
||||
|
||||
@@ -8,7 +8,7 @@ from openerp.tests import common
|
||||
from openerp.tools import mute_logger
|
||||
|
||||
|
||||
class TestNewFields(common.TransactionCase):
|
||||
class TestFields(common.TransactionCase):
|
||||
|
||||
def test_00_basics(self):
|
||||
""" test accessing new fields """
|
||||
@@ -405,6 +405,26 @@ class TestNewFields(common.TransactionCase):
|
||||
discussion_field = discussion.fields_get(['name'])['name']
|
||||
self.assertEqual(message_field['help'], discussion_field['help'])
|
||||
|
||||
def test_25_related_single(self):
|
||||
""" test related fields with a single field in the path. """
|
||||
record = self.env['test_new_api.related'].create({'name': 'A'})
|
||||
self.assertEqual(record.related_name, record.name)
|
||||
self.assertEqual(record.related_related_name, record.name)
|
||||
|
||||
# check searching on related fields
|
||||
records0 = record.search([('name', '=', 'A')])
|
||||
self.assertIn(record, records0)
|
||||
records1 = record.search([('related_name', '=', 'A')])
|
||||
self.assertEqual(records1, records0)
|
||||
records2 = record.search([('related_related_name', '=', 'A')])
|
||||
self.assertEqual(records2, records0)
|
||||
|
||||
# check writing on related fields
|
||||
record.write({'related_name': 'B'})
|
||||
self.assertEqual(record.name, 'B')
|
||||
record.write({'related_related_name': 'C'})
|
||||
self.assertEqual(record.name, 'C')
|
||||
|
||||
def test_25_related_multi(self):
|
||||
""" test write() on several related fields based on a common computed field. """
|
||||
foo = self.env['test_new_api.foo'].create({'name': 'A', 'value1': 1, 'value2': 2})
|
||||
@@ -427,6 +447,38 @@ class TestNewFields(common.TransactionCase):
|
||||
self.assertEqual(getattr(user, field), getattr(partner, field))
|
||||
self.assertEqual(user[field], partner[field])
|
||||
|
||||
def test_27_company_dependent(self):
|
||||
""" test company-dependent fields. """
|
||||
# consider three companies
|
||||
company0 = self.env.ref('base.main_company')
|
||||
company1 = self.env['res.company'].create({'name': 'A', 'parent_id': company0.id})
|
||||
company2 = self.env['res.company'].create({'name': 'B', 'parent_id': company1.id})
|
||||
# create one user per company
|
||||
user0 = self.env['res.users'].create({'name': 'Foo', 'login': 'foo',
|
||||
'company_id': company0.id, 'company_ids': []})
|
||||
user1 = self.env['res.users'].create({'name': 'Bar', 'login': 'bar',
|
||||
'company_id': company1.id, 'company_ids': []})
|
||||
user2 = self.env['res.users'].create({'name': 'Baz', 'login': 'baz',
|
||||
'company_id': company2.id, 'company_ids': []})
|
||||
# create a default value for the company-dependent field
|
||||
field = self.env['ir.model.fields'].search([('model', '=', 'test_new_api.company'),
|
||||
('name', '=', 'foo')])
|
||||
self.env['ir.property'].create({'name': 'foo', 'fields_id': field.id,
|
||||
'value': 'default', 'type': 'char'})
|
||||
|
||||
# create/modify a record, and check the value for each user
|
||||
record = self.env['test_new_api.company'].create({'foo': 'main'})
|
||||
record.invalidate_cache()
|
||||
self.assertEqual(record.sudo(user0).foo, 'main')
|
||||
self.assertEqual(record.sudo(user1).foo, 'default')
|
||||
self.assertEqual(record.sudo(user2).foo, 'default')
|
||||
|
||||
record.sudo(user1).foo = 'alpha'
|
||||
record.invalidate_cache()
|
||||
self.assertEqual(record.sudo(user0).foo, 'main')
|
||||
self.assertEqual(record.sudo(user1).foo, 'alpha')
|
||||
self.assertEqual(record.sudo(user2).foo, 'default')
|
||||
|
||||
def test_30_read(self):
|
||||
""" test computed fields as returned by read(). """
|
||||
discussion = self.env.ref('test_new_api.discussion_0')
|
||||
@@ -545,6 +597,57 @@ class TestNewFields(common.TransactionCase):
|
||||
self.assertIn(message, discussion.important_messages)
|
||||
|
||||
|
||||
class TestHtmlField(common.TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestHtmlField, self).setUp()
|
||||
self.model = self.env['test_new_api.mixed']
|
||||
|
||||
def test_00_sanitize(self):
|
||||
self.assertEqual(self.model._fields['comment1'].sanitize, False)
|
||||
self.assertEqual(self.model._fields['comment2'].sanitize, True)
|
||||
self.assertEqual(self.model._fields['comment2'].strip_classes, False)
|
||||
self.assertEqual(self.model._fields['comment3'].sanitize, True)
|
||||
self.assertEqual(self.model._fields['comment3'].strip_classes, True)
|
||||
|
||||
some_ugly_html = """<p>Oops this should maybe be sanitized
|
||||
% if object.some_field and not object.oriented:
|
||||
<table>
|
||||
% if object.other_field:
|
||||
<tr style="margin: 0px; border: 10px solid black;">
|
||||
${object.mako_thing}
|
||||
<td>
|
||||
</tr>
|
||||
<tr class="custom_class">
|
||||
This is some html.
|
||||
</tr>
|
||||
% endif
|
||||
<tr>
|
||||
%if object.dummy_field:
|
||||
<p>Youpie</p>
|
||||
%endif"""
|
||||
|
||||
record = self.model.create({
|
||||
'comment1': some_ugly_html,
|
||||
'comment2': some_ugly_html,
|
||||
'comment3': some_ugly_html,
|
||||
'comment4': some_ugly_html,
|
||||
})
|
||||
|
||||
self.assertEqual(record.comment1, some_ugly_html, 'Error in HTML field: content was sanitized but field has sanitize=False')
|
||||
|
||||
self.assertIn('<tr class="', record.comment2)
|
||||
|
||||
# sanitize should have closed tags left open in the original html
|
||||
self.assertIn('</table>', record.comment3, 'Error in HTML field: content does not seem to have been sanitized despise sanitize=True')
|
||||
self.assertIn('</td>', record.comment3, 'Error in HTML field: content does not seem to have been sanitized despise sanitize=True')
|
||||
self.assertIn('<tr style="', record.comment3, 'Style attr should not have been stripped')
|
||||
# sanitize does not keep classes if asked to
|
||||
self.assertNotIn('<tr class="', record.comment3)
|
||||
|
||||
self.assertNotIn('<tr style="', record.comment4, 'Style attr should have been stripped')
|
||||
|
||||
|
||||
class TestMagicFields(common.TransactionCase):
|
||||
|
||||
def test_write_date(self):
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from openerp.tests import common
|
||||
|
||||
|
||||
class test_no_infinite_recursion(common.TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(test_no_infinite_recursion, self).setUp()
|
||||
self.tstfct = self.registry['test_old_api.function_noinfiniterecursion']
|
||||
|
||||
def test_00_create_and_update(self):
|
||||
"""
|
||||
Check that computing old api function field does not cycle infinitely
|
||||
See https://github.com/odoo/odoo/pull/7558
|
||||
"""
|
||||
cr, uid, context, tstfct = self.cr, self.uid, {}, self.tstfct
|
||||
|
||||
vals = {
|
||||
'f0': 'Test create',
|
||||
}
|
||||
idnew = tstfct.create(cr, uid, vals, context=context)
|
||||
tst = tstfct.browse(cr, uid, idnew, context=context)
|
||||
|
||||
self.assertEqual(tst.f1, 'create')
|
||||
|
||||
vals = {
|
||||
'f0': 'Test write',
|
||||
}
|
||||
tstfct.write(cr, uid, idnew, vals, context=context)
|
||||
|
||||
self.assertEqual(tst.f1, 'write')
|
||||
@@ -1,172 +0,0 @@
|
||||
#
|
||||
# test cases for related fields, etc.
|
||||
#
|
||||
import unittest
|
||||
|
||||
from openerp.osv import fields
|
||||
from openerp.tests import common
|
||||
|
||||
class TestRelatedField(common.TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestRelatedField, self).setUp()
|
||||
self.alpha = self.registry('test_new_api.alpha')
|
||||
self.bravo = self.registry('test_new_api.bravo')
|
||||
self.alpha_id = self.alpha.create(self.cr, self.uid, {'name': 'Alpha'})
|
||||
self.alpha.create(self.cr, self.uid, {'name': 'Beta'})
|
||||
self.bravo.create(self.cr, self.uid, {'alpha_id': self.alpha_id})
|
||||
|
||||
def test_0_related(self):
|
||||
""" test an usual related field """
|
||||
# find bravos that satisfy [('alpha_id.name', '=', 'Alpha')]
|
||||
alpha_ids = self.alpha.search(self.cr, self.uid, [('name', '=', 'Alpha')])
|
||||
bravo_ids1 = self.bravo.search(self.cr, self.uid, [('alpha_id', 'in', alpha_ids)])
|
||||
bravo_ids2 = self.bravo.search(self.cr, self.uid, [('alpha_name', '=', 'Alpha')])
|
||||
self.assertEqual(bravo_ids1, bravo_ids2)
|
||||
|
||||
def do_test_company_field(self, field):
|
||||
# get a bravo with a non-null alpha_id
|
||||
ids = self.bravo.search(self.cr, self.uid, [('alpha_id', '!=', False)])
|
||||
bravo = self.bravo.browse(self.cr, self.uid, ids[0])
|
||||
|
||||
# check reading related field
|
||||
self.assertEqual(bravo[field], bravo.alpha_id)
|
||||
|
||||
# check that search on related field is equivalent to original field
|
||||
ids1 = self.bravo.search(self.cr, self.uid, [('alpha_id', '=', bravo.alpha_id.id)])
|
||||
ids2 = self.bravo.search(self.cr, self.uid, [(field, '=', bravo.alpha_id.id)])
|
||||
self.assertEqual(ids1, ids2)
|
||||
|
||||
def test_1_single_related(self):
|
||||
""" test a related field with a single indirection like fields.related('foo') """
|
||||
self.do_test_company_field('related_alpha_id')
|
||||
|
||||
def test_2_double_related(self):
|
||||
""" test a related field referring to a related field """
|
||||
self.do_test_company_field('related_related_alpha_id')
|
||||
|
||||
def test_3_read_write(self):
|
||||
""" write on a related field """
|
||||
# find an alpha with a non-null name
|
||||
alpha = self.alpha.browse(self.cr, self.uid, self.alpha_id)
|
||||
self.assertTrue(alpha.name)
|
||||
|
||||
# find partners that satisfy [('alpha_id.name', '=', alpha.name)]
|
||||
bravo_ids = self.bravo.search(self.cr, self.uid, [('alpha_name', '=', alpha.name)])
|
||||
self.assertTrue(bravo_ids)
|
||||
bravo = self.bravo.browse(self.cr, self.uid, bravo_ids[0])
|
||||
|
||||
# change the name of alpha through the related field, and check result
|
||||
NAME = 'Monthy Pythons'
|
||||
bravo.write({'alpha_name': NAME})
|
||||
self.assertEqual(bravo.alpha_id.name, NAME)
|
||||
self.assertEqual(bravo.alpha_name, NAME)
|
||||
|
||||
|
||||
class TestPropertyField(common.TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestPropertyField, self).setUp()
|
||||
self.user = self.registry('res.users')
|
||||
self.partner = self.registry('res.partner')
|
||||
self.company = self.registry('res.company')
|
||||
self.country = self.registry('res.country')
|
||||
self.property = self.registry('ir.property')
|
||||
self.imd = self.registry('ir.model.data')
|
||||
|
||||
@unittest.skip("invalid monkey-patching")
|
||||
def test_1_property_multicompany(self):
|
||||
cr, uid = self.cr, self.uid
|
||||
|
||||
parent_company_id = self.imd.get_object_reference(cr, uid, 'base', 'main_company')[1]
|
||||
country_be = self.imd.get_object_reference(cr, uid, 'base', 'be')[1]
|
||||
country_fr = self.imd.get_object_reference(cr, uid, 'base', 'fr')[1]
|
||||
group_partner_manager = self.imd.get_object_reference(cr, uid, 'base', 'group_partner_manager')[1]
|
||||
group_multi_company = self.imd.get_object_reference(cr, uid, 'base', 'group_multi_company')[1]
|
||||
|
||||
sub_company = self.company.create(cr, uid, {'name': 'MegaCorp', 'parent_id': parent_company_id})
|
||||
alice = self.user.create(cr, uid, {'name': 'Alice',
|
||||
'login':'alice',
|
||||
'email':'alice@youcompany.com',
|
||||
'company_id':parent_company_id,
|
||||
'company_ids':[(6, 0, [parent_company_id, sub_company])],
|
||||
'country_id':country_be,
|
||||
'groups_id': [(6, 0, [group_partner_manager, group_multi_company])]
|
||||
})
|
||||
bob = self.user.create(cr, uid, {'name': 'Bob',
|
||||
'login':'bob',
|
||||
'email':'bob@megacorp.com',
|
||||
'company_id':sub_company,
|
||||
'company_ids':[(6, 0, [parent_company_id, sub_company])],
|
||||
'country_id':country_fr,
|
||||
'groups_id': [(6, 0, [group_partner_manager, group_multi_company])]
|
||||
})
|
||||
|
||||
self.partner._columns = dict(self.partner._columns)
|
||||
self.partner._columns.update({
|
||||
'property_country': fields.property(type='many2one', relation="res.country", string="Country by company"),
|
||||
})
|
||||
self.partner._field_create(cr)
|
||||
|
||||
partner_id = self.partner.create(cr, alice, {
|
||||
'name': 'An International Partner',
|
||||
'email': 'partner@example.com',
|
||||
'company_id': parent_company_id,
|
||||
})
|
||||
self.partner.write(cr, bob, [partner_id], {'property_country': country_fr})
|
||||
self.assertEqual(self.partner.browse(cr, bob, partner_id).property_country.id, country_fr, "Bob does not see the value he has set on the property field")
|
||||
|
||||
self.partner.write(cr, alice, [partner_id], {'property_country': country_be})
|
||||
self.assertEqual(self.partner.browse(cr, alice, partner_id).property_country.id, country_be, "Alice does not see the value he has set on the property field")
|
||||
self.assertEqual(self.partner.browse(cr, bob, partner_id).property_country.id, country_fr, "Changes made by Alice have overwritten Bob's value")
|
||||
|
||||
|
||||
class TestHtmlField(common.TransactionCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestHtmlField, self).setUp()
|
||||
self.model = self.env['test_new_api.mixed']
|
||||
|
||||
def test_00_sanitize(self):
|
||||
self.assertEqual(self.model._fields['comment1'].sanitize, False)
|
||||
self.assertEqual(self.model._fields['comment2'].sanitize, True)
|
||||
self.assertEqual(self.model._fields['comment2'].strip_classes, False)
|
||||
self.assertEqual(self.model._fields['comment3'].sanitize, True)
|
||||
self.assertEqual(self.model._fields['comment3'].strip_classes, True)
|
||||
|
||||
some_ugly_html = """<p>Oops this should maybe be sanitized
|
||||
% if object.some_field and not object.oriented:
|
||||
<table>
|
||||
% if object.other_field:
|
||||
<tr style="margin: 0px; border: 10px solid black;">
|
||||
${object.mako_thing}
|
||||
<td>
|
||||
</tr>
|
||||
<tr class="custom_class">
|
||||
This is some html.
|
||||
</tr>
|
||||
% endif
|
||||
<tr>
|
||||
%if object.dummy_field:
|
||||
<p>Youpie</p>
|
||||
%endif"""
|
||||
|
||||
record = self.model.create({
|
||||
'comment1': some_ugly_html,
|
||||
'comment2': some_ugly_html,
|
||||
'comment3': some_ugly_html,
|
||||
'comment4': some_ugly_html,
|
||||
})
|
||||
|
||||
self.assertEqual(record.comment1, some_ugly_html, 'Error in HTML field: content was sanitized but field has sanitize=False')
|
||||
|
||||
self.assertIn('<tr class="', record.comment2)
|
||||
|
||||
# sanitize should have closed tags left open in the original html
|
||||
self.assertIn('</table>', record.comment3, 'Error in HTML field: content does not seem to have been sanitized despise sanitize=True')
|
||||
self.assertIn('</td>', record.comment3, 'Error in HTML field: content does not seem to have been sanitized despise sanitize=True')
|
||||
self.assertIn('<tr style="', record.comment3, 'Style attr should not have been stripped')
|
||||
# sanitize does not keep classes if asked to
|
||||
self.assertNotIn('<tr class="', record.comment3)
|
||||
|
||||
self.assertNotIn('<tr style="', record.comment4, 'Style attr should have been stripped')
|
||||
Reference in New Issue
Block a user