[FIX] fields: make `related_sudo` work for draft records (used by onchange)

Accessing a related field with `related_sudo=True` on a draft record should
effectively traverse the fields as the admin user.

This fixes #5121, #7138.
This commit is contained in:
Raphael Collet 2016-01-21 17:25:57 +01:00
parent ec0e413099
commit 748a719fd9
2 changed files with 30 additions and 5 deletions

View File

@ -4,9 +4,9 @@
from datetime import date, datetime
from collections import defaultdict
from openerp.exceptions import AccessError
from openerp.exceptions import AccessError, except_orm
from openerp.tests import common
from openerp.exceptions import except_orm
from openerp.tools import mute_logger
class TestNewFields(common.TransactionCase):
@ -391,7 +391,31 @@ class TestNewFields(common.TransactionCase):
self.assertEqual(message.name, "[%s] %s" % (discussion.name, ''))
self.assertEqual(message.size, len(BODY))
def test_41_defaults(self):
@mute_logger('openerp.addons.base.ir.ir_model')
def test_41_new_related(self):
""" test the behavior of related fields on new records. """
discussion = self.env.ref('test_new_api.discussion_0')
access = self.env.ref('test_new_api.access_discussion')
# make discussions unreadable for demo user
access.write({'perm_read': False})
# create an environment for demo user
demo_env = self.env(user=self.env.ref('base.user_demo'))
self.assertEqual(demo_env.user.login, "demo")
# create a new message as demo user
values = {'discussion': discussion.id}
message = demo_env['test_new_api.message'].new(values)
self.assertEqual(message.discussion, discussion)
# read the related field discussion_name
self.assertEqual(message.discussion.env, demo_env)
self.assertEqual(message.discussion_name, discussion.name)
with self.assertRaises(AccessError):
message.discussion.name
def test_50_defaults(self):
""" test default values. """
fields = ['discussion', 'body', 'author', 'size']
defaults = self.env['test_new_api.message'].default_get(fields)

View File

@ -539,8 +539,9 @@ class Field(object):
others = records.sudo() if self.related_sudo else records
for record, other in zip(records, others):
if not record.id:
# draft record, do not switch to another environment
other = record
# draft records: copy record's cache to other's cache first
for name, value in record._cache.iteritems():
other[name] = value
# traverse the intermediate fields; follow the first record at each step
for name in self.related[:-1]:
other = other[name][:1]