Skip to content

Commit

Permalink
[REF] models: refactor code to update parent_left/parent_right
Browse files Browse the repository at this point in the history
Put the code to update the MPTT in specific methods, and reduce the number of
queries being made (from 5-6 queries to 2-3 queries).  Add test on MPTT to
validate the refactoring.
  • Loading branch information
rco-odoo committed Jan 16, 2018
1 parent 47e6a55 commit 7154e99
Show file tree
Hide file tree
Showing 5 changed files with 277 additions and 112 deletions.
1 change: 1 addition & 0 deletions odoo/addons/base/tests/test_base.py
Expand Up @@ -443,6 +443,7 @@ def setUp(self):
super(TestParentStore, self).setUp()
# pretend the pool has finished loading to avoid deferring parent_store computation
self.patch(self.registry, '_init', False)
self.registry.do_parent_store(self.cr)

# force res_partner_category.copy() to copy children
category = self.env['res.partner.category']
Expand Down
8 changes: 7 additions & 1 deletion odoo/addons/test_new_api/models.py
Expand Up @@ -10,10 +10,16 @@

class Category(models.Model):
_name = 'test_new_api.category'
_order = 'name'
_parent_store = True
_parent_name = 'parent'
_parent_order = 'name'

name = fields.Char(required=True)
color = fields.Integer('Color Index')
parent = fields.Many2one('test_new_api.category')
parent = fields.Many2one('test_new_api.category', ondelete='cascade')
parent_left = fields.Integer("Left Parent", index=True)
parent_right = fields.Integer("Right Parent", index=True)
root_categ = fields.Many2one(_name, compute='_compute_root_categ')
display_name = fields.Char(compute='_compute_display_name', inverse='_inverse_display_name')
dummy = fields.Char(store=False)
Expand Down
122 changes: 121 additions & 1 deletion odoo/addons/test_new_api/tests/test_new_fields.py
Expand Up @@ -3,7 +3,7 @@
#
from datetime import date, datetime

from odoo.exceptions import AccessError, except_orm
from odoo.exceptions import AccessError, UserError, except_orm
from odoo.tests import common
from odoo.tools import mute_logger, float_repr, pycompat

Expand Down Expand Up @@ -937,3 +937,123 @@ def test_write_date(self):
record = self.env['test_new_api.discussion'].create({'name': 'Booba'})
self.assertEqual(record.create_uid, self.env.user)
self.assertEqual(record.write_uid, self.env.user)


class Tree(object):
def __init__(self, node, *children):
self.node = node
self.children = children

def __str__(self):
return "%s(%s, %s)" % (self.node.name, self.node.parent_left, self.node.parent_right)


class TestParentStore(common.TransactionCase):

def setUp(self):
super(TestParentStore, self).setUp()
# pretend the pool has finished loading to avoid deferring parent_store
# computation
self.patch(self.registry, '_init', False)
self.registry.do_parent_store(self.cr)

def assertTree(self, tree):
self.assertLess(tree.node.parent_left, tree.node.parent_right,
"incorrect node %s" % tree)
for child in tree.children:
self.assertLess(tree.node.parent_left, child.node.parent_left,
"incorrect parent %s - child %s" % (tree, child))
self.assertLess(child.node.parent_right, tree.node.parent_right,
"incorrect parent %s - child %s" % (tree, child))
self.assertTrees(*tree.children)

def assertTrees(self, *trees):
for tree in trees:
self.assertTree(tree)
for tree1, tree2 in pycompat.izip(trees, trees[1:]):
self.assertLess(tree1.node.parent_right, tree2.node.parent_left,
"wrong node order: %s < %s" % (tree1, tree2))

def test_parent_store(self):
""" Test parent_left/parent_right computation. """
Category = self.env['test_new_api.category']

def descendants(recs):
return Category.search([('id', 'child_of', recs.ids)])

def ascendants(recs):
return Category.search([('id', 'parent_of', recs.ids)])

# create root nodes
c = Category.create({'name': 'c'})
a = Category.create({'name': 'a'})
b = Category.create({'name': 'b'})
self.assertTrees(Tree(a), Tree(b), Tree(c))

# create nodes d, e, f under b
f = Category.create({'name': 'f', 'parent': b.id})
d = Category.create({'name': 'd', 'parent': b.id})
e = Category.create({'name': 'e', 'parent': b.id})
self.assertTrees(Tree(a), Tree(b, Tree(d), Tree(e), Tree(f)), Tree(c))
self.assertEqual(descendants(a), a)
self.assertEqual(descendants(b), b + d + e + f)
self.assertEqual(descendants(c), c)
self.assertEqual(descendants(d), d)
self.assertEqual(descendants(e), e)
self.assertEqual(descendants(f), f)
self.assertEqual(ascendants(a), a)
self.assertEqual(ascendants(b), b)
self.assertEqual(ascendants(c), c)
self.assertEqual(ascendants(d), b + d)
self.assertEqual(ascendants(e), b + e)
self.assertEqual(ascendants(f), b + f)

# move d, f under c
(f + d).write({'parent': c.id})
self.assertTrees(Tree(a), Tree(b, Tree(e)), Tree(c, Tree(d), Tree(f)))
self.assertEqual(descendants(a), a)
self.assertEqual(descendants(b), b + e)
self.assertEqual(descendants(c), c + d + f)
self.assertEqual(descendants(d), d)
self.assertEqual(descendants(e), e)
self.assertEqual(descendants(f), f)
self.assertEqual(ascendants(a), a)
self.assertEqual(ascendants(b), b)
self.assertEqual(ascendants(c), c)
self.assertEqual(ascendants(d), c + d)
self.assertEqual(ascendants(e), b + e)
self.assertEqual(ascendants(f), c + f)

# move b, c under a
(b + c).write({'parent': a.id})
self.assertTrees(Tree(a, Tree(b, Tree(e)), Tree(c, Tree(d), Tree(f))))
self.assertEqual(descendants(a), a + b + c + d + e + f)
self.assertEqual(descendants(b), b + e)
self.assertEqual(descendants(c), c + d + f)
self.assertEqual(descendants(d), d)
self.assertEqual(descendants(e), e)
self.assertEqual(descendants(f), f)
self.assertEqual(ascendants(a), a)
self.assertEqual(ascendants(b), a + b)
self.assertEqual(ascendants(c), a + c)
self.assertEqual(ascendants(d), a + c + d)
self.assertEqual(ascendants(e), a + b + e)
self.assertEqual(ascendants(f), a + c + f)

# remove node d
d.unlink()
self.assertTrees(Tree(a, Tree(b, Tree(e)), Tree(c, Tree(f))))
self.assertEqual(descendants(a), a + b + c + e + f)
self.assertEqual(descendants(b), b + e)
self.assertEqual(descendants(c), c + f)
self.assertEqual(descendants(e), e)
self.assertEqual(descendants(f), f)
self.assertEqual(ascendants(a), a)
self.assertEqual(ascendants(b), a + b)
self.assertEqual(ascendants(c), a + c)
self.assertEqual(ascendants(e), a + b + e)
self.assertEqual(ascendants(f), a + c + f)

# not cycle should occur
with self.assertRaises(UserError):
a.parent = e

0 comments on commit 7154e99

Please sign in to comment.