1 parent
cd51fce0b7
commit
7d040c8cb9
5 files changed
+51
-1
No files matched your search
@@ -1,3 +1,4 @@
|
||||
* Check button states when testing access
|
||||
* Remove the files of Binary fields from the Filestore
|
||||
* Add delete and delete_many to Filestore
|
||||
* Deprecate ``grouped_slice`` without size
|
||||
|
||||
@@ -282,6 +282,9 @@ this repository contains the full copyright notices and license terms. -->
|
||||
<record model="ir.message" id="msg_access_button_error">
|
||||
<field name="text">Calling button "%(button)s on "%(model)s" is not allowed.</field>
|
||||
</record>
|
||||
<record model="ir.message" id="msg_button_state_record">
|
||||
<field name="text">You can not call "%(button)s" on "%(record)s" of "%(model)s".</field>
|
||||
</record>
|
||||
|
||||
<record model="ir.message" id="msg_view_invalid_xml">
|
||||
<field name="text">Invalid XML for view "%(name)s".</field>
|
||||
|
||||
@@ -19,6 +19,7 @@ from . import fields
|
||||
from .fields import on_change_result
|
||||
from .fields.field import _set_value
|
||||
from .model import Model
|
||||
from .modelstorage import _pyson_encoder, _record_eval_pyson
|
||||
|
||||
__all__ = ['ModelView']
|
||||
|
||||
@@ -764,10 +765,20 @@ class ModelView(Model):
|
||||
raise AccessButtonError(
|
||||
gettext('ir.msg_access_button_error',
|
||||
button=func.__name__,
|
||||
model=cls.__name__))
|
||||
**cls.__names__()))
|
||||
else:
|
||||
ModelAccess.check(cls.__name__, 'write')
|
||||
|
||||
states = cls._buttons.get(func.__name__, {})
|
||||
for state_name in {'invisible', 'readonly'} & states.keys():
|
||||
state = _pyson_encoder.encode(states[state_name])
|
||||
for record in records:
|
||||
if _record_eval_pyson(record, state, encoded=True):
|
||||
raise AccessButtonError(
|
||||
gettext('ir.msg_button_state_record',
|
||||
button=func.__name__,
|
||||
**cls.__names__(record=record)))
|
||||
|
||||
if (transaction.user != 0) and check_access:
|
||||
button_rules = Button.get_rules(
|
||||
cls.__name__, func.__name__)
|
||||
|
||||
@@ -68,6 +68,12 @@ class ModelViewButton(ModelView):
|
||||
super().__setup__()
|
||||
cls._buttons = {
|
||||
'test': {},
|
||||
'test_invisible': {
|
||||
'invisible': Eval('value', 0) == 42,
|
||||
},
|
||||
'test_readonly': {
|
||||
'readonly': Eval('value', 0) == 42,
|
||||
},
|
||||
}
|
||||
|
||||
@classmethod
|
||||
@@ -79,6 +85,16 @@ class ModelViewButton(ModelView):
|
||||
def test_non_decorated(cls, records):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
def test_invisible(cls, records):
|
||||
pass
|
||||
|
||||
@classmethod
|
||||
@ModelView.button
|
||||
def test_readonly(cls, records):
|
||||
pass
|
||||
|
||||
|
||||
class ModelViewButtonDepends(ModelView):
|
||||
__name__ = 'test.modelview.button_depends'
|
||||
|
||||
@@ -454,6 +454,25 @@ class ModelView(TestCase):
|
||||
with self.assertRaises(AccessButtonError):
|
||||
TestModel.test([test])
|
||||
|
||||
@with_transaction(context={'_check_access': True})
|
||||
def test_button_access_state(self):
|
||||
"Test Button Access with states"
|
||||
pool = Pool()
|
||||
Model = pool.get('test.modelview.button')
|
||||
|
||||
record = Model()
|
||||
|
||||
Model.test_invisible([record])
|
||||
Model.test_readonly([record])
|
||||
|
||||
record = Model(value=42)
|
||||
|
||||
with self.assertRaises(AccessButtonError):
|
||||
Model.test_invisible([record])
|
||||
|
||||
with self.assertRaises(AccessButtonError):
|
||||
Model.test_readonly([record])
|
||||
|
||||
@with_transaction(context={'_check_access': True})
|
||||
def test_button_no_rule(self):
|
||||
"Test no Button Rule"
|
||||
|
||||
Reference in new issue
Block a user