summaryrefslogtreecommitdiff
path: root/bin
diff options
context:
space:
mode:
authorOlivier Dony <odo@openerp.com>2011-02-05 01:43:16 +0100
committerOlivier Dony <odo@openerp.com>2011-02-05 01:43:16 +0100
commit87a1392f994f927735c901d1ca3db86e6bed64b7 (patch)
tree395d7e79040cadd72c6438128c47445c80f57fc4 /bin
parent1eca241d52d7637ad5b7195e12e79997c945a854 (diff)
[IMP] osv: added test for parent_store computations + fix for another edge case
The yaml test create a tree structure and modifies it by copying nodes around and then moving them, checking that the child_of operator keeps working afterwards. This test caught another edge case, as a follow-up to the case of bug 708603 lp bug: https://launchpad.net/bugs/708603 fixed bzr revid: odo@openerp.com-20110205004316-zaw9qqfke1bcw0s7
Diffstat (limited to 'bin')
-rw-r--r--bin/addons/base/test/base_test.yml93
-rw-r--r--bin/osv/fields.py4
2 files changed, 96 insertions, 1 deletions
diff --git a/bin/addons/base/test/base_test.yml b/bin/addons/base/test/base_test.yml
index ab0de1c4e65..336b3be2a82 100644
--- a/bin/addons/base/test/base_test.yml
+++ b/bin/addons/base/test/base_test.yml
@@ -52,3 +52,96 @@
# but other exceptions probably indicate that open() was executed!
assert False, "safe_eval should not allow calling open() builtin"
+
+-
+ "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
+-
+ "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}: |
+ 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
+
diff --git a/bin/osv/fields.py b/bin/osv/fields.py
index 72df0e925ad..153adac6e86 100644
--- a/bin/osv/fields.py
+++ b/bin/osv/fields.py
@@ -501,10 +501,12 @@ class one2many(_column):
elif act[0] == 3:
cr.execute('update '+_table+' set '+self._fields_id+'=null where id=%s', (act[1],))
elif act[0] == 4:
- cr.execute('update '+_table+' set '+self._fields_id+'=%s where id=%s', (id, act[1]))
+ # Must use write() to recompute parent_store structure if needed
+ obj.write(cr, user, act[1], {self._fields_id:id}, context=context or {})
elif act[0] == 5:
cr.execute('update '+_table+' set '+self._fields_id+'=null where '+self._fields_id+'=%s', (id,))
elif act[0] == 6:
+ # Must use write() to recompute parent_store structure if needed
obj.write(cr, user, act[2], {self._fields_id:id}, context=context or {})
ids2 = act[2] or [0]
cr.execute('select id from '+_table+' where '+self._fields_id+'=%s and id <> ALL (%s)', (id,ids2))