cucumber-openerpscenario 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.DS_Store +0 -0
- data/README.txt +0 -0
- data/bin/cucumber-openerp +0 -0
- data/cucumber-openerp.gemspec +14 -0
- data/lib/.DS_Store +0 -0
- data/lib/cucumber/.DS_Store +0 -0
- data/lib/cucumber/lib/.DS_Store +0 -0
- data/lib/cucumber/lib/ERPConnector.rb +75 -0
- data/lib/cucumber/lib/Helpers/AccountBankStatement.rb +156 -0
- data/lib/cucumber/lib/Helpers/AccountInvoice.rb +122 -0
- data/lib/cucumber/lib/Helpers/AccountTax.rb +85 -0
- data/lib/cucumber/lib/Helpers/AccountVoucher.rb +51 -0
- data/lib/cucumber/lib/Helpers/IrModuleModule.rb +228 -0
- data/lib/cucumber/lib/Helpers/ModuleQualityCheck.rb +93 -0
- data/lib/cucumber/lib/Helpers/Ooor.rb +41 -0
- data/lib/cucumber/lib/Helpers/ProductProduct.rb +126 -0
- data/lib/cucumber/lib/Helpers/PurchaseOrder.rb +53 -0
- data/lib/cucumber/lib/Helpers/ResCurrency.rb +49 -0
- data/lib/cucumber/lib/Helpers/ResPartner.rb +89 -0
- data/lib/cucumber/lib/Helpers/ResUsers.rb +121 -0
- data/lib/cucumber/lib/Helpers/SaleOrder.rb +76 -0
- data/lib/cucumber/lib/Helpers/SaleOrderLine.rb +72 -0
- data/lib/cucumber/lib/Helpers/StockPicking.rb +49 -0
- data/lib/cucumber/lib/core_ext/basic_object.rb +19 -0
- data/lib/cucumber/lib/utils/memoizer_utils.rb +45 -0
- data/lib/cucumber/lib/utils/ooor_utils.rb +124 -0
- data/lib/cucumber/lib/utils/sequel_utils.rb +65 -0
- data/lib/cucumber/openerp/dsl.rb +81 -0
- data/lib/cucumber/openerp/world.rb +37 -0
- data/lib/cucumber/openerp.rb +26 -0
- metadata +129 -0
@@ -0,0 +1,49 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
#################################################################################
|
3
|
+
# #
|
4
|
+
# OERPScenario, OpenERP Functional Tests #
|
5
|
+
# Copyright (C) 2011 Akretion Benoît Guillot <benoit.guillot@akretion.com> #
|
6
|
+
# #
|
7
|
+
# This program is free software: you can redistribute it and/or modify #
|
8
|
+
# it under the terms of the GNU General Public License as published by #
|
9
|
+
# the Free Software Foundation, either version 3 Afero of the License, or #
|
10
|
+
# (at your option) any later version. #
|
11
|
+
# #
|
12
|
+
# This program is distributed in the hope that it will be useful, #
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of #
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the #
|
15
|
+
# GNU General Public License for more details. #
|
16
|
+
# #
|
17
|
+
# You should have received a copy of the GNU General Public License #
|
18
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>. #
|
19
|
+
# #
|
20
|
+
#################################################################################
|
21
|
+
require 'pp'
|
22
|
+
require 'rubygems'
|
23
|
+
require 'ooor'
|
24
|
+
|
25
|
+
begin
|
26
|
+
if Object.const_defined? 'StockPicking'
|
27
|
+
StockPicking.class_eval do
|
28
|
+
$utils.log.debug("Extending #{self.class} #{self.name}")
|
29
|
+
# Add useful methode on stock picking handling
|
30
|
+
|
31
|
+
def self.to_ary
|
32
|
+
return [name]
|
33
|
+
end
|
34
|
+
|
35
|
+
def validate_picking()
|
36
|
+
res = {'delivery_date' => (DateTime.now).strftime(fmt="%Y-%m-%d %H:%M:%S")}
|
37
|
+
stock_moves = move_lines
|
38
|
+
stock_moves.each do |move_line|
|
39
|
+
res["move#{move_line.id}"] = {'prodlot_id' => move_line.prodlot_id && move_line.prodlot_id.id || false, 'product_id' => move_line.product_id.id, 'product_uom' => move_line.product_uom.id, 'product_qty' => move_line.product_qty}
|
40
|
+
end
|
41
|
+
StockPicking.do_partial([id], res)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
else
|
45
|
+
$utils.log.debug("StockPicking helper not initialized")
|
46
|
+
end
|
47
|
+
rescue Exception => e
|
48
|
+
$utils.log.fatal("ERROR : #{e.to_s}")
|
49
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# taken from Sequel gem, BasicObject implementation for ruby 1.8
|
2
|
+
if RUBY_VERSION < '1.9.0'
|
3
|
+
# If on Ruby 1.8, create a <tt>Sequel::BasicObject</tt> class that is similar to the
|
4
|
+
# the Ruby 1.9 +BasicObject+ class. This is used in a few places where proxy
|
5
|
+
# objects are needed that respond to any method call.
|
6
|
+
class BasicObject
|
7
|
+
# The instance methods to not remove from the class when removing
|
8
|
+
# other methods.
|
9
|
+
KEEP_METHODS = %w"__id__ __send__ __metaclass__ instance_eval == equal? initialize method_missing"
|
10
|
+
|
11
|
+
# Remove all but the most basic instance methods from the class. A separate
|
12
|
+
# method so that it can be called again if necessary if you load libraries
|
13
|
+
# after Sequel that add instance methods to +Object+.
|
14
|
+
def self.remove_methods!
|
15
|
+
((private_instance_methods + instance_methods) - KEEP_METHODS).each{|m| undef_method(m)}
|
16
|
+
end
|
17
|
+
remove_methods!
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
###############################################################################
|
2
|
+
#
|
3
|
+
# OERPScenario, OpenERP Functional Tests
|
4
|
+
# Author Nicolas Bessi 2009
|
5
|
+
# Copyright Camptocamp SA
|
6
|
+
#
|
7
|
+
# This program is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 Afero of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
##############################################################################
|
21
|
+
|
22
|
+
module MemoizerUtils
|
23
|
+
# Define a memorizer to store object handled by the test
|
24
|
+
# Useful to store an invoice in a var which name = invoice name !
|
25
|
+
def set_var(name, value)
|
26
|
+
memoizer[name] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
def get_var(name)
|
30
|
+
memoizer[name]
|
31
|
+
end
|
32
|
+
|
33
|
+
def clean_var(name)
|
34
|
+
memoizer.delete(name)
|
35
|
+
end
|
36
|
+
|
37
|
+
def clean_all_var
|
38
|
+
memoizer.clear
|
39
|
+
end
|
40
|
+
|
41
|
+
def memoizer
|
42
|
+
@memoizer ||= {}
|
43
|
+
end
|
44
|
+
private :memoizer
|
45
|
+
end
|
@@ -0,0 +1,124 @@
|
|
1
|
+
###############################################################################
|
2
|
+
#
|
3
|
+
# OERPScenario, OpenERP Functional Tests
|
4
|
+
# Author Nicolas Bessi 2009
|
5
|
+
# Copyright Camptocamp SA
|
6
|
+
#
|
7
|
+
# This program is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 Afero of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
##############################################################################
|
21
|
+
|
22
|
+
module OoorUtils
|
23
|
+
|
24
|
+
def ooor
|
25
|
+
@ooor ||= init_ooor
|
26
|
+
end
|
27
|
+
|
28
|
+
def init_ooor
|
29
|
+
OoorProxy.new(log)
|
30
|
+
end
|
31
|
+
|
32
|
+
def ready?
|
33
|
+
!ooor.nil? && ooor.all_loaded_models.size == 0
|
34
|
+
end
|
35
|
+
|
36
|
+
def login(params={})
|
37
|
+
ooor.login(config.merge(params))
|
38
|
+
end
|
39
|
+
|
40
|
+
def create_ooor_connection(params={})
|
41
|
+
ooor.open_connection(config.merge(params))
|
42
|
+
load_helpers
|
43
|
+
end
|
44
|
+
|
45
|
+
def create_database_with_ooor(params={})
|
46
|
+
ooor.create_database(config.merge(params))
|
47
|
+
load_helpers
|
48
|
+
end
|
49
|
+
|
50
|
+
def setConnexionfromConf(params={})
|
51
|
+
log.warn('Deprecated: ScenarioUtils#setConnexionfromConf. Use ScenarioUtils#create_ooor_connection')
|
52
|
+
create_ooor_connection(params)
|
53
|
+
end
|
54
|
+
|
55
|
+
def createdatabasefromConf(params={})
|
56
|
+
log.warn('Deprecated: ScenarioUtils#createdatabasefromConf. Use ScenarioUtils#create_database_with_ooor')
|
57
|
+
create_database_with_ooor(params)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
|
62
|
+
class OoorProxy < BasicObject
|
63
|
+
# Delegate to OOOR except the OERPScenario methods to manage the connections
|
64
|
+
|
65
|
+
attr_reader :log
|
66
|
+
|
67
|
+
def initialize(log)
|
68
|
+
@log = log
|
69
|
+
end
|
70
|
+
|
71
|
+
def xmlrpc_url(params)
|
72
|
+
"http://#{params[:host]}:#{params[:port]}/xmlrpc"
|
73
|
+
end
|
74
|
+
private :xmlrpc_url
|
75
|
+
|
76
|
+
def login(params)
|
77
|
+
@ooor.global_login(params[:user], params[:pwd])
|
78
|
+
end
|
79
|
+
|
80
|
+
def init_ooor_connection(params)
|
81
|
+
::Ooor.new({:url => xmlrpc_url(params),
|
82
|
+
:database => params[:dbname],
|
83
|
+
:username => params[:user],
|
84
|
+
:password => params[:pwd],
|
85
|
+
:log_level => params[:log_level]})
|
86
|
+
end
|
87
|
+
private :init_ooor_connection
|
88
|
+
|
89
|
+
#read the base.conf file to set all the parameter to begin an xml rpc session with openerp
|
90
|
+
#you can override any of the parameters
|
91
|
+
def open_connection(params)
|
92
|
+
if @ooor
|
93
|
+
login(params)
|
94
|
+
else
|
95
|
+
begin
|
96
|
+
@ooor = init_ooor_connection(params)
|
97
|
+
rescue RuntimeError #We catch RuntimeError because ooor doesn't give the error name.
|
98
|
+
#we deduce in that case that the database doesn't exist and we have to create it.
|
99
|
+
log.warn("No database, try to create it")
|
100
|
+
create_database_with_ooor(params)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
self
|
104
|
+
end
|
105
|
+
|
106
|
+
def create_database(params)
|
107
|
+
log.info("Creating a new database")
|
108
|
+
begin
|
109
|
+
@ooor = Ooor.new(:url => xmlrpc_url(params))
|
110
|
+
@ooor.create(ooor_config[:pwd], params[:dbname], false, 'en_US', params[:pwd])
|
111
|
+
@ooor.load_models(false)
|
112
|
+
rescue RuntimeError
|
113
|
+
log.fatal("ERROR : Cannot create database")
|
114
|
+
raise 'Cannot create database'
|
115
|
+
end
|
116
|
+
self
|
117
|
+
end
|
118
|
+
|
119
|
+
def method_missing(name, *args, &block)
|
120
|
+
@ooor.send(name, *args, &block)
|
121
|
+
end
|
122
|
+
protected :method_missing
|
123
|
+
|
124
|
+
end
|
@@ -0,0 +1,65 @@
|
|
1
|
+
###############################################################################
|
2
|
+
#
|
3
|
+
# OERPScenario, OpenERP Functional Tests
|
4
|
+
# Author Guewen Baconnier
|
5
|
+
# Copyright Camptocamp SA 2012
|
6
|
+
#
|
7
|
+
# This program is free software: you can redistribute it and/or modify
|
8
|
+
# it under the terms of the GNU General Public License as published by
|
9
|
+
# the Free Software Foundation, either version 3 Afero of the License, or
|
10
|
+
# (at your option) any later version.
|
11
|
+
#
|
12
|
+
# This program is distributed in the hope that it will be useful,
|
13
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
14
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
15
|
+
# GNU General Public License for more details.
|
16
|
+
#
|
17
|
+
# You should have received a copy of the GNU General Public License
|
18
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
19
|
+
#
|
20
|
+
##############################################################################
|
21
|
+
|
22
|
+
module SequelUtils
|
23
|
+
attr_reader :sequel
|
24
|
+
|
25
|
+
def sequel(params={})
|
26
|
+
@sequel ||= init_sequel(params)
|
27
|
+
end
|
28
|
+
|
29
|
+
def init_sequel(params={})
|
30
|
+
if SEQUEL_ACTIVE
|
31
|
+
sequel_params = config.merge(params)
|
32
|
+
@sequel = SequelProxy.new(sequel_params, log)
|
33
|
+
else
|
34
|
+
msg = 'Please install the sequel and pg gems in order to use $utils.sequel.'
|
35
|
+
log.fatal(msg)
|
36
|
+
raise msg
|
37
|
+
end
|
38
|
+
end
|
39
|
+
private :init_sequel
|
40
|
+
end
|
41
|
+
|
42
|
+
if SEQUEL_ACTIVE
|
43
|
+
require 'sequel'
|
44
|
+
|
45
|
+
class SequelProxy < BasicObject
|
46
|
+
# Delegate to Sequel except the OERPScenario methods to manage the connections
|
47
|
+
|
48
|
+
attr_reader :log
|
49
|
+
|
50
|
+
def initialize(params, log)
|
51
|
+
@log = log
|
52
|
+
@db = ::Sequel.postgres(:host=>params[:db_host],
|
53
|
+
:database=>params[:dbname],
|
54
|
+
:user=>params[:db_user],
|
55
|
+
:password=>params[:db_password],
|
56
|
+
:port => params[:db_port] || 5432)
|
57
|
+
end
|
58
|
+
protected
|
59
|
+
|
60
|
+
def method_missing(name, *args, &block)
|
61
|
+
@db.send(name, *args, &block)
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
def prepare_args(args)
|
2
|
+
mixed = args.strip.split('and')
|
3
|
+
attrs = []
|
4
|
+
arguments = []
|
5
|
+
mixed.each do |set|
|
6
|
+
tmp = set.split(':')
|
7
|
+
attrs.push(tmp[0].strip)
|
8
|
+
arguments.push(tmp[1].strip)
|
9
|
+
end
|
10
|
+
attrs_string = attrs.join('_and_')
|
11
|
+
return attrs_string, arguments
|
12
|
+
end
|
13
|
+
|
14
|
+
def get_items(action, qty, model, args)
|
15
|
+
@found_items = nil
|
16
|
+
@found_item = nil
|
17
|
+
oclass = Object.const_get(model.split('.').collect {|s| s.capitalize}.join)
|
18
|
+
unique_mode = ['create', 'need', 'find or create']
|
19
|
+
if qty == 'all'
|
20
|
+
if unique_mode.include? action
|
21
|
+
raise "#{unique_mode.inspect} does not allows 'all' keyword"
|
22
|
+
end
|
23
|
+
qty = 'all_'
|
24
|
+
else
|
25
|
+
qty = ''
|
26
|
+
end
|
27
|
+
command_map = {'create' => 'new', 'need' => 'find_or_initialize_by_', 'shoud_have' => "find_#{qty}by_", 'find' => "find_#{qty}by_", 'find or create' => 'find_or_initialize_by_'}
|
28
|
+
comm_ext, arguments = prepare_args(args)
|
29
|
+
if command_map[action] == 'create'
|
30
|
+
if oclass.send(('find_by_'+comm_ext).to_sym, *arguments)
|
31
|
+
raise "Error object allerady exist if this is not the wished behavior please use need keyword"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
res = oclass.send((command_map[action]+comm_ext).to_sym, *arguments) # I know in case or create we do 2 search but as there should be nul it cost almost nothing
|
35
|
+
if @found_items.is_a? Array
|
36
|
+
@found_items = res
|
37
|
+
else
|
38
|
+
@found_item = res
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def _manage_col_search(field_def, value)
|
43
|
+
oclass = Object.const_get(field_def['relation'].split('.').collect {|s| s.capitalize}.join) # TODO use Scenario helper
|
44
|
+
oid = nil
|
45
|
+
if value.start_with? 'by '
|
46
|
+
comm_ext, arguments = prepare_args(value.gsub('by ', ''))
|
47
|
+
arguments.push({'fields'=>['id']})
|
48
|
+
oid = oclass.send(('find_by_'+comm_ext).to_sym, *arguments)
|
49
|
+
else
|
50
|
+
eval "oid = oclass.#{value}"
|
51
|
+
end
|
52
|
+
unless oid
|
53
|
+
raise "Can not find #{value}"
|
54
|
+
end
|
55
|
+
return oid
|
56
|
+
end
|
57
|
+
|
58
|
+
def manage_item_table(item, table)
|
59
|
+
fields = {}
|
60
|
+
fields.merge! item.class.many2one_associations
|
61
|
+
fields.merge! item.class.one2many_associations
|
62
|
+
fields.merge! item.class.many2many_associations
|
63
|
+
|
64
|
+
table.hashes.each do |dict|
|
65
|
+
if fields[dict['name']]
|
66
|
+
rel_item = _manage_col_search(fields[dict['name']], dict['value'])
|
67
|
+
eval "item.#{dict['name']} = rel_item.id"
|
68
|
+
else
|
69
|
+
eval "item.#{dict['name']} = dict['value']"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
Given /^I (create|need|should have|find|find or create) (a|all|last) "([^"]*)" with (.*)$/ do |action, qty, model, args|
|
75
|
+
get_items(action, qty, model, args)
|
76
|
+
end
|
77
|
+
|
78
|
+
Given /^having$/ do |table|
|
79
|
+
manage_item_table(@found_item, table)
|
80
|
+
@found_item.save
|
81
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require "cucumber/lib/ERPConnector.rb"
|
2
|
+
module CucumberOpenERP
|
3
|
+
attr_accessor :is_alive, :openerp
|
4
|
+
def am_i_alive?
|
5
|
+
puts 'did i live'
|
6
|
+
@@is_alive ||= false
|
7
|
+
return @@is_alive
|
8
|
+
end
|
9
|
+
def born
|
10
|
+
puts 'I m born'
|
11
|
+
@@is_alive = true
|
12
|
+
end
|
13
|
+
def openerp_ignition
|
14
|
+
unless am_i_alive?
|
15
|
+
openerp = ScenarioUtils.new() #$utils is deprecated please use openerp
|
16
|
+
begin
|
17
|
+
unless openerp.ready?
|
18
|
+
openerp.log.info("Attempt to connect")
|
19
|
+
openerp.create_ooor_connection
|
20
|
+
end
|
21
|
+
rescue Exception => e
|
22
|
+
openerp.log.warn("#{e.to_s}")
|
23
|
+
openerp.log.warn("Force reconnect")
|
24
|
+
openerp.create_ooor_connection
|
25
|
+
end
|
26
|
+
born
|
27
|
+
$util = openerp #for retro-compat
|
28
|
+
end
|
29
|
+
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
World(CucumberOpenERP)
|
34
|
+
|
35
|
+
Before do
|
36
|
+
openerp_ignition
|
37
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
env_caller = File.dirname(caller.detect{|f| f =~ /\/env\.rb:/}) if caller.detect{|f| f =~ /\/env\.rb:/}
|
2
|
+
if env_caller
|
3
|
+
require 'xmlrpc/client'
|
4
|
+
XMLRPC::Config::ENABLE_NIL_PARSER = true if not XMLRPC::Config::ENABLE_NIL_PARSER
|
5
|
+
XMLRPC::Config::ENABLE_NIL_CREATE = true if not XMLRPC::Config::ENABLE_NIL_CREATE
|
6
|
+
XMLRPC::Config::ENABLE_BIGINT = true if not XMLRPC::Config::ENABLE_BIGINT
|
7
|
+
begin
|
8
|
+
require 'sequel'
|
9
|
+
SEQUEL_ACTIVE = true
|
10
|
+
rescue LoadError => err
|
11
|
+
SEQUEL_ACTIVE = false
|
12
|
+
end
|
13
|
+
require 'ooor'
|
14
|
+
require 'pp'
|
15
|
+
require 'parseconfig'
|
16
|
+
require "ooor/finders"
|
17
|
+
require 'logger'
|
18
|
+
require 'cucumber/lib/core_ext/basic_object'
|
19
|
+
require 'cucumber/lib/utils/memoizer_utils'
|
20
|
+
require 'cucumber/lib/utils/ooor_utils'
|
21
|
+
require 'cucumber/lib/utils/sequel_utils'
|
22
|
+
require 'cucumber/openerp/dsl'
|
23
|
+
require 'cucumber/openerp/world'
|
24
|
+
else
|
25
|
+
warn "WARNING: Cucumber-openerp required outside of env.rb. The rest of loading is being defered until env.rb is called"
|
26
|
+
end
|