[MERGE] addons 16 survey
[odoo/odoo.git] / openerp / tests / test_orm.py
1 import unittest2
2
3 import openerp
4 import common
5
6 UID = common.ADMIN_USER_ID
7 DB = common.DB
8
9 class TestInherits(common.TransactionCase):
10     """ test the behavior of the orm for models that use _inherits;
11         specifically: res.users, that inherits from res.partner
12     """
13
14     def setUp(self):
15         super(TestInherits, self).setUp()
16         self.partner = self.registry('res.partner')
17         self.user = self.registry('res.users')
18
19     def test_create(self):
20         """ creating a user should automatically create a new partner """
21         partners_before = self.partner.search(self.cr, UID, [])
22         foo_id = self.user.create(self.cr, UID, {'name': 'Foo', 'login': 'foo', 'password': 'foo'})
23         foo = self.user.browse(self.cr, UID, foo_id)
24
25         self.assertNotIn(foo.partner_id.id, partners_before)
26
27     def test_create_with_ancestor(self):
28         """ creating a user with a specific 'partner_id' should not create a new partner """
29         par_id = self.partner.create(self.cr, UID, {'name': 'Foo'})
30         partners_before = self.partner.search(self.cr, UID, [])
31         foo_id = self.user.create(self.cr, UID, {'partner_id': par_id, 'login': 'foo', 'password': 'foo'})
32         partners_after = self.partner.search(self.cr, UID, [])
33
34         self.assertEqual(set(partners_before), set(partners_after))
35
36         foo = self.user.browse(self.cr, UID, foo_id)
37         self.assertEqual(foo.name, 'Foo')
38         self.assertEqual(foo.partner_id.id, par_id)
39
40     def test_read(self):
41         """ inherited fields should be read without any indirection """
42         foo_id = self.user.create(self.cr, UID, {'name': 'Foo', 'login': 'foo', 'password': 'foo'})
43         foo_values, = self.user.read(self.cr, UID, [foo_id])
44         partner_id = foo_values['partner_id'][0]
45         partner_values, = self.partner.read(self.cr, UID, [partner_id])
46         self.assertEqual(foo_values['name'], partner_values['name'])
47
48         foo = self.user.browse(self.cr, UID, foo_id)
49         self.assertEqual(foo.name, foo.partner_id.name)
50
51     def test_copy(self):
52         """ copying a user should automatically copy its partner, too """
53         foo_id = self.user.create(self.cr, UID, {'name': 'Foo', 'login': 'foo', 'password': 'foo'})
54         foo_before, = self.user.read(self.cr, UID, [foo_id])
55         bar_id = self.user.copy(self.cr, UID, foo_id, {'login': 'bar', 'password': 'bar'})
56         foo_after, = self.user.read(self.cr, UID, [foo_id])
57
58         self.assertEqual(foo_before, foo_after)
59
60         foo, bar = self.user.browse(self.cr, UID, [foo_id, bar_id])
61         self.assertEqual(bar.login, 'bar')
62         self.assertNotEqual(foo.id, bar.id)
63         self.assertNotEqual(foo.partner_id.id, bar.partner_id.id)
64
65     def test_copy_with_ancestor(self):
66         """ copying a user with 'parent_id' in defaults should not duplicate the partner """
67         foo_id = self.user.create(self.cr, UID, {'name': 'Foo', 'login': 'foo', 'password': 'foo'})
68         par_id = self.partner.create(self.cr, UID, {'name': 'Bar'})
69
70         foo_before, = self.user.read(self.cr, UID, [foo_id])
71         partners_before = self.partner.search(self.cr, UID, [])
72         bar_id = self.user.copy(self.cr, UID, foo_id, {'partner_id': par_id, 'login': 'bar'})
73         foo_after, = self.user.read(self.cr, UID, [foo_id])
74         partners_after = self.partner.search(self.cr, UID, [])
75
76         self.assertEqual(foo_before, foo_after)
77         self.assertEqual(set(partners_before), set(partners_after))
78
79         foo, bar = self.user.browse(self.cr, UID, [foo_id, bar_id])
80         self.assertNotEqual(foo.id, bar.id)
81         self.assertEqual(bar.partner_id.id, par_id)
82         self.assertEqual(bar.login, 'bar', "login is given from copy parameters")
83         self.assertEqual(bar.password, foo.password, "password is given from original record")
84         self.assertEqual(bar.name, 'Bar', "name is given from specific partner")
85
86
87
88 CREATE = lambda values: (0, False, values)
89 UPDATE = lambda id, values: (1, id, values)
90 DELETE = lambda id: (2, id, False)
91 FORGET = lambda id: (3, id, False)
92 LINK_TO = lambda id: (4, id, False)
93 DELETE_ALL = lambda: (5, False, False)
94 REPLACE_WITH = lambda ids: (6, False, ids)
95
96 def sorted_by_id(list_of_dicts):
97     "sort dictionaries by their 'id' field; useful for comparisons"
98     return sorted(list_of_dicts, key=lambda d: d.get('id'))
99
100 class TestO2MSerialization(common.TransactionCase):
101     """ test the orm method 'write' on one2many fields """
102
103     def setUp(self):
104         super(TestO2MSerialization, self).setUp()
105         self.partner = self.registry('res.partner')
106
107     def test_no_command(self):
108         " empty list of commands yields an empty list of records "
109         results = self.partner.resolve_2many_commands(
110             self.cr, UID, 'address', [])
111
112         self.assertEqual(results, [])
113
114     def test_CREATE_commands(self):
115         " returns the VALUES dict as-is "
116         values = [{'foo': 'bar'}, {'foo': 'baz'}, {'foo': 'baq'}]
117         results = self.partner.resolve_2many_commands(
118             self.cr, UID, 'address', map(CREATE, values))
119
120         self.assertEqual(results, values)
121
122     def test_LINK_TO_command(self):
123         " reads the records from the database, records are returned with their ids. "
124         ids = [
125             self.partner.create(self.cr, UID, {'name': 'foo'}),
126             self.partner.create(self.cr, UID, {'name': 'bar'}),
127             self.partner.create(self.cr, UID, {'name': 'baz'})
128         ]
129         commands = map(LINK_TO, ids)
130
131         results = self.partner.resolve_2many_commands(
132             self.cr, UID, 'address', commands, ['name'])
133
134         self.assertEqual(sorted_by_id(results), sorted_by_id([
135             {'id': ids[0], 'name': 'foo'},
136             {'id': ids[1], 'name': 'bar'},
137             {'id': ids[2], 'name': 'baz'}
138         ]))
139
140     def test_bare_ids_command(self):
141         " same as the equivalent LINK_TO commands "
142         ids = [
143             self.partner.create(self.cr, UID, {'name': 'foo'}),
144             self.partner.create(self.cr, UID, {'name': 'bar'}),
145             self.partner.create(self.cr, UID, {'name': 'baz'})
146         ]
147
148         results = self.partner.resolve_2many_commands(
149             self.cr, UID, 'address', ids, ['name'])
150
151         self.assertEqual(sorted_by_id(results), sorted_by_id([
152             {'id': ids[0], 'name': 'foo'},
153             {'id': ids[1], 'name': 'bar'},
154             {'id': ids[2], 'name': 'baz'}
155         ]))
156
157     def test_UPDATE_command(self):
158         " take the in-db records and merge the provided information in "
159         id_foo = self.partner.create(self.cr, UID, {'name': 'foo'})
160         id_bar = self.partner.create(self.cr, UID, {'name': 'bar'})
161         id_baz = self.partner.create(self.cr, UID, {'name': 'baz', 'city': 'tag'})
162
163         results = self.partner.resolve_2many_commands(
164             self.cr, UID, 'address', [
165                 LINK_TO(id_foo),
166                 UPDATE(id_bar, {'name': 'qux', 'city': 'tagtag'}),
167                 UPDATE(id_baz, {'name': 'quux'})
168             ], ['name', 'city'])
169
170         self.assertEqual(sorted_by_id(results), sorted_by_id([
171             {'id': id_foo, 'name': 'foo', 'city': False},
172             {'id': id_bar, 'name': 'qux', 'city': 'tagtag'},
173             {'id': id_baz, 'name': 'quux', 'city': 'tag'}
174         ]))
175
176     def test_DELETE_command(self):
177         " deleted records are not returned at all. "
178         ids = [
179             self.partner.create(self.cr, UID, {'name': 'foo'}),
180             self.partner.create(self.cr, UID, {'name': 'bar'}),
181             self.partner.create(self.cr, UID, {'name': 'baz'})
182         ]
183         commands = [DELETE(ids[0]), DELETE(ids[1]), DELETE(ids[2])]
184
185         results = self.partner.resolve_2many_commands(
186             self.cr, UID, 'address', commands, ['name'])
187
188         self.assertEqual(results, [])
189
190     def test_mixed_commands(self):
191         ids = [
192             self.partner.create(self.cr, UID, {'name': name})
193             for name in ['NObar', 'baz', 'qux', 'NOquux', 'NOcorge', 'garply']
194         ]
195
196         results = self.partner.resolve_2many_commands(
197             self.cr, UID, 'address', [
198                 CREATE({'name': 'foo'}),
199                 UPDATE(ids[0], {'name': 'bar'}),
200                 LINK_TO(ids[1]),
201                 DELETE(ids[2]),
202                 UPDATE(ids[3], {'name': 'quux',}),
203                 UPDATE(ids[4], {'name': 'corge'}),
204                 CREATE({'name': 'grault'}),
205                 LINK_TO(ids[5])
206             ], ['name'])
207
208         self.assertEqual(sorted_by_id(results), sorted_by_id([
209             {'name': 'foo'},
210             {'id': ids[0], 'name': 'bar'},
211             {'id': ids[1], 'name': 'baz'},
212             {'id': ids[3], 'name': 'quux'},
213             {'id': ids[4], 'name': 'corge'},
214             {'name': 'grault'},
215             {'id': ids[5], 'name': 'garply'}
216         ]))
217
218     def test_LINK_TO_pairs(self):
219         "LINK_TO commands can be written as pairs, instead of triplets"
220         ids = [
221             self.partner.create(self.cr, UID, {'name': 'foo'}),
222             self.partner.create(self.cr, UID, {'name': 'bar'}),
223             self.partner.create(self.cr, UID, {'name': 'baz'})
224         ]
225         commands = map(lambda id: (4, id), ids)
226
227         results = self.partner.resolve_2many_commands(
228             self.cr, UID, 'address', commands, ['name'])
229
230         self.assertEqual(sorted_by_id(results), sorted_by_id([
231             {'id': ids[0], 'name': 'foo'},
232             {'id': ids[1], 'name': 'bar'},
233             {'id': ids[2], 'name': 'baz'}
234         ]))
235
236     def test_singleton_commands(self):
237         "DELETE_ALL can appear as a singleton"
238         results = self.partner.resolve_2many_commands(
239             self.cr, UID, 'address', [DELETE_ALL()], ['name'])
240
241         self.assertEqual(results, [])
242
243 # vim:expandtab:smartindent:tabstop=4:softtabstop=4:shiftwidth=4: