diff --git a/addons/mail/tests/test_ir_actions.py b/addons/mail/tests/test_ir_actions.py
index bb08fdc7101..3748fdb715b 100644
--- a/addons/mail/tests/test_ir_actions.py
+++ b/addons/mail/tests/test_ir_actions.py
@@ -12,18 +12,17 @@ class TestServerActionsEmail(TestServerActionsBase):
'name': 'TestTemplate',
'email_from': 'myself@example.com',
'email_to': 'brigitte@example.com',
- 'partner_to': '%s' % self.test_partner_id,
- 'model_id': self.res_partner_model_id,
+ 'partner_to': '%s' % self.test_partner.id,
+ 'model_id': self.res_partner_model.id,
'subject': 'About ${object.name}',
'body_html': '
Dear ${object.name}, your parent is ${object.parent_id and object.parent_id.name or "False"}
',
})
- action = self.env['ir.actions.server'].browse(self.act_id)
- action.write({'state': 'email', 'template_id': email_template.id})
- run_res = action.with_context(self.context).run()
+ self.action.write({'state': 'email', 'template_id': email_template.id})
+ run_res = self.action.with_context(self.context).run()
self.assertFalse(run_res, 'ir_actions_server: email server action correctly finished should return False')
# check an email is waiting for sending
mail = self.env['mail.mail'].search([('subject', '=', 'About TestingPartner')])
- self.assertEqual(len(mail.ids), 1, 'ir_actions_server: TODO')
+ self.assertEqual(len(mail), 1, 'ir_actions_server: TODO')
# check email content
self.assertEqual(mail.body, 'Dear TestingPartner, your parent is False
',
'ir_actions_server: TODO')
diff --git a/openerp/addons/base/__openerp__.py b/openerp/addons/base/__openerp__.py
index 58d93fce011..4cd21782039 100644
--- a/openerp/addons/base/__openerp__.py
+++ b/openerp/addons/base/__openerp__.py
@@ -72,11 +72,7 @@ The kernel of Odoo, needed for all installation.
'res/res_partner_demo.yml',
'res/res_partner_image_demo.xml',
],
- 'test': [
- 'tests/base_test.yml',
- 'tests/test_osv_expression.yml',
- 'tests/test_ir_rule.yml', # <-- These tests modify/add/delete ir_rules.
- ],
+ 'test': [],
'installable': True,
'auto_install': True,
'post_init_hook': 'post_init',
diff --git a/openerp/addons/base/tests/__init__.py b/openerp/addons/base/tests/__init__.py
index e9414be9011..fbb2375f3c1 100644
--- a/openerp/addons/base/tests/__init__.py
+++ b/openerp/addons/base/tests/__init__.py
@@ -4,6 +4,7 @@ import test_base
import test_basecase
import test_db_cursor
import test_expression
+import test_float
import test_func
import test_ir_actions
import test_ir_attachment
@@ -16,6 +17,7 @@ import test_menu
import test_orm
import test_ormcache
import test_osv
+import test_phase
import test_qweb
import test_res_config
import test_res_lang
diff --git a/openerp/addons/base/tests/base_test.yml b/openerp/addons/base/tests/base_test.yml
deleted file mode 100644
index c7ab7f06ae9..00000000000
--- a/openerp/addons/base/tests/base_test.yml
+++ /dev/null
@@ -1,337 +0,0 @@
-- |
- To check that common dangerous operations are not allowed by the safe_eval mechanism, attempt to
- evaluate unauthorized expressions, and verify that they trigger an error.
--
- 1. Try a few common expressions to verify they work with safe_eval
--
- !python {model: ir.model}: |
- from openerp.tools.safe_eval import safe_eval
- expected = (1, {"a": 9 * 2}, (True, False, None))
- actual = safe_eval('(1, {"a": 9 * 2}, (True, False, None))')
- assert actual == expected, "Simple python expressions are not working with safe_eval"
--
- 2. Try simple literal definition to verify it works with literal_eval
--
- !python {model: ir.model}: |
- import ast
- expected = (1, {"a": 9}, (True, False, None))
- actual = ast.literal_eval('(1, {"a": 9}, (True, False, None))')
- assert actual == expected, "Simple python expressions are not working with literal_eval"
--
- 3. Try arithmetic expression in literal_eval to verify it does not work
--
- !python {model: ir.model}: |
- import ast
- try:
- ast.literal_eval('(1, {"a": 2*9}, (True, False, None))')
- assert False, "literal_eval should not accept arithmetic expressions"
- except ValueError:
- pass
--
- 4. Try forbidden expressions in literal_eval to verify they are not allowed
--
- !python {model: ir.model}: |
- import ast
- try:
- ast.literal_eval('{"a": True.__class__}')
- assert False, "literal_eval should accept only literals"
- except ValueError:
- pass
--
- 5. Try forbidden expressions in safe_eval to verify they are not allowed (open)
--
- !python {model: ir.model}: |
- from openerp.tools.safe_eval import safe_eval
- from openerp.tools.misc import mute_logger
- try:
- with mute_logger('openerp.tools.safe_eval'):
- safe_eval('open("/etc/passwd","r")')
- assert False, "safe_eval should not allow calling open() builtin"
- except ValueError:
- pass
-
--
- "ORM test: verify that parent_store computation are going right"
--
- 0. Emulate normal behavior of tree structure storing
--
- !python {model: res.partner.category}: |
- # pretend the pool has finished loading to avoid deferring parent_store computation
- self.pool._init = False
-
- # Force partner_categ.copy() to copy children
- self._fields['child_ids'].copy = True
- self._columns['child_ids'].copy = True
--
- "1.0 Setup test partner categories: parent root"
--
- !record {model: res.partner.category, id: test_categ_root}:
- name: Root category
--
- "1.1 Setup test partner categories: parent category"
--
- !record {model: res.partner.category, id: test_categ_0}:
- name: Parent category
- parent_id: test_categ_root
--
- "1.2 Setup test partner categories: child 1"
--
- !record {model: res.partner.category, id: test_categ_1}:
- name: Child 1
- parent_id: test_categ_0
--
- "1.3 Setup test partner categories: child 2"
--
- !record {model: res.partner.category, id: test_categ_2}:
- name: Child 2
- parent_id: test_categ_0
--
- "1.4 Setup test partner categories: child 2-1"
--
- !record {model: res.partner.category, id: test_categ_21}:
- name: Child 2-1
- parent_id: test_categ_2
--
- 2. Duplicate the parent category and verify that the children have been duplicated too and are below the new parent
--
- !python {model: res.partner.category}: |
- self._columns['child_ids'].copy = True # force copying children for test
- new_id = self.copy(cr, uid, ref('test_categ_0'))
- new_struct = self.search(cr, uid, [('parent_id', 'child_of', new_id)])
- assert len(new_struct) == 4, "After duplication, the new object must have the childs records"
- old_struct = self.search(cr, uid, [('parent_id', 'child_of', ref('test_categ_0'))])
- assert len(old_struct) == 4, "After duplication, previous record must have old childs records only"
- assert (not set(new_struct).intersection(old_struct)), "After duplication, nodes should not be mixed"
--
- 3. Duplicate the children then reassign them to the new parent (1st method) and check the parent_store structure.
--
- !python {model: res.partner.category}: |
- new_child1_id = self.copy(cr, uid, ref('test_categ_1'))
- new_child2_id = self.copy(cr, uid, ref('test_categ_2'))
- new_id = self.copy(cr, uid, ref('test_categ_0'), {'child_ids': []})
- self.write(cr, uid, [new_child1_id, new_child2_id], {'parent_id': new_id})
- new_struct = self.search(cr, uid, [('parent_id', 'child_of', new_id)])
- assert len(new_struct) == 4, "After duplication, the new object must have the childs records"
- old_struct = self.search(cr, uid, [('parent_id', 'child_of', ref('test_categ_0'))])
- assert len(old_struct) == 4, "After duplication, previous record must have old childs records only"
- assert (not set(new_struct).intersection(old_struct)), "After duplication, nodes should not be mixed"
--
- 4. Duplicate the children then reassign them to the new parent (2nd method) and check the parent_store structure.
--
- !python {model: res.partner.category}: |
- new_child1_id = self.copy(cr, uid, ref('test_categ_1'))
- new_child2_id = self.copy(cr, uid, ref('test_categ_2'))
- old_struct = self.search(cr, uid, [('parent_id', 'child_of', ref('test_categ_0'))])
- new_id = self.copy(cr, uid, ref('test_categ_0'), {'child_ids': [(6,0,[new_child1_id, new_child2_id])]})
- new_struct = self.search(cr, uid, [('parent_id', 'child_of', new_id)])
- assert len(new_struct) == 4, "After duplication, the new object must have the childs records"
- old_struct = self.search(cr, uid, [('parent_id', 'child_of', ref('test_categ_0'))])
- assert len(old_struct) == 4, "After duplication, previous record must have old childs records only"
- assert (not set(new_struct).intersection(old_struct)), "After duplication, nodes should not be mixed"
--
- 5. Duplicate the children then reassign them to the new parent (3rd method) and make sure the parent_store structure is still right.
--
- !python {model: res.partner.category}: |
- new_child1_id = self.copy(cr, uid, ref('test_categ_1'))
- new_child2_id = self.copy(cr, uid, ref('test_categ_2'))
- new_id = self.copy(cr, uid, ref('test_categ_0'), {'child_ids': []})
- self.write(cr, uid, [new_id], {'child_ids': [(4,new_child1_id), (4,new_child2_id)]})
- new_struct = self.search(cr, uid, [('parent_id', 'child_of', new_id)])
- assert len(new_struct) == 4, "After duplication, the new object must have the childs records"
- old_struct = self.search(cr, uid, [('parent_id', 'child_of', ref('test_categ_0'))])
- assert len(old_struct) == 4, "After duplication, previous record must have old childs records only"
- assert (not set(new_struct).intersection(old_struct)), "After duplication, nodes should not be mixed"
--
- 6. Restore pool state after the test
--
- !python {model: res.partner.category}: |
- self.pool._init = True
- self._fields['child_ids'].copy = False
- self._columns['child_ids'].copy = False
-
--
- "Float precision tests: verify that float rounding methods are working correctly via res.currency"
--
- !python {model: res.currency}: |
- from openerp.tools import float_repr
- from math import log10
- currency = self.browse(cr, uid, ref('base.EUR'))
- def try_round(amount, expected, self=self, cr=cr, currency=currency, float_repr=float_repr,
- log10=log10):
- digits = max(0,-int(log10(currency.rounding)))
- result = float_repr(self.round(cr, 1, currency, amount), precision_digits=digits)
- assert result == expected, 'Rounding error: got %s, expected %s' % (result, expected)
- try_round(2.674,'2.67')
- try_round(2.675,'2.68') # in Python 2.7.2, round(2.675,2) gives 2.67
- try_round(-2.675,'-2.68') # in Python 2.7.2, round(2.675,2) gives 2.67
- try_round(0.001,'0.00')
- try_round(-0.001,'-0.00')
- try_round(0.0049,'0.00') # 0.0049 is closer to 0 than to 0.01, so should round down
- try_round(0.005,'0.01') # the rule is to round half away from zero
- try_round(-0.005,'-0.01') # the rule is to round half away from zero
-
- def try_zero(amount, expected, self=self, cr=cr, currency=currency):
- assert self.is_zero(cr, 1, currency, amount) == expected, "Rounding error: %s should be zero!" % amount
- try_zero(0.01, False)
- try_zero(-0.01, False)
- try_zero(0.001, True)
- try_zero(-0.001, True)
- try_zero(0.0046, True)
- try_zero(-0.0046, True)
- try_zero(2.68-2.675, False) # 2.68 - 2.675 = 0.005 -> rounds to 0.01
- try_zero(2.68-2.676, True) # 2.68 - 2.675 = 0.004 -> rounds to 0.0
- try_zero(2.676-2.68, True) # 2.675 - 2.68 = -0.004 -> rounds to -0.0
- try_zero(2.675-2.68, False) # 2.675 - 2.68 = -0.005 -> rounds to -0.01
-
- def try_compare(amount1, amount2, expected, self=self, cr=cr, currency=currency):
- assert self.compare_amounts(cr, 1, currency, amount1, amount2) == expected, \
- "Rounding error, compare_amounts(%s,%s) should be %s" % (amount1, amount2, expected)
- try_compare(0.001, 0.001, 0)
- try_compare(-0.001, -0.001, 0)
- try_compare(0.001, 0.002, 0)
- try_compare(-0.001, -0.002, 0)
- try_compare(2.675, 2.68, 0)
- try_compare(2.676, 2.68, 0)
- try_compare(-2.676, -2.68, 0)
- try_compare(2.674, 2.68, -1)
- try_compare(-2.674, -2.68, 1)
- try_compare(3, 2.68, 1)
- try_compare(-3, -2.68, -1)
- try_compare(0.01, 0, 1)
- try_compare(-0.01, 0, -1)
-
--
- "Float precision tests: verify that float rounding methods are working correctly via tools"
--
- !python {model: res.currency}: |
- from openerp.tools import float_compare, float_is_zero, float_round, float_repr
- def try_round(amount, expected, precision_digits=3, float_round=float_round, float_repr=float_repr, rounding_method='HALF-UP'):
- result = float_repr(float_round(amount, precision_digits=precision_digits, rounding_method=rounding_method),
- precision_digits=precision_digits)
- assert result == expected, 'Rounding error: got %s, expected %s' % (result, expected)
- try_round(2.6745, '2.675')
- try_round(-2.6745, '-2.675')
- try_round(2.6744, '2.674')
- try_round(-2.6744, '-2.674')
- try_round(0.0004, '0.000')
- try_round(-0.0004, '-0.000')
- try_round(357.4555, '357.456')
- try_round(-357.4555, '-357.456')
- try_round(457.4554, '457.455')
- try_round(-457.4554, '-457.455')
-
- # Try some rounding value with rounding method UP instead of HALF-UP
- # We use 8.175 because when normalizing 8.175 with precision_digits=3 it gives
- # us 8175,0000000001234 as value, and if not handle correctly the rounding UP
- # value will be incorrect (should be 8,175 and not 8,176)
- try_round(8.175, '8.175', rounding_method='UP')
- try_round(8.1751, '8.176', rounding_method='UP')
- try_round(-8.175, '-8.175', rounding_method='UP')
- try_round(-8.1751, '-8.176', rounding_method='UP')
- try_round(-6.000, '-6.000', rounding_method='UP')
- try_round(1.8, '2', 0, rounding_method='UP')
- try_round(-1.8, '-2', 0, rounding_method='UP')
-
- # Extended float range test, inspired by Cloves Almeida's test on bug #882036.
- fractions = [.0, .015, .01499, .675, .67499, .4555, .4555, .45555]
- expecteds = ['.00', '.02', '.01', '.68', '.67', '.46', '.456', '.4556']
- precisions = [2, 2, 2, 2, 2, 2, 3, 4]
- # Note: max precision for double floats is 53 bits of precision or
- # 17 significant decimal digits
- for magnitude in range(7):
- for i in xrange(len(fractions)):
- frac, exp, prec = fractions[i], expecteds[i], precisions[i]
- for sign in [-1,1]:
- for x in xrange(0,10000,97):
- n = x * 10**magnitude
- f = sign * (n + frac)
- f_exp = ('-' if f != 0 and sign == -1 else '') + str(n) + exp
- try_round(f, f_exp, precision_digits=prec)
-
-
- def try_zero(amount, expected, float_is_zero=float_is_zero):
- assert float_is_zero(amount, precision_digits=3) == expected, "Rounding error: %s should be zero!" % amount
- try_zero(0.0002, True)
- try_zero(-0.0002, True)
- try_zero(0.00034, True)
- try_zero(0.0005, False)
- try_zero(-0.0005, False)
- try_zero(0.0008, False)
- try_zero(-0.0008, False)
-
- def try_compare(amount1, amount2, expected, float_compare=float_compare):
- assert float_compare(amount1, amount2, precision_digits=3) == expected, \
- "Rounding error, compare_amounts(%s,%s) should be %s" % (amount1, amount2, expected)
- try_compare(0.0003, 0.0004, 0)
- try_compare(-0.0003, -0.0004, 0)
- try_compare(0.0002, 0.0005, -1)
- try_compare(-0.0002, -0.0005, 1)
- try_compare(0.0009, 0.0004, 1)
- try_compare(-0.0009, -0.0004, -1)
- try_compare(557.4555, 557.4556, 0)
- try_compare(-557.4555, -557.4556, 0)
- try_compare(657.4444, 657.445, -1)
- try_compare(-657.4444, -657.445, 1)
-
- # Rounding to unusual rounding units (e.g. coin values)
- def try_round(amount, expected, precision_rounding=None, float_round=float_round, float_repr=float_repr):
- result = float_repr(float_round(amount, precision_rounding=precision_rounding),
- precision_digits=2)
- assert result == expected, 'Rounding error: got %s, expected %s' % (result, expected)
- try_round(-457.4554, '-457.45', precision_rounding=0.05)
- try_round(457.444, '457.50', precision_rounding=0.5)
- try_round(457.3, '455.00', precision_rounding=5)
- try_round(457.5, '460.00', precision_rounding=5)
- try_round(457.1, '456.00', precision_rounding=3)
-
--
- "Float precision tests: check that proper rounding is performed for float persistence"
--
- !python {model: res.currency}: |
- currency = self.browse(cr, uid, ref('base.EUR'))
- res_currency_rate = self.pool.get('res.currency.rate')
- from openerp.tools import float_compare, float_is_zero, float_round, float_repr
- def try_roundtrip(value, expected, self=self, cr=cr, currency=currency,
- res_currency_rate=res_currency_rate):
- rate_id = res_currency_rate.create(cr, 1, {'name':'2000-01-01',
- 'rate': value,
- 'currency_id': currency.id})
- rate = res_currency_rate.read(cr, 1, [rate_id], ['rate'])[0]['rate']
- assert rate == expected, 'Roundtrip error: got %s back from db, expected %s' % (rate, expected)
- # res.currency.rate uses 6 digits of precision by default
- try_roundtrip(2.6748955, 2.674896)
- try_roundtrip(-2.6748955, -2.674896)
- try_roundtrip(10000.999999, 10000.999999)
- try_roundtrip(-10000.999999, -10000.999999)
-
--
- "Float precision tests: verify that invalid parameters are forbidden"
--
- !python {model: res.currency}: |
- from openerp.tools import float_compare, float_is_zero, float_round
- try:
- float_is_zero(0.01, precision_digits=3, precision_rounding=0.01)
- except AssertionError:
- pass
- try:
- float_compare(0.01, 0.02, precision_digits=3, precision_rounding=0.01)
- except AssertionError:
- pass
- try:
- float_round(0.01, precision_digits=3, precision_rounding=0.01)
- except AssertionError:
- pass
--
- Test res.groups name search
--
- !python {model: res.groups}: |
- all_groups = self.search(cr, uid, [])
- full_names = [(group.id, group.full_name) for group in self.browse(cr, uid, all_groups)]
- group_ids = self.search(cr, uid, [('full_name', 'like', '%Sale%')])
- assert set(group_ids) == set([id for (id, full_name) in full_names if 'Sale' in full_name]), "did not match search for 'Sale'"
- group_ids = self.search(cr, uid, [('full_name', 'like', '%Technical%')])
- assert set(group_ids) == set([id for (id, full_name) in full_names if 'Technical' in full_name]), "did not match search for 'Technical'"
- group_ids = self.search(cr, uid, [('full_name', 'like', '%Sales /%')])
- assert set(group_ids) == set([id for (id, full_name) in full_names if 'Sales /' in full_name]), "did not match search for 'Sales /'"
- group_ids = self.search(cr, uid, [('full_name', 'in', ['Administration / Access Rights','Contact Creation'])])
- assert group_ids, "did not match search for 'Administration / Access Rights' and 'Contact Creation'"
diff --git a/openerp/addons/base/tests/test_acl.py b/openerp/addons/base/tests/test_acl.py
index d1f5ccd4771..84e851add5b 100644
--- a/openerp/addons/base/tests/test_acl.py
+++ b/openerp/addons/base/tests/test_acl.py
@@ -1,26 +1,23 @@
-import unittest
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
from lxml import etree
-from openerp.exceptions import AccessError
-from openerp.tools.misc import mute_logger
-from openerp.tests import common
+from odoo.exceptions import AccessError
+from odoo.tests.common import TransactionCase
+from odoo.tools.misc import mute_logger
# test group that demo user should not have
+USER_DEMO = 'base.user_demo'
GROUP_SYSTEM = 'base.group_system'
-GROUP_ERP_MANAGER = 'base.group_erp_manager'
-class TestACL(common.TransactionCase):
+class TestACL(TransactionCase):
def setUp(self):
super(TestACL, self).setUp()
- self.res_currency = self.registry('res.currency')
- self.res_partner = self.registry('res.partner')
- self.res_users = self.registry('res.users')
- self.res_company = self.registry('res.company')
- self.demo_uid = self.env.ref('base.user_demo').id
+ self.demo_user = self.env.ref(USER_DEMO)
self.erp_system_group = self.env.ref(GROUP_SYSTEM)
- self.erp_manager_group = self.env.ref(GROUP_ERP_MANAGER)
def _set_field_groups(self, model, field_name, groups):
field = model._fields[field_name]
@@ -32,109 +29,103 @@ class TestACL(common.TransactionCase):
def test_field_visibility_restriction(self):
"""Check that model-level ``groups`` parameter effectively restricts access to that
field for users who do not belong to one of the explicitly allowed groups"""
+ currency = self.env['res.currency'].sudo(self.demo_user)
+
# Verify the test environment first
- original_fields = self.res_currency.fields_get(self.cr, self.demo_uid, [])
- form_view = self.res_currency.fields_view_get(self.cr, self.demo_uid, False, 'form')
+ original_fields = currency.fields_get([])
+ form_view = currency.fields_view_get(False, 'form')
view_arch = etree.fromstring(form_view.get('arch'))
- has_group_system = self.res_users.has_group(self.cr, self.demo_uid, GROUP_SYSTEM)
+ has_group_system = self.demo_user.has_group(GROUP_SYSTEM)
self.assertFalse(has_group_system, "`demo` user should not belong to the restricted group before the test")
- self.assertTrue('decimal_places' in original_fields, "'decimal_places' field must be properly visible before the test")
+ self.assertIn('decimal_places', original_fields, "'decimal_places' field must be properly visible before the test")
self.assertNotEquals(view_arch.xpath("//field[@name='decimal_places']"), [],
"Field 'decimal_places' must be found in view definition before the test")
# restrict access to the field and check it's gone
- self._set_field_groups(self.res_currency, 'decimal_places', GROUP_SYSTEM)
+ self._set_field_groups(currency, 'decimal_places', GROUP_SYSTEM)
- fields = self.res_currency.fields_get(self.cr, self.demo_uid, [])
- form_view = self.res_currency.fields_view_get(self.cr, self.demo_uid, False, 'form')
+ fields = currency.fields_get([])
+ form_view = currency.fields_view_get(False, 'form')
view_arch = etree.fromstring(form_view.get('arch'))
- self.assertFalse('decimal_places' in fields, "'decimal_places' field should be gone")
+ self.assertNotIn('decimal_places', fields, "'decimal_places' field should be gone")
self.assertEquals(view_arch.xpath("//field[@name='decimal_places']"), [],
"Field 'decimal_places' must not be found in view definition")
# Make demo user a member of the restricted group and check that the field is back
- self.erp_system_group.write({'users': [(4, self.demo_uid)]})
- has_group_system = self.res_users.has_group(self.cr, self.demo_uid, GROUP_SYSTEM)
- fields = self.res_currency.fields_get(self.cr, self.demo_uid, [])
- form_view = self.res_currency.fields_view_get(self.cr, self.demo_uid, False, 'form')
+ self.erp_system_group.users += self.demo_user
+ has_group_system = self.demo_user.has_group(GROUP_SYSTEM)
+ fields = currency.fields_get([])
+ form_view = currency.fields_view_get(False, 'form')
view_arch = etree.fromstring(form_view.get('arch'))
- #import pprint; pprint.pprint(fields); pprint.pprint(form_view)
self.assertTrue(has_group_system, "`demo` user should now belong to the restricted group")
- self.assertTrue('decimal_places' in fields, "'decimal_places' field must be properly visible again")
+ self.assertIn('decimal_places', fields, "'decimal_places' field must be properly visible again")
self.assertNotEquals(view_arch.xpath("//field[@name='decimal_places']"), [],
"Field 'decimal_places' must be found in view definition again")
- #cleanup
- self.erp_system_group.write({'users': [(3, self.demo_uid)]})
-
@mute_logger('openerp.models')
def test_field_crud_restriction(self):
"Read/Write RPC access to restricted field should be forbidden"
+ partner = self.env['res.partner'].browse(1).sudo(self.demo_user)
+
# Verify the test environment first
- has_group_system = self.res_users.has_group(self.cr, self.demo_uid, GROUP_SYSTEM)
+ has_group_system = self.demo_user.has_group(GROUP_SYSTEM)
self.assertFalse(has_group_system, "`demo` user should not belong to the restricted group")
- self.assert_(self.res_partner.read(self.cr, self.demo_uid, [1], ['bank_ids']))
- self.assert_(self.res_partner.write(self.cr, self.demo_uid, [1], {'bank_ids': []}))
+ self.assert_(partner.read(['bank_ids']))
+ self.assert_(partner.write({'bank_ids': []}))
# Now restrict access to the field and check it's forbidden
- self._set_field_groups(self.res_partner, 'bank_ids', GROUP_SYSTEM)
+ self._set_field_groups(partner, 'bank_ids', GROUP_SYSTEM)
with self.assertRaises(AccessError):
- self.res_partner.read(self.cr, self.demo_uid, [1], ['bank_ids'])
+ partner.read(['bank_ids'])
with self.assertRaises(AccessError):
- self.res_partner.write(self.cr, self.demo_uid, [1], {'bank_ids': []})
+ partner.write({'bank_ids': []})
# Add the restricted group, and check that it works again
- self.erp_system_group.write({'users': [(4, self.demo_uid)]})
- has_group_system = self.res_users.has_group(self.cr, self.demo_uid, GROUP_SYSTEM)
+ self.erp_system_group.users += self.demo_user
+ has_group_system = self.demo_user.has_group(GROUP_SYSTEM)
self.assertTrue(has_group_system, "`demo` user should now belong to the restricted group")
- self.assert_(self.res_partner.read(self.cr, self.demo_uid, [1], ['bank_ids']))
- self.assert_(self.res_partner.write(self.cr, self.demo_uid, [1], {'bank_ids': []}))
-
- #cleanup
- self.erp_system_group.write({'users': [(3, self.demo_uid)]})
+ self.assert_(partner.read(['bank_ids']))
+ self.assert_(partner.write({'bank_ids': []}))
@mute_logger('openerp.models')
def test_fields_browse_restriction(self):
"""Test access to records having restricted fields"""
- self._set_field_groups(self.res_partner, 'email', GROUP_SYSTEM)
+ partner = self.env['res.partner'].sudo(self.demo_user)
+ self._set_field_groups(partner, 'email', GROUP_SYSTEM)
- pid = self.res_partner.search(self.cr, self.demo_uid, [], limit=1)[0]
- part = self.res_partner.browse(self.cr, self.demo_uid, pid)
# accessing fields must no raise exceptions...
- part.name
+ partner = partner.search([], limit=1)
+ partner.name
# ... except if they are restricted
- with self.assertRaises(AccessError) as cm:
+ with self.assertRaises(AccessError):
with mute_logger('openerp.models'):
- part.email
-
- #Useless because we get the title in the client side now in the chrome.js file(map_title)
- #self.assertEqual(cm.exception.args[0], 'Access Error')
+ partner.email
def test_view_create_edit_button_invisibility(self):
""" Test form view Create, Edit, Delete button visibility based on access right of model"""
methods = ['create', 'edit', 'delete']
- company_view = self.res_company.fields_view_get(self.cr, self.demo_uid, False, 'form')
+ company = self.env['res.company'].sudo(self.demo_user)
+ company_view = company.fields_view_get(False, 'form')
view_arch = etree.fromstring(company_view['arch'])
for method in methods:
self.assertEqual(view_arch.get(method), 'false')
def test_view_create_edit_button_visibility(self):
""" Test form view Create, Edit, Delete button visibility based on access right of model"""
+ self.erp_system_group.users += self.demo_user
methods = ['create', 'edit', 'delete']
- self.erp_manager_group.write({'users': [(4, self.demo_uid)]})
- company_view = self.res_company.fields_view_get(self.cr, self.demo_uid, False, 'form')
+ company = self.env['res.company'].sudo(self.demo_user)
+ company_view = company.fields_view_get(False, 'form')
view_arch = etree.fromstring(company_view['arch'])
for method in methods:
self.assertIsNone(view_arch.get(method))
- # cleanup
- self.erp_manager_group.write({'users': [(3, self.demo_uid)]})
def test_m2o_field_create_edit_invisibility(self):
""" Test many2one field Create and Edit option visibility based on access rights of relation field"""
methods = ['create', 'write']
-
- company_view = self.res_company.fields_view_get(self.cr, self.demo_uid, False, 'form')
+ company = self.env['res.company'].sudo(self.demo_user)
+ company_view = company.fields_view_get(False, 'form')
view_arch = etree.fromstring(company_view['arch'])
field_node = view_arch.xpath("//field[@name='currency_id']")
self.assertTrue(len(field_node), "currency_id field should be in company from view")
@@ -143,17 +134,125 @@ class TestACL(common.TransactionCase):
def test_m2o_field_create_edit_visibility(self):
""" Test many2one field Create and Edit option visibility based on access rights of relation field"""
+ self.erp_system_group.users += self.demo_user
methods = ['create', 'write']
-
- self.erp_system_group.write({'users': [(4, self.demo_uid)]})
- company_view = self.res_company.fields_view_get(self.cr, self.demo_uid, False, 'form')
+ company = self.env['res.company'].sudo(self.demo_user)
+ company_view = company.fields_view_get(False, 'form')
view_arch = etree.fromstring(company_view['arch'])
field_node = view_arch.xpath("//field[@name='currency_id']")
self.assertTrue(len(field_node), "currency_id field should be in company from view")
for method in methods:
self.assertEqual(field_node[0].get('can_' + method), 'true')
- # cleanup
- self.erp_manager_group.write({'users': [(3, self.demo_uid)]})
-if __name__ == '__main__':
- unittest.main()
+
+class TestIrRule(TransactionCase):
+
+ def test_ir_rule(self):
+ model_res_partner = self.env.ref('base.model_res_partner')
+ group_user = self.env.ref('base.group_user')
+ user_demo = self.env.ref('base.user_demo')
+
+ # create an ir_rule for the Employee group with an blank domain
+ rule1 = self.env['ir.rule'].create({
+ 'name': 'test_rule1',
+ 'model_id': model_res_partner.id,
+ 'domain_force': False,
+ 'groups': [(6, 0, group_user.ids)],
+ })
+
+ # read as demo user the partners (one blank domain)
+ partners_demo = self.env['res.partner'].sudo(user_demo)
+ partners = partners_demo.search([])
+ self.assertTrue(partners, "Demo user should see some partner.")
+
+ # same with domain 1=1
+ rule1.domain_force = "[(1,'=',1)]"
+ partners = partners_demo.search([])
+ self.assertTrue(partners, "Demo user should see some partner.")
+
+ # same with domain []
+ rule1.domain_force = "[]"
+ partners = partners_demo.search([])
+ self.assertTrue(partners, "Demo user should see some partner.")
+
+ # create another ir_rule for the Employee group (to test multiple rules)
+ rule2 = self.env['ir.rule'].create({
+ 'name': 'test_rule2',
+ 'model_id': model_res_partner.id,
+ 'domain_force': False,
+ 'groups': [(6, 0, group_user.ids)],
+ })
+
+ # read as demo user with domains [] and blank
+ partners = partners_demo.search([])
+ self.assertTrue(partners, "Demo user should see some partner.")
+
+ # same with domains 1=1 and blank
+ rule1.domain_force = "[(1,'=',1)]"
+ partners = partners_demo.search([])
+ self.assertTrue(partners, "Demo user should see some partner.")
+
+ # same with domains 1=1 and 1=1
+ rule2.domain_force = "[(1,'=',1)]"
+ partners = partners_demo.search([])
+ self.assertTrue(partners, "Demo user should see some partner.")
+
+ # create another ir_rule for the Employee group (to test multiple rules)
+ rule3 = self.env['ir.rule'].create({
+ 'name': 'test_rule3',
+ 'model_id': model_res_partner.id,
+ 'domain_force': False,
+ 'groups': [(6, 0, group_user.ids)],
+ })
+
+ # read the partners as demo user
+ partners = partners_demo.search([])
+ self.assertTrue(partners, "Demo user should see some partner.")
+
+ # same with domains 1=1, 1=1 and 1=1
+ rule3.domain_force = "[(1,'=',1)]"
+ partners = partners_demo.search([])
+ self.assertTrue(partners, "Demo user should see some partner.")
+
+ # modify the global rule on res_company which triggers a recursive check
+ # of the rules on company
+ global_rule = self.env.ref('base.res_company_rule_employee')
+ global_rule.domain_force = "[('id','child_of',[user.company_id.id])]"
+
+ # read as demo user (exercising the global company rule)
+ partners = partners_demo.search([])
+ self.assertTrue(partners, "Demo user should see some partner.")
+
+ # Modify the ir_rule for employee to have a rule that fordids seeing any
+ # record. We use a domain with implicit AND operator for later tests on
+ # normalization.
+ rule2.domain_force = "[('id','=',False),('name','=',False)]"
+
+ # check that demo user still sees partners, because group-rules are OR'ed
+ partners = partners_demo.search([])
+ self.assertTrue(partners, "Demo user should see some partner.")
+
+ # create a new group with demo user in it, and a complex rule
+ group_test = self.env['res.groups'].create({
+ 'name': 'Test Group',
+ 'users': [(6, 0, user_demo.ids)],
+ })
+
+ # add the rule to the new group, with a domain containing an implicit
+ # AND operator, which is more tricky because it will have to be
+ # normalized before combining it
+ rule3.write({
+ 'domain_force': "[('name','!=',False),('id','!=',False)]",
+ 'groups': [(6, 0, group_test.ids)],
+ })
+
+ # read the partners again as demo user, which should give results
+ partners = partners_demo.search([])
+ self.assertTrue(partners, "Demo user should see partners even with the combined rules.")
+
+ # delete global domains (to combine only group domains)
+ self.env['ir.rule'].search([('groups', '=', False)]).unlink()
+
+ # read the partners as demo user (several group domains, no global domain)
+ partners = partners_demo.search([])
+ self.assertTrue(partners, "Demo user should see some partners.")
diff --git a/openerp/addons/base/tests/test_api.py b/openerp/addons/base/tests/test_api.py
index 645c5d4ad9b..2c08f9c688c 100644
--- a/openerp/addons/base/tests/test_api.py
+++ b/openerp/addons/base/tests/test_api.py
@@ -1,8 +1,10 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp import models
-from openerp.tools import mute_logger
-from openerp.tests import common
-from openerp.exceptions import AccessError
+from odoo import models
+from odoo.tools import mute_logger
+from odoo.tests import common
+from odoo.exceptions import AccessError
class TestAPI(common.TransactionCase):
@@ -84,7 +86,7 @@ class TestAPI(common.TransactionCase):
ids = map(int, partners)
# modify those partners, and check that partners has not changed
- self.registry('res.partner').write(self.cr, self.uid, ids, {'active': False})
+ partners.write({'active': False})
self.assertEqual(ids, map(int, partners))
# redo the search, and check that the result is now empty
@@ -94,7 +96,7 @@ class TestAPI(common.TransactionCase):
@mute_logger('openerp.models')
def test_06_fields(self):
""" Check that relation fields return records, recordsets or nulls. """
- user = self.registry('res.users').browse(self.cr, self.uid, self.uid)
+ user = self.env.user
self.assertIsRecord(user, 'res.users')
self.assertIsRecord(user.partner_id, 'res.partner')
self.assertIsRecordset(user.groups_id, 'res.groups')
diff --git a/openerp/addons/base/tests/test_base.py b/openerp/addons/base/tests/test_base.py
index bbd54efa2e9..45910803b95 100644
--- a/openerp/addons/base/tests/test_base.py
+++ b/openerp/addons/base/tests/test_base.py
@@ -1,80 +1,113 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+import ast
import unittest
-import openerp.tests.common as common
-from openerp.exceptions import ValidationError
+from odoo.exceptions import ValidationError
+from odoo.tests.common import TransactionCase
+from odoo.tools import mute_logger
+from odoo.tools.safe_eval import safe_eval
-class test_base(common.TransactionCase):
- def setUp(self):
- super(test_base,self).setUp()
- self.res_partner = self.registry('res.partner')
- self.res_users = self.registry('res.users')
- self.res_partner_title = self.registry('res.partner.title')
+class TestSafeEval(unittest.TestCase):
- # samples use effective TLDs from the Mozilla public suffix
- # list at http://publicsuffix.org
- self.samples = [
- ('"Raoul Grosbedon" ', 'Raoul Grosbedon', 'raoul@chirurgiens-dentistes.fr'),
- ('ryu+giga-Sushi@aizubange.fukushima.jp', '', 'ryu+giga-Sushi@aizubange.fukushima.jp'),
- ('Raoul chirurgiens-dentistes.fr', 'Raoul chirurgiens-dentistes.fr', ''),
- (" Raoul O'hara ", "Raoul O'hara", '!@historicalsociety.museum')
- ]
+ def test_01_safe_eval(self):
+ """ Try a few common expressions to verify they work with safe_eval """
+ expected = (1, {"a": 9 * 2}, (True, False, None))
+ actual = safe_eval('(1, {"a": 9 * 2}, (True, False, None))')
+ self.assertEqual(actual, expected, "Simple python expressions are not working with safe_eval")
+
+ def test_02_literal_eval(self):
+ """ Try simple literal definition to verify it works with literal_eval """
+ expected = (1, {"a": 9}, (True, False, None))
+ actual = ast.literal_eval('(1, {"a": 9}, (True, False, None))')
+ self.assertEqual(actual, expected, "Simple python expressions are not working with literal_eval")
+
+ def test_03_literal_eval_arithmetic(self):
+ """ Try arithmetic expression in literal_eval to verify it does not work """
+ with self.assertRaises(ValueError):
+ ast.literal_eval('(1, {"a": 2*9}, (True, False, None))')
+
+ def test_04_literal_eval_forbidden(self):
+ """ Try forbidden expressions in literal_eval to verify they are not allowed """
+ with self.assertRaises(ValueError):
+ ast.literal_eval('{"a": True.__class__}')
+
+ @mute_logger('openerp.tools.safe_eval')
+ def test_05_safe_eval_forbiddon(self):
+ """ Try forbidden expressions in safe_eval to verify they are not allowed (open) """
+ with self.assertRaises(ValueError):
+ safe_eval('open("/etc/passwd","r")')
+
+
+# samples use effective TLDs from the Mozilla public suffix
+# list at http://publicsuffix.org
+SAMPLES = [
+ ('"Raoul Grosbedon" ', 'Raoul Grosbedon', 'raoul@chirurgiens-dentistes.fr'),
+ ('ryu+giga-Sushi@aizubange.fukushima.jp', '', 'ryu+giga-Sushi@aizubange.fukushima.jp'),
+ ('Raoul chirurgiens-dentistes.fr', 'Raoul chirurgiens-dentistes.fr', ''),
+ (" Raoul O'hara ", "Raoul O'hara", '!@historicalsociety.museum'),
+]
+
+class TestBase(TransactionCase):
def test_00_res_partner_name_create(self):
- cr, uid = self.cr, self.uid
- parse = self.res_partner._parse_partner_name
- for text, name, mail in self.samples:
- self.assertEqual((name,mail), parse(text), 'Partner name parsing failed')
- partner_id, dummy = self.res_partner.name_create(cr, uid, text)
- partner = self.res_partner.browse(cr, uid, partner_id)
+ res_partner = self.env['res.partner']
+ parse = res_partner._parse_partner_name
+ for text, name, mail in SAMPLES:
+ self.assertEqual((name, mail), parse(text), 'Partner name parsing failed')
+ partner_id, dummy = res_partner.name_create(text)
+ partner = res_partner.browse(partner_id)
self.assertEqual(name or mail, partner.name, 'Partner name incorrect')
self.assertEqual(mail or False, partner.email, 'Partner email incorrect')
def test_10_res_partner_find_or_create(self):
- cr,uid = self.cr, self.uid
- email = self.samples[0][0]
- partner_id, dummy = self.res_partner.name_create(cr, uid, email)
- found_id = self.res_partner.find_or_create(cr, uid, email)
+ res_partner = self.env['res.partner']
+ email = SAMPLES[0][0]
+ partner_id, dummy = res_partner.name_create(email)
+ found_id = res_partner.find_or_create(email)
self.assertEqual(partner_id, found_id, 'find_or_create failed')
- partner_id2, dummy2 = self.res_partner.name_create(cr, uid, 'sarah.john@connor.com')
- found_id2 = self.res_partner.find_or_create(cr, uid, 'john@connor.com')
+ partner_id2, dummy2 = res_partner.name_create('sarah.john@connor.com')
+ found_id2 = res_partner.find_or_create('john@connor.com')
self.assertNotEqual(partner_id2, found_id2, 'john@connor.com match sarah.john@connor.com')
- new_id = self.res_partner.find_or_create(cr, uid, self.samples[1][0])
+ new_id = res_partner.find_or_create(SAMPLES[1][0])
self.assertTrue(new_id > partner_id, 'find_or_create failed - should have created new one')
- new_id2 = self.res_partner.find_or_create(cr, uid, self.samples[2][0])
+ new_id2 = res_partner.find_or_create(SAMPLES[2][0])
self.assertTrue(new_id2 > new_id, 'find_or_create failed - should have created new one again')
def test_15_res_partner_name_search(self):
- cr,uid = self.cr, self.uid
- for name, active in [
+ res_partner = self.env['res.partner']
+ DATA = [
('"A Raoul Grosbedon" ', False),
('B Raoul chirurgiens-dentistes.fr', True),
("C Raoul O'hara ", True),
('ryu+giga-Sushi@aizubange.fukushima.jp', True),
- ]:
- partner_id, dummy = self.res_partner.name_create(cr, uid, name, context={'default_active': active})
- partners = self.res_partner.name_search(cr, uid, 'Raoul')
+ ]
+ for name, active in DATA:
+ partner_id, dummy = res_partner.with_context(default_active=active).name_create(name)
+ partners = res_partner.name_search('Raoul')
self.assertEqual(len(partners), 2, 'Incorrect search number result for name_search')
- partners = self.res_partner.name_search(cr, uid, 'Raoul', limit=1)
+ partners = res_partner.name_search('Raoul', limit=1)
self.assertEqual(len(partners), 1, 'Incorrect search number result for name_search with a limit')
self.assertEqual(partners[0][1], 'B Raoul chirurgiens-dentistes.fr', 'Incorrect partner returned, should be the first active')
def test_20_res_partner_address_sync(self):
- cr, uid = self.cr, self.uid
- ghoststep = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid,
- {'name': 'GhostStep',
- 'is_company': True,
- 'street': 'Main Street, 10',
- 'phone': '123456789',
- 'email': 'info@ghoststep.com',
- 'vat': 'BE0477472701',
- 'type': 'contact'}))
- p1 = self.res_partner.browse(cr, uid, self.res_partner.name_create(cr, uid, 'Denis Bladesmith ')[0])
+ res_partner = self.env['res.partner']
+ ghoststep = res_partner.create({
+ 'name': 'GhostStep',
+ 'is_company': True,
+ 'street': 'Main Street, 10',
+ 'phone': '123456789',
+ 'email': 'info@ghoststep.com',
+ 'vat': 'BE0477472701',
+ 'type': 'contact',
+ })
+ p1 = res_partner.browse(res_partner.name_create('Denis Bladesmith ')[0])
self.assertEqual(p1.type, 'contact', 'Default type must be "contact"')
p1phone = '123456789#34'
p1.write({'phone': p1phone,
'parent_id': ghoststep.id})
- p1.refresh()
self.assertEqual(p1.street, ghoststep.street, 'Address fields must be synced')
self.assertEqual(p1.phone, p1phone, 'Phone should be preserved after address sync')
self.assertEqual(p1.type, 'contact', 'Type should be preserved after address sync')
@@ -84,13 +117,11 @@ class test_base(common.TransactionCase):
p1street = 'Different street, 42'
p1.write({'street': p1street,
'type': 'invoice'})
- p1.refresh(), ghoststep.refresh()
self.assertEqual(p1.street, p1street, 'Address fields must not be synced after turning sync off')
self.assertNotEqual(ghoststep.street, p1street, 'Parent address must never be touched')
# turn on sync again
p1.write({'type': 'contact'})
- p1.refresh()
self.assertEqual(p1.street, ghoststep.street, 'Address fields must be synced again')
self.assertEqual(p1.phone, p1phone, 'Phone should be preserved after address sync')
self.assertEqual(p1.type, 'contact', 'Type should be preserved after address sync')
@@ -99,213 +130,197 @@ class test_base(common.TransactionCase):
# Modify parent, sync to children
ghoststreet = 'South Street, 25'
ghoststep.write({'street': ghoststreet})
- p1.refresh()
self.assertEqual(p1.street, ghoststreet, 'Address fields must be synced automatically')
self.assertEqual(p1.phone, p1phone, 'Phone should not be synced')
self.assertEqual(p1.email, 'denis.bladesmith@ghoststep.com', 'Email should be preserved after sync')
p1street = 'My Street, 11'
p1.write({'street': p1street})
- ghoststep.refresh()
self.assertEqual(ghoststep.street, ghoststreet, 'Touching contact should never alter parent')
def test_30_res_partner_first_contact_sync(self):
""" Test initial creation of company/contact pair where contact address gets copied to
company """
- cr, uid = self.cr, self.uid
- ironshield = self.res_partner.browse(cr, uid, self.res_partner.name_create(cr, uid, 'IronShield')[0])
+ res_partner = self.env['res.partner']
+ ironshield = res_partner.browse(res_partner.name_create('IronShield')[0])
self.assertFalse(ironshield.is_company, 'Partners are not companies by default')
self.assertEqual(ironshield.type, 'contact', 'Default type must be "contact"')
ironshield.write({'type': 'contact'})
- p1 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid,
- {'name': 'Isen Hardearth',
- 'street': 'Strongarm Avenue, 12',
- 'parent_id': ironshield.id}))
+
+ p1 = res_partner.create({
+ 'name': 'Isen Hardearth',
+ 'street': 'Strongarm Avenue, 12',
+ 'parent_id': ironshield.id,
+ })
self.assertEquals(p1.type, 'contact', 'Default type must be "contact", not the copied parent type')
- ironshield.refresh()
self.assertEqual(ironshield.street, p1.street, 'Address fields should be copied to company')
- def test_40_res_partner_address_getc(self):
+ def test_40_res_partner_address_get(self):
""" Test address_get address resolution mechanism: it should first go down through descendants,
stopping when encountering another is_copmany entity, then go up, stopping again at the first
is_company entity or the root ancestor and if nothing matches, it should use the provided partner
itself """
- cr, uid = self.cr, self.uid
- elmtree = self.res_partner.browse(cr, uid, self.res_partner.name_create(cr, uid, 'Elmtree')[0])
- branch1 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Branch 1',
- 'parent_id': elmtree.id,
- 'is_company': True}))
- leaf10 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Leaf 10',
- 'parent_id': branch1.id,
- 'type': 'invoice'}))
- branch11 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Branch 11',
- 'parent_id': branch1.id,
- 'type': 'other'}))
- leaf111 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Leaf 111',
- 'parent_id': branch11.id,
- 'type': 'delivery'}))
+ res_partner = self.env['res.partner']
+ elmtree = res_partner.browse(res_partner.name_create('Elmtree')[0])
+ branch1 = res_partner.create({'name': 'Branch 1',
+ 'parent_id': elmtree.id,
+ 'is_company': True})
+ leaf10 = res_partner.create({'name': 'Leaf 10',
+ 'parent_id': branch1.id,
+ 'type': 'invoice'})
+ branch11 = res_partner.create({'name': 'Branch 11',
+ 'parent_id': branch1.id,
+ 'type': 'other'})
+ leaf111 = res_partner.create({'name': 'Leaf 111',
+ 'parent_id': branch11.id,
+ 'type': 'delivery'})
branch11.write({'is_company': False}) # force is_company after creating 1rst child
- branch2 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Branch 2',
- 'parent_id': elmtree.id,
- 'is_company': True}))
- leaf21 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Leaf 21',
- 'parent_id': branch2.id,
- 'type': 'delivery'}))
- leaf22 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Leaf 22',
- 'parent_id': branch2.id}))
- leaf23 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid, {'name': 'Leaf 23',
- 'parent_id': branch2.id,
- 'type': 'contact'}))
+ branch2 = res_partner.create({'name': 'Branch 2',
+ 'parent_id': elmtree.id,
+ 'is_company': True})
+ leaf21 = res_partner.create({'name': 'Leaf 21',
+ 'parent_id': branch2.id,
+ 'type': 'delivery'})
+ leaf22 = res_partner.create({'name': 'Leaf 22',
+ 'parent_id': branch2.id})
+ leaf23 = res_partner.create({'name': 'Leaf 23',
+ 'parent_id': branch2.id,
+ 'type': 'contact'})
# go up, stop at branch1
- self.assertEqual(self.res_partner.address_get(cr, uid, [leaf111.id], ['delivery', 'invoice', 'contact', 'other']),
+ self.assertEqual(leaf111.address_get(['delivery', 'invoice', 'contact', 'other']),
{'delivery': leaf111.id,
'invoice': leaf10.id,
'contact': branch1.id,
'other': branch11.id}, 'Invalid address resolution')
- self.assertEqual(self.res_partner.address_get(cr, uid, [branch11.id], ['delivery', 'invoice', 'contact', 'other']),
+ self.assertEqual(branch11.address_get(['delivery', 'invoice', 'contact', 'other']),
{'delivery': leaf111.id,
'invoice': leaf10.id,
'contact': branch1.id,
'other': branch11.id}, 'Invalid address resolution')
# go down, stop at at all child companies
- self.assertEqual(self.res_partner.address_get(cr, uid, [elmtree.id], ['delivery', 'invoice', 'contact', 'other']),
+ self.assertEqual(elmtree.address_get(['delivery', 'invoice', 'contact', 'other']),
{'delivery': elmtree.id,
'invoice': elmtree.id,
'contact': elmtree.id,
'other': elmtree.id}, 'Invalid address resolution')
# go down through children
- self.assertEqual(self.res_partner.address_get(cr, uid, [branch1.id], ['delivery', 'invoice', 'contact', 'other']),
+ self.assertEqual(branch1.address_get(['delivery', 'invoice', 'contact', 'other']),
{'delivery': leaf111.id,
'invoice': leaf10.id,
'contact': branch1.id,
'other': branch11.id}, 'Invalid address resolution')
- self.assertEqual(self.res_partner.address_get(cr, uid, [branch2.id], ['delivery', 'invoice', 'contact', 'other']),
+ self.assertEqual(branch2.address_get(['delivery', 'invoice', 'contact', 'other']),
{'delivery': leaf21.id,
'invoice': branch2.id,
'contact': branch2.id,
'other': branch2.id}, 'Invalid address resolution. Company is the first encountered contact, therefore default for unfound addresses.')
# go up then down through siblings
- self.assertEqual(self.res_partner.address_get(cr, uid, [leaf21.id], ['delivery', 'invoice', 'contact', 'other']),
+ self.assertEqual(leaf21.address_get(['delivery', 'invoice', 'contact', 'other']),
{'delivery': leaf21.id,
'invoice': branch2.id,
'contact': branch2.id,
'other': branch2.id}, 'Invalid address resolution, should scan commercial entity ancestor and its descendants')
- self.assertEqual(self.res_partner.address_get(cr, uid, [leaf22.id], ['delivery', 'invoice', 'contact', 'other']),
+ self.assertEqual(leaf22.address_get(['delivery', 'invoice', 'contact', 'other']),
{'delivery': leaf21.id,
'invoice': leaf22.id,
'contact': leaf22.id,
'other': leaf22.id}, 'Invalid address resolution, should scan commercial entity ancestor and its descendants')
- self.assertEqual(self.res_partner.address_get(cr, uid, [leaf23.id], ['delivery', 'invoice', 'contact', 'other']),
+ self.assertEqual(leaf23.address_get(['delivery', 'invoice', 'contact', 'other']),
{'delivery': leaf21.id,
'invoice': leaf23.id,
'contact': leaf23.id,
'other': leaf23.id}, 'Invalid address resolution, `default` should only override if no partner with specific type exists')
# empty adr_pref means only 'contact'
- self.assertEqual(self.res_partner.address_get(cr, uid, [elmtree.id], []),
+ self.assertEqual(elmtree.address_get([]),
{'contact': elmtree.id}, 'Invalid address resolution, no contact means commercial entity ancestor')
- self.assertEqual(self.res_partner.address_get(cr, uid, [leaf111.id], []),
+ self.assertEqual(leaf111.address_get([]),
{'contact': branch1.id}, 'Invalid address resolution, no contact means finding contact in ancestors')
branch11.write({'type': 'contact'})
- self.assertEqual(self.res_partner.address_get(cr, uid, [leaf111.id], []),
+ self.assertEqual(leaf111.address_get([]),
{'contact': branch11.id}, 'Invalid address resolution, branch11 should now be contact')
-
- def test_50_res_partner_commercial_sync(self):
- cr, uid = self.cr, self.uid
- p0 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid,
- {'name': 'Sigurd Sunknife',
- 'email': 'ssunknife@gmail.com'}))
- sunhelm = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid,
- {'name': 'Sunhelm',
- 'is_company': True,
- 'street': 'Rainbow Street, 13',
- 'phone': '1122334455',
- 'email': 'info@sunhelm.com',
- 'vat': 'BE0477472701',
- 'child_ids': [(4, p0.id),
- (0, 0, {'name': 'Alrik Greenthorn',
- 'email': 'agr@sunhelm.com'})],
- }))
- p1 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid,
- {'name': 'Otto Blackwood',
- 'email': 'otto.blackwood@sunhelm.com',
- 'parent_id': sunhelm.id}))
- p11 = self.res_partner.browse(cr, uid, self.res_partner.create(cr, uid,
- {'name': 'Gini Graywool',
- 'email': 'ggr@sunhelm.com',
- 'parent_id': p1.id}))
- p2 = self.res_partner.browse(cr, uid, self.res_partner.search(cr, uid,
- [('email', '=', 'agr@sunhelm.com')])[0])
- self.res_partner.write(cr, uid, sunhelm.id, {'child_ids': [(0, 0, {'name': 'Ulrik Greenthorn',
- 'email': 'ugr@sunhelm.com'})]})
- p3 = self.res_partner.browse(cr, uid, self.res_partner.search(cr, uid,
- [('email', '=', 'ugr@sunhelm.com')])[0])
+ def test_50_res_partner_commercial_sync(self):
+ res_partner = self.env['res.partner']
+ p0 = res_partner.create({'name': 'Sigurd Sunknife',
+ 'email': 'ssunknife@gmail.com'})
+ sunhelm = res_partner.create({'name': 'Sunhelm',
+ 'is_company': True,
+ 'street': 'Rainbow Street, 13',
+ 'phone': '1122334455',
+ 'email': 'info@sunhelm.com',
+ 'vat': 'BE0477472701',
+ 'child_ids': [(4, p0.id),
+ (0, 0, {'name': 'Alrik Greenthorn',
+ 'email': 'agr@sunhelm.com'})]})
+ p1 = res_partner.create({'name': 'Otto Blackwood',
+ 'email': 'otto.blackwood@sunhelm.com',
+ 'parent_id': sunhelm.id})
+ p11 = res_partner.create({'name': 'Gini Graywool',
+ 'email': 'ggr@sunhelm.com',
+ 'parent_id': p1.id})
+ p2 = res_partner.search([('email', '=', 'agr@sunhelm.com')], limit=1)
+ sunhelm.write({'child_ids': [(0, 0, {'name': 'Ulrik Greenthorn',
+ 'email': 'ugr@sunhelm.com'})]})
+ p3 = res_partner.search([('email', '=', 'ugr@sunhelm.com')], limit=1)
for p in (p0, p1, p11, p2, p3):
- p.refresh()
self.assertEquals(p.commercial_partner_id, sunhelm, 'Incorrect commercial entity resolution')
self.assertEquals(p.vat, sunhelm.vat, 'Commercial fields must be automatically synced')
sunhelmvat = 'BE0123456789'
sunhelm.write({'vat': sunhelmvat})
for p in (p0, p1, p11, p2, p3):
- p.refresh()
self.assertEquals(p.vat, sunhelmvat, 'Commercial fields must be automatically and recursively synced')
p1vat = 'BE0987654321'
p1.write({'vat': p1vat})
for p in (sunhelm, p0, p11, p2, p3):
- p.refresh()
self.assertEquals(p.vat, sunhelmvat, 'Sync to children should only work downstream and on commercial entities')
# promote p1 to commercial entity
- p1.write({
- 'parent_id': sunhelm.id,
- 'is_company': True,
- 'name': 'Sunhelm Subsidiary'})
- p1.refresh()
+ p1.write({'parent_id': sunhelm.id,
+ 'is_company': True,
+ 'name': 'Sunhelm Subsidiary'})
self.assertEquals(p1.vat, p1vat, 'Setting is_company should stop auto-sync of commercial fields')
self.assertEquals(p1.commercial_partner_id, p1, 'Incorrect commercial entity resolution after setting is_company')
# writing on parent should not touch child commercial entities
sunhelmvat2 = 'BE0112233445'
sunhelm.write({'vat': sunhelmvat2})
- p1.refresh()
self.assertEquals(p1.vat, p1vat, 'Setting is_company should stop auto-sync of commercial fields')
- p0.refresh()
self.assertEquals(p0.vat, sunhelmvat2, 'Commercial fields must be automatically synced')
def test_60_read_group(self):
- cr, uid = self.cr, self.uid
- title_sir = self.res_partner_title.create(cr, uid, {'name': 'Sir...'})
- title_lady = self.res_partner_title.create(cr, uid, {'name': 'Lady...'})
+ title_sir = self.env['res.partner.title'].create({'name': 'Sir...'})
+ title_lady = self.env['res.partner.title'].create({'name': 'Lady...'})
test_users = [
- {'name': 'Alice', 'login': 'alice', 'color': 1, 'function': 'Friend', 'date': '2015-03-28', 'title': title_lady},
- {'name': 'Alice', 'login': 'alice2', 'color': 0, 'function': 'Friend', 'date': '2015-01-28', 'title': title_lady},
- {'name': 'Bob', 'login': 'bob', 'color': 2, 'function': 'Friend', 'date': '2015-03-02', 'title': title_sir},
- {'name': 'Eve', 'login': 'eve', 'color': 3, 'function': 'Eavesdropper', 'date': '2015-03-20', 'title': title_lady},
- {'name': 'Nab', 'login': 'nab', 'color': -3, 'function': '5$ Wrench', 'date': '2014-09-10', 'title': title_sir},
- {'name': 'Nab', 'login': 'nab-she', 'color': 6, 'function': '5$ Wrench', 'date': '2014-01-02', 'title': title_lady},
+ {'name': 'Alice', 'login': 'alice', 'color': 1, 'function': 'Friend', 'date': '2015-03-28', 'title': title_lady.id},
+ {'name': 'Alice', 'login': 'alice2', 'color': 0, 'function': 'Friend', 'date': '2015-01-28', 'title': title_lady.id},
+ {'name': 'Bob', 'login': 'bob', 'color': 2, 'function': 'Friend', 'date': '2015-03-02', 'title': title_sir.id},
+ {'name': 'Eve', 'login': 'eve', 'color': 3, 'function': 'Eavesdropper', 'date': '2015-03-20', 'title': title_lady.id},
+ {'name': 'Nab', 'login': 'nab', 'color': -3, 'function': '5$ Wrench', 'date': '2014-09-10', 'title': title_sir.id},
+ {'name': 'Nab', 'login': 'nab-she', 'color': 6, 'function': '5$ Wrench', 'date': '2014-01-02', 'title': title_lady.id},
]
- ids = [self.res_users.create(cr, uid, u) for u in test_users]
- domain = [('id', 'in', ids)]
+ res_users = self.env['res.users']
+ user_ids = [res_users.create(vals).id for vals in test_users]
+ domain = [('id', 'in', user_ids)]
# group on local char field without domain and without active_test (-> empty WHERE clause)
- groups_data = self.res_users.read_group(cr, uid, [], fields=['login'], groupby=['login'], orderby='login DESC', context={'active_test': False})
+ groups_data = res_users.with_context(active_test=False).read_group([], fields=['login'], groupby=['login'], orderby='login DESC')
self.assertGreater(len(groups_data), 6, "Incorrect number of results when grouping on a field")
# group on local char field with limit
- groups_data = self.res_users.read_group(cr, uid, domain, fields=['login'], groupby=['login'], orderby='login DESC', limit=3, offset=3)
+ groups_data = res_users.read_group(domain, fields=['login'], groupby=['login'], orderby='login DESC', limit=3, offset=3)
self.assertEqual(len(groups_data), 3, "Incorrect number of results when grouping on a field with limit")
self.assertEqual(['bob', 'alice2', 'alice'], [g['login'] for g in groups_data], 'Result mismatch')
# group on inherited char field, aggregate on int field (second groupby ignored on purpose)
- groups_data = self.res_users.read_group(cr, uid, domain, fields=['name', 'color', 'function'], groupby=['function', 'login'])
+ groups_data = res_users.read_group(domain, fields=['name', 'color', 'function'], groupby=['function', 'login'])
self.assertEqual(len(groups_data), 3, "Incorrect number of results when grouping on a field")
self.assertEqual(['5$ Wrench', 'Eavesdropper', 'Friend'], [g['function'] for g in groups_data], 'incorrect read_group order')
for group_data in groups_data:
@@ -313,210 +328,186 @@ class test_base(common.TransactionCase):
self.assertEqual(group_data['color'], 3, "Incorrect sum for aggregated data for the column 'color'")
# group on inherited char field, reverse order
- groups_data = self.res_users.read_group(cr, uid, domain, fields=['name', 'color'], groupby='name', orderby='name DESC')
+ groups_data = res_users.read_group(domain, fields=['name', 'color'], groupby='name', orderby='name DESC')
self.assertEqual(['Nab', 'Eve', 'Bob', 'Alice'], [g['name'] for g in groups_data], 'Incorrect ordering of the list')
# group on int field, default ordering
- groups_data = self.res_users.read_group(cr, uid, domain, fields=['color'], groupby='color')
+ groups_data = res_users.read_group(domain, fields=['color'], groupby='color')
self.assertEqual([-3, 0, 1, 2, 3, 6], [g['color'] for g in groups_data], 'Incorrect ordering of the list')
# multi group, second level is int field, should still be summed in first level grouping
- groups_data = self.res_users.read_group(cr, uid, domain, fields=['name', 'color'], groupby=['name', 'color'], orderby='name DESC')
+ groups_data = res_users.read_group(domain, fields=['name', 'color'], groupby=['name', 'color'], orderby='name DESC')
self.assertEqual(['Nab', 'Eve', 'Bob', 'Alice'], [g['name'] for g in groups_data], 'Incorrect ordering of the list')
self.assertEqual([3, 3, 2, 1], [g['color'] for g in groups_data], 'Incorrect ordering of the list')
# group on inherited char field, multiple orders with directions
- groups_data = self.res_users.read_group(cr, uid, domain, fields=['name', 'color'], groupby='name', orderby='color DESC, name')
+ groups_data = res_users.read_group(domain, fields=['name', 'color'], groupby='name', orderby='color DESC, name')
self.assertEqual(len(groups_data), 4, "Incorrect number of results when grouping on a field")
self.assertEqual(['Eve', 'Nab', 'Bob', 'Alice'], [g['name'] for g in groups_data], 'Incorrect ordering of the list')
self.assertEqual([1, 2, 1, 2], [g['name_count'] for g in groups_data], 'Incorrect number of results')
# group on inherited date column (res_partner.date) -> Year-Month, default ordering
- groups_data = self.res_users.read_group(cr, uid, domain, fields=['function', 'color', 'date'], groupby=['date'])
+ groups_data = res_users.read_group(domain, fields=['function', 'color', 'date'], groupby=['date'])
self.assertEqual(len(groups_data), 4, "Incorrect number of results when grouping on a field")
self.assertEqual(['January 2014', 'September 2014', 'January 2015', 'March 2015'], [g['date'] for g in groups_data], 'Incorrect ordering of the list')
self.assertEqual([1, 1, 1, 3], [g['date_count'] for g in groups_data], 'Incorrect number of results')
# group on inherited date column (res_partner.date) -> Year-Month, custom order
- groups_data = self.res_users.read_group(cr, uid, domain, fields=['function', 'color', 'date'], groupby=['date'], orderby='date DESC')
+ groups_data = res_users.read_group(domain, fields=['function', 'color', 'date'], groupby=['date'], orderby='date DESC')
self.assertEqual(len(groups_data), 4, "Incorrect number of results when grouping on a field")
self.assertEqual(['March 2015', 'January 2015', 'September 2014', 'January 2014'], [g['date'] for g in groups_data], 'Incorrect ordering of the list')
self.assertEqual([3, 1, 1, 1], [g['date_count'] for g in groups_data], 'Incorrect number of results')
# group on inherited many2one (res_partner.title), default order
- groups_data = self.res_users.read_group(cr, uid, domain, fields=['function', 'color', 'title'], groupby=['title'])
+ groups_data = res_users.read_group(domain, fields=['function', 'color', 'title'], groupby=['title'])
self.assertEqual(len(groups_data), 2, "Incorrect number of results when grouping on a field")
# m2o is returned as a (id, label) pair
- self.assertEqual([(title_lady, 'Lady...'), (title_sir, 'Sir...')], [g['title'] for g in groups_data], 'Incorrect ordering of the list')
+ self.assertEqual([(title_lady.id, 'Lady...'), (title_sir.id, 'Sir...')], [g['title'] for g in groups_data], 'Incorrect ordering of the list')
self.assertEqual([4, 2], [g['title_count'] for g in groups_data], 'Incorrect number of results')
self.assertEqual([10, -1], [g['color'] for g in groups_data], 'Incorrect aggregation of int column')
# group on inherited many2one (res_partner.title), reversed natural order
- groups_data = self.res_users.read_group(cr, uid, domain, fields=['function', 'color', 'title'], groupby=['title'], orderby="title desc")
+ groups_data = res_users.read_group(domain, fields=['function', 'color', 'title'], groupby=['title'], orderby="title desc")
self.assertEqual(len(groups_data), 2, "Incorrect number of results when grouping on a field")
# m2o is returned as a (id, label) pair
- self.assertEqual([(title_sir, 'Sir...'), (title_lady, 'Lady...')], [g['title'] for g in groups_data], 'Incorrect ordering of the list')
+ self.assertEqual([(title_sir.id, 'Sir...'), (title_lady.id, 'Lady...')], [g['title'] for g in groups_data], 'Incorrect ordering of the list')
self.assertEqual([2, 4], [g['title_count'] for g in groups_data], 'Incorrect number of results')
self.assertEqual([-1, 10], [g['color'] for g in groups_data], 'Incorrect aggregation of int column')
# group on inherited many2one (res_partner.title), multiple orders with m2o in second position
- groups_data = self.res_users.read_group(cr, uid, domain, fields=['function', 'color', 'title'], groupby=['title'], orderby="color desc, title desc")
+ groups_data = res_users.read_group(domain, fields=['function', 'color', 'title'], groupby=['title'], orderby="color desc, title desc")
self.assertEqual(len(groups_data), 2, "Incorrect number of results when grouping on a field")
# m2o is returned as a (id, label) pair
- self.assertEqual([(title_lady, 'Lady...'), (title_sir, 'Sir...')], [g['title'] for g in groups_data], 'Incorrect ordering of the result')
+ self.assertEqual([(title_lady.id, 'Lady...'), (title_sir.id, 'Sir...')], [g['title'] for g in groups_data], 'Incorrect ordering of the result')
self.assertEqual([4, 2], [g['title_count'] for g in groups_data], 'Incorrect number of results')
self.assertEqual([10, -1], [g['color'] for g in groups_data], 'Incorrect aggregation of int column')
# group on inherited many2one (res_partner.title), ordered by other inherited field (color)
- groups_data = self.res_users.read_group(cr, uid, domain, fields=['function', 'color', 'title'], groupby=['title'], orderby='color')
+ groups_data = res_users.read_group(domain, fields=['function', 'color', 'title'], groupby=['title'], orderby='color')
self.assertEqual(len(groups_data), 2, "Incorrect number of results when grouping on a field")
# m2o is returned as a (id, label) pair
- self.assertEqual([(title_sir, 'Sir...'), (title_lady, 'Lady...')], [g['title'] for g in groups_data], 'Incorrect ordering of the list')
+ self.assertEqual([(title_sir.id, 'Sir...'), (title_lady.id, 'Lady...')], [g['title'] for g in groups_data], 'Incorrect ordering of the list')
self.assertEqual([2, 4], [g['title_count'] for g in groups_data], 'Incorrect number of results')
self.assertEqual([-1, 10], [g['color'] for g in groups_data], 'Incorrect aggregation of int column')
-class test_partner_recursion(common.TransactionCase):
+class TestPartnerRecursion(TransactionCase):
def setUp(self):
- super(test_partner_recursion,self).setUp()
- self.res_partner = self.registry('res.partner')
- cr, uid = self.cr, self.uid
- self.p1 = self.res_partner.name_create(cr, uid, 'Elmtree')[0]
- self.p2 = self.res_partner.create(cr, uid, {'name': 'Elmtree Child 1', 'parent_id': self.p1})
- self.p3 = self.res_partner.create(cr, uid, {'name': 'Elmtree Grand-Child 1.1', 'parent_id': self.p2})
+ super(TestPartnerRecursion,self).setUp()
+ res_partner = self.env['res.partner']
+ self.p1 = res_partner.browse(res_partner.name_create('Elmtree')[0])
+ self.p2 = res_partner.create({'name': 'Elmtree Child 1', 'parent_id': self.p1.id})
+ self.p3 = res_partner.create({'name': 'Elmtree Grand-Child 1.1', 'parent_id': self.p2.id})
# split 101, 102, 103 tests to force SQL rollback between them
def test_101_res_partner_recursion(self):
- cr, uid, p1, p3 = self.cr, self.uid, self.p1, self.p3
- self.assertRaises(ValidationError, self.res_partner.write, cr, uid, [p1], {'parent_id': p3})
+ with self.assertRaises(ValidationError):
+ self.p1.write({'parent_id': self.p3.id})
def test_102_res_partner_recursion(self):
- cr, uid, p2, p3 = self.cr, self.uid, self.p2, self.p3
- self.assertRaises(ValidationError, self.res_partner.write, cr, uid, [p2], {'parent_id': p3})
+ with self.assertRaises(ValidationError):
+ self.p2.write({'parent_id': self.p3.id})
def test_103_res_partner_recursion(self):
- cr, uid, p3 = self.cr, self.uid, self.p3
- self.assertRaises(ValidationError, self.res_partner.write, cr, uid, [p3], {'parent_id': p3})
+ with self.assertRaises(ValidationError):
+ self.p3.write({'parent_id': self.p3.id})
def test_104_res_partner_recursion_indirect_cycle(self):
""" Indirect hacky write to create cycle in children """
- cr, uid, p2, p3 = self.cr, self.uid, self.p2, self.p3
- p3b = self.res_partner.create(cr, uid, {'name': 'Elmtree Grand-Child 1.2', 'parent_id': self.p2})
- self.assertRaises(ValidationError, self.res_partner.write, cr, uid, [p2],
- {'child_ids': [(1, p3, {'parent_id': p3b}), (1, p3b, {'parent_id': p3})]})
+ p3b = self.p1.create({'name': 'Elmtree Grand-Child 1.2', 'parent_id': self.p2.id})
+ with self.assertRaises(ValidationError):
+ self.p2.write({'child_ids': [(1, self.p3.id, {'parent_id': p3b.id}),
+ (1, p3b.id, {'parent_id': self.p3.id})]})
def test_110_res_partner_recursion_multi_update(self):
""" multi-write on several partners in same hierarchy must not trigger a false cycle detection """
- cr, uid, p1, p2, p3 = self.cr, self.uid, self.p1, self.p2, self.p3
- self.assertTrue(self.res_partner.write(cr, uid, [p1,p2,p3], {'phone': '123456'}))
+ ps = self.p1 + self.p2 + self.p3
+ self.assertTrue(ps.write({'phone': '123456'}))
-class test_translation(common.TransactionCase):
+
+class TestParentStore(TransactionCase):
+ """ Verify that parent_store computation is done right """
def setUp(self):
- super(test_translation, self).setUp()
- self.res_category = self.registry('res.partner.category')
- self.ir_translation = self.registry('ir.translation')
- cr, uid = self.cr, self.uid
- self.registry('ir.translation').load_module_terms(cr, ['base'], ['fr_FR'])
- self.cat_id = self.res_category.create(cr, uid, {'name': 'Customers'})
- self.ir_translation.create(cr, uid, {'name': 'res.partner.category,name', 'module':'base',
- 'value': 'Clients', 'res_id': self.cat_id, 'lang':'fr_FR', 'state':'translated', 'type': 'model'})
+ super(TestParentStore, self).setUp()
+ # pretend the pool has finished loading to avoid deferring parent_store computation
+ self.patch(self.registry, '_init', False)
- def test_101_create_translated_record(self):
- cr, uid = self.cr, self.uid
-
- no_context_cat = self.res_category.browse(cr, uid, self.cat_id)
- self.assertEqual(no_context_cat.name, 'Customers', "Error in basic name_get")
+ # force res_partner_category.copy() to copy children
+ category = self.env['res.partner.category']
+ self.patch(category._fields['child_ids'], 'copy', True)
+ self.patch(category._columns['child_ids'], 'copy', True)
- fr_context_cat = self.res_category.browse(cr, uid, self.cat_id, context={'lang':'fr_FR'})
- self.assertEqual(fr_context_cat.name, 'Clients', "Translation not found")
+ # setup categories
+ self.root = category.create({'name': 'Root category'})
+ self.cat0 = category.create({'name': 'Parent category', 'parent_id': self.root.id})
+ self.cat1 = category.create({'name': 'Child 1', 'parent_id': self.cat0.id})
+ self.cat2 = category.create({'name': 'Child 2', 'parent_id': self.cat0.id})
+ self.cat21 = category.create({'name': 'Child 2-1', 'parent_id': self.cat2.id})
- def test_102_duplicate_record(self):
- cr, uid = self.cr, self.uid
- self.new_cat_id = self.res_category.copy(cr, uid, self.cat_id, context={'lang':'fr_FR'})
+ def test_duplicate_parent(self):
+ """ Duplicate the parent category and verify that the children have been duplicated too """
+ new_cat0 = self.cat0.copy()
+ new_struct = new_cat0.search([('parent_id', 'child_of', new_cat0.id)])
+ self.assertEqual(len(new_struct), 4, "After duplication, the new object must have the childs records")
+ old_struct = new_cat0.search([('parent_id', 'child_of', self.cat0.id)])
+ self.assertEqual(len(old_struct), 4, "After duplication, previous record must have old childs records only")
+ self.assertFalse(new_struct & old_struct, "After duplication, nodes should not be mixed")
- no_context_cat = self.res_category.browse(cr, uid, self.new_cat_id)
- self.assertEqual(no_context_cat.name, 'Customers', "Duplication did not set untranslated value")
+ def test_duplicate_children_01(self):
+ """ Duplicate the children then reassign them to the new parent (1st method). """
+ new_cat1 = self.cat1.copy()
+ new_cat2 = self.cat2.copy()
+ new_cat0 = self.cat0.copy({'child_ids': []})
+ (new_cat1 + new_cat2).write({'parent_id': new_cat0.id})
+ new_struct = new_cat0.search([('parent_id', 'child_of', new_cat0.id)])
+ self.assertEqual(len(new_struct), 4, "After duplication, the new object must have the childs records")
+ old_struct = new_cat0.search([('parent_id', 'child_of', self.cat0.id)])
+ self.assertEqual(len(old_struct), 4, "After duplication, previous record must have old childs records only")
+ self.assertFalse(new_struct & old_struct, "After duplication, nodes should not be mixed")
- fr_context_cat = self.res_category.browse(cr, uid, self.new_cat_id, context={'lang':'fr_FR'})
- self.assertEqual(fr_context_cat.name, 'Clients', "Did not found translation for initial value")
+ def test_duplicate_children_02(self):
+ """ Duplicate the children then reassign them to the new parent (2nd method). """
+ new_cat1 = self.cat1.copy()
+ new_cat2 = self.cat2.copy()
+ new_cat0 = self.cat0.copy({'child_ids': [(6, 0, (new_cat1 + new_cat2).ids)]})
+ new_struct = new_cat0.search([('parent_id', 'child_of', new_cat0.id)])
+ self.assertEqual(len(new_struct), 4, "After duplication, the new object must have the childs records")
+ old_struct = new_cat0.search([('parent_id', 'child_of', self.cat0.id)])
+ self.assertEqual(len(old_struct), 4, "After duplication, previous record must have old childs records only")
+ self.assertFalse(new_struct & old_struct, "After duplication, nodes should not be mixed")
- def test_103_duplicate_record_fr(self):
- cr, uid = self.cr, self.uid
- self.new_fr_cat_id = self.res_category.copy(cr, uid, self.cat_id, default={'name': 'Clients (copie)'}, context={'lang':'fr_FR'})
+ def test_duplicate_children_03(self):
+ """ Duplicate the children then reassign them to the new parent (3rd method). """
+ new_cat1 = self.cat1.copy()
+ new_cat2 = self.cat2.copy()
+ new_cat0 = self.cat0.copy({'child_ids': []})
+ new_cat0.write({'child_ids': [(4, new_cat1.id), (4, new_cat2.id)]})
+ new_struct = new_cat0.search([('parent_id', 'child_of', new_cat0.id)])
+ self.assertEqual(len(new_struct), 4, "After duplication, the new object must have the childs records")
+ old_struct = new_cat0.search([('parent_id', 'child_of', self.cat0.id)])
+ self.assertEqual(len(old_struct), 4, "After duplication, previous record must have old childs records only")
+ self.assertFalse(new_struct & old_struct, "After duplication, nodes should not be mixed")
- no_context_cat = self.res_category.browse(cr, uid, self.new_fr_cat_id)
- self.assertEqual(no_context_cat.name, 'Customers', "Duplication erased original untranslated value")
- fr_context_cat = self.res_category.browse(cr, uid, self.new_fr_cat_id, context={'lang':'fr_FR'})
- self.assertEqual(fr_context_cat.name, 'Clients (copie)', "Did not used default value for translated value")
+class TestGroups(TransactionCase):
- def test_104_orderby_translated_field(self):
- """ Test search ordered by a translated field. """
- # create a category with a French translation
- category = self.env['res.partner.category'].create({'name': 'Padawans'})
- category_fr = category.with_context(lang='fr_FR')
- category_fr.write({'name': 'Apprentis'})
- # search for categories, and sort them by (translated) name
- categories = category_fr.search([('id', 'in', [self.cat_id, category.id])], order='name')
- self.assertEqual(categories.ids, [category.id, self.cat_id],
- "Search ordered by translated name should return Padawans (Apprentis) before Customers (Clients)")
+ def test_res_groups_fullname_search(self):
+ all_groups = self.env['res.groups'].search([])
-test_state = None
-#: Stores state information across multiple test classes
-def setUpModule():
- global test_state
- test_state = {}
-def tearDownModule():
- global test_state
- test_state = None
+ groups = all_groups.search([('full_name', 'like', '%Sale%')])
+ self.assertItemsEqual(groups.ids, [g.id for g in all_groups if 'Sale' in g.full_name],
+ "did not match search for 'Sale'")
-class TestPhaseInstall00(unittest.TestCase):
- """
- WARNING: Relies on tests being run in alphabetical order
- """
- @classmethod
- def setUpClass(cls):
- cls.state = None
+ groups = all_groups.search([('full_name', 'like', '%Technical%')])
+ self.assertItemsEqual(groups.ids, [g.id for g in all_groups if 'Technical' in g.full_name],
+ "did not match search for 'Technical'")
- def test_00_setup(self):
- type(self).state = 'init'
+ groups = all_groups.search([('full_name', 'like', '%Sales /%')])
+ self.assertItemsEqual(groups.ids, [g.id for g in all_groups if 'Sales /' in g.full_name],
+ "did not match search for 'Sales /'")
- @common.at_install(False)
- def test_01_no_install(self):
- type(self).state = 'error'
-
- def test_02_check(self):
- self.assertEqual(
- self.state, 'init',
- "Testcase state should not have been transitioned from 00")
-
-class TestPhaseInstall01(unittest.TestCase):
- at_install = False
-
- def test_default_norun(self):
- self.fail("An unmarket test in a non-at-install case should not run")
-
- @common.at_install(True)
- def test_set_run(self):
- test_state['set_at_install'] = True
-
-class TestPhaseInstall02(unittest.TestCase):
- """
- Can't put the check for test_set_run in the same class: if
- @common.at_install does not work for test_set_run, it won't work for
- the other one either. Thus move checking of whether test_set_run has
- correctly run indeed to a separate class.
-
- Warning: relies on *classes* being run in alphabetical order in test
- modules
- """
- def test_check_state(self):
- self.assertTrue(
- test_state.get('set_at_install'),
- "The flag should be set if local overriding of runstate")
-
-if __name__ == '__main__':
- unittest.main()
+ groups = all_groups.search([('full_name', 'in', ['Administration / Access Rights','Contact Creation'])])
+ self.assertTrue(groups, "did not match search for 'Administration / Access Rights' and 'Contact Creation'")
diff --git a/openerp/addons/base/tests/test_basecase.py b/openerp/addons/base/tests/test_basecase.py
index 42b47749bf7..8bd78f860fa 100644
--- a/openerp/addons/base/tests/test_basecase.py
+++ b/openerp/addons/base/tests/test_basecase.py
@@ -1,86 +1,72 @@
# -*- coding: utf-8 -*-
-import unittest
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp.tests import common
+from odoo.tests import common
-class test_single_transaction_case(common.SingleTransactionCase):
+
+class TestSingleTransactionCase(common.SingleTransactionCase):
"""
Check the whole-class transaction behavior of SingleTransactionCase.
"""
def test_00(self):
- """Create a partner."""
- cr, uid = self.cr, self.uid
- self.registry('res.partner').create(cr, uid, {'name': 'test_per_class_teardown_partner'})
- ids = self.registry('res.partner').search(cr, uid, [('name', '=', 'test_per_class_teardown_partner')])
- self.assertEqual(1, len(ids), "Test partner not found.")
+ """ Create a partner. """
+ self.env['res.partner'].create({'name': 'test_per_class_teardown_partner'})
+ partners = self.env['res.partner'].search([('name', '=', 'test_per_class_teardown_partner')])
+ self.assertEqual(1, len(partners), "Test partner not found.")
def test_01(self):
- """Find the created partner."""
- cr, uid = self.cr, self.uid
- ids = self.registry('res.partner').search(cr, uid, [('name', '=', 'test_per_class_teardown_partner')])
- self.assertEqual(1, len(ids), "Test partner not found.")
+ """ Find the created partner. """
+ partners = self.env['res.partner'].search([('name', '=', 'test_per_class_teardown_partner')])
+ self.assertEqual(1, len(partners), "Test partner not found.")
def test_20a(self):
""" Create a partner with a XML ID """
- cr, uid = self.cr, self.uid
- res_partner = self.registry('res.partner')
- ir_model_data = self.registry('ir.model.data')
- pid, _ = res_partner.name_create(cr, uid, 'Mr Blue')
- ir_model_data.create(cr, uid, {'name': 'test_partner_blue',
- 'module': 'base',
- 'model': 'res.partner',
- 'res_id': pid})
+ pid, _ = self.env['res.partner'].name_create('Mr Blue')
+ self.env['ir.model.data'].create({'name': 'test_partner_blue',
+ 'module': 'base',
+ 'model': 'res.partner',
+ 'res_id': pid})
+
def test_20b(self):
""" Resolve xml id with ref() and browse_ref() """
- cr, uid = self.cr, self.uid
- res_partner = self.registry('res.partner')
xid = 'base.test_partner_blue'
- p_ref = self.ref(xid)
- self.assertTrue(p_ref, "ref() should resolve xid to database ID")
- partner = res_partner.browse(cr, uid, p_ref)
- p_browse_ref = self.browse_ref(xid)
- self.assertEqual(partner, p_browse_ref, "browse_ref() should resolve xid to browse records")
-
+ partner = self.env.ref(xid)
+ pid = self.ref(xid)
+ self.assertTrue(pid, "ref() should resolve xid to database ID")
+ self.assertEqual(pid, partner.id, "ref() is not consistent with env.ref()")
+ partner2 = self.browse_ref(xid)
+ self.assertEqual(partner, partner2, "browse_ref() should resolve xid to browse records")
-class test_transaction_case(common.TransactionCase):
+class TestTransactionCase(common.TransactionCase):
"""
Check the per-method transaction behavior of TransactionCase.
"""
def test_00(self):
- """Create a partner."""
- cr, uid = self.cr, self.uid
- ids = self.registry('res.partner').search(cr, uid, [('name', '=', 'test_per_class_teardown_partner')])
- self.assertEqual(0, len(ids), "Test partner found.")
- self.registry('res.partner').create(cr, uid, {'name': 'test_per_class_teardown_partner'})
- ids = self.registry('res.partner').search(cr, uid, [('name', '=', 'test_per_class_teardown_partner')])
- self.assertEqual(1, len(ids), "Test partner not found.")
+ """ Create a partner. """
+ partners = self.env['res.partner'].search([('name', '=', 'test_per_class_teardown_partner')])
+ self.assertEqual(0, len(partners), "Test partner found.")
+ self.env['res.partner'].create({'name': 'test_per_class_teardown_partner'})
+ partners = self.env['res.partner'].search([('name', '=', 'test_per_class_teardown_partner')])
+ self.assertEqual(1, len(partners), "Test partner not found.")
def test_01(self):
- """Don't find the created partner."""
- cr, uid = self.cr, self.uid
- ids = self.registry('res.partner').search(cr, uid, [('name', '=', 'test_per_class_teardown_partner')])
- self.assertEqual(0, len(ids), "Test partner found.")
-
+ """ Don't find the created partner. """
+ partners = self.env['res.partner'].search([('name', '=', 'test_per_class_teardown_partner')])
+ self.assertEqual(0, len(partners), "Test partner found.")
def test_20a(self):
""" Create a partner with a XML ID then resolve xml id with ref() and browse_ref() """
- cr, uid = self.cr, self.uid
- res_partner = self.registry('res.partner')
- ir_model_data = self.registry('ir.model.data')
- pid, _ = res_partner.name_create(cr, uid, 'Mr Yellow')
- ir_model_data.create(cr, uid, {'name': 'test_partner_yellow',
- 'module': 'base',
- 'model': 'res.partner',
- 'res_id': pid})
+ pid, _ = self.env['res.partner'].name_create('Mr Yellow')
+ self.env['ir.model.data'].create({'name': 'test_partner_yellow',
+ 'module': 'base',
+ 'model': 'res.partner',
+ 'res_id': pid})
xid = 'base.test_partner_yellow'
- p_ref = self.ref(xid)
- self.assertEquals(p_ref, pid, "ref() should resolve xid to database ID")
- partner = res_partner.browse(cr, uid, pid)
- p_browse_ref = self.browse_ref(xid)
- self.assertEqual(partner, p_browse_ref, "browse_ref() should resolve xid to browse records")
-
-if __name__ == '__main__':
- unittest.main()
+ partner = self.env.ref(xid)
+ pid = self.ref(xid)
+ self.assertEquals(pid, partner.id, "ref() should resolve xid to database ID")
+ partner2 = self.browse_ref(xid)
+ self.assertEqual(partner, partner2, "browse_ref() should resolve xid to browse records")
diff --git a/openerp/addons/base/tests/test_db_cursor.py b/openerp/addons/base/tests/test_db_cursor.py
index 9fa61493f99..c58c6c3fccc 100644
--- a/openerp/addons/base/tests/test_db_cursor.py
+++ b/openerp/addons/base/tests/test_db_cursor.py
@@ -1,18 +1,19 @@
# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
import unittest
-import openerp
-from openerp.tools.misc import mute_logger
-from openerp.tests import common
+import odoo
+from odoo.tests import common
+from odoo.tools.misc import mute_logger
ADMIN_USER_ID = common.ADMIN_USER_ID
def registry():
- return openerp.modules.registry.RegistryManager.get(common.get_db_name())
+ return odoo.registry(common.get_db_name())
-class test_cr_execute(unittest.TestCase):
+class TestExecute(unittest.TestCase):
""" Try cr.execute with wrong parameters """
@mute_logger('openerp.sql_db')
diff --git a/openerp/addons/base/tests/test_expression.py b/openerp/addons/base/tests/test_expression.py
index e3b94aac3b3..62f42f92bdd 100644
--- a/openerp/addons/base/tests/test_expression.py
+++ b/openerp/addons/base/tests/test_expression.py
@@ -1,128 +1,99 @@
-import unittest
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
-import openerp
-import openerp.osv.expression as expression
-from openerp.osv.expression import get_unaccent_wrapper
-from openerp.osv.orm import BaseModel
-import openerp.tests.common as common
+import psycopg2
-class test_expression(common.TransactionCase):
+from odoo.models import BaseModel
+from odoo.tests.common import TransactionCase
+from odoo.tools import mute_logger
+import odoo.osv.expression as expression
- def _reinit_mock(self):
- self.query_list = list()
- def _mock_base_model_where_calc(self, model, *args, **kwargs):
- """ Mock build_email to be able to test its values. Store them into
- some internal variable for latter processing. """
- self.query_list.append(self._base_model_where_calc(model, *args, **kwargs))
- # return the lastly stored query, the one the ORM wants to perform
- return self.query_list[-1]
-
- def setUp(self):
- super(test_expression, self).setUp()
- # Mock BaseModel._where_calc(), to be able to proceed to some tests about generated expression
- self._reinit_mock()
- self._base_model_where_calc = BaseModel._where_calc
- BaseModel._where_calc = lambda model, cr, uid, args, context: self._mock_base_model_where_calc(model, cr, uid, args, context)
-
- def tearDown(self):
- # Remove mocks
- BaseModel._where_calc = self._base_model_where_calc
- super(test_expression, self).tearDown()
+class TestExpression(TransactionCase):
def test_00_in_not_in_m2m(self):
- registry, cr, uid = self.registry, self.cr, self.uid
-
# Create 4 partners with no category, or one or two categories (out of two categories).
+ categories = self.env['res.partner.category']
+ cat_a = categories.create({'name': 'test_expression_category_A'})
+ cat_b = categories.create({'name': 'test_expression_category_B'})
- categories = registry('res.partner.category')
- cat_a = categories.create(cr, uid, {'name': 'test_expression_category_A'})
- cat_b = categories.create(cr, uid, {'name': 'test_expression_category_B'})
-
- partners = registry('res.partner')
- a = partners.create(cr, uid, {'name': 'test_expression_partner_A', 'category_id': [(6, 0, [cat_a])]})
- b = partners.create(cr, uid, {'name': 'test_expression_partner_B', 'category_id': [(6, 0, [cat_b])]})
- ab = partners.create(cr, uid, {'name': 'test_expression_partner_AB', 'category_id': [(6, 0, [cat_a, cat_b])]})
- c = partners.create(cr, uid, {'name': 'test_expression_partner_C'})
+ partners = self.env['res.partner']
+ a = partners.create({'name': 'test_expression_partner_A', 'category_id': [(6, 0, [cat_a.id])]})
+ b = partners.create({'name': 'test_expression_partner_B', 'category_id': [(6, 0, [cat_b.id])]})
+ ab = partners.create({'name': 'test_expression_partner_AB', 'category_id': [(6, 0, [cat_a.id, cat_b.id])]})
+ c = partners.create({'name': 'test_expression_partner_C'})
# The tests.
# On a one2many or many2many field, `in` should be read `contains` (and
# `not in` should be read `doesn't contain`.
- with_a = partners.search(cr, uid, [('category_id', 'in', [cat_a])])
- self.assertEqual(set([a, ab]), set(with_a), "Search for category_id in cat_a failed.")
+ with_a = partners.search([('category_id', 'in', [cat_a.id])])
+ self.assertEqual(a + ab, with_a, "Search for category_id in cat_a failed.")
- with_b = partners.search(cr, uid, [('category_id', 'in', [cat_b])])
- self.assertEqual(set([ab, b]), set(with_b), "Search for category_id in cat_b failed.")
+ with_b = partners.search([('category_id', 'in', [cat_b.id])])
+ self.assertEqual(b + ab, with_b, "Search for category_id in cat_b failed.")
# Partners with the category A or the category B.
- with_a_or_b = partners.search(cr, uid, [('category_id', 'in', [cat_a, cat_b])])
- self.assertEqual(set([ab, a, b]), set(with_a_or_b), "Search for category_id contains cat_a or cat_b failed.")
+ with_a_or_b = partners.search([('category_id', 'in', [cat_a.id, cat_b.id])])
+ self.assertEqual(a + b + ab, with_a_or_b, "Search for category_id contains cat_a or cat_b failed.")
# Show that `contains list` is really `contains element or contains element`.
- with_a_or_with_b = partners.search(cr, uid, ['|', ('category_id', 'in', [cat_a]), ('category_id', 'in', [cat_b])])
- self.assertEqual(set([ab, a, b]), set(with_a_or_with_b), "Search for category_id contains cat_a or contains cat_b failed.")
+ with_a_or_with_b = partners.search(['|', ('category_id', 'in', [cat_a.id]), ('category_id', 'in', [cat_b.id])])
+ self.assertEqual(a + b + ab, with_a_or_with_b, "Search for category_id contains cat_a or contains cat_b failed.")
# If we change the OR in AND...
- with_a_and_b = partners.search(cr, uid, [('category_id', 'in', [cat_a]), ('category_id', 'in', [cat_b])])
- self.assertEqual(set([ab]), set(with_a_and_b), "Search for category_id contains cat_a and cat_b failed.")
+ with_a_and_b = partners.search([('category_id', 'in', [cat_a.id]), ('category_id', 'in', [cat_b.id])])
+ self.assertEqual(ab, with_a_and_b, "Search for category_id contains cat_a and cat_b failed.")
# Partners without category A and without category B.
- without_a_or_b = partners.search(cr, uid, [('category_id', 'not in', [cat_a, cat_b])])
- self.assertTrue(all(i not in without_a_or_b for i in [a, b, ab]), "Search for category_id doesn't contain cat_a or cat_b failed (1).")
+ without_a_or_b = partners.search([('category_id', 'not in', [cat_a.id, cat_b.id])])
+ self.assertFalse(without_a_or_b & (a + b + ab), "Search for category_id doesn't contain cat_a or cat_b failed (1).")
self.assertTrue(c in without_a_or_b, "Search for category_id doesn't contain cat_a or cat_b failed (2).")
# Show that `doesn't contain list` is really `doesn't contain element and doesn't contain element`.
- without_a_and_without_b = partners.search(cr, uid, [('category_id', 'not in', [cat_a]), ('category_id', 'not in', [cat_b])])
- self.assertTrue(all(i not in without_a_and_without_b for i in [a, b, ab]), "Search for category_id doesn't contain cat_a and cat_b failed (1).")
+ without_a_and_without_b = partners.search([('category_id', 'not in', [cat_a.id]), ('category_id', 'not in', [cat_b.id])])
+ self.assertFalse(without_a_and_without_b & (a + b + ab), "Search for category_id doesn't contain cat_a and cat_b failed (1).")
self.assertTrue(c in without_a_and_without_b, "Search for category_id doesn't contain cat_a and cat_b failed (2).")
# We can exclude any partner containing the category A.
- without_a = partners.search(cr, uid, [('category_id', 'not in', [cat_a])])
+ without_a = partners.search([('category_id', 'not in', [cat_a.id])])
self.assertTrue(a not in without_a, "Search for category_id doesn't contain cat_a failed (1).")
self.assertTrue(ab not in without_a, "Search for category_id doesn't contain cat_a failed (2).")
- self.assertTrue(set([b, c]).issubset(set(without_a)), "Search for category_id doesn't contain cat_a failed (3).")
+ self.assertLessEqual(b + c, without_a, "Search for category_id doesn't contain cat_a failed (3).")
# (Obviously we can do the same for cateory B.)
- without_b = partners.search(cr, uid, [('category_id', 'not in', [cat_b])])
+ without_b = partners.search([('category_id', 'not in', [cat_b.id])])
self.assertTrue(b not in without_b, "Search for category_id doesn't contain cat_b failed (1).")
self.assertTrue(ab not in without_b, "Search for category_id doesn't contain cat_b failed (2).")
- self.assertTrue(set([a, c]).issubset(set(without_b)), "Search for category_id doesn't contain cat_b failed (3).")
-
- # We can't express the following: Partners with a category different than A.
- # with_any_other_than_a = ...
- # self.assertTrue(a not in with_any_other_than_a, "Search for category_id with any other than cat_a failed (1).")
- # self.assertTrue(ab in with_any_other_than_a, "Search for category_id with any other than cat_a failed (2).")
+ self.assertLessEqual(a + c, without_b, "Search for category_id doesn't contain cat_b failed (3).")
def test_05_not_str_m2m(self):
- registry, cr, uid = self.registry, self.cr, self.uid
+ partners = self.env['res.partner']
+ categories = self.env['res.partner.category']
- partners = registry('res.partner')
- categories = registry('res.partner.category')
+ cids = {}
+ for name in 'A B AB'.split():
+ cids[name] = categories.create({'name': name}).id
- cats = {}
- for cat in 'A B AB'.split():
- cats[cat] = categories.create(cr, uid, {'name': cat})
-
- _partners = {
+ partners_config = {
'0': [],
- 'a': [cats['A']],
- 'b': [cats['B']],
- 'ab': [cats['AB']],
- 'a b': [cats['A'], cats['B']],
- 'b ab': [cats['B'], cats['AB']],
+ 'a': [cids['A']],
+ 'b': [cids['B']],
+ 'ab': [cids['AB']],
+ 'a b': [cids['A'], cids['B']],
+ 'b ab': [cids['B'], cids['AB']],
}
pids = {}
- for p in _partners:
- pids[p] = partners.create(cr, uid, {'name': p, 'category_id': [(6, 0, _partners[p])]})
+ for name, cat_ids in partners_config.iteritems():
+ pids[name] = partners.create({'name': name, 'category_id': [(6, 0, cat_ids)]}).id
base_domain = [('id', 'in', pids.values())]
def test(op, value, expected):
- ids = set(partners.search(cr, uid, base_domain + [('category_id', op, value)]))
- expected_ids = set(map(pids.__getitem__, expected))
- self.assertSetEqual(ids, expected_ids, '%s %r should return %r' % (op, value, expected))
+ found_ids = partners.search(base_domain + [('category_id', op, value)]).ids
+ expected_ids = [pids[name] for name in expected]
+ self.assertItemsEqual(found_ids, expected_ids, '%s %r should return %r' % (op, value, expected))
test('=', 'A', ['a', 'a b'])
test('!=', 'B', ['0', 'a', 'ab'])
@@ -130,73 +101,573 @@ class test_expression(common.TransactionCase):
test('not ilike', 'B', ['0', 'a'])
test('not like', 'AB', ['0', 'a', 'b', 'a b'])
- def test_10_expression_parse(self):
+ def test_10_hierarchy_in_m2m(self):
+ Partner = self.env['res.partner']
+ Category = self.env['res.partner.category']
+
+ # search through m2m relation
+ partners = Partner.search([('category_id', 'child_of', self.ref('base.res_partner_category_0'))])
+ self.assertTrue(partners)
+
+ # setup test partner categories
+ categ_root = Category.create({'name': 'Root category'})
+ categ_0 = Category.create({'name': 'Parent category', 'parent_id': categ_root.id})
+ categ_1 = Category.create({'name': 'Child1', 'parent_id': categ_0.id})
+
+ # test hierarchical search in m2m with child id (list of ids)
+ cats = Category.search([('id', 'child_of', categ_root.ids)])
+ self.assertEqual(len(cats), 3)
+
+ # test hierarchical search in m2m with child id (single id)
+ cats = Category.search([('id', 'child_of', categ_root.id)])
+ self.assertEqual(len(cats), 3)
+
+ # test hierarchical search in m2m with child ids
+ cats = Category.search([('id', 'child_of', (categ_0 + categ_1).ids)])
+ self.assertEqual(len(cats), 2)
+
+ # test hierarchical search in m2m with child ids
+ cats = Category.search([('id', 'child_of', categ_0.ids)])
+ self.assertEqual(len(cats), 2)
+
+ # test hierarchical search in m2m with child ids
+ cats = Category.search([('id', 'child_of', categ_1.ids)])
+ self.assertEqual(len(cats), 1)
+
+ # test hierarchical search in m2m with parent id (list of ids)
+ cats = Category.search([('id', 'parent_of', categ_1.ids)])
+ self.assertEqual(len(cats), 3)
+
+ # test hierarchical search in m2m with parent id (single id)
+ cats = Category.search([('id', 'parent_of', categ_1.id)])
+ self.assertEqual(len(cats), 3)
+
+ # test hierarchical search in m2m with parent ids
+ cats = Category.search([('id', 'parent_of', (categ_root + categ_0).ids)])
+ self.assertEqual(len(cats), 2)
+
+ # test hierarchical search in m2m with parent ids
+ cats = Category.search([('id', 'parent_of', categ_0.ids)])
+ self.assertEqual(len(cats), 2)
+
+ # test hierarchical search in m2m with parent ids
+ cats = Category.search([('id', 'parent_of', categ_root.ids)])
+ self.assertEqual(len(cats), 1)
+
+ def test_10_equivalent_id(self):
+ # equivalent queries
+ Currency = self.env['res.currency']
+ non_currency_id = max(Currency.search([]).ids) + 1003
+ res_0 = Currency.search([])
+ res_1 = Currency.search([('name', 'not like', 'probably_unexisting_name')])
+ self.assertEqual(res_0, res_1)
+ res_2 = Currency.search([('id', 'not in', [non_currency_id])])
+ self.assertEqual(res_0, res_2)
+ res_3 = Currency.search([('id', 'not in', [])])
+ self.assertEqual(res_0, res_3)
+ res_4 = Currency.search([('id', '!=', False)])
+ self.assertEqual(res_0, res_4)
+
+ # equivalent queries, integer and string
+ Partner = self.env['res.partner']
+ all_partners = Partner.search([])
+ self.assertTrue(len(all_partners) > 1)
+ one = all_partners[0]
+ others = all_partners[1:]
+
+ res_1 = Partner.search([('id', '=', one.id)])
+ self.assertEqual(one, res_1)
+ # Partner.search([('id', '!=', others)]) # not permitted
+ res_2 = Partner.search([('id', 'not in', others.ids)])
+ self.assertEqual(one, res_2)
+ res_3 = Partner.search(['!', ('id', '!=', one.id)])
+ self.assertEqual(one, res_3)
+ res_4 = Partner.search(['!', ('id', 'in', others.ids)])
+ self.assertEqual(one, res_4)
+ # res_5 = Partner.search([('id', 'in', one)]) # TODO make it permitted, just like for child_of
+ # self.assertEqual(one, res_5)
+ res_6 = Partner.search([('id', 'in', [one.id])])
+ self.assertEqual(one, res_6)
+ res_7 = Partner.search([('name', '=', one.name)])
+ self.assertEqual(one, res_7)
+ res_8 = Partner.search([('name', 'in', [one.name])])
+ # res_9 = Partner.search([('name', 'in', one.name)]) # TODO
+
+ def test_15_m2o(self):
+ Partner = self.env['res.partner']
+
+ # testing equality with name
+ partners = Partner.search([('parent_id', '=', 'Agrolait')])
+ self.assertTrue(partners)
+
+ # testing the in operator with name
+ partners = Partner.search([('parent_id', 'in', 'Agrolait')])
+ self.assertTrue(partners)
+
+ # testing the in operator with a list of names
+ partners = Partner.search([('parent_id', 'in', ['Agrolait', 'ASUStek'])])
+ self.assertTrue(partners)
+
+ # check if many2one works with empty search list
+ partners = Partner.search([('company_id', 'in', [])])
+ self.assertFalse(partners)
+
+ # create new company with partners, and partners with no company
+ company2 = self.env['res.company'].create({'name': 'Acme 2'})
+ for i in xrange(4):
+ Partner.create({'name': 'P of Acme %s' % i, 'company_id': company2.id})
+ for i in xrange(4):
+ Partner.create({'name': 'P of All %s' % i, 'company_id': False})
+
+ # check if many2one works with negative empty list
+ all_partners = Partner.search([])
+ res_partners = Partner.search(['|', ('company_id', 'not in', []), ('company_id', '=', False)])
+ self.assertEqual(all_partners, res_partners, "not in [] fails")
+
+ # check that many2one will pick the correct records with a list
+ partners = Partner.search([('company_id', 'in', [False])])
+ self.assertTrue(len(partners) >= 4, "We should have at least 4 partners with no company")
+
+ # check that many2one will exclude the correct records with a list
+ partners = Partner.search([('company_id', 'not in', [1])])
+ self.assertTrue(len(partners) >= 4, "We should have at least 4 partners not related to company #1")
+
+ # check that many2one will exclude the correct records with a list and False
+ partners = Partner.search(['|', ('company_id', 'not in', [1]),
+ ('company_id', '=', False)])
+ self.assertTrue(len(partners) >= 8, "We should have at least 8 partners not related to company #1")
+
+ # check that multi-level expressions also work
+ partners = Partner.search([('company_id.partner_id', 'in', [])])
+ self.assertFalse(partners)
+
+ # check that multi-level expressions with negative op work
+ all_partners = Partner.search([('company_id', '!=', False)])
+ res_partners = Partner.search([('company_id.partner_id', 'not in', [])])
+ self.assertEqual(all_partners, res_partners, "not in [] fails")
+
+ # Test the '(not) like/in' behavior. res.partner and its parent_id
+ # column are used because parent_id is a many2one, allowing to test the
+ # Null value, and there are actually some null and non-null values in
+ # the demo data.
+ all_partners = Partner.search([])
+ non_partner_id = max(all_partners.ids) + 1
+
+ with_parent = all_partners.filtered(lambda p: p.parent_id)
+ without_parent = all_partners.filtered(lambda p: not p.parent_id)
+ with_website = all_partners.filtered(lambda p: p.website)
+
+ # We treat null values differently than in SQL. For instance in SQL:
+ # SELECT id FROM res_partner WHERE parent_id NOT IN (0)
+ # will return only the records with non-null parent_id.
+ # SELECT id FROM res_partner WHERE parent_id IN (0)
+ # will return expectedly nothing (our ids always begin at 1).
+ # This means the union of those two results will give only some
+ # records, but not all present in database.
+ #
+ # When using domains and the ORM's search method, we think it is
+ # more intuitive that the union returns all the records, and that
+ # a domain like ('parent_id', 'not in', [0]) will return all
+ # the records. For instance, if you perform a search for the companies
+ # that don't have OpenERP has a parent company, you expect to find,
+ # among others, the companies that don't have parent company.
+ #
+
+ # existing values be treated similarly if we simply check that some
+ # existing value belongs to them.
+ res_0 = Partner.search([('parent_id', 'not like', 'probably_unexisting_name')]) # get all rows, included null parent_id
+ self.assertEqual(res_0, all_partners)
+ res_1 = Partner.search([('parent_id', 'not in', [non_partner_id])]) # get all rows, included null parent_id
+ self.assertEqual(res_1, all_partners)
+ res_2 = Partner.search([('parent_id', '!=', False)]) # get rows with not null parent_id, deprecated syntax
+ self.assertEqual(res_2, with_parent)
+ res_3 = Partner.search([('parent_id', 'not in', [])]) # get all rows, included null parent_id
+ self.assertEqual(res_3, all_partners)
+ res_4 = Partner.search([('parent_id', 'not in', [False])]) # get rows with not null parent_id
+ self.assertEqual(res_4, with_parent)
+ res_4b = Partner.search([('parent_id', 'not ilike', '')]) # get only rows without parent
+ self.assertEqual(res_4b, without_parent)
+
+ # The results of these queries, when combined with queries 0..4 must
+ # give the whole set of ids.
+ res_5 = Partner.search([('parent_id', 'like', 'probably_unexisting_name')])
+ self.assertFalse(res_5)
+ res_6 = Partner.search([('parent_id', 'in', [non_partner_id])])
+ self.assertFalse(res_6)
+ res_7 = Partner.search([('parent_id', '=', False)])
+ self.assertEqual(res_7, without_parent)
+ res_8 = Partner.search([('parent_id', 'in', [])])
+ self.assertFalse(res_8)
+ res_9 = Partner.search([('parent_id', 'in', [False])])
+ self.assertEqual(res_9, without_parent)
+ res_9b = Partner.search([('parent_id', 'ilike', '')]) # get those with a parent
+ self.assertEqual(res_9b, with_parent)
+
+ # These queries must return exactly the results than the queries 0..4,
+ # i.e. not ... in ... must be the same as ... not in ... .
+ res_10 = Partner.search(['!', ('parent_id', 'like', 'probably_unexisting_name')])
+ self.assertEqual(res_0, res_10)
+ res_11 = Partner.search(['!', ('parent_id', 'in', [non_partner_id])])
+ self.assertEqual(res_1, res_11)
+ res_12 = Partner.search(['!', ('parent_id', '=', False)])
+ self.assertEqual(res_2, res_12)
+ res_13 = Partner.search(['!', ('parent_id', 'in', [])])
+ self.assertEqual(res_3, res_13)
+ res_14 = Partner.search(['!', ('parent_id', 'in', [False])])
+ self.assertEqual(res_4, res_14)
+
+ # Testing many2one field is not enough, a regular char field is tested
+ res_15 = Partner.search([('website', 'in', [])])
+ self.assertFalse(res_15)
+ res_16 = Partner.search([('website', 'not in', [])])
+ self.assertEqual(res_16, all_partners)
+ res_17 = Partner.search([('website', '!=', False)])
+ self.assertEqual(res_17, with_website)
+
+ # check behavior for required many2one fields: currency_id is required
+ companies = self.env['res.company'].search([])
+ res_101 = companies.search([('currency_id', 'not ilike', '')]) # get no companies
+ self.assertFalse(res_101)
+ res_102 = companies.search([('currency_id', 'ilike', '')]) # get all companies
+ self.assertEqual(res_102, companies)
+
+ def test_in_operator(self):
+ """ check that we can use the 'in' operator for plain fields """
+ menus = self.env['ir.ui.menu'].search([('sequence', 'in', [1, 2, 10, 20])])
+ self.assertTrue(menus)
+
+ def test_15_o2m(self):
+ Partner = self.env['res.partner']
+
+ # test one2many operator with empty search list
+ partners = Partner.search([('child_ids', 'in', [])])
+ self.assertFalse(partners)
+
+ # test one2many operator with False
+ partners = Partner.search([('child_ids', '=', False)])
+ for partner in partners:
+ self.assertFalse(partner.child_ids)
+
+ # verify domain evaluation for one2many != False and one2many == False
+ categories = self.env['res.partner.category'].search([])
+ parents = categories.search([('child_ids', '!=', False)])
+ self.assertEqual(parents, categories.filtered(lambda c: c.child_ids))
+ leafs = categories.search([('child_ids', '=', False)])
+ self.assertEqual(leafs, categories.filtered(lambda c: not c.child_ids))
+
+ # test many2many operator with empty search list
+ partners = Partner.search([('category_id', 'in', [])])
+ self.assertFalse(partners)
+
+ # test many2many operator with False
+ partners = Partner.search([('category_id', '=', False)])
+ for partner in partners:
+ self.assertFalse(partner.category_id)
+
+ # filtering on nonexistent value across x2many should return nothing
+ partners = Partner.search([('child_ids.city', '=', 'foo')])
+ self.assertFalse(partners)
+
+ def test_15_equivalent_one2many_1(self):
+ Company = self.env['res.company']
+ company3 = Company.create({'name': 'Acme 3'})
+ company4 = Company.create({'name': 'Acme 4', 'parent_id': company3.id})
+
+ # one2many towards same model
+ res_1 = Company.search([('child_ids', 'in', company3.child_ids.ids)]) # any company having a child of company3 as child
+ self.assertEqual(res_1, company3)
+ res_2 = Company.search([('child_ids', 'in', company3.child_ids[0].ids)]) # any company having the first child of company3 as child
+ self.assertEqual(res_2, company3)
+
+ # child_of x returns x and its children (direct or not).
+ expected = company3 + company4
+ res_1 = Company.search([('id', 'child_of', [company3.id])])
+ self.assertEqual(res_1, expected)
+ res_2 = Company.search([('id', 'child_of', company3.id)])
+ self.assertEqual(res_2, expected)
+ res_3 = Company.search([('id', 'child_of', [company3.name])])
+ self.assertEqual(res_3, expected)
+ res_4 = Company.search([('id', 'child_of', company3.name)])
+ self.assertEqual(res_4, expected)
+
+ # parent_of x returns x and its parents (direct or not).
+ expected = company3 + company4
+ res_1 = Company.search([('id', 'parent_of', [company4.id])])
+ self.assertEqual(res_1, expected)
+ res_2 = Company.search([('id', 'parent_of', company4.id)])
+ self.assertEqual(res_2, expected)
+ res_3 = Company.search([('id', 'parent_of', [company4.name])])
+ self.assertEqual(res_3, expected)
+ res_4 = Company.search([('id', 'parent_of', company4.name)])
+ self.assertEqual(res_4, expected)
+
+ # try testing real subsets with IN/NOT IN
+ Partner = self.env['res.partner']
+ Users = self.env['res.users']
+ p1, _ = Partner.name_create("Dédé Boitaclou")
+ p2, _ = Partner.name_create("Raoulette Pizza O'poil")
+ u1a = Users.create({'login': 'dbo', 'partner_id': p1}).id
+ u1b = Users.create({'login': 'dbo2', 'partner_id': p1}).id
+ u2 = Users.create({'login': 'rpo', 'partner_id': p2}).id
+ self.assertEqual([p1], Partner.search([('user_ids', 'in', u1a)]).ids, "o2m IN accept single int on right side")
+ self.assertEqual([p1], Partner.search([('user_ids', '=', 'Dédé Boitaclou')]).ids, "o2m NOT IN matches none on the right side")
+ self.assertEqual([], Partner.search([('user_ids', 'in', [10000])]).ids, "o2m NOT IN matches none on the right side")
+ self.assertEqual([p1,p2], Partner.search([('user_ids', 'in', [u1a,u2])]).ids, "o2m IN matches any on the right side")
+ all_ids = Partner.search([]).ids
+ self.assertEqual(set(all_ids) - set([p1]), set(Partner.search([('user_ids', 'not in', u1a)]).ids), "o2m NOT IN matches none on the right side")
+ self.assertEqual(set(all_ids) - set([p1]), set(Partner.search([('user_ids', '!=', 'Dédé Boitaclou')]).ids), "o2m NOT IN matches none on the right side")
+ self.assertEqual(set(all_ids) - set([p1,p2]), set(Partner.search([('user_ids', 'not in', [u1b, u2])]).ids), "o2m NOT IN matches none on the right side")
+
+ def test_15_equivalent_one2many_2(self):
+ Currency = self.env['res.currency']
+ CurrencyRate = self.env['res.currency.rate']
+
+ # create a currency and a currency rate
+ currency = Currency.create({'name': 'ZZZ', 'symbol': 'ZZZ', 'rounding': 1.0})
+ currency_rate = CurrencyRate.create({'name': '2010-01-01', 'currency_id': currency.id, 'rate': 1.0})
+ non_currency_id = currency_rate.id + 1000
+ default_currency = Currency.browse(1)
+
+ # search the currency via its rates one2many (the one2many must point back at the currency)
+ currency_rate1 = CurrencyRate.search([('name', 'not like', 'probably_unexisting_name')])
+ currency_rate2 = CurrencyRate.search([('id', 'not in', [non_currency_id])])
+ self.assertEqual(currency_rate1, currency_rate2)
+ currency_rate3 = CurrencyRate.search([('id', 'not in', [])])
+ self.assertEqual(currency_rate1, currency_rate3)
+
+ # one2many towards another model
+ res_3 = Currency.search([('rate_ids', 'in', default_currency.rate_ids.ids)]) # currencies having a rate of main currency
+ self.assertEqual(res_3, default_currency)
+ res_4 = Currency.search([('rate_ids', 'in', default_currency.rate_ids[0].ids)]) # currencies having first rate of main currency
+ self.assertEqual(res_4, default_currency)
+ res_5 = Currency.search([('rate_ids', 'in', default_currency.rate_ids[0].id)]) # currencies having first rate of main currency
+ self.assertEqual(res_5, default_currency)
+ # res_6 = Currency.search([('rate_ids', 'in', [default_currency.rate_ids[0].name])])
+ # res_7 = Currency.search([('rate_ids', '=', default_currency.rate_ids[0].name)])
+ # res_8 = Currency.search([('rate_ids', 'like', default_currency.rate_ids[0].name)])
+
+ res_9 = Currency.search([('rate_ids', 'like', 'probably_unexisting_name')])
+ self.assertFalse(res_9)
+ # Currency.search([('rate_ids', 'unexisting_op', 'probably_unexisting_name')]) # TODO expected exception
+
+ # get the currencies referenced by some currency rates using a weird negative domain
+ res_10 = Currency.search([('rate_ids', 'not like', 'probably_unexisting_name')])
+ res_11 = Currency.search([('rate_ids', 'not in', [non_currency_id])])
+ self.assertEqual(res_10, res_11)
+ res_12 = Currency.search([('rate_ids', '!=', False)])
+ self.assertEqual(res_10, res_12)
+ res_13 = Currency.search([('rate_ids', 'not in', [])])
+ self.assertEqual(res_10, res_13)
+
+ def test_20_expression_parse(self):
# TDE note: those tests have been added when refactoring the expression.parse() method.
- # They come in addition to the already existing test_osv_expression.yml; maybe some tests
+ # They come in addition to the already existing tests; maybe some tests
# will be a bit redundant
- registry, cr, uid = self.registry, self.cr, self.uid
- users_obj = registry('res.users')
+ Users = self.env['res.users']
# Create users
- a = users_obj.create(cr, uid, {'name': 'test_A', 'login': 'test_A'})
- b1 = users_obj.create(cr, uid, {'name': 'test_B', 'login': 'test_B'})
- b1_user = users_obj.browse(cr, uid, [b1])[0]
- b2 = users_obj.create(cr, uid, {'name': 'test_B2', 'login': 'test_B2', 'parent_id': b1_user.partner_id.id})
+ a = Users.create({'name': 'test_A', 'login': 'test_A'})
+ b1 = Users.create({'name': 'test_B', 'login': 'test_B'})
+ b2 = Users.create({'name': 'test_B2', 'login': 'test_B2', 'parent_id': b1.partner_id.id})
# Test1: simple inheritance
- user_ids = users_obj.search(cr, uid, [('name', 'like', 'test')])
- self.assertEqual(set(user_ids), set([a, b1, b2]), 'searching through inheritance failed')
- user_ids = users_obj.search(cr, uid, [('name', '=', 'test_B')])
- self.assertEqual(set(user_ids), set([b1]), 'searching through inheritance failed')
+ users = Users.search([('name', 'like', 'test')])
+ self.assertEqual(users, a + b1 + b2, 'searching through inheritance failed')
+ users = Users.search([('name', '=', 'test_B')])
+ self.assertEqual(users, b1, 'searching through inheritance failed')
# Test2: inheritance + relational fields
- user_ids = users_obj.search(cr, uid, [('child_ids.name', 'like', 'test_B')])
- self.assertEqual(set(user_ids), set([b1]), 'searching through inheritance failed')
+ users = Users.search([('child_ids.name', 'like', 'test_B')])
+ self.assertEqual(users, b1, 'searching through inheritance failed')
# Special =? operator mean "is equal if right is set, otherwise always True"
- user_ids = users_obj.search(cr, uid, [('name', 'like', 'test'), ('parent_id', '=?', False)])
- self.assertEqual(set(user_ids), set([a, b1, b2]), '(x =? False) failed')
- user_ids = users_obj.search(cr, uid, [('name', 'like', 'test'), ('parent_id', '=?', b1_user.partner_id.id)])
- self.assertEqual(set(user_ids), set([b2]), '(x =? id) failed')
+ users = Users.search([('name', 'like', 'test'), ('parent_id', '=?', False)])
+ self.assertEqual(users, a + b1 + b2, '(x =? False) failed')
+ users = Users.search([('name', 'like', 'test'), ('parent_id', '=?', b1.partner_id.id)])
+ self.assertEqual(users, b2, '(x =? id) failed')
- def test_20_auto_join(self):
- registry, cr, uid = self.registry, self.cr, self.uid
- unaccent = get_unaccent_wrapper(cr)
+ def test_30_normalize_domain(self):
+ norm_domain = domain = ['&', (1, '=', 1), ('a', '=', 'b')]
+ self.assertEqual(norm_domain, expression.normalize_domain(domain), "Normalized domains should be left untouched")
+ domain = [('x', 'in', ['y', 'z']), ('a.v', '=', 'e'), '|', '|', ('a', '=', 'b'), '!', ('c', '>', 'd'), ('e', '!=', 'f'), ('g', '=', 'h')]
+ norm_domain = ['&', '&', '&'] + domain
+ self.assertEqual(norm_domain, expression.normalize_domain(domain), "Non-normalized domains should be properly normalized")
+
+ def test_40_negating_long_expression(self):
+ source = ['!', '&', ('user_id', '=', 4), ('partner_id', 'in', [1, 2])]
+ expect = ['|', ('user_id', '!=', 4), ('partner_id', 'not in', [1, 2])]
+ self.assertEqual(expression.distribute_not(source), expect,
+ "distribute_not on expression applied wrongly")
+
+ pos_leaves = [[('a', 'in', [])], [('d', '!=', 3)]]
+ neg_leaves = [[('a', 'not in', [])], [('d', '=', 3)]]
+
+ source = expression.OR([expression.AND(pos_leaves)] * 1000)
+ expect = source
+ self.assertEqual(expression.distribute_not(source), expect,
+ "distribute_not on long expression without negation operator should not alter it")
+
+ source = ['!'] + source
+ expect = expression.AND([expression.OR(neg_leaves)] * 1000)
+ self.assertEqual(expression.distribute_not(source), expect,
+ "distribute_not on long expression applied wrongly")
+
+ def test_accent(self):
+ if not self.registry.has_unaccent:
+ return
+ Company = self.env['res.company']
+ helene = Company.create({'name': u'Hélène'})
+ self.assertEqual(helene, Company.search([('name','ilike','Helene')]))
+ self.assertEqual(helene, Company.search([('name','ilike','hélène')]))
+ self.assertNotIn(helene, Company.search([('name','not ilike','Helene')]))
+ self.assertNotIn(helene, Company.search([('name','not ilike','hélène')]))
+
+ def test_like_wildcards(self):
+ # check that =like/=ilike expressions are working on an untranslated field
+ Partner = self.env['res.partner']
+ partners = Partner.search([('name', '=like', 'A_U_TeK')])
+ self.assertTrue(len(partners) == 1, "Must match one partner (ASUSTeK)")
+ partners = Partner.search([('name', '=ilike', 'c%')])
+ self.assertTrue(len(partners) >= 1, "Must match one partner (China Export)")
+
+ # check that =like/=ilike expressions are working on translated field
+ Country = self.env['res.country']
+ countries = Country.search([('name', '=like', 'Ind__')])
+ self.assertTrue(len(countries) == 1, "Must match India only")
+ countries = Country.search([('name', '=ilike', 'z%')])
+ self.assertTrue(len(countries) == 3, "Must match only countries with names starting with Z (currently 3)")
+
+ def test_translate_search(self):
+ Country = self.env['res.country']
+ belgium = self.env.ref('base.be')
+ domains = [
+ [('name', '=', 'Belgium')],
+ [('name', 'ilike', 'Belgi')],
+ [('name', 'in', ['Belgium', 'Care Bears'])],
+ ]
+
+ for domain in domains:
+ countries = Country.search(domain)
+ self.assertEqual(countries, belgium)
+
+ def test_long_table_alias(self):
+ # To test the 64 characters limit for table aliases in PostgreSQL
+ self.patch_order('res.users', 'partner_id')
+ self.patch_order('res.partner', 'commercial_partner_id,company_id,name')
+ self.patch_order('res.company', 'parent_id')
+ self.env['res.users'].search([('name', '=', 'test')])
+
+ @mute_logger('openerp.sql_db')
+ def test_invalid(self):
+ """ verify that invalid expressions are refused, even for magic fields """
+ Country = self.env['res.country']
+
+ with self.assertRaises(ValueError):
+ Country.search([('does_not_exist', '=', 'foo')])
+
+ with self.assertRaises(ValueError):
+ Country.search([('create_date', '>>', 'foo')])
+
+ with self.assertRaises(psycopg2.DataError):
+ Country.search([('create_date', '=', "1970-01-01'); --")])
+
+ def test_active(self):
+ # testing for many2many field with category vendor and active=False
+ Partner = self.env['res.partner']
+ vals = {
+ 'name': 'OpenERP Test',
+ 'active': False,
+ 'category_id': [(6, 0, [self.ref("base.res_partner_category_1")])],
+ 'child_ids': [(0, 0, {'name': 'address of OpenERP Test', 'country_id': self.ref("base.be")})],
+ }
+ Partner.create(vals)
+ partner = Partner.search([('category_id', 'ilike', 'vendor'), ('active', '=', False)])
+ self.assertTrue(partner, "Record not Found with category vendor and active False.")
+
+ # testing for one2many field with country Belgium and active=False
+ partner = Partner.search([('child_ids.country_id','=','Belgium'),('active','=',False)])
+ self.assertTrue(partner, "Record not Found with country Belgium and active False.")
+
+ def test_lp1071710(self):
+ """ Check that we can exclude translated fields (bug lp:1071710) """
+ # first install french language
+ self.env['ir.translation'].load_module_terms(['base'], ['fr_FR'])
+
+ # actual test
+ Country = self.env['res.country']
+ be = self.env.ref('base.be')
+ not_be = Country.with_context(lang='fr_FR').search([('name', '!=', 'Belgique')])
+ self.assertNotIn(be, not_be)
+
+ # indirect search via m2o
+ Partner = self.env['res.partner']
+ agrolait = Partner.search([('name', '=', 'Agrolait')])
+
+ not_be = Partner.search([('country_id', '!=', 'Belgium')])
+ self.assertNotIn(agrolait, not_be)
+
+ not_be = Partner.with_context(lang='fr_FR').search([('country_id', '!=', 'Belgique')])
+ self.assertNotIn(agrolait, not_be)
+
+
+class TestAutoJoin(TransactionCase):
+
+ def setUp(self):
+ super(TestAutoJoin, self).setUp()
+ # Mock BaseModel._where_calc(), to be able to proceed to some tests about generated expression
+ self._reinit_mock()
+ BaseModel_where_calc = BaseModel._where_calc
+
+ def _where_calc(model, *args, **kwargs):
+ """ Mock `_where_calc` to be able to test its results. Store them
+ into some internal variable for latter processing. """
+ query = BaseModel_where_calc(model, *args, **kwargs)
+ self.query_list.append(query)
+ return query
+
+ self.patch(BaseModel, '_where_calc', _where_calc)
+
+ def _reinit_mock(self):
+ self.query_list = []
+
+ def test_auto_join(self):
+ unaccent = expression.get_unaccent_wrapper(self.cr)
# Get models
- partner_obj = registry('res.partner')
- state_obj = registry('res.country.state')
- bank_obj = registry('res.partner.bank')
+ partner_obj = self.env['res.partner']
+ state_obj = self.env['res.country.state']
+ bank_obj = self.env['res.partner.bank']
# Get test columns
- partner_state_id_col = partner_obj._columns.get('state_id') # many2one on res.partner to res.country.state
- partner_parent_id_col = partner_obj._columns.get('parent_id') # many2one on res.partner to res.partner
- state_country_id_col = state_obj._columns.get('country_id') # many2one on res.country.state on res.country
- partner_child_ids_col = partner_obj._columns.get('child_ids') # one2many on res.partner to res.partner
- partner_bank_ids_col = partner_obj._columns.get('bank_ids') # one2many on res.partner to res.partner.bank
- category_id_col = partner_obj._columns.get('category_id') # many2many on res.partner to res.partner.category
+ def patch_auto_join(model, fname, value):
+ self.patch(model._fields[fname], 'auto_join', value)
+ self.patch(model._columns[fname], '_auto_join', value)
+
+ def patch_domain(model, fname, value):
+ self.patch(model._fields[fname], 'domain', value)
+ self.patch(model._columns[fname], '_domain', value)
# Get country/state data
- country_us_id = registry('res.country').search(cr, uid, [('code', 'like', 'US')])[0]
- state_ids = registry('res.country.state').search(cr, uid, [('country_id', '=', country_us_id)], limit=2)
+ country_us = self.env['res.country'].search([('code', 'like', 'US')], limit=1)
+ states = self.env['res.country.state'].search([('country_id', '=', country_us.id)], limit=2)
# Create demo data: partners and bank object
- p_a = partner_obj.create(cr, uid, {'name': 'test__A', 'state_id': state_ids[0]})
- p_b = partner_obj.create(cr, uid, {'name': 'test__B', 'state_id': state_ids[1]})
- p_aa = partner_obj.create(cr, uid, {'name': 'test__AA', 'parent_id': p_a, 'state_id': state_ids[0]})
- p_ab = partner_obj.create(cr, uid, {'name': 'test__AB', 'parent_id': p_a, 'state_id': state_ids[1]})
- p_ba = partner_obj.create(cr, uid, {'name': 'test__BA', 'parent_id': p_b, 'state_id': state_ids[0]})
- b_aa = bank_obj.create(cr, uid, {'acc_number': '123', 'acc_type': 'bank', 'partner_id': p_aa})
- b_ab = bank_obj.create(cr, uid, {'acc_number': '456', 'acc_type': 'bank', 'partner_id': p_ab})
- b_ba = bank_obj.create(cr, uid, {'acc_number': '789', 'acc_type': 'bank', 'partner_id': p_ba})
+ p_a = partner_obj.create({'name': 'test__A', 'state_id': states[0].id})
+ p_b = partner_obj.create({'name': 'test__B', 'state_id': states[1].id})
+ p_aa = partner_obj.create({'name': 'test__AA', 'parent_id': p_a.id, 'state_id': states[0].id})
+ p_ab = partner_obj.create({'name': 'test__AB', 'parent_id': p_a.id, 'state_id': states[1].id})
+ p_ba = partner_obj.create({'name': 'test__BA', 'parent_id': p_b.id, 'state_id': states[0].id})
+ b_aa = bank_obj.create({'acc_number': '123', 'acc_type': 'bank', 'partner_id': p_aa.id})
+ b_ab = bank_obj.create({'acc_number': '456', 'acc_type': 'bank', 'partner_id': p_ab.id})
+ b_ba = bank_obj.create({'acc_number': '789', 'acc_type': 'bank', 'partner_id': p_ba.id})
# --------------------------------------------------
# Test1: basics about the attribute
# --------------------------------------------------
- category_id_col._auto_join = True
- self.assertRaises(NotImplementedError, partner_obj.search, cr, uid, [('category_id.name', '=', 'foo')])
- category_id_col._auto_join = False
+ patch_auto_join(partner_obj, 'category_id', True)
+ with self.assertRaises(NotImplementedError):
+ partner_obj.search([('category_id.name', '=', 'foo')])
# --------------------------------------------------
# Test2: one2many
@@ -206,9 +677,9 @@ class test_expression(common.TransactionCase):
# Do: one2many without _auto_join
self._reinit_mock()
- partner_ids = partner_obj.search(cr, uid, [('bank_ids.sanitized_acc_number', 'like', name_test)])
+ partners = partner_obj.search([('bank_ids.sanitized_acc_number', 'like', name_test)])
# Test result
- self.assertEqual(set(partner_ids), set([p_aa]),
+ self.assertEqual(partners, p_aa,
"_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..'): incorrect result")
# Test produced queries
self.assertEqual(len(self.query_list), 3,
@@ -221,32 +692,32 @@ class test_expression(common.TransactionCase):
self.assertIn(expected, sql_query[1],
"_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') first query incorrect where condition")
- self.assertEqual(set(['%' + name_test + '%']), set(sql_query[2]),
+ self.assertEqual(['%' + name_test + '%'], sql_query[2],
"_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') first query incorrect parameter")
sql_query = self.query_list[2].get_sql()
self.assertIn('res_partner', sql_query[0],
"_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') third query incorrect main table")
self.assertIn('"res_partner"."id" in (%s)', sql_query[1],
"_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') third query incorrect where condition")
- self.assertEqual(set([p_aa]), set(sql_query[2]),
+ self.assertIn(p_aa.id, sql_query[2],
"_auto_join off: ('bank_ids.sanitized_acc_number', 'like', '..') third query incorrect parameter")
# Do: cascaded one2many without _auto_join
self._reinit_mock()
- partner_ids = partner_obj.search(cr, uid, [('child_ids.bank_ids.id', 'in', [b_aa, b_ba])])
+ partners = partner_obj.search([('child_ids.bank_ids.id', 'in', [b_aa.id, b_ba.id])])
# Test result
- self.assertEqual(set(partner_ids), set([p_a, p_b]),
+ self.assertEqual(partners, p_a + p_b,
"_auto_join off: ('child_ids.bank_ids.id', 'in', [..]): incorrect result")
# Test produced queries
self.assertEqual(len(self.query_list), 5,
"_auto_join off: ('child_ids.bank_ids.id', 'in', [..]) should produce 5 queries (1 in res_partner_bank, 4 on res_partner)")
# Do: one2many with _auto_join
- partner_bank_ids_col._auto_join = True
+ patch_auto_join(partner_obj, 'bank_ids', True)
self._reinit_mock()
- partner_ids = partner_obj.search(cr, uid, [('bank_ids.sanitized_acc_number', 'like', '12')])
+ partners = partner_obj.search([('bank_ids.sanitized_acc_number', 'like', name_test)])
# Test result
- self.assertEqual(set(partner_ids), set([p_aa]),
+ self.assertEqual(partners, p_aa,
"_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') incorrect result")
# Test produced queries
self.assertEqual(len(self.query_list), 1,
@@ -263,14 +734,15 @@ class test_expression(common.TransactionCase):
self.assertIn('"res_partner"."id"="res_partner__bank_ids"."partner_id"', sql_query[1],
"_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect join condition")
- self.assertEqual(set(['%' + name_test + '%']), set(sql_query[2]),
+ self.assertIn('%' + name_test + '%', sql_query[2],
"_auto_join on: ('bank_ids.sanitized_acc_number', 'like', '..') query incorrect parameter")
# Do: one2many with _auto_join, test final leaf is an id
self._reinit_mock()
- partner_ids = partner_obj.search(cr, uid, [('bank_ids.id', 'in', [b_aa, b_ab])])
+ bank_ids = [b_aa.id, b_ab.id]
+ partners = partner_obj.search([('bank_ids.id', 'in', bank_ids)])
# Test result
- self.assertEqual(set(partner_ids), set([p_aa, p_ab]),
+ self.assertEqual(partners, p_aa + p_ab,
"_auto_join on: ('bank_ids.id', 'in', [..]) incorrect result")
# Test produced queries
self.assertEqual(len(self.query_list), 1,
@@ -280,15 +752,16 @@ class test_expression(common.TransactionCase):
"_auto_join on: ('bank_ids.id', 'in', [..]) query incorrect main table")
self.assertIn('"res_partner__bank_ids"."id" in (%s,%s)', sql_query[1],
"_auto_join on: ('bank_ids.id', 'in', [..]) query incorrect where condition")
- self.assertEqual(set([b_aa, b_ab]), set(sql_query[2]),
+ self.assertLessEqual(set(bank_ids), set(sql_query[2]),
"_auto_join on: ('bank_ids.id', 'in', [..]) query incorrect parameter")
# Do: 2 cascaded one2many with _auto_join, test final leaf is an id
- partner_child_ids_col._auto_join = True
+ patch_auto_join(partner_obj, 'child_ids', True)
self._reinit_mock()
- partner_ids = partner_obj.search(cr, uid, [('child_ids.bank_ids.id', 'in', [b_aa, b_ba])])
+ bank_ids = [b_aa.id, b_ba.id]
+ partners = partner_obj.search([('child_ids.bank_ids.id', 'in', bank_ids)])
# Test result
- self.assertEqual(set(partner_ids), set([p_a, p_b]),
+ self.assertEqual(partners, p_a + p_b,
"_auto_join on: ('child_ids.bank_ids.id', 'not in', [..]): incorrect result")
# # Test produced queries
self.assertEqual(len(self.query_list), 1,
@@ -306,31 +779,30 @@ class test_expression(common.TransactionCase):
"_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect join condition")
self.assertIn('"res_partner__child_ids"."id"="res_partner__child_ids__bank_ids"."partner_id"', sql_query[1],
"_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect join condition")
- self.assertEqual(set([b_aa, b_ba]), set(sql_query[2][-2:]),
+ self.assertLessEqual(set(bank_ids), set(sql_query[2][-2:]),
"_auto_join on: ('child_ids.bank_ids.id', 'in', [..]) query incorrect parameter")
# --------------------------------------------------
# Test3: many2one
# --------------------------------------------------
-
name_test = 'US'
# Do: many2one without _auto_join
self._reinit_mock()
- partner_ids = partner_obj.search(cr, uid, [('state_id.country_id.code', 'like', name_test)])
+ partners = partner_obj.search([('state_id.country_id.code', 'like', name_test)])
# Test result: at least our added data + demo data
- self.assertTrue(set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)),
+ self.assertLessEqual(p_a + p_b + p_aa + p_ab + p_ba, partners,
"_auto_join off: ('state_id.country_id.code', 'like', '..') incorrect result")
# Test produced queries
self.assertEqual(len(self.query_list), 3,
"_auto_join off: ('state_id.country_id.code', 'like', '..') should produce 3 queries (1 on res_country, 1 on res_country_state, 1 on res_partner)")
# Do: many2one with 1 _auto_join on the first many2one
- partner_state_id_col._auto_join = True
+ patch_auto_join(partner_obj, 'state_id', True)
self._reinit_mock()
- partner_ids = partner_obj.search(cr, uid, [('state_id.country_id.code', 'like', name_test)])
+ partners = partner_obj.search([('state_id.country_id.code', 'like', name_test)])
# Test result: at least our added data + demo data
- self.assertTrue(set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)),
+ self.assertLessEqual(p_a + p_b + p_aa + p_ab + p_ba, partners,
"_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') incorrect result")
# Test produced queries
self.assertEqual(len(self.query_list), 2,
@@ -356,12 +828,12 @@ class test_expression(common.TransactionCase):
"_auto_join on for state_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect join condition")
# Do: many2one with 1 _auto_join on the second many2one
- partner_state_id_col._auto_join = False
- state_country_id_col._auto_join = True
+ patch_auto_join(partner_obj, 'state_id', False)
+ patch_auto_join(state_obj, 'country_id', True)
self._reinit_mock()
- partner_ids = partner_obj.search(cr, uid, [('state_id.country_id.code', 'like', name_test)])
+ partners = partner_obj.search([('state_id.country_id.code', 'like', name_test)])
# Test result: at least our added data + demo data
- self.assertTrue(set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)),
+ self.assertLessEqual(p_a + p_b + p_aa + p_ab + p_ba, partners,
"_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') incorrect result")
# Test produced queries
self.assertEqual(len(self.query_list), 2,
@@ -389,12 +861,12 @@ class test_expression(common.TransactionCase):
"_auto_join on for country_id: ('state_id.country_id.code', 'like', '..') query 2 incorrect where condition")
# Do: many2one with 2 _auto_join
- partner_state_id_col._auto_join = True
- state_country_id_col._auto_join = True
+ patch_auto_join(partner_obj, 'state_id', True)
+ patch_auto_join(state_obj, 'country_id', True)
self._reinit_mock()
- partner_ids = partner_obj.search(cr, uid, [('state_id.country_id.code', 'like', name_test)])
+ partners = partner_obj.search([('state_id.country_id.code', 'like', name_test)])
# Test result: at least our added data + demo data
- self.assertTrue(set([p_a, p_b, p_aa, p_ab, p_ba]).issubset(set(partner_ids)),
+ self.assertLessEqual(p_a + p_b + p_aa + p_ab + p_ba, partners,
"_auto_join on: ('state_id.country_id.code', 'like', '..') incorrect result")
# Test produced queries
self.assertEqual(len(self.query_list), 1,
@@ -415,28 +887,28 @@ class test_expression(common.TransactionCase):
"_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join condition")
self.assertIn('"res_partner__state_id"."country_id"="res_partner__state_id__country_id"."id"', sql_query[1],
"_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect join condition")
- self.assertEqual(['%' + name_test + '%'], sql_query[2],
+ self.assertIn('%' + name_test + '%', sql_query[2],
"_auto_join on: ('state_id.country_id.code', 'like', '..') query incorrect parameter")
# --------------------------------------------------
# Test4: domain attribute on one2many fields
# --------------------------------------------------
- partner_child_ids_col._auto_join = True
- partner_bank_ids_col._auto_join = True
- partner_child_ids_col._domain = lambda self: ['!', ('name', '=', self._name)]
- partner_bank_ids_col._domain = [('sanitized_acc_number', 'like', '2')]
+ patch_auto_join(partner_obj, 'child_ids', True)
+ patch_auto_join(partner_obj, 'bank_ids', True)
+ patch_domain(partner_obj, 'child_ids', lambda self: ['!', ('name', '=', self._name)])
+ patch_domain(partner_obj, 'bank_ids', [('sanitized_acc_number', 'like', '2')])
# Do: 2 cascaded one2many with _auto_join, test final leaf is an id
self._reinit_mock()
- partner_ids = partner_obj.search(cr, uid, ['&', (1, '=', 1), ('child_ids.bank_ids.id', 'in', [b_aa, b_ba])])
+ partners = partner_obj.search(['&', (1, '=', 1), ('child_ids.bank_ids.id', 'in', [b_aa.id, b_ba.id])])
# Test result: at least one of our added data
- self.assertTrue(set([p_a]).issubset(set(partner_ids)),
+ self.assertLessEqual(p_a, partners,
"_auto_join on one2many with domains incorrect result")
- self.assertTrue(set([p_ab, p_ba]) not in set(partner_ids),
+ self.assertFalse((p_ab + p_ba) & partners,
"_auto_join on one2many with domains incorrect result")
# Test produced queries that domains effectively present
sql_query = self.query_list[0].get_sql()
-
+
expected = "%s::text like %s" % (unaccent('"res_partner__child_ids__bank_ids"."sanitized_acc_number"'), unaccent('%s'))
self.assertIn(expected, sql_query[1],
"_auto_join on one2many with domains incorrect result")
@@ -444,101 +916,44 @@ class test_expression(common.TransactionCase):
self.assertIn('"res_partner__child_ids"."name" = %s', sql_query[1],
"_auto_join on one2many with domains incorrect result")
- partner_child_ids_col._domain = lambda self: [('name', '=', '__%s' % self._name)]
+ patch_domain(partner_obj, 'child_ids', lambda self: [('name', '=', '__%s' % self._name)])
self._reinit_mock()
- partner_ids = partner_obj.search(cr, uid, ['&', (1, '=', 1), ('child_ids.bank_ids.id', 'in', [b_aa, b_ba])])
+ partners = partner_obj.search(['&', (1, '=', 1), ('child_ids.bank_ids.id', 'in', [b_aa.id, b_ba.id])])
# Test result: no one
- self.assertFalse(partner_ids,
+ self.assertFalse(partners,
"_auto_join on one2many with domains incorrect result")
# ----------------------------------------
# Test5: result-based tests
# ----------------------------------------
- partner_bank_ids_col._auto_join = False
- partner_child_ids_col._auto_join = False
- partner_state_id_col._auto_join = False
- partner_parent_id_col._auto_join = False
- state_country_id_col._auto_join = False
- partner_child_ids_col._domain = []
- partner_bank_ids_col._domain = []
+ patch_auto_join(partner_obj, 'bank_ids', False)
+ patch_auto_join(partner_obj, 'child_ids', False)
+ patch_auto_join(partner_obj, 'state_id', False)
+ patch_auto_join(partner_obj, 'parent_id', False)
+ patch_auto_join(state_obj, 'country_id', False)
+ patch_domain(partner_obj, 'child_ids', [])
+ patch_domain(partner_obj, 'bank_ids', [])
# Do: ('child_ids.state_id.country_id.code', 'like', '..') without _auto_join
self._reinit_mock()
- partner_ids = partner_obj.search(cr, uid, [('child_ids.state_id.country_id.code', 'like', name_test)])
+ partners = partner_obj.search([('child_ids.state_id.country_id.code', 'like', name_test)])
# Test result: at least our added data + demo data
- self.assertTrue(set([p_a, p_b]).issubset(set(partner_ids)),
+ self.assertLessEqual(p_a + p_b, partners,
"_auto_join off: ('child_ids.state_id.country_id.code', 'like', '..') incorrect result")
# Test produced queries
self.assertEqual(len(self.query_list), 5,
"_auto_join off: ('child_ids.state_id.country_id.code', 'like', '..') number of queries incorrect")
# Do: ('child_ids.state_id.country_id.code', 'like', '..') with _auto_join
- partner_child_ids_col._auto_join = True
- partner_state_id_col._auto_join = True
- state_country_id_col._auto_join = True
+ patch_auto_join(partner_obj, 'child_ids', True)
+ patch_auto_join(partner_obj, 'state_id', True)
+ patch_auto_join(state_obj, 'country_id', True)
self._reinit_mock()
- partner_ids = partner_obj.search(cr, uid, [('child_ids.state_id.country_id.code', 'like', name_test)])
+ partners = partner_obj.search([('child_ids.state_id.country_id.code', 'like', name_test)])
# Test result: at least our added data + demo data
- self.assertTrue(set([p_a, p_b]).issubset(set(partner_ids)),
+ self.assertLessEqual(p_a + p_b, partners,
"_auto_join on: ('child_ids.state_id.country_id.code', 'like', '..') incorrect result")
# Test produced queries
self.assertEqual(len(self.query_list), 1,
"_auto_join on: ('child_ids.state_id.country_id.code', 'like', '..') number of queries incorrect")
-
- # Remove mocks and modifications
- partner_bank_ids_col._auto_join = False
- partner_child_ids_col._auto_join = False
- partner_state_id_col._auto_join = False
- partner_parent_id_col._auto_join = False
- state_country_id_col._auto_join = False
-
- def test_30_normalize_domain(self):
- expression = openerp.osv.expression
- norm_domain = domain = ['&', (1, '=', 1), ('a', '=', 'b')]
- assert norm_domain == expression.normalize_domain(domain), "Normalized domains should be left untouched"
- domain = [('x', 'in', ['y', 'z']), ('a.v', '=', 'e'), '|', '|', ('a', '=', 'b'), '!', ('c', '>', 'd'), ('e', '!=', 'f'), ('g', '=', 'h')]
- norm_domain = ['&', '&', '&'] + domain
- assert norm_domain == expression.normalize_domain(domain), "Non-normalized domains should be properly normalized"
-
- def test_40_negating_long_expression(self):
- source = ['!','&',('user_id','=',4),('partner_id','in',[1,2])]
- expect = ['|',('user_id','!=',4),('partner_id','not in',[1,2])]
- self.assertEqual(expression.distribute_not(source), expect,
- "distribute_not on expression applied wrongly")
-
- pos_leaves = [[('a', 'in', [])], [('d', '!=', 3)]]
- neg_leaves = [[('a', 'not in', [])], [('d', '=', 3)]]
-
- source = expression.OR([expression.AND(pos_leaves)] * 1000)
- expect = source
- self.assertEqual(expression.distribute_not(source), expect,
- "distribute_not on long expression without negation operator should not alter it")
-
- source = ['!'] + source
- expect = expression.AND([expression.OR(neg_leaves)] * 1000)
- self.assertEqual(expression.distribute_not(source), expect,
- "distribute_not on long expression applied wrongly")
-
- def test_translate_search(self):
- Country = self.registry('res.country')
- be = self.ref('base.be')
- domains = [
- [('name', '=', 'Belgium')],
- [('name', 'ilike', 'Belgi')],
- [('name', 'in', ['Belgium', 'Care Bears'])],
- ]
-
- for domain in domains:
- ids = Country.search(self.cr, self.uid, domain)
- self.assertListEqual([be], ids)
-
- def test_long_table_alias(self):
- # To test the 64 characters limit for table aliases in PostgreSQL
- self.patch_order('res.users', 'partner_id')
- self.patch_order('res.partner', 'commercial_partner_id,company_id,name')
- self.patch_order('res.company', 'parent_id')
- self.env['res.users'].search([('name', '=', 'test')])
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/openerp/addons/base/tests/test_float.py b/openerp/addons/base/tests/test_float.py
new file mode 100644
index 00000000000..6737cbc63df
--- /dev/null
+++ b/openerp/addons/base/tests/test_float.py
@@ -0,0 +1,177 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from math import log10
+
+from odoo.tests.common import TransactionCase
+from odoo.tools import float_compare, float_is_zero, float_repr, float_round
+
+
+class TestFloatPrecision(TransactionCase):
+ """ Tests on float precision. """
+
+ def test_rounding_02(self):
+ """ Test rounding methods with 2 digits. """
+ currency = self.env.ref('base.EUR')
+
+ def try_round(amount, expected):
+ digits = max(0, -int(log10(currency.rounding)))
+ result = float_repr(currency.round(amount), precision_digits=digits)
+ self.assertEqual(result, expected, 'Rounding error: got %s, expected %s' % (result, expected))
+
+ try_round(2.674,'2.67')
+ try_round(2.675,'2.68') # in Python 2.7.2, round(2.675,2) gives 2.67
+ try_round(-2.675,'-2.68') # in Python 2.7.2, round(2.675,2) gives 2.67
+ try_round(0.001,'0.00')
+ try_round(-0.001,'-0.00')
+ try_round(0.0049,'0.00') # 0.0049 is closer to 0 than to 0.01, so should round down
+ try_round(0.005,'0.01') # the rule is to round half away from zero
+ try_round(-0.005,'-0.01') # the rule is to round half away from zero
+
+ def try_zero(amount, expected):
+ self.assertEqual(currency.is_zero(amount), expected,
+ "Rounding error: %s should be zero!" % amount)
+
+ try_zero(0.01, False)
+ try_zero(-0.01, False)
+ try_zero(0.001, True)
+ try_zero(-0.001, True)
+ try_zero(0.0046, True)
+ try_zero(-0.0046, True)
+ try_zero(2.68-2.675, False) # 2.68 - 2.675 = 0.005 -> rounds to 0.01
+ try_zero(2.68-2.676, True) # 2.68 - 2.675 = 0.004 -> rounds to 0.0
+ try_zero(2.676-2.68, True) # 2.675 - 2.68 = -0.004 -> rounds to -0.0
+ try_zero(2.675-2.68, False) # 2.675 - 2.68 = -0.005 -> rounds to -0.01
+
+ def try_compare(amount1, amount2, expected):
+ self.assertEqual(currency.compare_amounts(amount1, amount2), expected,
+ "Rounding error, compare_amounts(%s,%s) should be %s" % (amount1, amount2, expected))
+
+ try_compare(0.001, 0.001, 0)
+ try_compare(-0.001, -0.001, 0)
+ try_compare(0.001, 0.002, 0)
+ try_compare(-0.001, -0.002, 0)
+ try_compare(2.675, 2.68, 0)
+ try_compare(2.676, 2.68, 0)
+ try_compare(-2.676, -2.68, 0)
+ try_compare(2.674, 2.68, -1)
+ try_compare(-2.674, -2.68, 1)
+ try_compare(3, 2.68, 1)
+ try_compare(-3, -2.68, -1)
+ try_compare(0.01, 0, 1)
+ try_compare(-0.01, 0, -1)
+
+ def test_rounding_03(self):
+ """ Test rounding methods with 3 digits. """
+
+ def try_round(amount, expected, digits=3, method='HALF-UP'):
+ value = float_round(amount, precision_digits=digits, rounding_method=method)
+ result = float_repr(value, precision_digits=digits)
+ self.assertEqual(result, expected, 'Rounding error: got %s, expected %s' % (result, expected))
+
+ try_round(2.6745, '2.675')
+ try_round(-2.6745, '-2.675')
+ try_round(2.6744, '2.674')
+ try_round(-2.6744, '-2.674')
+ try_round(0.0004, '0.000')
+ try_round(-0.0004, '-0.000')
+ try_round(357.4555, '357.456')
+ try_round(-357.4555, '-357.456')
+ try_round(457.4554, '457.455')
+ try_round(-457.4554, '-457.455')
+
+ # Try some rounding value with rounding method UP instead of HALF-UP
+ # We use 8.175 because when normalizing 8.175 with precision_digits=3 it gives
+ # us 8175,0000000001234 as value, and if not handle correctly the rounding UP
+ # value will be incorrect (should be 8,175 and not 8,176)
+ try_round(8.175, '8.175', method='UP')
+ try_round(8.1751, '8.176', method='UP')
+ try_round(-8.175, '-8.175', method='UP')
+ try_round(-8.1751, '-8.176', method='UP')
+ try_round(-6.000, '-6.000', method='UP')
+ try_round(1.8, '2', 0, method='UP')
+ try_round(-1.8, '-2', 0, method='UP')
+
+ # Extended float range test, inspired by Cloves Almeida's test on bug #882036.
+ fractions = [.0, .015, .01499, .675, .67499, .4555, .4555, .45555]
+ expecteds = ['.00', '.02', '.01', '.68', '.67', '.46', '.456', '.4556']
+ precisions = [2, 2, 2, 2, 2, 2, 3, 4]
+ # Note: max precision for double floats is 53 bits of precision or
+ # 17 significant decimal digits
+ for magnitude in range(7):
+ for i in xrange(len(fractions)):
+ frac, exp, prec = fractions[i], expecteds[i], precisions[i]
+ for sign in [-1,1]:
+ for x in xrange(0,10000,97):
+ n = x * 10**magnitude
+ f = sign * (n + frac)
+ f_exp = ('-' if f != 0 and sign == -1 else '') + str(n) + exp
+ try_round(f, f_exp, digits=prec)
+
+ def try_zero(amount, expected):
+ self.assertEqual(float_is_zero(amount, precision_digits=3), expected,
+ "Rounding error: %s should be zero!" % amount)
+
+ try_zero(0.0002, True)
+ try_zero(-0.0002, True)
+ try_zero(0.00034, True)
+ try_zero(0.0005, False)
+ try_zero(-0.0005, False)
+ try_zero(0.0008, False)
+ try_zero(-0.0008, False)
+
+ def try_compare(amount1, amount2, expected):
+ self.assertEqual(float_compare(amount1, amount2, precision_digits=3), expected,
+ "Rounding error, compare_amounts(%s,%s) should be %s" % (amount1, amount2, expected))
+
+ try_compare(0.0003, 0.0004, 0)
+ try_compare(-0.0003, -0.0004, 0)
+ try_compare(0.0002, 0.0005, -1)
+ try_compare(-0.0002, -0.0005, 1)
+ try_compare(0.0009, 0.0004, 1)
+ try_compare(-0.0009, -0.0004, -1)
+ try_compare(557.4555, 557.4556, 0)
+ try_compare(-557.4555, -557.4556, 0)
+ try_compare(657.4444, 657.445, -1)
+ try_compare(-657.4444, -657.445, 1)
+
+ # Rounding to unusual rounding units (e.g. coin values)
+ def try_round(amount, expected, precision_rounding=None):
+ value = float_round(amount, precision_rounding=precision_rounding)
+ result = float_repr(value, precision_digits=2)
+ self.assertEqual(result, expected, 'Rounding error: got %s, expected %s' % (result, expected))
+
+ try_round(-457.4554, '-457.45', precision_rounding=0.05)
+ try_round(457.444, '457.50', precision_rounding=0.5)
+ try_round(457.3, '455.00', precision_rounding=5)
+ try_round(457.5, '460.00', precision_rounding=5)
+ try_round(457.1, '456.00', precision_rounding=3)
+
+ def test_rounding_04(self):
+ """ check that proper rounding is performed for float persistence """
+ currency = self.env.ref('base.EUR')
+ currency_rate = self.env['res.currency.rate']
+
+ def try_roundtrip(value, expected):
+ rate = currency_rate.create({'name':'2000-01-01',
+ 'rate': value,
+ 'currency_id': currency.id})
+ self.assertEqual(rate.rate, expected,
+ 'Roundtrip error: got %s back from db, expected %s' % (rate, expected))
+
+ # res.currency.rate uses 6 digits of precision by default
+ try_roundtrip(2.6748955, 2.674896)
+ try_roundtrip(-2.6748955, -2.674896)
+ try_roundtrip(10000.999999, 10000.999999)
+ try_roundtrip(-10000.999999, -10000.999999)
+
+ def test_rounding_invalid(self):
+ """ verify that invalid parameters are forbidden """
+ with self.assertRaises(AssertionError):
+ float_is_zero(0.01, precision_digits=3, precision_rounding=0.01)
+
+ with self.assertRaises(AssertionError):
+ float_compare(0.01, 0.02, precision_digits=3, precision_rounding=0.01)
+
+ with self.assertRaises(AssertionError):
+ float_round(0.01, precision_digits=3, precision_rounding=0.01)
diff --git a/openerp/addons/base/tests/test_func.py b/openerp/addons/base/tests/test_func.py
index 1be2469666a..ac394cb9b79 100644
--- a/openerp/addons/base/tests/test_func.py
+++ b/openerp/addons/base/tests/test_func.py
@@ -1,16 +1,17 @@
# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
import functools
import unittest
-from openerp.tools.func import compose
-from openerp.tools import frozendict
+from odoo.tools import frozendict
+from odoo.tools.func import compose
+
class TestCompose(unittest.TestCase):
def test_basic(self):
str_add = compose(str, lambda a, b: a + b)
- self.assertEqual(
- str_add(1, 2),
- "3")
+ self.assertEqual(str_add(1, 2), "3")
def test_decorator(self):
""" ensure compose() can be partially applied as a decorator
@@ -21,6 +22,7 @@ class TestCompose(unittest.TestCase):
self.assertEqual(mul(5, 42), u"210")
+
class TestFrozendict(unittest.TestCase):
def test_frozendict_immutable(self):
""" Ensure that a frozendict is immutable. """
diff --git a/openerp/addons/base/tests/test_ir_actions.py b/openerp/addons/base/tests/test_ir_actions.py
index ee494ad84a7..a03ef2e0d0b 100644
--- a/openerp/addons/base/tests/test_ir_actions.py
+++ b/openerp/addons/base/tests/test_ir_actions.py
@@ -1,58 +1,50 @@
-import unittest
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp.exceptions import ValidationError
-import openerp.tests.common as common
-from openerp.tools import mute_logger
+from odoo.exceptions import ValidationError
+from odoo.tools import mute_logger
+import odoo.tests.common as common
+import odoo.workflow
class TestServerActionsBase(common.TransactionCase):
def setUp(self):
super(TestServerActionsBase, self).setUp()
- cr, uid = self.cr, self.uid
-
- # Models
- self.ir_actions_server = self.registry('ir.actions.server')
- self.ir_actions_client = self.registry('ir.actions.client')
- self.ir_values = self.registry('ir.values')
- self.ir_model = self.registry('ir.model')
- self.ir_model_fields = self.registry('ir.model.fields')
- self.res_partner = self.registry('res.partner')
- self.res_country = self.registry('res.country')
# Data on which we will run the server action
- self.test_country_id = self.res_country.create(cr, uid, {
+ self.test_country = self.env['res.country'].create({
'name': 'TestingCountry',
'code': 'TY',
'address_format': 'SuperFormat',
})
- self.test_country = self.res_country.browse(cr, uid, self.test_country_id)
- self.test_partner_id = self.res_partner.create(cr, uid, {
+ self.test_partner = self.env['res.partner'].create({
'name': 'TestingPartner',
'city': 'OrigCity',
- 'country_id': self.test_country_id,
+ 'country_id': self.test_country.id,
})
- self.test_partner = self.res_partner.browse(cr, uid, self.test_partner_id)
self.context = {
- 'active_id': self.test_partner_id,
'active_model': 'res.partner',
+ 'active_id': self.test_partner.id,
}
# Model data
- self.res_partner_model_id = self.ir_model.search(cr, uid, [('model', '=', 'res.partner')])[0]
- self.res_partner_name_field_id = self.ir_model_fields.search(cr, uid, [('model', '=', 'res.partner'), ('name', '=', 'name')])[0]
- self.res_partner_city_field_id = self.ir_model_fields.search(cr, uid, [('model', '=', 'res.partner'), ('name', '=', 'city')])[0]
- self.res_partner_country_field_id = self.ir_model_fields.search(cr, uid, [('model', '=', 'res.partner'), ('name', '=', 'country_id')])[0]
- self.res_partner_parent_field_id = self.ir_model_fields.search(cr, uid, [('model', '=', 'res.partner'), ('name', '=', 'parent_id')])[0]
- self.res_country_model_id = self.ir_model.search(cr, uid, [('model', '=', 'res.country')])[0]
- self.res_country_name_field_id = self.ir_model_fields.search(cr, uid, [('model', '=', 'res.country'), ('name', '=', 'name')])[0]
- self.res_country_code_field_id = self.ir_model_fields.search(cr, uid, [('model', '=', 'res.country'), ('name', '=', 'code')])[0]
+ Model = self.env['ir.model']
+ Fields = self.env['ir.model.fields']
+ self.res_partner_model = Model.search([('model', '=', 'res.partner')])
+ self.res_partner_name_field = Fields.search([('model', '=', 'res.partner'), ('name', '=', 'name')])
+ self.res_partner_city_field = Fields.search([('model', '=', 'res.partner'), ('name', '=', 'city')])
+ self.res_partner_country_field = Fields.search([('model', '=', 'res.partner'), ('name', '=', 'country_id')])
+ self.res_partner_parent_field = Fields.search([('model', '=', 'res.partner'), ('name', '=', 'parent_id')])
+ self.res_country_model = Model.search([('model', '=', 'res.country')])
+ self.res_country_name_field = Fields.search([('model', '=', 'res.country'), ('name', '=', 'name')])
+ self.res_country_code_field = Fields.search([('model', '=', 'res.country'), ('name', '=', 'code')])
# create server action to
- self.act_id = self.ir_actions_server.create(cr, uid, {
+ self.action = self.env['ir.actions.server'].create({
'name': 'TestAction',
'condition': 'True',
- 'model_id': self.res_partner_model_id,
+ 'model_id': self.res_partner_model.id,
'state': 'code',
'code': 'obj.write({"comment": "MyComment"})',
})
@@ -61,346 +53,318 @@ class TestServerActionsBase(common.TransactionCase):
class TestServerActions(TestServerActionsBase):
def test_00_action(self):
- cr, uid = self.cr, self.uid
-
# Do: eval 'True' condition
- self.ir_actions_server.run(cr, uid, [self.act_id], self.context)
- self.test_partner.refresh()
+ self.action.with_context(self.context).run()
self.assertEqual(self.test_partner.comment, 'MyComment', 'ir_actions_server: invalid condition check')
self.test_partner.write({'comment': False})
# Do: eval False condition, that should be considered as True (void = True)
- self.ir_actions_server.write(cr, uid, [self.act_id], {'condition': False})
- self.ir_actions_server.run(cr, uid, [self.act_id], self.context)
- self.test_partner.refresh()
+ self.action.write({'condition': False})
+ self.action.with_context(self.context).run()
self.assertEqual(self.test_partner.comment, 'MyComment', 'ir_actions_server: invalid condition check')
# Do: create contextual action
- self.ir_actions_server.create_action(cr, uid, [self.act_id])
+ self.action.create_action()
# Test: ir_values created
- ir_values_ids = self.ir_values.search(cr, uid, [('name', '=', 'Run TestAction')])
- self.assertEqual(len(ir_values_ids), 1, 'ir_actions_server: create_action should have created an entry in ir_values')
- ir_value = self.ir_values.browse(cr, uid, ir_values_ids[0])
- self.assertEqual(ir_value.value, 'ir.actions.server,%s' % self.act_id, 'ir_actions_server: created ir_values should reference the server action')
- self.assertEqual(ir_value.model, 'res.partner', 'ir_actions_server: created ir_values should be linked to the action base model')
+ ir_values = self.env['ir.values'].search([('name', '=', 'Run TestAction')])
+ self.assertEqual(len(ir_values), 1, 'ir_actions_server: create_action should have created an entry in ir_values')
+ self.assertEqual(ir_values.value, 'ir.actions.server,%s' % self.action.id, 'ir_actions_server: created ir_values should reference the server action')
+ self.assertEqual(ir_values.model, 'res.partner', 'ir_actions_server: created ir_values should be linked to the action base model')
# Do: remove contextual action
- self.ir_actions_server.unlink_action(cr, uid, [self.act_id])
+ self.action.unlink_action()
# Test: ir_values removed
- ir_values_ids = self.ir_values.search(cr, uid, [('name', '=', 'Run TestAction')])
- self.assertEqual(len(ir_values_ids), 0, 'ir_actions_server: unlink_action should remove the ir_values record')
+ ir_values = self.env['ir.values'].search([('name', '=', 'Run TestAction')])
+ self.assertEqual(len(ir_values), 0, 'ir_actions_server: unlink_action should remove the ir_values record')
def test_10_code(self):
- cr, uid = self.cr, self.uid
- self.ir_actions_server.write(cr, uid, self.act_id, {
+ self.action.write({
'state': 'code',
- 'code': """partner_name = obj.name + '_code'
-self.pool["res.partner"].create(cr, uid, {"name": partner_name}, context=context)
-workflow"""
+ 'code': ("partner_name = obj.name + '_code'\n"
+ "obj.env['res.partner'].create({'name': partner_name})\n"
+ "workflow"),
})
- run_res = self.ir_actions_server.run(cr, uid, [self.act_id], context=self.context)
+ run_res = self.action.with_context(self.context).run()
self.assertFalse(run_res, 'ir_actions_server: code server action correctly finished should return False')
- pids = self.res_partner.search(cr, uid, [('name', 'ilike', 'TestingPartner_code')])
- self.assertEqual(len(pids), 1, 'ir_actions_server: 1 new partner should have been created')
+ partners = self.test_partner.search([('name', 'ilike', 'TestingPartner_code')])
+ self.assertEqual(len(partners), 1, 'ir_actions_server: 1 new partner should have been created')
def test_20_trigger(self):
- cr, uid = self.cr, self.uid
+ Workflow = self.env['workflow']
+ WorkflowActivity = self.env['workflow.activity']
+ WorkflowTransition = self.env['workflow.transition']
# Data: code server action (at this point code-based actions should work)
- act_id2 = self.ir_actions_server.create(cr, uid, {
+ action2 = self.action.create({
'name': 'TestAction2',
'type': 'ir.actions.server',
'condition': 'True',
- 'model_id': self.res_partner_model_id,
+ 'model_id': self.res_partner_model.id,
'state': 'code',
'code': 'obj.write({"comment": "MyComment"})',
})
- act_id3 = self.ir_actions_server.create(cr, uid, {
+ action3 = self.action.create({
'name': 'TestAction3',
'type': 'ir.actions.server',
'condition': 'True',
- 'model_id': self.res_country_model_id,
+ 'model_id': self.res_country_model.id,
'state': 'code',
'code': 'obj.write({"code": "ZZ"})',
})
# Data: create workflows
- partner_wf_id = self.registry('workflow').create(cr, uid, {
+ partner_workflow = Workflow.create({
'name': 'TestWorkflow',
'osv': 'res.partner',
'on_create': True,
})
- partner_act1_id = self.registry('workflow.activity').create(cr, uid, {
+ partner_activity1 = WorkflowActivity.create({
'name': 'PartnerStart',
- 'wkf_id': partner_wf_id,
- 'flow_start': True
+ 'wkf_id': partner_workflow.id,
+ 'flow_start': True,
})
- partner_act2_id = self.registry('workflow.activity').create(cr, uid, {
+ partner_activity2 = WorkflowActivity.create({
'name': 'PartnerTwo',
- 'wkf_id': partner_wf_id,
+ 'wkf_id': partner_workflow.id,
'kind': 'function',
'action': 'True',
- 'action_id': act_id2,
+ 'action_id': action2.id,
})
- partner_trs1_id = self.registry('workflow.transition').create(cr, uid, {
+ partner_transition1 = WorkflowTransition.create({
'signal': 'partner_trans',
- 'act_from': partner_act1_id,
- 'act_to': partner_act2_id
+ 'act_from': partner_activity1.id,
+ 'act_to': partner_activity2.id,
})
- country_wf_id = self.registry('workflow').create(cr, uid, {
+ country_workflow = Workflow.create({
'name': 'TestWorkflow',
'osv': 'res.country',
'on_create': True,
})
- country_act1_id = self.registry('workflow.activity').create(cr, uid, {
+ country_activity1 = WorkflowActivity.create({
'name': 'CountryStart',
- 'wkf_id': country_wf_id,
- 'flow_start': True
+ 'wkf_id': country_workflow.id,
+ 'flow_start': True,
})
- country_act2_id = self.registry('workflow.activity').create(cr, uid, {
+ country_activity2 = WorkflowActivity.create({
'name': 'CountryTwo',
- 'wkf_id': country_wf_id,
+ 'wkf_id': country_workflow.id,
'kind': 'function',
'action': 'True',
- 'action_id': act_id3,
+ 'action_id': action3.id,
})
- country_trs1_id = self.registry('workflow.transition').create(cr, uid, {
+ country_transition1 = WorkflowTransition.create({
'signal': 'country_trans',
- 'act_from': country_act1_id,
- 'act_to': country_act2_id
+ 'act_from': country_activity1.id,
+ 'act_to': country_activity2.id,
})
# Data: re-create country and partner to benefit from the workflows
- self.test_country_id = self.res_country.create(cr, uid, {
+ country = self.test_country.create({
'name': 'TestingCountry2',
'code': 'T2',
})
- self.test_country = self.res_country.browse(cr, uid, self.test_country_id)
- self.test_partner_id = self.res_partner.create(cr, uid, {
+ partner = self.test_partner.create({
'name': 'TestingPartner2',
- 'country_id': self.test_country_id,
+ 'country_id': country.id,
})
- self.test_partner = self.res_partner.browse(cr, uid, self.test_partner_id)
- self.context = {
- 'active_id': self.test_partner_id,
- 'active_model': 'res.partner',
- }
+ context = dict(self.context, active_id=partner.id)
# Run the action on partner object itself ('base')
- self.ir_actions_server.write(cr, uid, [self.act_id], {
+ self.action.write({
'state': 'trigger',
'use_relational_model': 'base',
- 'wkf_model_id': self.res_partner_model_id,
- 'wkf_transition_id': partner_trs1_id,
+ 'wkf_model_id': self.res_partner_model.id,
+ 'wkf_transition_id': partner_transition1.id,
})
- self.ir_actions_server.run(cr, uid, [self.act_id], self.context)
- self.test_partner.refresh()
- self.assertEqual(self.test_partner.comment, 'MyComment', 'ir_actions_server: incorrect signal trigger')
+ self.action.with_context(context).run()
+ self.assertEqual(partner.comment, 'MyComment', 'ir_actions_server: incorrect signal trigger')
# Run the action on related country object ('relational')
- self.ir_actions_server.write(cr, uid, [self.act_id], {
+ self.action.write({
'use_relational_model': 'relational',
- 'wkf_model_id': self.res_country_model_id,
- 'wkf_field_id': self.res_partner_country_field_id,
- 'wkf_transition_id': country_trs1_id,
+ 'wkf_model_id': self.res_country_model.id,
+ 'wkf_field_id': self.res_partner_country_field.id,
+ 'wkf_transition_id': country_transition1.id,
})
- self.ir_actions_server.run(cr, uid, [self.act_id], self.context)
- self.test_country.refresh()
- self.assertEqual(self.test_country.code, 'ZZ', 'ir_actions_server: incorrect signal trigger')
+ self.action.with_context(context).run()
+ self.assertEqual(country.code, 'ZZ', 'ir_actions_server: incorrect signal trigger')
- # Clear workflow cache, otherwise openerp will try to create workflows even if it has been deleted
- from openerp.workflow import clear_cache
- clear_cache(cr, uid)
+ # Clear workflow cache, otherwise odoo will try to create workflows even if it has been deleted
+ odoo.workflow.clear_cache(self.cr, self.uid)
def test_30_client(self):
- cr, uid = self.cr, self.uid
- client_action_id = self.registry('ir.actions.client').create(cr, uid, {
+ client_action = self.env['ir.actions.client'].create({
'name': 'TestAction2',
'tag': 'Test',
})
- self.ir_actions_server.write(cr, uid, [self.act_id], {
+ self.action.write({
'state': 'client_action',
- 'action_id': client_action_id,
+ 'action_id': client_action.id,
})
- res = self.ir_actions_server.run(cr, uid, [self.act_id], context=self.context)
+ res = self.action.with_context(self.context).run()
self.assertEqual(res['name'], 'TestAction2', 'ir_actions_server: incorrect return result for a client action')
def test_40_crud_create(self):
- cr, uid = self.cr, self.uid
_city = 'TestCity'
_name = 'TestNew'
# Do: create a new record in the same model and link it
- self.ir_actions_server.write(cr, uid, [self.act_id], {
+ self.action.write({
'state': 'object_create',
'use_create': 'new',
'link_new_record': True,
- 'link_field_id': self.res_partner_parent_field_id,
- 'fields_lines': [(0, 0, {'col1': self.res_partner_name_field_id, 'value': _name}),
- (0, 0, {'col1': self.res_partner_city_field_id, 'value': _city})],
+ 'link_field_id': self.res_partner_parent_field.id,
+ 'fields_lines': [(0, 0, {'col1': self.res_partner_name_field.id, 'value': _name}),
+ (0, 0, {'col1': self.res_partner_city_field.id, 'value': _city})],
})
- run_res = self.ir_actions_server.run(cr, uid, [self.act_id], context=self.context)
+ run_res = self.action.with_context(self.context).run()
self.assertFalse(run_res, 'ir_actions_server: create record action correctly finished should return False')
# Test: new partner created
- pids = self.res_partner.search(cr, uid, [('name', 'ilike', _name)])
- self.assertEqual(len(pids), 1, 'ir_actions_server: TODO')
- partner = self.res_partner.browse(cr, uid, pids[0])
+ partner = self.test_partner.search([('name', 'ilike', _name)])
+ self.assertEqual(len(partner), 1, 'ir_actions_server: TODO')
self.assertEqual(partner.city, _city, 'ir_actions_server: TODO')
# Test: new partner linked
- self.test_partner.refresh()
- self.assertEqual(self.test_partner.parent_id.id, pids[0], 'ir_actions_server: TODO')
+ self.assertEqual(self.test_partner.parent_id, partner, 'ir_actions_server: TODO')
# Do: copy current record
- self.ir_actions_server.write(cr, uid, [self.act_id], {'fields_lines': [[5]]})
- self.ir_actions_server.write(cr, uid, [self.act_id], {
+ self.action.write({
'state': 'object_create',
'use_create': 'copy_current',
'link_new_record': False,
- 'fields_lines': [(0, 0, {'col1': self.res_partner_name_field_id, 'value': 'TestCopyCurrent'}),
- (0, 0, {'col1': self.res_partner_city_field_id, 'value': 'TestCity'})],
+ 'fields_lines': [(5,),
+ (0, 0, {'col1': self.res_partner_name_field.id, 'value': 'TestCopyCurrent'}),
+ (0, 0, {'col1': self.res_partner_city_field.id, 'value': 'TestCity'})],
})
- run_res = self.ir_actions_server.run(cr, uid, [self.act_id], context=self.context)
+ run_res = self.action.with_context(self.context).run()
self.assertFalse(run_res, 'ir_actions_server: create record action correctly finished should return False')
# Test: new partner created
- pids = self.res_partner.search(cr, uid, [('name', 'ilike', 'TestingPartner (copy)')]) # currently res_partner overrides default['name'] whatever its value
- self.assertEqual(len(pids), 1, 'ir_actions_server: TODO')
- partner = self.res_partner.browse(cr, uid, pids[0])
+ partner = self.test_partner.search([('name', 'ilike', 'TestingPartner (copy)')]) # currently res_partner overrides default['name'] whatever its value
+ self.assertEqual(len(partner), 1, 'ir_actions_server: TODO')
self.assertEqual(partner.city, 'TestCity', 'ir_actions_server: TODO')
- self.assertEqual(partner.country_id.id, self.test_partner.country_id.id, 'ir_actions_server: TODO')
+ self.assertEqual(partner.country_id, self.test_partner.country_id, 'ir_actions_server: TODO')
# Do: create a new record in another model
- self.ir_actions_server.write(cr, uid, [self.act_id], {'fields_lines': [[5]]})
- self.ir_actions_server.write(cr, uid, [self.act_id], {
+ self.action.write({
'state': 'object_create',
'use_create': 'new_other',
- 'crud_model_id': self.res_country_model_id,
+ 'crud_model_id': self.res_country_model.id,
'link_new_record': False,
- 'fields_lines': [(0, 0, {'col1': self.res_country_name_field_id, 'value': 'obj.name', 'type': 'equation'}),
- (0, 0, {'col1': self.res_country_code_field_id, 'value': 'obj.name[0:2]', 'type': 'equation'})],
+ 'fields_lines': [(5,),
+ (0, 0, {'col1': self.res_country_name_field.id, 'value': 'obj.name', 'type': 'equation'}),
+ (0, 0, {'col1': self.res_country_code_field.id, 'value': 'obj.name[0:2]', 'type': 'equation'})],
})
- run_res = self.ir_actions_server.run(cr, uid, [self.act_id], context=self.context)
+ run_res = self.action.with_context(self.context).run()
self.assertFalse(run_res, 'ir_actions_server: create record action correctly finished should return False')
# Test: new country created
- cids = self.res_country.search(cr, uid, [('name', 'ilike', 'TestingPartner')])
- self.assertEqual(len(cids), 1, 'ir_actions_server: TODO')
- country = self.res_country.browse(cr, uid, cids[0])
+ country = self.test_country.search([('name', 'ilike', 'TestingPartner')])
+ self.assertEqual(len(country), 1, 'ir_actions_server: TODO')
self.assertEqual(country.code, 'TE', 'ir_actions_server: TODO')
# Do: copy a record in another model
- self.ir_actions_server.write(cr, uid, [self.act_id], {'fields_lines': [[5]]})
- self.ir_actions_server.write(cr, uid, [self.act_id], {
+ self.action.write({
'state': 'object_create',
'use_create': 'copy_other',
- 'crud_model_id': self.res_country_model_id,
+ 'crud_model_id': self.res_country_model.id,
'link_new_record': False,
- 'ref_object': 'res.country,%s' % self.test_country_id,
- 'fields_lines': [(0, 0, {'col1': self.res_country_name_field_id, 'value': 'NewCountry', 'type': 'value'}),
- (0, 0, {'col1': self.res_country_code_field_id, 'value': 'NY', 'type': 'value'})],
+ 'ref_object': 'res.country,%s' % self.test_country.id,
+ 'fields_lines': [(5,),
+ (0, 0, {'col1': self.res_country_name_field.id, 'value': 'NewCountry', 'type': 'value'}),
+ (0, 0, {'col1': self.res_country_code_field.id, 'value': 'NY', 'type': 'value'})],
})
- run_res = self.ir_actions_server.run(cr, uid, [self.act_id], context=self.context)
+ run_res = self.action.with_context(self.context).run()
self.assertFalse(run_res, 'ir_actions_server: create record action correctly finished should return False')
# Test: new country created
- cids = self.res_country.search(cr, uid, [('name', 'ilike', 'NewCountry')])
- self.assertEqual(len(cids), 1, 'ir_actions_server: TODO')
- country = self.res_country.browse(cr, uid, cids[0])
+ country = self.test_country.search([('name', 'ilike', 'NewCountry')])
+ self.assertEqual(len(country), 1, 'ir_actions_server: TODO')
self.assertEqual(country.code, 'NY', 'ir_actions_server: TODO')
self.assertEqual(country.address_format, 'SuperFormat', 'ir_actions_server: TODO')
def test_50_crud_write(self):
- cr, uid = self.cr, self.uid
_name = 'TestNew'
# Do: create a new record in the same model and link it
- self.ir_actions_server.write(cr, uid, [self.act_id], {
+ self.action.write({
'state': 'object_write',
'use_write': 'current',
- 'fields_lines': [(0, 0, {'col1': self.res_partner_name_field_id, 'value': _name})],
+ 'fields_lines': [(0, 0, {'col1': self.res_partner_name_field.id, 'value': _name})],
})
- run_res = self.ir_actions_server.run(cr, uid, [self.act_id], context=self.context)
+ run_res = self.action.with_context(self.context).run()
self.assertFalse(run_res, 'ir_actions_server: create record action correctly finished should return False')
# Test: new partner created
- pids = self.res_partner.search(cr, uid, [('name', 'ilike', _name)])
- self.assertEqual(len(pids), 1, 'ir_actions_server: TODO')
- partner = self.res_partner.browse(cr, uid, pids[0])
+ partner = self.test_partner.search([('name', 'ilike', _name)])
+ self.assertEqual(len(partner), 1, 'ir_actions_server: TODO')
self.assertEqual(partner.city, 'OrigCity', 'ir_actions_server: TODO')
# Do: copy current record
- self.ir_actions_server.write(cr, uid, [self.act_id], {'fields_lines': [[5]]})
- self.ir_actions_server.write(cr, uid, [self.act_id], {
+ self.action.write({
'use_write': 'other',
- 'crud_model_id': self.res_country_model_id,
- 'ref_object': 'res.country,%s' % self.test_country_id,
- 'fields_lines': [(0, 0, {'col1': self.res_country_name_field_id, 'value': 'obj.name', 'type': 'equation'})],
+ 'crud_model_id': self.res_country_model.id,
+ 'ref_object': 'res.country,%s' % self.test_country.id,
+ 'fields_lines': [(5,), (0, 0, {'col1': self.res_country_name_field.id, 'value': 'obj.name', 'type': 'equation'})],
})
- run_res = self.ir_actions_server.run(cr, uid, [self.act_id], context=self.context)
+ run_res = self.action.with_context(self.context).run()
self.assertFalse(run_res, 'ir_actions_server: create record action correctly finished should return False')
# Test: new country created
- cids = self.res_country.search(cr, uid, [('name', 'ilike', 'TestNew')])
- self.assertEqual(len(cids), 1, 'ir_actions_server: TODO')
+ country = self.test_country.search([('name', 'ilike', 'TestNew')])
+ self.assertEqual(len(country), 1, 'ir_actions_server: TODO')
# Do: copy a record in another model
- self.ir_actions_server.write(cr, uid, [self.act_id], {'fields_lines': [[5]]})
- self.ir_actions_server.write(cr, uid, [self.act_id], {
+ self.action.write({
'use_write': 'expression',
- 'crud_model_id': self.res_country_model_id,
+ 'crud_model_id': self.res_country_model.id,
'write_expression': 'object.country_id',
- 'fields_lines': [(0, 0, {'col1': self.res_country_name_field_id, 'value': 'NewCountry', 'type': 'value'})],
+ 'fields_lines': [(5,), (0, 0, {'col1': self.res_country_name_field.id, 'value': 'NewCountry', 'type': 'value'})],
})
- run_res = self.ir_actions_server.run(cr, uid, [self.act_id], context=self.context)
+ run_res = self.action.with_context(self.context).run()
self.assertFalse(run_res, 'ir_actions_server: create record action correctly finished should return False')
# Test: new country created
- cids = self.res_country.search(cr, uid, [('name', 'ilike', 'NewCountry')])
- self.assertEqual(len(cids), 1, 'ir_actions_server: TODO')
+ country = self.test_country.search([('name', 'ilike', 'NewCountry')])
+ self.assertEqual(len(country), 1, 'ir_actions_server: TODO')
@mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
def test_60_multi(self):
- cr, uid = self.cr, self.uid
-
# Data: 2 server actions that will be nested
- act1_id = self.ir_actions_server.create(cr, uid, {
+ action1 = self.action.create({
'name': 'Subaction1',
'sequence': 1,
- 'model_id': self.res_partner_model_id,
+ 'model_id': self.res_partner_model.id,
'state': 'code',
'code': 'action = {"type": "ir.actions.act_window"}',
})
- act2_id = self.ir_actions_server.create(cr, uid, {
+ action2 = self.action.create({
'name': 'Subaction2',
'sequence': 2,
- 'model_id': self.res_partner_model_id,
+ 'model_id': self.res_partner_model.id,
'state': 'object_create',
'use_create': 'copy_current',
})
- act3_id = self.ir_actions_server.create(cr, uid, {
+ action3 = self.action.create({
'name': 'Subaction3',
'sequence': 3,
- 'model_id': self.res_partner_model_id,
+ 'model_id': self.res_partner_model.id,
'state': 'code',
'code': 'action = {"type": "ir.actions.act_url"}',
})
- self.ir_actions_server.write(cr, uid, [self.act_id], {
+ self.action.write({
'state': 'multi',
- 'child_ids': [(6, 0, [act1_id, act2_id, act3_id])],
+ 'child_ids': [(6, 0, [action1.id, action2.id, action3.id])],
})
# Do: run the action
- res = self.ir_actions_server.run(cr, uid, [self.act_id], context=self.context)
+ res = self.action.with_context(self.context).run()
# Test: new partner created
- pids = self.res_partner.search(cr, uid, [('name', 'ilike', 'TestingPartner (copy)')]) # currently res_partner overrides default['name'] whatever its value
- self.assertEqual(len(pids), 1, 'ir_actions_server: TODO')
+ # currently res_partner overrides default['name'] whatever its value
+ partner = self.test_partner.search([('name', 'ilike', 'TestingPartner (copy)')])
+ self.assertEqual(len(partner), 1, 'ir_actions_server: TODO')
# Test: action returned
self.assertEqual(res.get('type'), 'ir.actions.act_url')
# Test loops
with self.assertRaises(ValidationError):
- self.ir_actions_server.write(cr, uid, [self.act_id], {
- 'child_ids': [(6, 0, [self.act_id])]
+ self.action.write({
+ 'child_ids': [(6, 0, [self.action.id])]
})
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/openerp/addons/base/tests/test_ir_attachment.py b/openerp/addons/base/tests/test_ir_attachment.py
index 891b38b7dc3..d515cfc354d 100644
--- a/openerp/addons/base/tests/test_ir_attachment.py
+++ b/openerp/addons/base/tests/test_ir_attachment.py
@@ -1,17 +1,20 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
import hashlib
import os
-import openerp
-import openerp.tests.common
+from odoo.tests.common import TransactionCase
HASH_SPLIT = 2 # FIXME: testing implementations detail is not a good idea
-class test_ir_attachment(openerp.tests.common.TransactionCase):
+
+class TestIrAttachment(TransactionCase):
def setUp(self):
- super(test_ir_attachment, self).setUp()
- registry, cr, uid = self.registry, self.cr, self.uid
- self.ira = registry('ir.attachment')
- self.filestore = self.ira._filestore(cr, uid)
+ super(TestIrAttachment, self).setUp()
+ self.Attachment = self.env['ir.attachment']
+ self.ira = self.Attachment._model
+ self.filestore = self.Attachment._filestore()
# Blob1
self.blob1 = 'blob1'
@@ -20,73 +23,55 @@ class test_ir_attachment(openerp.tests.common.TransactionCase):
self.blob1_fname = blob1_hash[:HASH_SPLIT] + '/' + blob1_hash
# Blob2
- blob2 = 'blob2'
- self.blob2_b64 = blob2.encode('base64')
+ self.blob2 = 'blob2'
+ self.blob2_b64 = self.blob2.encode('base64')
def test_01_store_in_db(self):
- registry, cr, uid = self.registry, self.cr, self.uid
-
# force storing in database
- registry('ir.config_parameter').set_param(cr, uid, 'ir_attachment.location', 'db')
+ self.env['ir.config_parameter'].set_param('ir_attachment.location', 'db')
# 'ir_attachment.location' is undefined test database storage
- a1 = self.ira.create(cr, uid, {'name': 'a1', 'datas': self.blob1_b64})
- a1_read = self.ira.read(cr, uid, [a1], ['datas'])
- self.assertEqual(a1_read[0]['datas'], self.blob1_b64)
+ a1 = self.Attachment.create({'name': 'a1', 'datas': self.blob1_b64})
+ self.assertEqual(a1.datas, self.blob1_b64)
- a1_db_datas = self.ira.browse(cr, uid, a1).db_datas
+ a1_db_datas = a1.db_datas
self.assertEqual(a1_db_datas, self.blob1_b64)
def test_02_store_on_disk(self):
- registry, cr, uid = self.registry, self.cr, self.uid
-
- a2 = self.ira.create(cr, uid, {'name': 'a2', 'datas': self.blob1_b64})
- a2_store_fname = self.ira.browse(cr, uid, a2).store_fname
-
- self.assertEqual(a2_store_fname, self.blob1_fname)
- self.assertTrue(os.path.isfile(os.path.join(self.filestore, a2_store_fname)))
+ a2 = self.Attachment.create({'name': 'a2', 'datas': self.blob1_b64})
+ self.assertEqual(a2.store_fname, self.blob1_fname)
+ self.assertTrue(os.path.isfile(os.path.join(self.filestore, a2.store_fname)))
def test_03_no_duplication(self):
- registry, cr, uid = self.registry, self.cr, self.uid
-
- a2 = self.ira.create(cr, uid, {'name': 'a2', 'datas': self.blob1_b64})
- a2_store_fname = self.ira.browse(cr, uid, a2).store_fname
-
- a3 = self.ira.create(cr, uid, {'name': 'a3', 'datas': self.blob1_b64})
- a3_store_fname = self.ira.browse(cr, uid, a3).store_fname
-
- self.assertEqual(a3_store_fname, a2_store_fname)
+ a2 = self.Attachment.create({'name': 'a2', 'datas': self.blob1_b64})
+ a3 = self.Attachment.create({'name': 'a3', 'datas': self.blob1_b64})
+ self.assertEqual(a3.store_fname, a2.store_fname)
def test_04_keep_file(self):
- registry, cr, uid = self.registry, self.cr, self.uid
+ a2 = self.Attachment.create({'name': 'a2', 'datas': self.blob1_b64})
+ a3 = self.Attachment.create({'name': 'a3', 'datas': self.blob1_b64})
- a2 = self.ira.create(cr, uid, {'name': 'a2', 'datas': self.blob1_b64})
- a3 = self.ira.create(cr, uid, {'name': 'a3', 'datas': self.blob1_b64})
+ a2_fn = os.path.join(self.filestore, a2.store_fname)
- a2_store_fname = self.ira.browse(cr, uid, a2).store_fname
- a2_fn = os.path.join(self.filestore, a2_store_fname)
-
- self.ira.unlink(cr, uid, [a3])
+ a3.unlink()
self.assertTrue(os.path.isfile(a2_fn))
# delete a2 it is unlinked
- self.ira.unlink(cr, uid, [a2])
+ a2.unlink()
self.assertFalse(os.path.isfile(a2_fn))
def test_05_change_data_change_file(self):
- registry, cr, uid = self.registry, self.cr, self.uid
-
- a2 = self.ira.create(cr, uid, {'name': 'a2', 'datas': self.blob1_b64})
- a2_store_fname = self.ira.browse(cr, uid, a2).store_fname
- a2_fn = os.path.join(self.filestore, a2_store_fname)
+ a2 = self.Attachment.create({'name': 'a2', 'datas': self.blob1_b64})
+ a2_store_fname1 = a2.store_fname
+ a2_fn = os.path.join(self.filestore, a2_store_fname1)
self.assertTrue(os.path.isfile(a2_fn))
- self.ira.write(cr, uid, [a2], {'datas': self.blob2_b64})
+ a2.write({'datas': self.blob2_b64})
self.assertFalse(os.path.isfile(a2_fn))
- new_a2_store_fname = self.ira.browse(cr, uid, a2).store_fname
- self.assertNotEqual(a2_store_fname, new_a2_store_fname)
+ a2_store_fname2 = a2.store_fname
+ self.assertNotEqual(a2_store_fname1, a2_store_fname2)
- new_a2_fn = os.path.join(self.filestore, new_a2_store_fname)
- self.assertTrue(os.path.isfile(new_a2_fn))
+ a2_fn = os.path.join(self.filestore, a2_store_fname2)
+ self.assertTrue(os.path.isfile(a2_fn))
diff --git a/openerp/addons/base/tests/test_ir_filters.py b/openerp/addons/base/tests/test_ir_filters.py
index 2132fdb946b..d932f16be11 100644
--- a/openerp/addons/base/tests/test_ir_filters.py
+++ b/openerp/addons/base/tests/test_ir_filters.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
-import functools
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp import exceptions
-from openerp.tests import common
+from odoo import exceptions
+from odoo.tests.common import TransactionCase, ADMIN_USER_ID
def noid(d):
""" Removes values that are not relevant for the test comparisons """
@@ -10,17 +10,19 @@ def noid(d):
d.pop('action_id', None)
return d
-class FiltersCase(common.TransactionCase):
+
+class FiltersCase(TransactionCase):
def build(self, model, *args):
- Model = self.registry(model)
- for vars in args:
- Model.create(self.cr, common.ADMIN_USER_ID, vars, {})
+ Model = self.env[model].sudo(ADMIN_USER_ID)
+ for vals in args:
+ Model.create(vals)
+
class TestGetFilters(FiltersCase):
def setUp(self):
super(TestGetFilters, self).setUp()
- self.USER = self.registry('res.users').name_search(self.cr, self.uid, 'demo')[0]
- self.USER_ID = self.USER[0]
+ self.USER_NG = self.env['res.users'].name_search('demo')[0]
+ self.USER_ID = self.USER_NG[0]
def test_own_filters(self):
self.build(
@@ -30,14 +32,13 @@ class TestGetFilters(FiltersCase):
dict(name='c', user_id=self.USER_ID, model_id='ir.filters'),
dict(name='d', user_id=self.USER_ID, model_id='ir.filters'))
- filters = self.registry('ir.filters').get_filters(
- self.cr, self.USER_ID, 'ir.filters')
+ filters = self.env['ir.filters'].sudo(self.USER_ID).get_filters('ir.filters')
self.assertItemsEqual(map(noid, filters), [
- dict(name='a', is_default=False, user_id=self.USER, domain='[]', context='{}', sort='[]'),
- dict(name='b', is_default=False, user_id=self.USER, domain='[]', context='{}', sort='[]'),
- dict(name='c', is_default=False, user_id=self.USER, domain='[]', context='{}', sort='[]'),
- dict(name='d', is_default=False, user_id=self.USER, domain='[]', context='{}', sort='[]'),
+ dict(name='a', is_default=False, user_id=self.USER_NG, domain='[]', context='{}', sort='[]'),
+ dict(name='b', is_default=False, user_id=self.USER_NG, domain='[]', context='{}', sort='[]'),
+ dict(name='c', is_default=False, user_id=self.USER_NG, domain='[]', context='{}', sort='[]'),
+ dict(name='d', is_default=False, user_id=self.USER_NG, domain='[]', context='{}', sort='[]'),
])
def test_global_filters(self):
@@ -49,8 +50,7 @@ class TestGetFilters(FiltersCase):
dict(name='d', user_id=False, model_id='ir.filters'),
)
- filters = self.registry('ir.filters').get_filters(
- self.cr, self.USER_ID, 'ir.filters')
+ filters = self.env['ir.filters'].sudo(self.USER_ID).get_filters('ir.filters')
self.assertItemsEqual(map(noid, filters), [
dict(name='a', is_default=False, user_id=False, domain='[]', context='{}', sort='[]'),
@@ -63,40 +63,40 @@ class TestGetFilters(FiltersCase):
self.build(
'ir.filters',
dict(name='a', user_id=False, model_id='ir.filters'),
- dict(name='b', user_id=common.ADMIN_USER_ID, model_id='ir.filters'),
+ dict(name='b', user_id=ADMIN_USER_ID, model_id='ir.filters'),
dict(name='c', user_id=self.USER_ID, model_id='ir.filters'),
- dict(name='d', user_id=common.ADMIN_USER_ID, model_id='ir.filters') )
+ dict(name='d', user_id=ADMIN_USER_ID, model_id='ir.filters') )
- filters = self.registry('ir.filters').get_filters(
- self.cr, self.USER_ID, 'ir.filters')
+ filters = self.env['ir.filters'].sudo(self.USER_ID).get_filters('ir.filters')
self.assertItemsEqual(map(noid, filters), [
dict(name='a', is_default=False, user_id=False, domain='[]', context='{}', sort='[]'),
- dict(name='c', is_default=False, user_id=self.USER, domain='[]', context='{}', sort='[]'),
+ dict(name='c', is_default=False, user_id=self.USER_NG, domain='[]', context='{}', sort='[]'),
])
+
class TestOwnDefaults(FiltersCase):
def setUp(self):
super(TestOwnDefaults, self).setUp()
- self.USER = self.registry('res.users').name_search(self.cr, self.uid, 'demo')[0]
- self.USER_ID = self.USER[0]
+ self.USER_NG = self.env['res.users'].name_search('demo')[0]
+ self.USER_ID = self.USER_NG[0]
def test_new_no_filter(self):
"""
When creating a @is_default filter with no existing filter, that new
filter gets the default flag
"""
- Filters = self.registry('ir.filters')
- Filters.create_or_replace(self.cr, self.USER_ID, {
+ Filters = self.env['ir.filters'].sudo(self.USER_ID)
+ Filters.create_or_replace({
'name': 'a',
'model_id': 'ir.filters',
'user_id': self.USER_ID,
'is_default': True,
})
- filters = Filters.get_filters(self.cr, self.USER_ID, 'ir.filters')
+ filters = Filters.get_filters('ir.filters')
self.assertItemsEqual(map(noid, filters), [
- dict(name='a', user_id=self.USER, is_default=True,
+ dict(name='a', user_id=self.USER_NG, is_default=True,
domain='[]', context='{}', sort='[]')
])
@@ -111,19 +111,19 @@ class TestOwnDefaults(FiltersCase):
dict(name='b', user_id=self.USER_ID, model_id='ir.filters'),
)
- Filters = self.registry('ir.filters')
- Filters.create_or_replace(self.cr, self.USER_ID, {
+ Filters = self.env['ir.filters'].sudo(self.USER_ID)
+ Filters.create_or_replace({
'name': 'c',
'model_id': 'ir.filters',
'user_id': self.USER_ID,
'is_default': True,
})
- filters = Filters.get_filters(self.cr, self.USER_ID, 'ir.filters')
+ filters = Filters.get_filters('ir.filters')
self.assertItemsEqual(map(noid, filters), [
- dict(name='a', user_id=self.USER, is_default=False, domain='[]', context='{}', sort='[]'),
- dict(name='b', user_id=self.USER, is_default=False, domain='[]', context='{}', sort='[]'),
- dict(name='c', user_id=self.USER, is_default=True, domain='[]', context='{}', sort='[]'),
+ dict(name='a', user_id=self.USER_NG, is_default=False, domain='[]', context='{}', sort='[]'),
+ dict(name='b', user_id=self.USER_NG, is_default=False, domain='[]', context='{}', sort='[]'),
+ dict(name='c', user_id=self.USER_NG, is_default=True, domain='[]', context='{}', sort='[]'),
])
def test_new_filter_existing_default(self):
@@ -137,19 +137,19 @@ class TestOwnDefaults(FiltersCase):
dict(name='b', is_default=True, user_id=self.USER_ID, model_id='ir.filters'),
)
- Filters = self.registry('ir.filters')
- Filters.create_or_replace(self.cr, self.USER_ID, {
+ Filters = self.env['ir.filters'].sudo(self.USER_ID)
+ Filters.create_or_replace({
'name': 'c',
'model_id': 'ir.filters',
'user_id': self.USER_ID,
'is_default': True,
})
- filters = Filters.get_filters(self.cr, self.USER_ID, 'ir.filters')
+ filters = Filters.get_filters('ir.filters')
self.assertItemsEqual(map(noid, filters), [
- dict(name='a', user_id=self.USER, is_default=False, domain='[]', context='{}', sort='[]'),
- dict(name='b', user_id=self.USER, is_default=False, domain='[]', context='{}', sort='[]'),
- dict(name='c', user_id=self.USER, is_default=True, domain='[]', context='{}', sort='[]'),
+ dict(name='a', user_id=self.USER_NG, is_default=False, domain='[]', context='{}', sort='[]'),
+ dict(name='b', user_id=self.USER_NG, is_default=False, domain='[]', context='{}', sort='[]'),
+ dict(name='c', user_id=self.USER_NG, is_default=True, domain='[]', context='{}', sort='[]'),
])
def test_update_filter_set_default(self):
@@ -163,25 +163,26 @@ class TestOwnDefaults(FiltersCase):
dict(name='b', is_default=True, user_id=self.USER_ID, model_id='ir.filters'),
)
- Filters = self.registry('ir.filters')
- Filters.create_or_replace(self.cr, self.USER_ID, {
+ Filters = self.env['ir.filters'].sudo(self.USER_ID)
+ Filters.create_or_replace({
'name': 'a',
'model_id': 'ir.filters',
'user_id': self.USER_ID,
'is_default': True,
})
- filters = Filters.get_filters(self.cr, self.USER_ID, 'ir.filters')
+ filters = Filters.get_filters('ir.filters')
self.assertItemsEqual(map(noid, filters), [
- dict(name='a', user_id=self.USER, is_default=True, domain='[]', context='{}', sort='[]'),
- dict(name='b', user_id=self.USER, is_default=False, domain='[]', context='{}', sort='[]'),
+ dict(name='a', user_id=self.USER_NG, is_default=True, domain='[]', context='{}', sort='[]'),
+ dict(name='b', user_id=self.USER_NG, is_default=False, domain='[]', context='{}', sort='[]'),
])
+
class TestGlobalDefaults(FiltersCase):
def setUp(self):
super(TestGlobalDefaults, self).setUp()
- self.USER = self.registry('res.users').name_search(self.cr, self.uid, 'demo')[0]
- self.USER_ID = self.USER[0]
+ self.USER_NG = self.env['res.users'].name_search('demo')[0]
+ self.USER_ID = self.USER_NG[0]
def test_new_filter_not_default(self):
"""
@@ -194,14 +195,14 @@ class TestGlobalDefaults(FiltersCase):
dict(name='b', user_id=False, model_id='ir.filters'),
)
- Filters = self.registry('ir.filters')
- Filters.create_or_replace(self.cr, self.USER_ID, {
+ Filters = self.env['ir.filters'].sudo(self.USER_ID)
+ Filters.create_or_replace({
'name': 'c',
'model_id': 'ir.filters',
'user_id': False,
'is_default': True,
})
- filters = Filters.get_filters(self.cr, self.USER_ID, 'ir.filters')
+ filters = Filters.get_filters('ir.filters')
self.assertItemsEqual(map(noid, filters), [
dict(name='a', user_id=False, is_default=False, domain='[]', context='{}', sort='[]'),
@@ -220,9 +221,9 @@ class TestGlobalDefaults(FiltersCase):
dict(name='b', is_default=True, user_id=False, model_id='ir.filters'),
)
- Filters = self.registry('ir.filters')
+ Filters = self.env['ir.filters'].sudo(self.USER_ID)
with self.assertRaises(exceptions.Warning):
- Filters.create_or_replace(self.cr, self.USER_ID, {
+ Filters.create_or_replace({
'name': 'c',
'model_id': 'ir.filters',
'user_id': False,
@@ -240,10 +241,9 @@ class TestGlobalDefaults(FiltersCase):
dict(name='b', is_default=True, user_id=False, model_id='ir.filters'),
)
- Filters = self.registry('ir.filters')
-
+ Filters = self.env['ir.filters'].sudo(self.USER_ID)
with self.assertRaises(exceptions.Warning):
- Filters.create_or_replace(self.cr, self.USER_ID, {
+ Filters.create_or_replace({
'name': 'a',
'model_id': 'ir.filters',
'user_id': False,
@@ -260,42 +260,37 @@ class TestGlobalDefaults(FiltersCase):
dict(name='b', is_default=True, user_id=False, model_id='ir.filters'),
)
- Filters = self.registry('ir.filters')
+ Filters = self.env['ir.filters'].sudo(self.USER_ID)
context_value = "{'some_key': True}"
- Filters.create_or_replace(self.cr, self.USER_ID, {
+ Filters.create_or_replace({
'name': 'b',
'model_id': 'ir.filters',
'user_id': False,
'context': context_value,
'is_default': True,
})
- filters = Filters.get_filters(self.cr, self.USER_ID, 'ir.filters')
+ filters = Filters.get_filters('ir.filters')
self.assertItemsEqual(map(noid, filters), [
dict(name='a', user_id=False, is_default=False, domain='[]', context='{}', sort='[]'),
dict(name='b', user_id=False, is_default=True, domain='[]', context=context_value, sort='[]'),
])
-from openerp.tests.common import TransactionCase
class TestReadGroup(TransactionCase):
"""Test function read_group with groupby on a many2one field to a model
(in test, "user_id" to "res.users") which is ordered by an inherited not stored field (in
test, "name" inherited from "res.partners").
"""
-
- def setUp(self):
- super(TestReadGroup, self).setUp()
- self.ir_filters_model = self.env['ir.filters']
- self.res_partner_model = self.env['res.partner']
- self.res_users_model = self.env['res.users']
-
def test_read_group_1(self):
- self.assertEqual(self.res_users_model._order, "name, login", "Model res.users must be ordered by name, login")
- self.assertFalse(self.res_users_model._fields['name'].store, "Field name is not stored in res.users")
+ Users = self.env['res.users']
+ self.assertEqual(Users._order, "name, login", "Model res.users must be ordered by name, login")
+ self.assertFalse(Users._fields['name'].store, "Field name is not stored in res.users")
- filter_a = self.ir_filters_model.create(dict(name="Filter_A", model_id="ir.filters"))
- filter_b = self.ir_filters_model.create(dict(name="Filter_B", model_id="ir.filters"))
+ Filters = self.env['ir.filters']
+ filter_a = Filters.create(dict(name="Filter_A", model_id="ir.filters"))
+ filter_b = Filters.create(dict(name="Filter_B", model_id="ir.filters"))
filter_b.write(dict(user_id=False))
- res = self.ir_filters_model.read_group([], ['name', 'user_id'], ['user_id'])
+
+ res = Filters.read_group([], ['name', 'user_id'], ['user_id'])
self.assertTrue(any(val['user_id'] == False for val in res), "At least one group must contain val['user_id'] == False.")
diff --git a/openerp/addons/base/tests/test_ir_rule.yml b/openerp/addons/base/tests/test_ir_rule.yml
deleted file mode 100644
index 02fc2e3d3b4..00000000000
--- a/openerp/addons/base/tests/test_ir_rule.yml
+++ /dev/null
@@ -1,189 +0,0 @@
--
- Exercise ir_rule.py code (and indirectly expression.py).
--
- Create an ir_rule for the Employee group (called base.group_user)
- with an blank domain.
--
- !record {model: ir.rule, id: test_rule}:
- model_id: base.model_res_partner
- domain_force: False
- name: test_rule
- groups:
- - base.group_user
- perm_unlink: 1
- perm_write: 1
- perm_read: 1
- perm_create: 1
--
- Read as demo user the partners (one blank domain).
--
- !python {model: res.partner }: |
- ids = self.search(cr, ref('base.user_demo'), [])
- assert ids, "Demo user should see some partner."
--
- Domain is not empty.
--
- !record {model: ir.rule, id: test_rule}:
- model_id: base.model_res_partner
- domain_force: "[(1,'=',1)]"
--
- Read as demo user the partners (one 1=1 domain).
--
- !python {model: res.partner }: |
- ids = self.search(cr, ref('base.user_demo'), [])
- assert ids, "Demo user should see some partner."
--
- Domain is an empty list.
--
- !record {model: ir.rule, id: test_rule}:
- model_id: base.model_res_partner
- domain_force: "[]"
--
- Read as demo user the partners (one [] domain).
--
- !python {model: res.partner }: |
- ids = self.search(cr, ref('base.user_demo'), [])
- assert ids, "Demo user should see some partner."
--
- Create another ir_rule for the Employee group (to test rules from
- multiple groups).
--
- !record {model: ir.rule, id: test_rule2}:
- model_id: base.model_res_partner
- domain_force: False
- name: test_rule2
- groups:
- - base.group_user
- perm_unlink: 1
- perm_write: 1
- perm_read: 1
- perm_create: 1
--
- Read as demo user the partners (blank and [] domains).
--
- !python {model: res.partner }: |
- ids = self.search(cr, ref('base.user_demo'), [])
- assert ids, "Demo user should see some partner."
--
- Domain is not empty.
--
- !record {model: ir.rule, id: test_rule}:
- model_id: base.model_res_partner
- domain_force: "[(1,'=',1)]"
--
- Read as demo user the partners (1=1 and blank domain).
--
- !python {model: res.partner }: |
- ids = self.search(cr, ref('base.user_demo'), [])
- assert ids, "Demo user should see some partner."
--
- Domain is not empty.
--
- !record {model: ir.rule, id: test_rule2}:
- model_id: base.model_res_partner
- domain_force: "[(1,'=',1)]"
--
- Read as demo user the partners (two 1=1 domains).
--
- !python {model: res.partner }: |
- ids = self.search(cr, ref('base.user_demo'), [])
- assert ids, "Demo user should see some partner."
--
- Create another ir_rule for the Employee group (to test rules from
- multiple groups).
--
- !record {model: ir.rule, id: test_rule3}:
- model_id: base.model_res_partner
- domain_force: False
- name: test_rule3
- groups:
- - base.group_user
- perm_unlink: 1
- perm_write: 1
- perm_read: 1
- perm_create: 1
--
- Read as demo user the partners.
--
- !python {model: res.partner }: |
- ids = self.search(cr, ref('base.user_demo'), [])
- assert ids, "Demo user should see some partner."
--
- Domain is not empty.
--
- !record {model: ir.rule, id: test_rule3}:
- model_id: base.model_res_partner
- domain_force: "[(1,'=',1)]"
--
- Read as demo user the partners (three 1=1 domains).
--
- !python {model: res.partner }: |
- ids = self.search(cr, ref('base.user_demo'), [])
- assert ids, "Demo user should see some partner."
--
- Modify the global rule on res_company which triggers a recursive check
- of the rules on company.
--
- !record {model: ir.rule, id: res_company_rule_employee}:
- domain_force: "[('id','child_of',[user.company_id.id])]"
--
- Read as demo user the partners (exercising the global company rule).
--
- !python {model: res.partner }: |
- ids = self.search(cr, ref('base.user_demo'), [])
- assert ids, "Demo user should see some partner."
--
- Modify the ir_rule for employee to have a rule that fordids
- seeing any record.
- We use a domain with implicit AND operator for later tests
- on normalization.
--
- !record {model: ir.rule, id: test_rule2}:
- domain_force: "[('id','=',False),('name','=',False)]"
--
- Check that demo user still sees partners, because group-rules are OR'ed.
--
- !python {model: res.partner }: |
- ids = self.search(cr, ref('base.user_demo'), [])
- assert ids, "Demo user should see some partner."
--
- Create a new group with demo user in it, and a complex rule.
- Demo should still see partners.
--
- !record {model: res.groups, id: test_group}:
- name: Test Group
- users:
- - base.user_demo
--
- Add the rule to the new group, with a domain containing an implicit AND operator,
- which is more tricky because it will have to be normalized before combining it.
--
- !record {model: ir.rule, id: test_rule3}:
- model_id: base.model_res_partner
- domain_force: "[('name', '!=', False),('id', '!=', False)]"
- name: test_rule4
- groups:
- - test_group
- perm_unlink: 1
- perm_write: 1
- perm_read: 1
- perm_create: 1
--
- Read the partners again as demo user, which should give results.
--
- !python {model: res.partner }: |
- ids = self.search(cr, ref('base.user_demo'), [])
- assert ids, "Demo user should see partners even with the combined rules."
--
- Delete global domains (to combine only group domains).
--
- !python {model: ir.rule}: |
- ids = self.search(cr, uid, [('groups','=',False)])
- assert ids, "Demo user should see some partner."
- self.unlink(cr, uid, ids)
--
- Read as demo user the partners (several group domains, no global domain).
--
- !python {model: res.partner }: |
- ids = self.search(cr, ref('base.user_demo'), [])
- assert ids, "Demo user should see some partner."
diff --git a/openerp/addons/base/tests/test_ir_sequence.py b/openerp/addons/base/tests/test_ir_sequence.py
index 3d2f891c63e..76db66d7008 100644
--- a/openerp/addons/base/tests/test_ir_sequence.py
+++ b/openerp/addons/base/tests/test_ir_sequence.py
@@ -1,193 +1,177 @@
# -*- coding: utf-8 -*-
-# Run with one of these commands:
-# > OPENERP_ADDONS_PATH='../../addons/trunk' OPENERP_PORT=8069 \
-# OPENERP_DATABASE=yy PYTHONPATH=. python tests/test_ir_sequence.py
-# > OPENERP_ADDONS_PATH='../../addons/trunk' OPENERP_PORT=8069 \
-# OPENERP_DATABASE=yy nosetests tests/test_ir_sequence.py
-# > OPENERP_ADDONS_PATH='../../../addons/trunk' OPENERP_PORT=8069 \
-# OPENERP_DATABASE=yy PYTHONPATH=../:. unit2 test_ir_sequence
-# This assume an existing database.
-import psycopg2
-import psycopg2.errorcodes
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from contextlib import contextmanager
import unittest
-import openerp
-from openerp.tests import common
+import psycopg2
+import psycopg2.errorcodes
+
+import odoo
+from odoo.tests import common
ADMIN_USER_ID = common.ADMIN_USER_ID
-def registry(model):
- return openerp.modules.registry.RegistryManager.get(common.get_db_name())[model]
-
-def cursor():
- return openerp.modules.registry.RegistryManager.get(common.get_db_name()).cursor()
+@contextmanager
+def environment():
+ """ Return an environment with a new cursor for the current database; the
+ cursor is committed and closed after the context block.
+ """
+ registry = odoo.registry(common.get_db_name())
+ with registry.cursor() as cr:
+ yield odoo.api.Environment(cr, ADMIN_USER_ID, {})
+ cr.commit()
def drop_sequence(code):
- cr = cursor()
- s = registry('ir.sequence')
- ids = s.search(cr, ADMIN_USER_ID, [('code', '=', code)])
- s.unlink(cr, ADMIN_USER_ID, ids)
- cr.commit()
- cr.close()
+ with environment() as env:
+ seq = env['ir.sequence'].search([('code', '=', code)])
+ seq.unlink()
-class test_ir_sequence_standard(unittest.TestCase):
+
+class TestIrSequenceStandard(unittest.TestCase):
""" A few tests for a 'Standard' (i.e. PostgreSQL) sequence. """
def test_ir_sequence_create(self):
""" Try to create a sequence object. """
- cr = cursor()
- d = dict(code='test_sequence_type', name='Test sequence')
- c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
- assert c
- cr.commit()
- cr.close()
+ with environment() as env:
+ seq = env['ir.sequence'].create({
+ 'code': 'test_sequence_type',
+ 'name': 'Test sequence',
+ })
+ self.assertTrue(seq)
def test_ir_sequence_search(self):
""" Try a search. """
- cr = cursor()
- ids = registry('ir.sequence').search(cr, ADMIN_USER_ID, [], {})
- assert ids
- cr.commit()
- cr.close()
+ with environment() as env:
+ seqs = env['ir.sequence'].search([])
+ self.assertTrue(seqs)
def test_ir_sequence_draw(self):
""" Try to draw a number. """
- cr = cursor()
- n = registry('ir.sequence').next_by_code(cr, ADMIN_USER_ID, 'test_sequence_type', {})
- assert n
- cr.commit()
- cr.close()
+ with environment() as env:
+ n = env['ir.sequence'].next_by_code('test_sequence_type')
+ self.assertTrue(n)
def test_ir_sequence_draw_twice(self):
""" Try to draw a number from two transactions. """
- cr0 = cursor()
- cr1 = cursor()
- n0 = registry('ir.sequence').next_by_code(cr0, ADMIN_USER_ID, 'test_sequence_type', {})
- assert n0
- n1 = registry('ir.sequence').next_by_code(cr1, ADMIN_USER_ID, 'test_sequence_type', {})
- assert n1
- cr0.commit()
- cr1.commit()
- cr0.close()
- cr1.close()
+ with environment() as env0:
+ with environment() as env1:
+ n0 = env0['ir.sequence'].next_by_code('test_sequence_type')
+ self.assertTrue(n0)
+ n1 = env1['ir.sequence'].next_by_code('test_sequence_type')
+ self.assertTrue(n1)
@classmethod
def tearDownClass(cls):
drop_sequence('test_sequence_type')
-class test_ir_sequence_no_gap(unittest.TestCase):
+
+class TestIrSequenceNoGap(unittest.TestCase):
""" Copy of the previous tests for a 'No gap' sequence. """
def test_ir_sequence_create_no_gap(self):
""" Try to create a sequence object. """
- cr = cursor()
- d = dict(code='test_sequence_type_2', name='Test sequence',
- implementation='no_gap')
- c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
- assert c
- cr.commit()
- cr.close()
+ with environment() as env:
+ seq = env['ir.sequence'].create({
+ 'code': 'test_sequence_type_2',
+ 'name': 'Test sequence',
+ 'implementation': 'no_gap',
+ })
+ self.assertTrue(seq)
def test_ir_sequence_draw_no_gap(self):
""" Try to draw a number. """
- cr = cursor()
- n = registry('ir.sequence').next_by_code(cr, ADMIN_USER_ID, 'test_sequence_type_2', {})
- assert n
- cr.commit()
- cr.close()
+ with environment() as env:
+ n = env['ir.sequence'].next_by_code('test_sequence_type_2')
+ self.assertTrue(n)
def test_ir_sequence_draw_twice_no_gap(self):
""" Try to draw a number from two transactions.
This is expected to not work.
"""
- cr0 = cursor()
- cr1 = cursor()
- cr1._default_log_exceptions = False # Prevent logging a traceback
- with self.assertRaises(psycopg2.OperationalError) as e:
- n0 = registry('ir.sequence').next_by_code(cr0, ADMIN_USER_ID, 'test_sequence_type_2', {})
- assert n0
- n1 = registry('ir.sequence').next_by_code(cr1, ADMIN_USER_ID, 'test_sequence_type_2', {})
- self.assertEqual(e.exception.pgcode, psycopg2.errorcodes.LOCK_NOT_AVAILABLE, msg="postgresql returned an incorrect errcode")
- cr0.close()
- cr1.close()
+ with environment() as env0:
+ with environment() as env1:
+ env1.cr._default_log_exceptions = False # Prevent logging a traceback
+ with self.assertRaises(psycopg2.OperationalError) as e:
+ n0 = env0['ir.sequence'].next_by_code('test_sequence_type_2')
+ self.assertTrue(n0)
+ n1 = env1['ir.sequence'].next_by_code('test_sequence_type_2')
+ self.assertEqual(e.exception.pgcode, psycopg2.errorcodes.LOCK_NOT_AVAILABLE, msg="postgresql returned an incorrect errcode")
@classmethod
def tearDownClass(cls):
drop_sequence('test_sequence_type_2')
-class test_ir_sequence_change_implementation(unittest.TestCase):
+
+class TestIrSequenceChangeImplementation(unittest.TestCase):
""" Create sequence objects and change their ``implementation`` field. """
def test_ir_sequence_1_create(self):
""" Try to create a sequence object. """
- cr = cursor()
- d = dict(code='test_sequence_type_3', name='Test sequence')
- c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
- assert c
- d = dict(code='test_sequence_type_4', name='Test sequence',
- implementation='no_gap')
- c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
- assert c
- cr.commit()
- cr.close()
+ with environment() as env:
+ seq = env['ir.sequence'].create({
+ 'code': 'test_sequence_type_3',
+ 'name': 'Test sequence',
+ })
+ self.assertTrue(seq)
+ seq = env['ir.sequence'].create({
+ 'code': 'test_sequence_type_4',
+ 'name': 'Test sequence',
+ 'implementation': 'no_gap',
+ })
+ self.assertTrue(seq)
def test_ir_sequence_2_write(self):
- cr = cursor()
- ids = registry('ir.sequence').search(cr, ADMIN_USER_ID,
- [('code', 'in', ['test_sequence_type_3', 'test_sequence_type_4'])], {})
- registry('ir.sequence').write(cr, ADMIN_USER_ID, ids,
- {'implementation': 'standard'}, {})
- registry('ir.sequence').write(cr, ADMIN_USER_ID, ids,
- {'implementation': 'no_gap'}, {})
- cr.commit()
- cr.close()
+ with environment() as env:
+ domain = [('code', 'in', ['test_sequence_type_3', 'test_sequence_type_4'])]
+ seqs = env['ir.sequence'].search(domain)
+ seqs.write({'implementation': 'standard'})
+ seqs.write({'implementation': 'no_gap'})
def test_ir_sequence_3_unlink(self):
- cr = cursor()
- ids = registry('ir.sequence').search(cr, ADMIN_USER_ID,
- [('code', 'in', ['test_sequence_type_3', 'test_sequence_type_4'])], {})
- registry('ir.sequence').unlink(cr, ADMIN_USER_ID, ids, {})
- cr.commit()
- cr.close()
+ with environment() as env:
+ domain = [('code', 'in', ['test_sequence_type_3', 'test_sequence_type_4'])]
+ seqs = env['ir.sequence'].search(domain)
+ seqs.unlink()
@classmethod
def tearDownClass(cls):
drop_sequence('test_sequence_type_3')
drop_sequence('test_sequence_type_4')
-class test_ir_sequence_generate(unittest.TestCase):
+
+class TestIrSequenceGenerate(unittest.TestCase):
""" Create sequence objects and generate some values. """
def test_ir_sequence_create(self):
""" Try to create a sequence object. """
- cr = cursor()
- d = dict(code='test_sequence_type_5', name='Test sequence')
- c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
- assert c
- cr.commit()
- cr.close()
+ with environment() as env:
+ seq = env['ir.sequence'].create({
+ 'code': 'test_sequence_type_5',
+ 'name': 'Test sequence',
+ })
+ self.assertTrue(seq)
- cr = cursor()
- f = lambda *a: registry('ir.sequence').next_by_code(cr, ADMIN_USER_ID, 'test_sequence_type_5', {})
- assert all(str(x) == f() for x in xrange(1,10))
- cr.commit()
- cr.close()
+ with environment() as env:
+ for i in xrange(1, 10):
+ n = env['ir.sequence'].next_by_code('test_sequence_type_5')
+ self.assertEqual(n, str(i))
def test_ir_sequence_create_no_gap(self):
""" Try to create a sequence object. """
- cr = cursor()
- d = dict(code='test_sequence_type_6', name='Test sequence', implementation='no_gap')
- c = registry('ir.sequence').create(cr, ADMIN_USER_ID, d, {})
- assert c
- cr.commit()
- cr.close()
+ with environment() as env:
+ seq = env['ir.sequence'].create({
+ 'code': 'test_sequence_type_6',
+ 'name': 'Test sequence',
+ 'implementation': 'no_gap',
+ })
+ self.assertTrue(seq)
- cr = cursor()
- f = lambda *a: registry('ir.sequence').next_by_code(cr, ADMIN_USER_ID, 'test_sequence_type_6', {})
- assert all(str(x) == f() for x in xrange(1,10))
- cr.commit()
- cr.close()
+ with environment() as env:
+ for i in xrange(1, 10):
+ n = env['ir.sequence'].next_by_code('test_sequence_type_6')
+ self.assertEqual(n, str(i))
@classmethod
def tearDownClass(cls):
@@ -195,33 +179,29 @@ class test_ir_sequence_generate(unittest.TestCase):
drop_sequence('test_sequence_type_6')
-class Test_ir_sequence_init(common.TransactionCase):
+class TestIrSequenceInit(common.TransactionCase):
def test_00(self):
- registry, cr, uid = self.registry, self.cr, self.uid
-
- # test if read statement return the good number_next value (from postgreSQL sequence and not ir_sequence value)
- sequence = registry('ir.sequence')
+ """ test whether the read method returns the right number_next value
+ (from postgreSQL sequence and not ir_sequence value)
+ """
# first creation of sequence (normal)
- values = {'number_next': 1,
- 'company_id': 1,
- 'padding': 4,
- 'number_increment': 1,
- 'implementation': 'standard',
- 'name': 'test-sequence-00'}
- seq_id = sequence.create(cr, uid, values)
- # Call get next 4 times
- sequence.next_by_id(cr, uid, seq_id)
- sequence.next_by_id(cr, uid, seq_id)
- sequence.next_by_id(cr, uid, seq_id)
- read_sequence = sequence.next_by_id(cr, uid, seq_id)
+ seq = self.env['ir.sequence'].create({
+ 'number_next': 1,
+ 'company_id': 1,
+ 'padding': 4,
+ 'number_increment': 1,
+ 'implementation': 'standard',
+ 'name': 'test-sequence-00',
+ })
+ # Call next() 4 times, and check the last returned value
+ seq.next_by_id()
+ seq.next_by_id()
+ seq.next_by_id()
+ n = seq.next_by_id()
+ self.assertEqual(n, "0004", 'The actual sequence value must be 4. reading : %s' % n)
+ # reset sequence to 1 by write()
+ seq.write({'number_next': 1})
# Read the value of the current sequence
- assert read_sequence == "0004", 'The actual sequence value must be 4. reading : %s' % read_sequence
- # reset sequence to 1 by write method calling
- sequence.write(cr, uid, [seq_id], {'number_next': 1})
- # Read the value of the current sequence
- read_sequence = sequence.next_by_id(cr, uid, seq_id)
- assert read_sequence == "0001", 'The actual sequence value must be 1. reading : %s' % read_sequence
-
-if __name__ == "__main__":
- unittest.main()
+ n = seq.next_by_id()
+ self.assertEqual(n, "0001", 'The actual sequence value must be 1. reading : %s' % n)
diff --git a/openerp/addons/base/tests/test_ir_sequence_date_range.py b/openerp/addons/base/tests/test_ir_sequence_date_range.py
index c2ddc4e4f0f..147b0f26050 100644
--- a/openerp/addons/base/tests/test_ir_sequence_date_range.py
+++ b/openerp/addons/base/tests/test_ir_sequence_date_range.py
@@ -1,122 +1,142 @@
-import unittest
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
-from openerp.tests import common
from datetime import date
+from odoo.tests.common import SingleTransactionCase
+from odoo.tools import DEFAULT_SERVER_DATE_FORMAT as DATE_FORMAT
-class test_ir_sequence_date_range_standard(common.SingleTransactionCase):
+
+class TestIrSequenceDateRangeStandard(SingleTransactionCase):
""" A few tests for a 'Standard' (i.e. PostgreSQL) sequence. """
def test_ir_sequence_date_range_1_create(self):
""" Try to create a sequence object with date ranges enabled. """
- d = dict(code='test_sequence_date_range', name='Test sequence', use_date_range=True)
- c = self.registry('ir.sequence').create(self.cr, self.uid, d, {})
- assert c
+ seq = self.env['ir.sequence'].create({
+ 'code': 'test_sequence_date_range',
+ 'name': 'Test sequence',
+ 'use_date_range': True,
+ })
+ self.assertTrue(seq)
def test_ir_sequence_date_range_2_change_dates(self):
""" Draw numbers to create a first subsequence then change its date range. Then, try to draw a new number adn check a new subsequence was correctly created. """
- year = str(int(date.today().strftime("%Y")) - 1)
- dt = "{}-01-16".format(year)
- n = self.registry('ir.sequence').next_by_code(self.cr, self.uid, 'test_sequence_date_range', {'ir_sequence_date': dt})
+ year = date.today().year - 1
+ january = lambda d: date(year, 1, d).strftime(DATE_FORMAT)
+
+ seq16 = self.env['ir.sequence'].with_context({'ir_sequence_date': january(16)})
+ n = seq16.next_by_code('test_sequence_date_range')
self.assertEqual(n, '1')
- n = self.registry('ir.sequence').next_by_code(self.cr, self.uid, 'test_sequence_date_range', {'ir_sequence_date': dt})
+ n = seq16.next_by_code('test_sequence_date_range')
self.assertEqual(n, '2')
+
# modify the range of date created
- domain = [('sequence_id.code', '=', 'test_sequence_date_range'), ('date_from', '=', '{}-01-01'.format(year))]
- seq_date_range_id = self.registry('ir.sequence.date_range').search(self.cr, self.uid, domain, {})
- self.registry('ir.sequence.date_range').write(self.cr, self.uid, seq_date_range_id, {'date_from': '{}-01-18'.format(year)}, {})
- n = self.registry('ir.sequence').next_by_code(self.cr, self.uid, 'test_sequence_date_range', {'ir_sequence_date': dt})
+ domain = [('sequence_id.code', '=', 'test_sequence_date_range'), ('date_from', '=', january(1))]
+ seq_date_range = self.env['ir.sequence.date_range'].search(domain)
+ seq_date_range.write({'date_from': january(18)})
+ n = seq16.next_by_code('test_sequence_date_range')
self.assertEqual(n, '1')
+
# check the newly created sequence stops at the 17th of January
- domain = [('sequence_id.code', '=', 'test_sequence_date_range'), ('date_from', '=', '{}-01-01'.format(year))]
- seq_date_range_id = self.registry('ir.sequence.date_range').search(self.cr, self.uid, domain, {})
- seq_date_range = self.registry('ir.sequence.date_range').browse(self.cr, self.uid, seq_date_range_id[0])
- self.assertEqual(seq_date_range.date_to, '{}-01-17'.format(year))
+ domain = [('sequence_id.code', '=', 'test_sequence_date_range'), ('date_from', '=', january(1))]
+ seq_date_range = self.env['ir.sequence.date_range'].search(domain)
+ self.assertEqual(seq_date_range.date_to, january(17))
def test_ir_sequence_date_range_3_unlink(self):
- ids = self.registry('ir.sequence').search(self.cr, self.uid, [('code', '=', 'test_sequence_date_range')])
- self.registry('ir.sequence').unlink(self.cr, self.uid, ids)
+ seq = self.env['ir.sequence'].search([('code', '=', 'test_sequence_date_range')])
+ seq.unlink()
-class test_ir_sequence_date_range_no_gap(common.SingleTransactionCase):
+class TestIrSequenceDateRangeNoGap(SingleTransactionCase):
""" Copy of the previous tests for a 'No gap' sequence. """
def test_ir_sequence_date_range_1_create_no_gap(self):
""" Try to create a sequence object. """
- d = dict(code='test_sequence_date_range_2', name='Test sequence',
- implementation='no_gap', use_date_range=True)
- c = self.registry('ir.sequence').create(self.cr, self.uid, d, {})
- assert c
+ seq = self.env['ir.sequence'].create({
+ 'code': 'test_sequence_date_range_2',
+ 'name': 'Test sequence',
+ 'use_date_range': True,
+ 'implementation': 'no_gap',
+ })
+ self.assertTrue(seq)
def test_ir_sequence_date_range_2_change_dates(self):
""" Draw numbers to create a first subsequence then change its date range. Then, try to draw a new number adn check a new subsequence was correctly created. """
- year = str(int(date.today().strftime("%Y")) - 1)
- dt = "{}-01-16".format(year)
- n = self.registry('ir.sequence').next_by_code(self.cr, self.uid, 'test_sequence_date_range_2', {'ir_sequence_date': dt})
+ year = date.today().year - 1
+ january = lambda d: date(year, 1, d).strftime(DATE_FORMAT)
+
+ seq16 = self.env['ir.sequence'].with_context({'ir_sequence_date': january(16)})
+ n = seq16.next_by_code('test_sequence_date_range_2')
self.assertEqual(n, '1')
- n = self.registry('ir.sequence').next_by_code(self.cr, self.uid, 'test_sequence_date_range_2', {'ir_sequence_date': dt})
+ n = seq16.next_by_code('test_sequence_date_range_2')
self.assertEqual(n, '2')
+
# modify the range of date created
- domain = [('sequence_id.code', '=', 'test_sequence_date_range_2'), ('date_from', '=', '{}-01-01'.format(year))]
- seq_date_range_id = self.registry('ir.sequence.date_range').search(self.cr, self.uid, domain, {})
- self.registry('ir.sequence.date_range').write(self.cr, self.uid, seq_date_range_id, {'date_from': '{}-01-18'.format(year)}, {})
- n = self.registry('ir.sequence').next_by_code(self.cr, self.uid, 'test_sequence_date_range_2', {'ir_sequence_date': dt})
+ domain = [('sequence_id.code', '=', 'test_sequence_date_range_2'), ('date_from', '=', january(1))]
+ seq_date_range = self.env['ir.sequence.date_range'].search(domain)
+ seq_date_range.write({'date_from': january(18)})
+ n = seq16.next_by_code('test_sequence_date_range_2')
self.assertEqual(n, '1')
+
# check the newly created sequence stops at the 17th of January
- domain = [('sequence_id.code', '=', 'test_sequence_date_range_2'), ('date_from', '=', '{}-01-01'.format(year))]
- seq_date_range_id = self.registry('ir.sequence.date_range').search(self.cr, self.uid, domain, {})
- seq_date_range = self.registry('ir.sequence.date_range').browse(self.cr, self.uid, seq_date_range_id[0])
- self.assertEqual(seq_date_range.date_to, '{}-01-17'.format(year))
+ domain = [('sequence_id.code', '=', 'test_sequence_date_range_2'), ('date_from', '=', january(1))]
+ seq_date_range = self.env['ir.sequence.date_range'].search(domain)
+ self.assertEqual(seq_date_range.date_to, january(17))
def test_ir_sequence_date_range_3_unlink(self):
- ids = self.registry('ir.sequence').search(self.cr, self.uid, [('code', '=', 'test_sequence_date_range_2')])
- self.registry('ir.sequence').unlink(self.cr, self.uid, ids)
+ seq = self.env['ir.sequence'].search([('code', '=', 'test_sequence_date_range_2')])
+ seq.unlink()
-class test_ir_sequence_date_range_change_implementation(common.SingleTransactionCase):
+class TestIrSequenceDateRangeChangeImplementation(SingleTransactionCase):
""" Create sequence objects and change their ``implementation`` field. """
def test_ir_sequence_date_range_1_create(self):
""" Try to create a sequence object. """
- d = dict(code='test_sequence_date_range_3', name='Test sequence', use_date_range=True)
- c = self.registry('ir.sequence').create(self.cr, self.uid, d, {})
- assert c
- d = {
+ seq = self.env['ir.sequence'].create({
+ 'code': 'test_sequence_date_range_3',
+ 'name': 'Test sequence',
+ 'use_date_range': True,
+ })
+ self.assertTrue(seq)
+
+ seq = self.env['ir.sequence'].create({
'code': 'test_sequence_date_range_4',
'name': 'Test sequence',
+ 'use_date_range': True,
'implementation': 'no_gap',
- 'use_date_range': True
- }
- c = self.registry('ir.sequence').create(self.cr, self.uid, d, {})
- assert c
+ })
+ self.assertTrue(seq)
def test_ir_sequence_date_range_2_use(self):
""" Make some use of the sequences to create some subsequences """
- year = str(int(date.today().strftime("%Y")) - 1)
- dt = "{}-01-16".format(year)
- f = lambda *a: self.registry('ir.sequence').next_by_code(self.cr, self.uid, 'test_sequence_date_range_3', {})
- assert all(str(x) == f() for x in xrange(1, 5))
- f = lambda *a: self.registry('ir.sequence').next_by_code(self.cr, self.uid, 'test_sequence_date_range_3', {'ir_sequence_date': dt})
- assert all(str(x) == f() for x in xrange(1, 5))
- f = lambda *a: self.registry('ir.sequence').next_by_code(self.cr, self.uid, 'test_sequence_date_range_4', {})
- assert all(str(x) == f() for x in xrange(1, 5))
- f = lambda *a: self.registry('ir.sequence').next_by_code(self.cr, self.uid, 'test_sequence_date_range_4', {'ir_sequence_date': dt})
- assert all(str(x) == f() for x in xrange(1, 5))
+ year = date.today().year - 1
+ january = lambda d: date(year, 1, d).strftime(DATE_FORMAT)
+
+ seq = self.env['ir.sequence']
+ seq16 = self.env['ir.sequence'].with_context({'ir_sequence_date': january(16)})
+
+ for i in xrange(1, 5):
+ n = seq.next_by_code('test_sequence_date_range_3')
+ self.assertEqual(n, str(i))
+ for i in xrange(1, 5):
+ n = seq16.next_by_code('test_sequence_date_range_3')
+ self.assertEqual(n, str(i))
+ for i in xrange(1, 5):
+ n = seq.next_by_code('test_sequence_date_range_4')
+ self.assertEqual(n, str(i))
+ for i in xrange(1, 5):
+ n = seq16.next_by_code('test_sequence_date_range_4')
+ self.assertEqual(n, str(i))
def test_ir_sequence_date_range_3_write(self):
"""swap the implementation method on both"""
- ids = self.registry('ir.sequence').search(self.cr, self.uid, [
- ('code', 'in', ['test_sequence_date_range_3', 'test_sequence_date_range_4'])
- ], {})
- self.registry('ir.sequence').write(self.cr, self.uid, ids, {'implementation': 'standard'})
- self.registry('ir.sequence').write(self.cr, self.uid, ids, {'implementation': 'no_gap'})
+ domain = [('code', 'in', ['test_sequence_date_range_3', 'test_sequence_date_range_4'])]
+ seqs = self.env['ir.sequence'].search(domain)
+ seqs.write({'implementation': 'standard'})
+ seqs.write({'implementation': 'no_gap'})
def test_ir_sequence_date_range_4_unlink(self):
- ids = self.registry('ir.sequence').search(self.cr, self.uid, [
- ('code', 'in', ['test_sequence_date_range_3', 'test_sequence_date_range_4'])
- ], {})
- self.registry('ir.sequence').unlink(self.cr, self.uid, ids, {})
-
-
-if __name__ == '__main__':
- unittest.main()
+ domain = [('code', 'in', ['test_sequence_date_range_3', 'test_sequence_date_range_4'])]
+ seqs = self.env['ir.sequence'].search(domain)
+ seqs.unlink()
diff --git a/openerp/addons/base/tests/test_ir_values.py b/openerp/addons/base/tests/test_ir_values.py
index 435421ea845..8cdf35e4d40 100644
--- a/openerp/addons/base/tests/test_ir_values.py
+++ b/openerp/addons/base/tests/test_ir_values.py
@@ -1,98 +1,99 @@
-import unittest
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
-import openerp.tests.common as common
+from odoo.tests.common import TransactionCase
-class test_ir_values(common.TransactionCase):
+
+class TestIrValues(TransactionCase):
def test_00(self):
# Create some default value for some (non-existing) model, for all users.
- ir_values = self.registry('ir.values')
+ ir_values = self.env['ir.values']
# use the old API
- ir_values.set(self.cr, self.uid, 'default', False, 'my_test_field',
- ['unexisting_model'], 'global value')
+ ir_values.set('default', False, 'my_test_field', ['unexisting_model'],
+ 'global value')
# use the new API
- ir_values.set_default(self.cr, self.uid, 'other_unexisting_model',
- 'my_other_test_field', 'conditional value', condition='foo=bar')
-
+ ir_values.set_default('other_unexisting_model', 'my_other_test_field',
+ 'conditional value', condition='foo=bar')
# Retrieve them.
- ir_values = self.registry('ir.values')
# d is a list of triplets (id, name, value)
# Old API
- d = ir_values.get(self.cr, self.uid, 'default', False, ['unexisting_model'])
- assert len(d) == 1, "Only one single value should be retrieved for this model"
- assert d[0][1] == 'my_test_field', "Can't retrieve the created default value. (1)"
- assert d[0][2] == 'global value', "Can't retrieve the created default value. (2)"
+ d = ir_values.get('default', False, ['unexisting_model'])
+ self.assertEqual(len(d), 1, "Only one single value should be retrieved for this model")
+ self.assertEqual(d[0][1], 'my_test_field', "Can't retrieve the created default value. (1)")
+ self.assertEqual(d[0][2], 'global value', "Can't retrieve the created default value. (2)")
# New API, Conditional version
- d = ir_values.get_defaults(self.cr, self.uid, 'other_unexisting_model')
- assert len(d) == 0, "No value should be retrieved, the condition is not met"
- d = ir_values.get_defaults(self.cr, self.uid, 'other_unexisting_model', condition="foo=eggs")
- assert len(d) == 0, 'Condition is not met either, no defaults should be returned'
- d = ir_values.get_defaults(self.cr, self.uid, 'other_unexisting_model', condition="foo=bar")
- assert len(d) == 1, "Only one single value should be retrieved"
- assert d[0][1] == 'my_other_test_field', "Can't retrieve the created default value. (5)"
- assert d[0][2] == 'conditional value', "Can't retrieve the created default value. (6)"
+ d = ir_values.get_defaults('other_unexisting_model')
+ self.assertEqual(len(d), 0, "No value should be retrieved, the condition is not met")
+ d = ir_values.get_defaults('other_unexisting_model', condition="foo=eggs")
+ self.assertEqual(len(d), 0, 'Condition is not met either, no defaults should be returned')
+ d = ir_values.get_defaults('other_unexisting_model', condition="foo=bar")
+ self.assertEqual(len(d), 1, "Only one single value should be retrieved")
+ self.assertEqual(d[0][1], 'my_other_test_field', "Can't retrieve the created default value. (5)")
+ self.assertEqual(d[0][2], 'conditional value', "Can't retrieve the created default value. (6)")
# Do it again but for a specific user.
- ir_values = self.registry('ir.values')
- ir_values.set(self.cr, self.uid, 'default', False, 'my_test_field',['unexisting_model'], 'specific value', preserve_user=True)
+ ir_values.set('default', False, 'my_test_field',['unexisting_model'],
+ 'specific value', preserve_user=True)
# Retrieve it and check it is the one for the current user.
- ir_values = self.registry('ir.values')
- d = ir_values.get(self.cr, self.uid, 'default', False, ['unexisting_model'])
- assert len(d) == 1, "Only one default must be returned per field"
- assert d[0][1] == 'my_test_field', "Can't retrieve the created default value."
- assert d[0][2] == 'specific value', "Can't retrieve the created default value."
+
+ d = ir_values.get('default', False, ['unexisting_model'])
+ self.assertEqual(len(d), 1, "Only one default must be returned per field")
+ self.assertEqual(d[0][1], 'my_test_field', "Can't retrieve the created default value.")
+ self.assertEqual(d[0][2], 'specific value', "Can't retrieve the created default value.")
# Create some action bindings for a non-existing model.
act_id_1 = self.ref('base.act_values_form_action')
act_id_2 = self.ref('base.act_values_form_defaults')
act_id_3 = self.ref('base.action_res_company_form')
-
- ir_values = self.registry('ir.values')
- ir_values.set(self.cr, self.uid, 'action', 'tree_but_open', 'OnDblClick Action', ['unexisting_model'], 'ir.actions.act_window,%d' % act_id_1, isobject=True)
- ir_values.set(self.cr, self.uid, 'action', 'tree_but_open', 'OnDblClick Action 2', ['unexisting_model'], 'ir.actions.act_window,%d' % act_id_2, isobject=True)
- ir_values.set(self.cr, self.uid, 'action', 'client_action_multi', 'Side Wizard', ['unexisting_model'], 'ir.actions.act_window,%d' % act_id_3, isobject=True)
- report_ids = self.registry('ir.actions.report.xml').search(self.cr, self.uid, [], {})
- reports = self.registry('ir.actions.report.xml').browse(self.cr, self.uid, report_ids, {})
- report_id = [report.id for report in reports if not report.groups_id][0] # assume at least one
- ir_values.set(self.cr, self.uid, 'action', 'client_print_multi', 'Nice Report', ['unexisting_model'], 'ir.actions.report.xml,%d' % report_id, isobject=True)
+ ir_values.set('action', 'tree_but_open', 'OnDblClick Action', ['unexisting_model'],
+ 'ir.actions.act_window,%d' % act_id_1, isobject=True)
+ ir_values.set('action', 'tree_but_open', 'OnDblClick Action 2', ['unexisting_model'],
+ 'ir.actions.act_window,%d' % act_id_2, isobject=True)
+ ir_values.set('action', 'client_action_multi', 'Side Wizard', ['unexisting_model'],
+ 'ir.actions.act_window,%d' % act_id_3, isobject=True)
+ reports = self.env['ir.actions.report.xml'].search([])
+ report_id = next(report.id for report in reports if not report.groups_id)
+ ir_values.set('action', 'client_print_multi', 'Nice Report', ['unexisting_model'],
+ 'ir.actions.report.xml,%d' % report_id, isobject=True)
# Replace one action binding to set a new name.
- ir_values = self.registry('ir.values')
- ir_values.set(self.cr, self.uid, 'action', 'tree_but_open', 'OnDblClick Action New', ['unexisting_model'], 'ir.actions.act_window,%d' % act_id_1, isobject=True)
+ ir_values.set('action', 'tree_but_open', 'OnDblClick Action New', ['unexisting_model'],
+ 'ir.actions.act_window,%d' % act_id_1, isobject=True)
# Retrieve the action bindings and check they're correct
- ir_values = self.registry('ir.values')
- actions = ir_values.get(self.cr, self.uid, 'action', 'tree_but_open', ['unexisting_model'])
- assert len(actions) == 2, "Mismatching number of bound actions"
+ actions = ir_values.get('action', 'tree_but_open', ['unexisting_model'])
+ self.assertEqual(len(actions), 2, "Mismatching number of bound actions")
#first action
- assert len(actions[0]) == 3, "Malformed action definition"
- assert actions[0][1] == 'OnDblClick Action 2', 'Bound action does not match definition'
- assert isinstance(actions[0][2], dict) and actions[0][2]['id'] == act_id_2, 'Bound action does not match definition'
+ self.assertEqual(len(actions[0]), 3, "Malformed action definition")
+ self.assertEqual(actions[0][1], 'OnDblClick Action 2', 'Bound action does not match definition')
+ self.assertTrue(isinstance(actions[0][2], dict) and actions[0][2]['id'] == act_id_2,
+ 'Bound action does not match definition')
#second action - this ones comes last because it was re-created with a different name
- assert len(actions[1]) == 3, "Malformed action definition"
- assert actions[1][1] == 'OnDblClick Action New', 'Re-Registering an action should replace it'
- assert isinstance(actions[1][2], dict) and actions[1][2]['id'] == act_id_1, 'Bound action does not match definition'
+ self.assertEqual(len(actions[1]), 3, "Malformed action definition")
+ self.assertEqual(actions[1][1], 'OnDblClick Action New', 'Re-Registering an action should replace it')
+ self.assertTrue(isinstance(actions[1][2], dict) and actions[1][2]['id'] == act_id_1,
+ 'Bound action does not match definition')
- actions = ir_values.get(self.cr, self.uid, 'action', 'client_action_multi', ['unexisting_model'])
- assert len(actions) == 1, "Mismatching number of bound actions"
- assert len(actions[0]) == 3, "Malformed action definition"
- assert actions[0][1] == 'Side Wizard', 'Bound action does not match definition'
- assert isinstance(actions[0][2], dict) and actions[0][2]['id'] == act_id_3, 'Bound action does not match definition'
+ actions = ir_values.get('action', 'client_action_multi', ['unexisting_model'])
+ self.assertEqual(len(actions), 1, "Mismatching number of bound actions")
+ self.assertEqual(len(actions[0]), 3, "Malformed action definition")
+ self.assertEqual(actions[0][1], 'Side Wizard', 'Bound action does not match definition')
+ self.assertTrue(isinstance(actions[0][2], dict) and actions[0][2]['id'] == act_id_3,
+ 'Bound action does not match definition')
- actions = ir_values.get(self.cr, self.uid, 'action', 'client_print_multi', ['unexisting_model'])
- assert len(actions) == 1, "Mismatching number of bound actions"
- assert len(actions[0]) == 3, "Malformed action definition"
- assert actions[0][1] == 'Nice Report', 'Bound action does not match definition'
- assert isinstance(actions[0][2], dict) and actions[0][2]['id'] == report_id, 'Bound action does not match definition'
-
-if __name__ == '__main__':
- unittest.main()
+ actions = ir_values.get('action', 'client_print_multi', ['unexisting_model'])
+ self.assertEqual(len(actions), 1, "Mismatching number of bound actions")
+ self.assertEqual(len(actions[0]), 3, "Malformed action definition")
+ self.assertEqual(actions[0][1], 'Nice Report', 'Bound action does not match definition')
+ self.assertTrue(isinstance(actions[0][2], dict) and actions[0][2]['id'] == report_id,
+ 'Bound action does not match definition')
diff --git a/openerp/addons/base/tests/test_mail.py b/openerp/addons/base/tests/test_mail.py
index 96e1973ed49..a751b7a76e3 100644
--- a/openerp/addons/base/tests/test_mail.py
+++ b/openerp/addons/base/tests/test_mail.py
@@ -1,14 +1,11 @@
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
-# This test can be run stand-alone with something like:
-# > PYTHONPATH=. python2 openerp/tests/test_misc.py
# Part of Odoo. See LICENSE file for full copyright and licensing details.
import cgi
import unittest
-from openerp.tools import html_sanitize, append_content_to_html, plaintext2html, email_split
-import test_mail_examples
+from odoo.tools import html_sanitize, append_content_to_html, plaintext2html, email_split
+from . import test_mail_examples
class TestSanitizer(unittest.TestCase):
@@ -325,7 +322,3 @@ class TestEmailTools(unittest.TestCase):
]
for text, expected in cases:
self.assertEqual(email_split(text), expected, 'email_split is broken')
-
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/openerp/addons/base/tests/test_mail_examples.py b/openerp/addons/base/tests/test_mail_examples.py
index 19cadd6f156..a83e668d940 100644
--- a/openerp/addons/base/tests/test_mail_examples.py
+++ b/openerp/addons/base/tests/test_mail_examples.py
@@ -1,5 +1,5 @@
-#!/usr/bin/env python
# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
MISC_HTML_SOURCE = """
test1
@@ -515,4 +515,4 @@ REMOVE_CLASS_IN = [
REMOVE_CLASS_OUT = [
'