Files
tryton/trytond/tests/test_tree.py
T
Cédric Krier 33b9833b65 Recompute path if part of the old path has already been updated
This happens when multiple parent are modified at the same time.
In such case the new path previously computed is no more correct.

issue11266
review368141002
2022-02-22 22:57:03 +01:00

414 lines
11 KiB
Python

# This file is part of Tryton. The COPYRIGHT file at the top level of
# this repository contains the full copyright notices and license terms.
import unittest
from trytond.model.exceptions import DomainValidationError, RecursionError
from trytond.pool import Pool
from trytond.tests.test_tryton import activate_module, with_transaction
class TreeTestCaseMixin:
model_name = None
@classmethod
def setUpClass(cls):
activate_module('tests')
def create(self):
pool = Pool()
Model = pool.get(self.model_name)
new_records = [None, None, None]
for j in range(3):
parent_records = new_records
new_records = []
k = 0
to_create = []
for parent_record in parent_records:
to_create.extend([{
'name': 'Test %d %d %d' % (j, k, i),
'parent': (parent_record.id
if parent_record else None),
} for i in range(3)])
k += 1
new_records = Model.create(to_create)
def check_tree(self):
raise NotImplementedError
def change_parent(self, parent=None, restore=False):
pool = Pool()
Model = pool.get(self.model_name)
records = Model.search([
('parent', '=', parent),
])
if not records:
return
for record in records[::2]:
for record2 in records[1::2]:
record.parent = record2
record.save()
if restore:
record.parent = parent
record.save()
for record in records:
self.change_parent(record, restore=restore)
@with_transaction()
def test_create(self):
"Test create tree"
self.create()
self.check_tree()
@with_transaction()
def test_reparent(self):
"Test re-parent"
self.create()
self.change_parent(restore=True)
self.check_tree()
@with_transaction()
def test_move(self):
"Test move"
self.create()
self.change_parent()
self.check_tree()
@with_transaction()
def test_active(self):
"Test active"
pool = Pool()
Model = pool.get(self.model_name)
self.create()
records = Model.search([])
for record in records:
if record.id % 2:
record.active = False
record.save()
self.check_tree()
self.change_parent()
self.check_tree()
records = Model.search([])
Model.write(records, {
'active': True,
})
Model.write(records[::2], {
'active': False
})
self.check_tree()
records = Model.search([])
Model.write(records, {
'active': True,
})
Model.write(records[:len(records) // 2], {
'active': False
})
self.check_tree()
records = Model.search([])
Model.write(records, {
'active': False
})
self.change_parent()
self.check_tree()
@with_transaction()
def test_delete(self):
"Test delete"
pool = Pool()
Model = pool.get(self.model_name)
self.create()
records = Model.search([])
for record in records:
if record.id % 2:
Model.delete([record])
self.check_tree()
records = Model.search([])
Model.delete(records[:len(records) // 2])
self.check_tree()
records = Model.search([])
Model.delete(records)
self.check_tree()
@with_transaction()
def test_write_multiple_parents(self):
"Test write multiple parents"
pool = Pool()
Model = pool.get(self.model_name)
record1 = Model(name="Root")
record1.save()
record2 = Model(name="Child", parent=record1)
record2.save()
record3 = Model(name="Grand Child", parent=record2)
record3.save()
self.check_tree()
Model.write([record2, record3], {'parent': None})
self.check_tree()
def rebuild(self):
raise NotImplementedError
@with_transaction()
def test_rebuild(self):
"Test rebuild"
self.create()
self.rebuild()
self.check_tree()
class TreeMixinTestCase(unittest.TestCase):
"Test TreeMixin"
@classmethod
def setUpClass(cls):
activate_module('tests')
@with_transaction()
def test_name_domain(self):
"Test name domain"
pool = Pool()
Tree = pool.get('test.tree')
record = Tree(name="foo / bar")
with self.assertRaises(DomainValidationError):
record.save()
@with_transaction()
def test_rec_name(self):
"Test rec_name"
pool = Pool()
Tree = pool.get('test.tree')
parent = Tree(name="parent")
parent.save()
record = Tree(name="record", parent=parent)
record.save()
self.assertEqual(record.rec_name, "parent / record")
@with_transaction()
def test_search_rec_name_equals(self):
"Test search_rec_name equals"
pool = Pool()
Tree = pool.get('test.tree')
parent = Tree(name="parent")
parent.save()
record = Tree(name="record", parent=parent)
record.save()
records = Tree.search([('rec_name', '=', 'parent / record')])
self.assertEqual(records, [record])
@with_transaction()
def test_search_rec_name_equals_toplevel(self):
"Test search_rec_name equals top-level"
pool = Pool()
Tree = pool.get('test.tree')
parent = Tree(name="parent")
parent.save()
record = Tree(name="record", parent=parent)
record.save()
records = Tree.search([('rec_name', '=', 'parent')])
self.assertEqual(records, [parent])
@with_transaction()
def test_search_rec_name_equals_none(self):
"Test search_rec_name equals"
pool = Pool()
Tree = pool.get('test.tree')
parent = Tree(name="parent")
parent.save()
record = Tree(name="record", parent=parent)
record.save()
records = Tree.search([('rec_name', '=', None)])
self.assertEqual(records, [])
@with_transaction()
def test_search_rec_name_non_equals(self):
"Test search_rec_name non equals"
pool = Pool()
Tree = pool.get('test.tree')
parent = Tree(name="parent")
parent.save()
record = Tree(name="record", parent=parent)
record.save()
records = Tree.search([('rec_name', '!=', 'parent / record')])
self.assertEqual(records, [parent])
@with_transaction()
def test_search_rec_name_non_equals_toplevel(self):
"Test search_rec_name non equals top-level"
pool = Pool()
Tree = pool.get('test.tree')
parent = Tree(name="parent")
parent.save()
record = Tree(name="record", parent=parent)
record.save()
records = Tree.search([('rec_name', '!=', 'parent')])
self.assertEqual(records, [record])
@with_transaction()
def test_search_rec_name_non_equals_none(self):
"Test search_rec_name equals"
pool = Pool()
Tree = pool.get('test.tree')
parent = Tree(name="parent")
parent.save()
record = Tree(name="record", parent=parent)
record.save()
records = Tree.search([('rec_name', '!=', None)])
self.assertEqual(records, [parent, record])
@with_transaction()
def test_search_rec_name_in(self):
"Test search_rec_name in"
pool = Pool()
Tree = pool.get('test.tree')
parent = Tree(name="parent")
parent.save()
record = Tree(name="record", parent=parent)
record.save()
records = Tree.search([('rec_name', 'in', ['parent / record'])])
self.assertEqual(records, [record])
@with_transaction()
def test_search_rec_name_in_toplevel(self):
"Test search_rec_name in top-level"
pool = Pool()
Tree = pool.get('test.tree')
parent = Tree(name="parent")
parent.save()
record = Tree(name="record", parent=parent)
record.save()
records = Tree.search([('rec_name', 'in', ['parent'])])
self.assertEqual(records, [parent])
@with_transaction()
def test_search_rec_name_like(self):
"Test search_rec_name like"
pool = Pool()
Tree = pool.get('test.tree')
parent = Tree(name="parent")
parent.save()
record = Tree(name="record", parent=parent)
record.save()
child = Tree(name="child", parent=record)
child.save()
records = Tree.search([('rec_name', 'like', '%record%')])
self.assertEqual(records, [record, child])
@with_transaction()
def test_search_rec_name_like_toplevel(self):
"Test search_rec_name like top-level"
pool = Pool()
Tree = pool.get('test.tree')
parent = Tree(name="parent")
parent.save()
record = Tree(name="record", parent=parent)
record.save()
child = Tree(name="child", parent=record)
child.save()
records = Tree.search([('rec_name', 'like', 'parent / record%')])
self.assertEqual(records, [record, child])
@with_transaction()
def test_search_rec_name_like_lowlevel(self):
"Test search_rec_name like low-level"
pool = Pool()
Tree = pool.get('test.tree')
parent = Tree(name="parent")
parent.save()
record = Tree(name="record", parent=parent)
record.save()
child = Tree(name="child", parent=record)
child.save()
records = Tree.search([('rec_name', 'like', '%record')])
self.assertEqual(records, [record])
@with_transaction()
def test_check_recursion(self):
"Test check_recursion"
pool = Pool()
Tree = pool.get('test.tree')
parent = Tree(name="parent")
parent.save()
record = Tree(name="record", parent=parent)
record.save()
child = Tree(name="child", parent=record)
child.save()
with self.assertRaises(RecursionError):
parent.parent = child
parent.save()
@with_transaction()
def test_check_recursion_polytree(self):
"Test check_recursion on polytree"
pool = Pool()
Polytree = pool.get('test.polytree')
parent1 = Polytree(name="parent1")
parent1.save()
parent2 = Polytree(name="parent2")
parent2.save()
record = Polytree(name="record", parents=[parent1, parent2])
record.save()
child = Polytree(name="child", parents=[record])
child.save()
with self.assertRaises(RecursionError):
parent1.parents = [child]
parent1.save()
def suite():
return unittest.TestLoader().loadTestsFromTestCase(TreeMixinTestCase)