ooor 1.9.2 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +23 -71
- data/Rakefile +5 -0
- data/bin/ooor +1 -0
- data/lib/ooor.rb +87 -129
- data/lib/ooor/associations.rb +64 -0
- data/lib/ooor/base.rb +218 -0
- data/lib/{app/models → ooor}/base64.rb +0 -0
- data/lib/ooor/connection.rb +37 -0
- data/lib/ooor/errors.rb +120 -0
- data/lib/ooor/field_methods.rb +153 -0
- data/lib/{app → ooor}/helpers/core_helpers.rb +2 -2
- data/lib/ooor/locale.rb +13 -0
- data/lib/ooor/mini_active_resource.rb +94 -0
- data/lib/ooor/model_registry.rb +19 -0
- data/lib/ooor/naming.rb +73 -0
- data/lib/ooor/rack.rb +114 -0
- data/lib/ooor/railtie.rb +41 -0
- data/lib/ooor/reflection.rb +537 -0
- data/lib/ooor/reflection_ooor.rb +92 -0
- data/lib/{app/models → ooor}/relation.rb +61 -22
- data/lib/ooor/relation/finder_methods.rb +113 -0
- data/lib/ooor/report.rb +53 -0
- data/lib/{app/models → ooor}/serialization.rb +18 -6
- data/lib/ooor/services.rb +133 -0
- data/lib/ooor/session.rb +120 -0
- data/lib/ooor/session_handler.rb +63 -0
- data/lib/ooor/transport.rb +34 -0
- data/lib/ooor/transport/json_client.rb +53 -0
- data/lib/ooor/transport/xml_rpc_client.rb +15 -0
- data/lib/ooor/type_casting.rb +193 -0
- data/lib/ooor/version.rb +8 -0
- data/spec/helpers/test_helper.rb +11 -0
- data/spec/install_nightly.sh +17 -0
- data/spec/ooor_spec.rb +197 -79
- data/spec/requirements.txt +19 -0
- metadata +58 -20
- data/lib/app/models/client_xmlrpc.rb +0 -34
- data/lib/app/models/open_object_resource.rb +0 -486
- data/lib/app/models/services.rb +0 -47
- data/lib/app/models/type_casting.rb +0 -134
- data/lib/app/models/uml.rb +0 -210
- data/lib/app/ui/action_window.rb +0 -96
- data/lib/app/ui/client_base.rb +0 -36
- data/lib/app/ui/form_model.rb +0 -88
- data/ooor.yml +0 -27
data/lib/ooor/version.rb
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
# Install the nightly version of OpenERP
|
3
|
+
sudo apt-get -ym install python-dateutil python-docutils python-feedparser python-gdata python-jinja2 python-ldap python-lxml python-mako python-mock python-openid python-psycopg2 python-psutil python-pybabel python-pychart python-pydot python-pyparsing python-reportlab python-simplejson python-tz python-unittest2 python-vatnumber python-vobject python-webdav python-werkzeug python-xlwt python-yaml python-zsi python-imaging
|
4
|
+
wget http://nightly.openerp.com/7.0/nightly/src/openerp-7.0-latest.tar.gz
|
5
|
+
mkdir -p src
|
6
|
+
tar -xf openerp-7.0-latest.tar.gz -C src
|
7
|
+
|
8
|
+
for f in ./src/*
|
9
|
+
do
|
10
|
+
echo "$f" | grep -Eq '^\./abc.[0-9]+$' && continue
|
11
|
+
echo "Something with $f here"
|
12
|
+
done
|
13
|
+
|
14
|
+
mv $f openerp
|
15
|
+
rm -rf ./src
|
16
|
+
cd openerp
|
17
|
+
python setup.py --quiet install
|
data/spec/ooor_spec.rb
CHANGED
@@ -3,13 +3,17 @@
|
|
3
3
|
# Author: Raphaël Valyi
|
4
4
|
# Licensed under the MIT license, see MIT-LICENSE file
|
5
5
|
|
6
|
+
if ENV["CI"]
|
7
|
+
require 'coveralls'
|
8
|
+
Coveralls.wear!
|
9
|
+
end
|
6
10
|
require File.dirname(__FILE__) + '/../lib/ooor'
|
7
11
|
|
8
12
|
#RSpec executable specification; see http://rspec.info/ for more information.
|
9
13
|
#Run the file with the rspec command from the rspec gem
|
10
14
|
describe Ooor do
|
11
15
|
before(:all) do
|
12
|
-
@url = 'http://localhost:
|
16
|
+
@url = 'http://localhost:8069/xmlrpc'
|
13
17
|
@db_password = 'admin'
|
14
18
|
@username = 'admin'
|
15
19
|
@password = 'admin'
|
@@ -18,21 +22,20 @@ describe Ooor do
|
|
18
22
|
end
|
19
23
|
|
20
24
|
it "should keep quiet if no database is mentioned" do
|
21
|
-
@ooor.
|
25
|
+
@ooor.models.should be_empty
|
22
26
|
end
|
23
27
|
|
24
28
|
it "should be able to list databases" do
|
25
|
-
@ooor.list.should be_kind_of(Array)
|
29
|
+
@ooor.db.list.should be_kind_of(Array)
|
26
30
|
end
|
27
31
|
|
28
32
|
it "should be able to create a new database with demo data" do
|
29
|
-
unless @ooor.list.index(@database)
|
30
|
-
@ooor.create(@db_password, @database)
|
33
|
+
unless @ooor.db.list.index(@database)
|
34
|
+
@ooor.db.create(@db_password, @database)
|
31
35
|
end
|
32
|
-
@ooor.list.index(@database).should_not be_nil
|
36
|
+
@ooor.db.list.index(@database).should_not be_nil
|
33
37
|
end
|
34
38
|
|
35
|
-
|
36
39
|
describe "Configure existing database" do
|
37
40
|
before(:all) do
|
38
41
|
@ooor = Ooor.new(:url => @url, :username => @username, :password => @password, :database => @database)
|
@@ -49,40 +52,70 @@ describe Ooor do
|
|
49
52
|
wizard = BaseModuleUpgrade.create
|
50
53
|
wizard.upgrade_module
|
51
54
|
@ooor.load_models
|
52
|
-
|
53
|
-
# config5.action_next
|
54
|
-
@ooor.loaded_models.should_not be_empty
|
55
|
+
@ooor.models.keys.should_not be_empty
|
55
56
|
end
|
56
57
|
|
57
58
|
it "should be able to configure the database" do
|
58
|
-
# chart_module_id = IrModuleModule.search([['category_id', '=', 'Account Charts'], ['name','=', 'l10n_fr']])[0]
|
59
59
|
if AccountTax.search.empty?
|
60
60
|
w1 = @ooor.const_get('account.installer').create(:charts => "configurable")
|
61
61
|
w1.action_next
|
62
62
|
w1 = @ooor.const_get('wizard.multi.charts.accounts').create(:charts => "configurable", :code_digits => 2)
|
63
63
|
w1.action_next
|
64
|
-
# w3 = @ooor.const_get('wizard.multi.charts.accounts').create
|
65
|
-
# w3.action_create
|
66
64
|
end
|
67
65
|
end
|
68
66
|
end
|
69
67
|
|
70
|
-
|
71
68
|
describe "Do operations on configured database" do
|
72
69
|
before(:all) do
|
73
70
|
@ooor = Ooor.new(:url => @url, :username => @username, :password => @password, :database => @database,
|
74
|
-
:models => ['res.user', 'res.partner', 'product.product', 'sale.order', 'account.invoice', 'product.category', 'stock.move', 'ir.ui.menu'])
|
71
|
+
:models => ['res.user', 'res.partner', 'product.product', 'sale.order', 'account.invoice', 'product.category', 'stock.move', 'ir.ui.menu', 'ir.module.module'])
|
75
72
|
end
|
76
73
|
|
77
74
|
describe "Finders operations" do
|
78
|
-
|
79
75
|
it "should be able to find data by id" do
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
76
|
+
product1 = ProductProduct.find(1)
|
77
|
+
expect(product1).not_to be_nil
|
78
|
+
expect(ProductProduct.find(:first).attributes).to eq product1.attributes
|
79
|
+
end
|
80
|
+
|
81
|
+
it "fetches data given an array of ids" do
|
82
|
+
products = ProductProduct.find([1,2])
|
83
|
+
products.size.should == 2
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should fetches data given an implicit array of ids" do
|
87
|
+
products = ProductProduct.find(1,2)
|
88
|
+
products.size.should == 2
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should fetches data even if an id is passed as a string (web usage)" do
|
92
|
+
product = ProductProduct.find("1")
|
93
|
+
product.should be_kind_of(ProductProduct)
|
94
|
+
end
|
95
|
+
|
96
|
+
it "should fetches data even with array containing string" do
|
97
|
+
products = ProductProduct.find(["1", 2])
|
98
|
+
products.size.should == 2
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should fetches data even with an implicit array containing string" do
|
102
|
+
products = ProductProduct.find("1", 2)
|
103
|
+
products.size.should == 2
|
104
|
+
end
|
105
|
+
|
106
|
+
it "should accept hash domain in find" do
|
107
|
+
products = ProductProduct.find(active: true)
|
108
|
+
products.should be_kind_of(Array)
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should accept array domain in find" do
|
112
|
+
products = ProductProduct.find(['active', '=', true])
|
113
|
+
products.should be_kind_of(Array)
|
114
|
+
end
|
115
|
+
|
116
|
+
it "fetches last data created last" do
|
117
|
+
last_product_id = ProductProduct.search([], 0, 1, "create_date DESC").first
|
118
|
+
expect(ProductProduct.find(:last).id).to eq last_product_id
|
86
119
|
end
|
87
120
|
|
88
121
|
it "should load required models on the fly" do
|
@@ -125,6 +158,13 @@ describe Ooor do
|
|
125
158
|
products.should be_kind_of(Array)
|
126
159
|
end
|
127
160
|
|
161
|
+
it "should support writing with a context" do
|
162
|
+
p = ProductProduct.find(1, fields: ['name'])
|
163
|
+
ProductProduct.write(1, {name: p.name}, {lang: 'en_US'})
|
164
|
+
ProductProduct.write(1, {name: p.name}, lang: 'en_US')
|
165
|
+
p.write({name: p.name}, lang: 'en_US')
|
166
|
+
end
|
167
|
+
|
128
168
|
it "should support OpenERP search method" do
|
129
169
|
partners = ResPartner.search([['name', 'ilike', 'a']], 0, 2)
|
130
170
|
partners.should_not be_empty
|
@@ -140,7 +180,6 @@ describe Ooor do
|
|
140
180
|
it "should be able to call any Class method" do
|
141
181
|
ResPartner.name_search('ax', [], 'ilike', {}).should_not be_nil
|
142
182
|
end
|
143
|
-
|
144
183
|
end
|
145
184
|
|
146
185
|
describe "Relations reading" do
|
@@ -188,21 +227,15 @@ describe Ooor do
|
|
188
227
|
p.categ_id.id.should == 1
|
189
228
|
end
|
190
229
|
|
191
|
-
it "should support
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
products = ProductProduct.find([1, 2, 3], :context => {:lang => 'en_US', :user_id=>1, :password => 'admin'})
|
201
|
-
p = products[0]
|
202
|
-
p.object_session[:context][:lang].should == 'en_US'
|
203
|
-
p.object_session[:user_id].should == 1
|
204
|
-
p.object_session[:password].should == "admin"
|
205
|
-
p.save
|
230
|
+
it "should support read on new objects" do
|
231
|
+
u = ResUsers.new({name: "joe", login: "joe"})
|
232
|
+
u.id.should be_nil
|
233
|
+
u.name.should == "joe"
|
234
|
+
u.email.should == nil
|
235
|
+
u.save
|
236
|
+
u.id.should_not be_nil
|
237
|
+
u.name.should == "joe"
|
238
|
+
u.destroy
|
206
239
|
end
|
207
240
|
|
208
241
|
it "should be able to create an order" do
|
@@ -286,9 +319,67 @@ describe Ooor do
|
|
286
319
|
end
|
287
320
|
end
|
288
321
|
|
289
|
-
describe "
|
322
|
+
describe "Rails associations methods" do
|
323
|
+
it "should read m2o id with an extra _id suffix" do
|
324
|
+
p = ProductProduct.find(1)
|
325
|
+
p.categ_id_id.should be_kind_of(Integer)
|
326
|
+
end
|
327
|
+
|
328
|
+
it "should read o2m with an extra _ids suffix" do
|
329
|
+
so = SaleOrder.find :first
|
330
|
+
so.order_line_ids.should be_kind_of(Array)
|
331
|
+
end
|
332
|
+
|
333
|
+
it "should read m2m with an extra _ids suffix" do
|
334
|
+
p = ProductProduct.find(1)
|
335
|
+
p.taxes_id_ids.should be_kind_of(Array)
|
336
|
+
end
|
337
|
+
|
338
|
+
it "should support Rails nested attributes" do
|
339
|
+
so = SaleOrder.find :first
|
340
|
+
so.respond_to?(:order_line_attributes).should be_true
|
341
|
+
so.respond_to?(:order_line_attributes=).should be_true
|
342
|
+
end
|
343
|
+
|
344
|
+
it "should be able to call build upon a o2m association" do
|
345
|
+
so = SaleOrder.find :first
|
346
|
+
so.order_line.build().should be_kind_of(SaleOrderLine)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
describe "Fields validations" do
|
351
|
+
it "should point to invalid fields" do
|
352
|
+
p = ProductProduct.find :first
|
353
|
+
p.ean13 = 'invalid_ean'
|
354
|
+
p.save.should == false
|
355
|
+
p.errors.messages[:ean13].should_not be_nil
|
356
|
+
end
|
357
|
+
end
|
358
|
+
|
359
|
+
describe "ARel emulation" do
|
360
|
+
it "should have an 'all' method" do
|
361
|
+
ResUsers.all.should be_kind_of(Array)
|
362
|
+
end
|
363
|
+
|
364
|
+
it "should be ready for Kaminari pagination via ARel scoping" do
|
365
|
+
num = 2
|
366
|
+
default_per_page = 5
|
367
|
+
collection = ProductProduct.limit(default_per_page).offset(default_per_page * ([num.to_i, 1].max - 1))
|
368
|
+
collection.all(fields:['name']).should be_kind_of(Array)
|
369
|
+
collection.all.size.should == 5
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
describe "report support" do
|
374
|
+
it "should print reports" do
|
375
|
+
base_id = IrModuleModule.search(name:'base')[0]
|
376
|
+
IrModuleModule.get_report_data("ir.module.reference", [base_id], 'pdf', {}).should be_kind_of(Array)
|
377
|
+
end
|
378
|
+
end
|
379
|
+
|
380
|
+
describe "wizard management" do
|
290
381
|
it "should be possible to pay an invoice in one step" do
|
291
|
-
inv = AccountInvoice.find(:
|
382
|
+
inv = AccountInvoice.find(:first).copy() # creates a draft invoice
|
292
383
|
inv.state.should == "draft"
|
293
384
|
inv.wkf_action('invoice_open')
|
294
385
|
inv.state.should == "open"
|
@@ -297,10 +388,7 @@ describe Ooor do
|
|
297
388
|
voucher.save
|
298
389
|
voucher.wkf_action 'proforma_voucher'
|
299
390
|
|
300
|
-
#wizard = inv.old_wizard_step('account.invoice.pay') #tip: you can inspect the wizard fields, arch and datas
|
301
|
-
#inv = wizard.reconcile({:journal_id => 6, :name =>"from_rails"}) #if you want to pay all; will give you a reloaded invoice
|
302
391
|
inv.reload
|
303
|
-
# inv.state.should == "paid" #TODO!!
|
304
392
|
end
|
305
393
|
|
306
394
|
it "should be possible to call resource actions and workflow actions" do
|
@@ -317,10 +405,6 @@ describe Ooor do
|
|
317
405
|
end
|
318
406
|
end
|
319
407
|
|
320
|
-
describe "New style wizards" do
|
321
|
-
#already tested, see database configuration test
|
322
|
-
end
|
323
|
-
|
324
408
|
describe "Delete resources" do
|
325
409
|
it "should be able to call unlink" do
|
326
410
|
ids = ProductProduct.search([['name', 'ilike', 'testProduct']])
|
@@ -338,58 +422,59 @@ describe Ooor do
|
|
338
422
|
|
339
423
|
end
|
340
424
|
|
341
|
-
|
342
|
-
describe "Offer Web Client core features" do
|
425
|
+
describe "Object context abilities" do
|
343
426
|
before(:all) do
|
344
|
-
@ooor = Ooor.new(:url => @url, :
|
345
|
-
:models => ['res.user', 'res.partner', 'product.product', 'sale.order', 'account.invoice', 'product.category', 'stock.move', 'ir.ui.menu'])
|
346
|
-
end
|
347
|
-
|
348
|
-
it "should find the default user action" do
|
349
|
-
@ooor.get_init_menu(1)
|
427
|
+
@ooor = Ooor.new(:url => @url, :database => @database)
|
350
428
|
end
|
351
429
|
|
352
|
-
it "should
|
353
|
-
|
354
|
-
|
355
|
-
|
356
|
-
|
430
|
+
it "should support context when instanciating collections" do
|
431
|
+
@ooor.const_get('product.product')
|
432
|
+
products = ProductProduct.find([1, 2, 3], :context => {:lang => 'en_US'})
|
433
|
+
p = products[0]
|
434
|
+
p.object_session[:lang].should == 'en_US'
|
435
|
+
p.save
|
357
436
|
end
|
437
|
+
end
|
358
438
|
|
359
|
-
|
360
|
-
|
361
|
-
end
|
439
|
+
describe "Web SEO utilities" do
|
440
|
+
include Ooor
|
362
441
|
|
363
|
-
it "should
|
364
|
-
Ooor
|
442
|
+
it "should support model aliases" do
|
443
|
+
Ooor.session_handler.reset!() # alias isn't part of the connection spec, we don't want connectio reuse here
|
444
|
+
with_ooor_session(:url => @url, :database => @database, :username => @username, :password => @password, :aliases => {en_US: {products: 'product.product'}}, :param_keys => {'product.product' => 'name'}) do |session|
|
445
|
+
session['products'].search().should be_kind_of(Array)
|
446
|
+
end
|
365
447
|
end
|
366
448
|
|
367
|
-
it
|
368
|
-
Ooor
|
449
|
+
it "should find by permalink" do
|
450
|
+
Ooor.session_handler.reset!() # alias isn't part of the connection spec, we don't want connectio reuse here
|
451
|
+
with_ooor_session(:url => @url, :database => @database, :username => @username, :password => @password, :aliases => {en_US: {products: 'product.product'}}, :param_keys => {'product.product' => 'name'}) do |session|
|
452
|
+
lang = Ooor::Locale.to_erp_locale('en')
|
453
|
+
session['products'].find_by_permalink('Service', context: {'lang' => lang}, fields: ['name']).should be_kind_of(Ooor::Base)
|
454
|
+
end
|
369
455
|
end
|
370
456
|
end
|
371
457
|
|
372
|
-
|
373
|
-
describe "UML features" do
|
458
|
+
describe "Ative-Record like Reflection" do
|
374
459
|
before(:all) do
|
375
|
-
@ooor = Ooor.new(:url => @url, :username => @username, :password => @password, :database => @database,
|
376
|
-
:models => ['res.user', 'res.partner', 'product.product', 'sale.order', 'account.invoice', 'product.category', 'stock.move', 'ir.ui.menu'])
|
460
|
+
@ooor = Ooor.new(:url => @url, :username => @username, :password => @password, :database => @database, :models => ['product.product'], :reload => true)
|
377
461
|
end
|
378
462
|
|
379
|
-
it "should
|
380
|
-
|
463
|
+
it "should test correct class attributes" do
|
464
|
+
object = Ooor::Reflection::AssociationReflection.new(:test, :people, {}, nil)
|
465
|
+
object.name.should == :people
|
466
|
+
object.macro.should == :test
|
467
|
+
object.options.should == {}
|
381
468
|
end
|
382
469
|
|
383
|
-
it "should
|
384
|
-
Ooor::
|
470
|
+
it "should test correct class name matching wit class name" do
|
471
|
+
object = Ooor::Reflection::AssociationReflection.new(:test, 'product_product', {class_name: 'product.product'}, nil)
|
472
|
+
object.connection = @ooor
|
473
|
+
object.klass.should == ProductProduct
|
385
474
|
end
|
386
475
|
|
387
|
-
it "should accept rendering options" do
|
388
|
-
SaleOrder.print_uml({:detailed => true}).should be_true
|
389
|
-
end
|
390
476
|
end
|
391
477
|
|
392
|
-
|
393
478
|
describe "Multi-instance and class name scoping" do
|
394
479
|
before(:all) do
|
395
480
|
@ooor1 = Ooor.new(:url => @url, :username => @username, :password => @password, :database => @database, :scope_prefix => 'OE1', :models => ['res.partner', 'product.product'], :reload => true)
|
@@ -407,6 +492,39 @@ describe Ooor do
|
|
407
492
|
end
|
408
493
|
end
|
409
494
|
|
495
|
+
describe "Multi-sessions mode" do
|
496
|
+
include Ooor
|
497
|
+
it "should allow with_session" do
|
498
|
+
with_ooor_session(:url => @url, :username => @username, :password => @password, :database => @database) do |session|
|
499
|
+
session['res.users'].search().should be_kind_of(Array)
|
500
|
+
new_user = session['res.users'].create(name: 'User created by OOOR as admin', login: 'ooor1')
|
501
|
+
new_user.destroy
|
502
|
+
end
|
503
|
+
|
504
|
+
with_ooor_session(:url => @url, :username => 'demo', :password => 'demo', :database => @database) do |session|
|
505
|
+
h = session['res.users'].read([1], ["password"])
|
506
|
+
h[0]['password'].should == "********"
|
507
|
+
end
|
508
|
+
|
509
|
+
with_ooor_default_session(:url => @url, :username => @username, :password => @password, :database => @database) do |session|
|
510
|
+
session['res.users'].search().should be_kind_of(Array)
|
511
|
+
end
|
512
|
+
end
|
513
|
+
end
|
514
|
+
|
515
|
+
|
516
|
+
describe "Multi-format serialization" do
|
517
|
+
before(:all) do
|
518
|
+
@ooor = Ooor.new(:url => @url, :username => @username, :password => @password, :database => @database)
|
519
|
+
end
|
520
|
+
|
521
|
+
it "should serialize in json" do
|
522
|
+
ProductProduct.find(1).as_json
|
523
|
+
end
|
524
|
+
it "should serialize in json" do
|
525
|
+
ProductProduct.find(1).to_xml
|
526
|
+
end
|
527
|
+
end
|
410
528
|
|
411
529
|
describe "Ruby OpenERP extensions" do
|
412
530
|
before(:all) do
|