ooor 1.3.0 → 1.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/spec/ooor_spec.rb +356 -0
- metadata +3 -2
data/spec/ooor_spec.rb
ADDED
@@ -0,0 +1,356 @@
|
|
1
|
+
require "lib/ooor.rb"
|
2
|
+
|
3
|
+
#RSpec executable specification; see http://rspec.info/ for more information.
|
4
|
+
#Run the file with the rspec command from the rspec gem
|
5
|
+
describe Ooor do
|
6
|
+
before(:all) do
|
7
|
+
@url = 'http://localhost:8069/xmlrpc'
|
8
|
+
@db_password = 'admin'
|
9
|
+
@username = 'admin'
|
10
|
+
@password = 'admin'
|
11
|
+
@database = 'ooor_test'
|
12
|
+
@ooor = Ooor.new(:url => @url, :username => @username, :admin => @password)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should keep quiet if no database is mentioned" do
|
16
|
+
@ooor.loaded_models.should be_empty
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be able to list databases" do
|
20
|
+
@ooor.list.should be_kind_of(Array)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should be able to create a new database with demo data" do
|
24
|
+
unless @ooor.list.index(@database)
|
25
|
+
@ooor.create(@db_password, @database)
|
26
|
+
end
|
27
|
+
@ooor.list.index(@database).should_not be_nil
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
describe "Configure existing database" do
|
32
|
+
before(:all) do
|
33
|
+
@ooor = Ooor.new(:url => @url, :username => @username, :admin => @password, :database => @database)
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should be able to load a profile" do
|
37
|
+
manufacturing_module_id = IrModuleModule.search([['name','=', 'profile_manufacturing']])[0]
|
38
|
+
unless IrModuleModule.find(manufacturing_module_id).state == "installed"
|
39
|
+
w = @ooor.old_wizard_step('base_setup.base_setup')
|
40
|
+
w.company(:profile => manufacturing_module_id)
|
41
|
+
w.update(:name => 'Akretion.com', :state_id => false)
|
42
|
+
w.finish
|
43
|
+
@ooor.load_models
|
44
|
+
@ooor.loaded_models.should_not be_empty
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should be able to configure the database" do
|
49
|
+
chart_module_id = IrModuleModule.search([['category_id', '=', 'Account Charts'], ['name','=', 'l10n_fr']])[0]
|
50
|
+
unless IrModuleModule.find(chart_module_id).state == "installed"
|
51
|
+
w2 = @ooor.const_get('account.config.wizard').create(:charts => chart_module_id)
|
52
|
+
w2.action_create
|
53
|
+
w3 = @ooor.const_get('wizard.multi.charts.accounts').create
|
54
|
+
w3.action_create
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
describe "Do operations on configured database" do
|
61
|
+
before(:all) do
|
62
|
+
@ooor = Ooor.new(:url => @url, :username => @username, :admin => @password, :database => @database,
|
63
|
+
:models => ['res.user', 'res.partner', 'product.product', 'sale.order', 'account.invoice', 'product.category', 'stock.move', 'ir.ui.menu'])
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "Finders operations" do
|
67
|
+
|
68
|
+
it "should be able to find data by id" do
|
69
|
+
p = ProductProduct.find(1)
|
70
|
+
p.should_not be_nil
|
71
|
+
l = ProductProduct.find([1,2])
|
72
|
+
l.size.should == 2
|
73
|
+
a = AccountInvoice.find(1)
|
74
|
+
a.should_not be_nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should load required models on the fly" do
|
78
|
+
SaleOrder.find(1).shop_id.should be_kind_of(SaleShop)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should be able to specify the fields to read" do
|
82
|
+
p = ProductProduct.find(1, :fields=>["state", "id"])
|
83
|
+
p.should_not be_nil
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should be able to find using ir.model.data absolute ids" do
|
87
|
+
p = ProductProduct.find('product_product_pc1')
|
88
|
+
p.should_not be_nil
|
89
|
+
p = ProductProduct.find('product.product_product_pc1')#module scoping is optionnal
|
90
|
+
p.should_not be_nil
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should be able to use OpenERP domains" do
|
94
|
+
partners = ResPartner.find(:all, :domain=>[['supplier', '=', 1],['active','=',1]], :fields=>["id", "name"])
|
95
|
+
partners.should_not be_empty
|
96
|
+
products = ProductProduct.find(:all, :domain=>[['categ_id','=',1],'|',['name', '=', 'PC1'],['name','=','PC2']])
|
97
|
+
products.should be_kind_of(Array)
|
98
|
+
end
|
99
|
+
|
100
|
+
it "should mimic ActiveResource scoping" do
|
101
|
+
partners = ResPartner.find(:all, :params => {:supplier => true})
|
102
|
+
partners.should_not be_empty
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should support OpenERP context in finders" do
|
106
|
+
p = ProductProduct.find(1, :context => {:my_key => 'value'})
|
107
|
+
p.should_not be_nil
|
108
|
+
end
|
109
|
+
|
110
|
+
it "should support OpenERP search method" do
|
111
|
+
partners = ResPartner.search([['name', 'ilike', 'a']], 0, 2)
|
112
|
+
partners.should_not be_empty
|
113
|
+
end
|
114
|
+
|
115
|
+
it "should cast dates properly from OpenERP to Ruby" do
|
116
|
+
o = SaleOrder.find(1)
|
117
|
+
o.date_order.should be_kind_of(Date)
|
118
|
+
m = StockMove.find(1)
|
119
|
+
m.date.should be_kind_of(Time)
|
120
|
+
end
|
121
|
+
|
122
|
+
it "should be able to call any Class method" do
|
123
|
+
ResPartner.name_search('ax', [], 'ilike', {}).should_not be_nil
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
describe "Relations reading" do
|
129
|
+
it "should read many2one relations" do
|
130
|
+
o = SaleOrder.find(1)
|
131
|
+
o.partner_id.should be_kind_of(ResPartner)
|
132
|
+
p = ProductProduct.find(1) #inherited via product template
|
133
|
+
p.categ_id.should be_kind_of(ProductCategory)
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should read one2many relations" do
|
137
|
+
o = SaleOrder.find(1)
|
138
|
+
o.order_line.each do |line|
|
139
|
+
line.should be_kind_of(SaleOrderLine)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
it "should read many2many relations" do
|
144
|
+
SaleOrder.find(1).order_line[1].invoice_ids.should be_kind_of(Array)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should read polymorphic references" do
|
148
|
+
IrUiMenu.find(:first, :domain => [['name', '=', 'Partners'], ['parent_id', '!=', false]]).action.should be_kind_of(IrActionsAct_window)
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
describe "Basic creations" do
|
153
|
+
it "should be able to create a product" do
|
154
|
+
p = ProductProduct.create(:name => "testProduct1", :categ_id => 1)
|
155
|
+
ProductProduct.find(p.id).categ_id.id.should == 1
|
156
|
+
p = ProductProduct.new(:name => "testProduct1")
|
157
|
+
p.categ_id = 1
|
158
|
+
p.save
|
159
|
+
p.categ_id.id.should == 1
|
160
|
+
end
|
161
|
+
|
162
|
+
it "should be able to create an order" do
|
163
|
+
o = SaleOrder.create(:partner_id => ResPartner.search([['name', 'ilike', 'Agrolait']])[0],
|
164
|
+
:partner_order_id => 1, :partner_invoice_id => 1, :partner_shipping_id => 1, :pricelist_id => 1)
|
165
|
+
o.id.should be_kind_of(Integer)
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should be able to to create an invoice" do
|
169
|
+
i = AccountInvoice.new(:origin => 'ooor_test')
|
170
|
+
partner_id = ResPartner.search([['name', 'ilike', 'Agrolait']])[0]
|
171
|
+
i.on_change('onchange_partner_id', :partner_id, partner_id, 'out_invoice', partner_id, false, false)
|
172
|
+
i.save
|
173
|
+
i.id.should be_kind_of(Integer)
|
174
|
+
end
|
175
|
+
|
176
|
+
it "should be able to call on_change" do
|
177
|
+
o = SaleOrder.new
|
178
|
+
partner_id = ResPartner.search([['name', 'ilike', 'Agrolait']])[0]
|
179
|
+
o.on_change('onchange_partner_id', :partner_id, partner_id, partner_id)
|
180
|
+
o.save
|
181
|
+
line = SaleOrderLine.new(:order_id => o.id)
|
182
|
+
product_id = 1
|
183
|
+
pricelist_id = 1
|
184
|
+
product_uom_qty = 1
|
185
|
+
line.on_change('product_id_change', :product_id, product_id, pricelist_id, product_id, product_uom_qty, false, 1, false, false, o.partner_id.id, 'en_US', true, false, false, false)
|
186
|
+
line.save
|
187
|
+
SaleOrder.find(o.id).order_line.size.should == 1
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should use default fields on creation" do
|
191
|
+
p = ProductProduct.new
|
192
|
+
p.sale_delay.should be_kind_of(Integer)
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "Basic updates" do
|
197
|
+
it "should cast properly from Ruby to OpenERP" do
|
198
|
+
o = SaleOrder.find(1).copy()
|
199
|
+
o.date_order = 2.days.ago
|
200
|
+
o.save
|
201
|
+
end
|
202
|
+
|
203
|
+
it "should be able to reload resource" do
|
204
|
+
s = SaleOrder.find(1)
|
205
|
+
s.reload.should be_kind_of(SaleOrder)
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
describe "Relations assignations" do
|
210
|
+
it "should be able to do product.taxes_id = [1,2]" do
|
211
|
+
p = ProductProduct.find(1)
|
212
|
+
p.taxes_id = [1, 2]
|
213
|
+
p.save
|
214
|
+
p.taxes_id[0].id.should == 1
|
215
|
+
p.taxes_id[1].id.should == 2
|
216
|
+
end
|
217
|
+
|
218
|
+
it "should be able to create one2many relations on the fly" do
|
219
|
+
so = SaleOrder.new
|
220
|
+
partner_id = ResPartner.search([['name', 'ilike', 'Agrolait']])[0]
|
221
|
+
so.on_change('onchange_partner_id', :partner_id, partner_id, partner_id) #auto-complete the address and other data based on the partner
|
222
|
+
so.order_line = [SaleOrderLine.new(:name => 'sl1', :product_id => 1, :price_unit => 21, :product_uom => 1), SaleOrderLine.new(:name => 'sl2', :product_id => 1, :price_unit => 21, :product_uom => 1)] #create one order line
|
223
|
+
so.save
|
224
|
+
so.amount_total.should == 42.0
|
225
|
+
end
|
226
|
+
|
227
|
+
it "should be able to assign a polymorphic relation" do
|
228
|
+
#TODO implement!
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
describe "Old wizard management" do
|
233
|
+
it "should be possible to pay an invoice in one step" do
|
234
|
+
inv = AccountInvoice.find(1).copy() #creates a draft invoice
|
235
|
+
inv.state.should == "draft"
|
236
|
+
inv.wkf_action('invoice_open')
|
237
|
+
inv.state.should == "open"
|
238
|
+
wizard = inv.old_wizard_step('account.invoice.pay') #tip: you can inspect the wizard fields, arch and datas
|
239
|
+
inv = wizard.reconcile({:journal_id => 6, :name =>"from_rails"}) #if you want to pay all; will give you a reloaded invoice
|
240
|
+
inv.state.should == "paid"
|
241
|
+
end
|
242
|
+
|
243
|
+
it "should be possible to pay an invoice using an intermediary wizard step" do
|
244
|
+
inv = AccountInvoice.find(1).copy() #creates a draft invoice
|
245
|
+
inv.wkf_action('invoice_open')
|
246
|
+
wizard = inv.old_wizard_step('account.invoice.pay')
|
247
|
+
wizard.writeoff_check({"amount" => inv.amount_total - 1, "journal_id" => AccountJournal.search([['code', 'ilike', 'CHK']])[0], "name" =>'from_rails'}) #use the button name as the wizard method
|
248
|
+
inv = wizard.reconcile({:name => 'from_ooor', :writeoff_acc_id => 13, :writeoff_journal_id => AccountJournal.search([['code', 'ilike', 'EXJ']])[0], :journal_id => AccountJournal.search([['code', 'ilike', 'CHK']])[0]})
|
249
|
+
inv.state.should == "paid"
|
250
|
+
end
|
251
|
+
|
252
|
+
it "should be possible to call resource actions and workflow actions" do
|
253
|
+
s = SaleOrder.find(1).copy()
|
254
|
+
s.wkf_action('order_confirm')
|
255
|
+
s.wkf_action('manual_invoice')
|
256
|
+
i = s.invoice_ids[0]
|
257
|
+
i.journal_id.update_posted = true
|
258
|
+
i.journal_id.save
|
259
|
+
i.wkf_action('invoice_open')
|
260
|
+
i.wkf_action('invoice_cancel')
|
261
|
+
i.action_cancel_draft
|
262
|
+
s.reload.state.should == "invoice_except"
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
describe "New style wizards" do
|
267
|
+
#already tested, see database configuration test
|
268
|
+
end
|
269
|
+
|
270
|
+
describe "Delete resources" do
|
271
|
+
it "should be able to call unlink" do
|
272
|
+
ids = ProductProduct.search([['name', 'ilike', 'testProduct']])
|
273
|
+
ProductProduct.unlink(ids)
|
274
|
+
end
|
275
|
+
|
276
|
+
it "should be able to destroy loaded business objects" do
|
277
|
+
orders = SaleOrder.find(:all, :domain => [['origin', 'ilike', 'ooor_test']])
|
278
|
+
orders.each {|order| order.destroy}
|
279
|
+
|
280
|
+
invoices = AccountInvoice.find(:all, :domain => [['origin', 'ilike', 'ooor_test']])
|
281
|
+
invoices.each {|inv| inv.destroy}
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
end
|
286
|
+
|
287
|
+
|
288
|
+
describe "Offer Web Client core features" do
|
289
|
+
before(:all) do
|
290
|
+
@ooor = Ooor.new(:url => @url, :username => @username, :admin => @password, :database => @database,
|
291
|
+
:models => ['res.user', 'res.partner', 'product.product', 'sale.order', 'account.invoice', 'product.category', 'stock.move', 'ir.ui.menu'])
|
292
|
+
end
|
293
|
+
|
294
|
+
it "should find the default user action" do
|
295
|
+
@ooor.get_init_menu(1)
|
296
|
+
end
|
297
|
+
|
298
|
+
it "should be able to find the sub-menus of a menu" do
|
299
|
+
menu = IrUiMenu.find(:first, :domain => [['name', '=', 'Partners'], ['parent_id', '!=', false]])
|
300
|
+
menu.child_id.each do |sub_menu|
|
301
|
+
sub_menu.should be_kind_of(IrUiMenu)
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
it "should retrieve the action of a menu" do
|
306
|
+
IrUiMenu.find(:first, :domain => [['name', '=', 'Partners'], ['parent_id', '!=', false]]).action.should be_kind_of(IrActionsAct_window)
|
307
|
+
end
|
308
|
+
|
309
|
+
it "should be able to open a list view of a menu action" do
|
310
|
+
@ooor.menu_class.find(:first, :domain => [['name', '=', 'Partners'], ['parent_id', '!=', false]]).action.open('tree')
|
311
|
+
end
|
312
|
+
|
313
|
+
it "should be able to open a form view of a menu action" do
|
314
|
+
@ooor.menu_class.find(:first, :domain => [['name', '=', 'Partners'], ['parent_id', '!=', false]]).action.open('form', [1])
|
315
|
+
end
|
316
|
+
end
|
317
|
+
|
318
|
+
|
319
|
+
describe "UML features" do
|
320
|
+
before(:all) do
|
321
|
+
@ooor = Ooor.new(:url => @url, :username => @username, :admin => @password, :database => @database,
|
322
|
+
:models => ['res.user', 'res.partner', 'product.product', 'sale.order', 'account.invoice', 'product.category', 'stock.move', 'ir.ui.menu'])
|
323
|
+
end
|
324
|
+
|
325
|
+
it "should be able to draw the UML of any class" do
|
326
|
+
SaleOrder.print_uml.should be_true
|
327
|
+
end
|
328
|
+
|
329
|
+
it "should be able to draw the UML of several classes" do
|
330
|
+
UML.print_uml([SaleOrder, SaleShop]).should be_true
|
331
|
+
end
|
332
|
+
|
333
|
+
it "should accept rendering options" do
|
334
|
+
SaleOrder.print_uml(:all, :detailed).should be_true
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
|
339
|
+
describe "Multi-instance and class name scoping" do
|
340
|
+
before(:all) do
|
341
|
+
@ooor1 = Ooor.new(:url => @url, :username => @username, :admin => @password, :database => @database, :scope_prefix => 'OE1', :models => ['product.product'])
|
342
|
+
@ooor2 = Ooor.new(:url => @url, :username => @username, :admin => @password, :database => @database, :scope_prefix => 'OE2', :models => ['product.product'])
|
343
|
+
end
|
344
|
+
|
345
|
+
it "should still be possible to find a ressource using an absolute id" do
|
346
|
+
OE1::ProductProduct.find('product_product_pc1').should be_kind_of(OE1::ProductProduct)
|
347
|
+
end
|
348
|
+
|
349
|
+
it "should be able to read in one instance and write in an other" do
|
350
|
+
p1 = OE1::ProductProduct.find(1)
|
351
|
+
p2 = OE2::ProductProduct.create(:name => p1.name, :categ_id => p1.categ_id.id)
|
352
|
+
p2.should be_kind_of(OE2::ProductProduct)
|
353
|
+
end
|
354
|
+
end
|
355
|
+
|
356
|
+
end
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 1
|
7
7
|
- 3
|
8
|
-
-
|
9
|
-
version: 1.3.
|
8
|
+
- 1
|
9
|
+
version: 1.3.1
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Raphael Valyi - www.akretion.com
|
@@ -52,6 +52,7 @@ files:
|
|
52
52
|
- lib/app/ui/client_base.rb
|
53
53
|
- lib/app/ui/form_model.rb
|
54
54
|
- lib/app/ui/menu.rb
|
55
|
+
- spec/ooor_spec.rb
|
55
56
|
has_rdoc: true
|
56
57
|
homepage: http://github.com/rvalyi/ooor
|
57
58
|
licenses: []
|