397 lines
15 KiB
Python
397 lines
15 KiB
Python
#
|
|
# test cases for new-style fields
|
|
#
|
|
from datetime import date, datetime
|
|
from collections import defaultdict
|
|
|
|
from openerp.exceptions import AccessError
|
|
from openerp.tests import common
|
|
from openerp.exceptions import except_orm
|
|
|
|
|
|
class TestNewFields(common.TransactionCase):
|
|
|
|
def test_00_basics(self):
|
|
""" test accessing new fields """
|
|
# find a discussion
|
|
discussion = self.env.ref('test_new_api.discussion_0')
|
|
|
|
# read field as a record attribute or as a record item
|
|
self.assertIsInstance(discussion.name, basestring)
|
|
self.assertIsInstance(discussion['name'], basestring)
|
|
self.assertEqual(discussion['name'], discussion.name)
|
|
|
|
# read it with method read()
|
|
values = discussion.read(['name'])[0]
|
|
self.assertEqual(values['name'], discussion.name)
|
|
|
|
def test_01_basic_get_assertion(self):
|
|
""" test item getter """
|
|
# field access works on single record
|
|
record = self.env.ref('test_new_api.message_0_0')
|
|
self.assertEqual(len(record), 1)
|
|
ok = record.body
|
|
|
|
# field access fails on multiple records
|
|
records = self.env['test_new_api.message'].search([])
|
|
assert len(records) > 1
|
|
with self.assertRaises(except_orm):
|
|
faulty = records.body
|
|
|
|
def test_01_basic_set_assertion(self):
|
|
""" test item setter """
|
|
# field assignment works on single record
|
|
record = self.env.ref('test_new_api.message_0_0')
|
|
self.assertEqual(len(record), 1)
|
|
record.body = 'OK'
|
|
|
|
# field assignment fails on multiple records
|
|
records = self.env['test_new_api.message'].search([])
|
|
assert len(records) > 1
|
|
with self.assertRaises(except_orm):
|
|
records.body = 'Faulty'
|
|
|
|
def test_10_computed(self):
|
|
""" check definition of computed fields """
|
|
# by default function fields are not stored and readonly
|
|
field = self.env['test_new_api.message']._fields['size']
|
|
self.assertFalse(field.store)
|
|
self.assertTrue(field.readonly)
|
|
|
|
field = self.env['test_new_api.message']._fields['name']
|
|
self.assertTrue(field.store)
|
|
self.assertTrue(field.readonly)
|
|
|
|
def test_10_non_stored(self):
|
|
""" test non-stored fields """
|
|
# find messages
|
|
for message in self.env['test_new_api.message'].search([]):
|
|
# check definition of field
|
|
self.assertEqual(message.size, len(message.body or ''))
|
|
|
|
# check recomputation after record is modified
|
|
size = message.size
|
|
message.write({'body': (message.body or '') + "!!!"})
|
|
self.assertEqual(message.size, size + 3)
|
|
|
|
# special case: computed field without dependency must be computed
|
|
record = self.env['test_new_api.mixed'].create({})
|
|
self.assertTrue(record.now)
|
|
|
|
def test_11_stored(self):
|
|
""" test stored fields """
|
|
# find the demo discussion
|
|
discussion = self.env.ref('test_new_api.discussion_0')
|
|
self.assertTrue(len(discussion.messages) > 0)
|
|
|
|
# check messages
|
|
name0 = discussion.name or ""
|
|
for message in discussion.messages:
|
|
self.assertEqual(message.name, "[%s] %s" % (name0, message.author.name))
|
|
|
|
# modify discussion name, and check again messages
|
|
discussion.name = name1 = 'Talking about stuff...'
|
|
for message in discussion.messages:
|
|
self.assertEqual(message.name, "[%s] %s" % (name1, message.author.name))
|
|
|
|
# switch message from discussion, and check again
|
|
name2 = 'Another discussion'
|
|
discussion2 = discussion.copy({'name': name2})
|
|
message2 = discussion.messages[0]
|
|
message2.discussion = discussion2
|
|
for message in discussion2.messages:
|
|
self.assertEqual(message.name, "[%s] %s" % (name2, message.author.name))
|
|
|
|
def test_12_recursive(self):
|
|
""" test recursively dependent fields """
|
|
Category = self.env['test_new_api.category']
|
|
abel = Category.create({'name': 'Abel'})
|
|
beth = Category.create({'name': 'Bethany'})
|
|
cath = Category.create({'name': 'Catherine'})
|
|
dean = Category.create({'name': 'Dean'})
|
|
ewan = Category.create({'name': 'Ewan'})
|
|
finn = Category.create({'name': 'Finnley'})
|
|
gabe = Category.create({'name': 'Gabriel'})
|
|
|
|
cath.parent = finn.parent = gabe
|
|
abel.parent = beth.parent = cath
|
|
dean.parent = ewan.parent = finn
|
|
|
|
self.assertEqual(abel.display_name, "Gabriel / Catherine / Abel")
|
|
self.assertEqual(beth.display_name, "Gabriel / Catherine / Bethany")
|
|
self.assertEqual(cath.display_name, "Gabriel / Catherine")
|
|
self.assertEqual(dean.display_name, "Gabriel / Finnley / Dean")
|
|
self.assertEqual(ewan.display_name, "Gabriel / Finnley / Ewan")
|
|
self.assertEqual(finn.display_name, "Gabriel / Finnley")
|
|
self.assertEqual(gabe.display_name, "Gabriel")
|
|
|
|
ewan.parent = cath
|
|
self.assertEqual(ewan.display_name, "Gabriel / Catherine / Ewan")
|
|
|
|
cath.parent = finn
|
|
self.assertEqual(ewan.display_name, "Gabriel / Finnley / Catherine / Ewan")
|
|
|
|
def test_12_cascade(self):
|
|
""" test computed field depending on computed field """
|
|
message = self.env.ref('test_new_api.message_0_0')
|
|
message.invalidate_cache()
|
|
double_size = message.double_size
|
|
self.assertEqual(double_size, message.size)
|
|
|
|
def test_13_inverse(self):
|
|
""" test inverse computation of fields """
|
|
Category = self.env['test_new_api.category']
|
|
abel = Category.create({'name': 'Abel'})
|
|
beth = Category.create({'name': 'Bethany'})
|
|
cath = Category.create({'name': 'Catherine'})
|
|
dean = Category.create({'name': 'Dean'})
|
|
ewan = Category.create({'name': 'Ewan'})
|
|
finn = Category.create({'name': 'Finnley'})
|
|
gabe = Category.create({'name': 'Gabriel'})
|
|
self.assertEqual(ewan.display_name, "Ewan")
|
|
|
|
ewan.display_name = "Abel / Bethany / Catherine / Erwan"
|
|
|
|
self.assertEqual(beth.parent, abel)
|
|
self.assertEqual(cath.parent, beth)
|
|
self.assertEqual(ewan.parent, cath)
|
|
self.assertEqual(ewan.name, "Erwan")
|
|
|
|
def test_14_search(self):
|
|
""" test search on computed fields """
|
|
discussion = self.env.ref('test_new_api.discussion_0')
|
|
|
|
# determine message sizes
|
|
sizes = set(message.size for message in discussion.messages)
|
|
|
|
# search for messages based on their size
|
|
for size in sizes:
|
|
messages0 = self.env['test_new_api.message'].search(
|
|
[('discussion', '=', discussion.id), ('size', '<=', size)])
|
|
|
|
messages1 = self.env['test_new_api.message'].browse()
|
|
for message in discussion.messages:
|
|
if message.size <= size:
|
|
messages1 += message
|
|
|
|
self.assertEqual(messages0, messages1)
|
|
|
|
def test_15_constraint(self):
|
|
""" test new-style Python constraints """
|
|
discussion = self.env.ref('test_new_api.discussion_0')
|
|
|
|
# remove oneself from discussion participants: we can no longer create
|
|
# messages in discussion
|
|
discussion.participants -= self.env.user
|
|
with self.assertRaises(Exception):
|
|
self.env['test_new_api.message'].create({'discussion': discussion.id, 'body': 'Whatever'})
|
|
|
|
# make sure that assertRaises() does not leave fields to recompute
|
|
self.assertFalse(self.env.has_todo())
|
|
|
|
# put back oneself into discussion participants: now we can create
|
|
# messages in discussion
|
|
discussion.participants += self.env.user
|
|
self.env['test_new_api.message'].create({'discussion': discussion.id, 'body': 'Whatever'})
|
|
|
|
def test_20_float(self):
|
|
""" test float fields """
|
|
record = self.env['test_new_api.mixed'].create({})
|
|
|
|
# assign value, and expect rounding
|
|
record.write({'number': 2.4999999999999996})
|
|
self.assertEqual(record.number, 2.50)
|
|
|
|
# same with field setter
|
|
record.number = 2.4999999999999996
|
|
self.assertEqual(record.number, 2.50)
|
|
|
|
def test_21_date(self):
|
|
""" test date fields """
|
|
record = self.env['test_new_api.mixed'].create({})
|
|
|
|
# one may assign False or None
|
|
record.date = None
|
|
self.assertFalse(record.date)
|
|
|
|
# one may assign date and datetime objects
|
|
record.date = date(2012, 05, 01)
|
|
self.assertEqual(record.date, '2012-05-01')
|
|
|
|
record.date = datetime(2012, 05, 01, 10, 45, 00)
|
|
self.assertEqual(record.date, '2012-05-01')
|
|
|
|
# one may assign dates in the default format, and it must be checked
|
|
record.date = '2012-05-01'
|
|
self.assertEqual(record.date, '2012-05-01')
|
|
|
|
with self.assertRaises(ValueError):
|
|
record.date = '12-5-1'
|
|
|
|
def test_22_selection(self):
|
|
""" test selection fields """
|
|
record = self.env['test_new_api.mixed'].create({})
|
|
|
|
# one may assign False or None
|
|
record.lang = None
|
|
self.assertFalse(record.lang)
|
|
|
|
# one may assign a value, and it must be checked
|
|
for language in self.env['res.lang'].search([]):
|
|
record.lang = language.code
|
|
with self.assertRaises(ValueError):
|
|
record.lang = 'zz_ZZ'
|
|
|
|
def test_23_relation(self):
|
|
""" test relation fields """
|
|
demo = self.env.ref('base.user_demo')
|
|
message = self.env.ref('test_new_api.message_0_0')
|
|
|
|
# check environment of record and related records
|
|
self.assertEqual(message.env, self.env)
|
|
self.assertEqual(message.discussion.env, self.env)
|
|
|
|
demo_env = self.env(user=demo)
|
|
self.assertNotEqual(demo_env, self.env)
|
|
|
|
# check environment of record and related records
|
|
self.assertEqual(message.env, self.env)
|
|
self.assertEqual(message.discussion.env, self.env)
|
|
|
|
# "migrate" message into demo_env, and check again
|
|
demo_message = message.sudo(demo)
|
|
self.assertEqual(demo_message.env, demo_env)
|
|
self.assertEqual(demo_message.discussion.env, demo_env)
|
|
|
|
# assign record's parent to a record in demo_env
|
|
message.discussion = message.discussion.copy({'name': 'Copy'})
|
|
|
|
# both message and its parent field must be in self.env
|
|
self.assertEqual(message.env, self.env)
|
|
self.assertEqual(message.discussion.env, self.env)
|
|
|
|
def test_24_reference(self):
|
|
""" test reference fields. """
|
|
record = self.env['test_new_api.mixed'].create({})
|
|
|
|
# one may assign False or None
|
|
record.reference = None
|
|
self.assertFalse(record.reference)
|
|
|
|
# one may assign a user or a partner...
|
|
record.reference = self.env.user
|
|
self.assertEqual(record.reference, self.env.user)
|
|
record.reference = self.env.user.partner_id
|
|
self.assertEqual(record.reference, self.env.user.partner_id)
|
|
# ... but no record from a model that starts with 'ir.'
|
|
with self.assertRaises(ValueError):
|
|
record.reference = self.env['ir.model'].search([], limit=1)
|
|
|
|
def test_25_related(self):
|
|
""" test related fields. """
|
|
message = self.env.ref('test_new_api.message_0_0')
|
|
discussion = message.discussion
|
|
|
|
# by default related fields are not stored
|
|
field = message._fields['discussion_name']
|
|
self.assertFalse(field.store)
|
|
self.assertFalse(field.readonly)
|
|
|
|
# check value of related field
|
|
self.assertEqual(message.discussion_name, discussion.name)
|
|
|
|
# change discussion name, and check result
|
|
discussion.name = 'Foo'
|
|
self.assertEqual(message.discussion_name, 'Foo')
|
|
|
|
# change discussion name via related field, and check result
|
|
message.discussion_name = 'Bar'
|
|
self.assertEqual(discussion.name, 'Bar')
|
|
self.assertEqual(message.discussion_name, 'Bar')
|
|
|
|
# search on related field, and check result
|
|
search_on_related = self.env['test_new_api.message'].search([('discussion_name', '=', 'Bar')])
|
|
search_on_regular = self.env['test_new_api.message'].search([('discussion.name', '=', 'Bar')])
|
|
self.assertEqual(search_on_related, search_on_regular)
|
|
|
|
# check that field attributes are copied
|
|
message_field = message.fields_get(['discussion_name'])['discussion_name']
|
|
discussion_field = discussion.fields_get(['name'])['name']
|
|
self.assertEqual(message_field['help'], discussion_field['help'])
|
|
|
|
def test_26_inherited(self):
|
|
""" test inherited fields. """
|
|
# a bunch of fields are inherited from res_partner
|
|
for user in self.env['res.users'].search([]):
|
|
partner = user.partner_id
|
|
for field in ('is_company', 'name', 'email', 'country_id'):
|
|
self.assertEqual(getattr(user, field), getattr(partner, field))
|
|
self.assertEqual(user[field], partner[field])
|
|
|
|
def test_30_read(self):
|
|
""" test computed fields as returned by read(). """
|
|
discussion = self.env.ref('test_new_api.discussion_0')
|
|
|
|
for message in discussion.messages:
|
|
display_name = message.display_name
|
|
size = message.size
|
|
|
|
data = message.read(['display_name', 'size'])[0]
|
|
self.assertEqual(data['display_name'], display_name)
|
|
self.assertEqual(data['size'], size)
|
|
|
|
def test_31_prefetch(self):
|
|
""" test prefetch of records handle AccessError """
|
|
Category = self.env['test_new_api.category']
|
|
cat_1 = Category.create({'name': 'NOACCESS'}).id
|
|
cat_2 = Category.create({'name': 'ACCESS', 'parent': cat_1}).id
|
|
|
|
self.env.clear()
|
|
|
|
cat = Category.browse(cat_2)
|
|
self.assertEqual(cat.name, 'ACCESS')
|
|
# both categories should be in prefetch ids
|
|
self.assertSetEqual(self.env.prefetch[Category._name], set([cat_1, cat_2]))
|
|
# but due to our (lame) overwrite of `read`, it should not forbid us to read records we have access to
|
|
self.assertFalse(len(cat.discussions))
|
|
self.assertEqual(cat.parent.id, cat_1)
|
|
with self.assertRaises(AccessError):
|
|
Category.browse(cat_1).name
|
|
|
|
def test_40_new(self):
|
|
""" test new records. """
|
|
discussion = self.env.ref('test_new_api.discussion_0')
|
|
|
|
# create a new message
|
|
message = self.env['test_new_api.message'].new()
|
|
self.assertFalse(message.id)
|
|
|
|
# assign some fields; should have no side effect
|
|
message.discussion = discussion
|
|
message.body = BODY = "May the Force be with you."
|
|
self.assertEqual(message.discussion, discussion)
|
|
self.assertEqual(message.body, BODY)
|
|
self.assertFalse(message.author)
|
|
self.assertNotIn(message, discussion.messages)
|
|
|
|
# check computed values of fields
|
|
self.assertEqual(message.name, "[%s] %s" % (discussion.name, ''))
|
|
self.assertEqual(message.size, len(BODY))
|
|
|
|
def test_41_defaults(self):
|
|
""" test default values. """
|
|
fields = ['discussion', 'body', 'author', 'size']
|
|
defaults = self.env['test_new_api.message'].default_get(fields)
|
|
self.assertEqual(defaults, {'author': self.env.uid})
|
|
|
|
defaults = self.env['test_new_api.mixed'].default_get(['number'])
|
|
self.assertEqual(defaults, {'number': 3.14})
|
|
|
|
|
|
class TestMagicFields(common.TransactionCase):
|
|
|
|
def test_write_date(self):
|
|
record = self.env['test_new_api.discussion'].create({'name': 'Booba'})
|
|
self.assertEqual(record.create_uid, self.env.user)
|
|
self.assertEqual(record.write_uid, self.env.user)
|