sugarcrm 0.9.12 → 0.9.13

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/README.rdoc CHANGED
@@ -38,7 +38,10 @@ A less clunky way to interact with SugarCRM via REST.
38
38
  SugarCRM.modules
39
39
 
40
40
  # Retrieve a User by user_name
41
- SugarCRM::User.find_by_user_name("admin")
41
+ users = SugarCRM::User.find_by_user_name("admin")
42
+
43
+ # Return a User instance's SugarCRM URL (also works for any other module instance)
44
+ users.url
42
45
 
43
46
  # Update a User's title
44
47
  u = SugarCRM::User.find_by_first_name_and_last_name("Will", "Westin")
@@ -95,6 +98,9 @@ A less clunky way to interact with SugarCRM via REST.
95
98
  a.contacts.delete(c)
96
99
  a.save # or a.contacts.save
97
100
 
101
+ # Retrieve the number of accounts in CRM with 'Inc' in their name
102
+ SugarCRM::Account.count(:conditions => {:name => "LIKE '%Inc'"})
103
+
98
104
  # Look up the Case with the smallest case number
99
105
  SugarCRM::Case.first({
100
106
  :order_by => 'case_number'
@@ -116,6 +122,12 @@ A less clunky way to interact with SugarCRM via REST.
116
122
  SugarCRM::Account.all({
117
123
  :conditions => { :name => "LIKE '%Fund%'" } # note that SQL operators must be uppercase
118
124
  })
125
+
126
+ # Use block to iterate over results: print all account names
127
+ SugarCRM::Account.all{|a| puts a.name } # note: this method will be much quicker than SugarCRM::Account.all.each{|a| puts a.name }
128
+ # because records are passed to the block as they get fetched from SugarCRM (whereas `each`
129
+ # will fetch all records, and only then pass them to the block). This will make a major difference
130
+ # in resource use and execution time if you're dealing with many records.
119
131
 
120
132
  # Look up the fields for a given module
121
133
  SugarCRM::Module.find("Accounts").fields
@@ -149,7 +161,9 @@ Note: this gem requires Rails 3 as it depends on Active Support >= 3.
149
161
  4. Run `rails g sugarcrm:config`
150
162
  5. Edit the configuration file in `config/sugarcrm.yml` to match your environment
151
163
 
152
- Example app here: https://github.com/davidsulc/sugar_on_rails_basic
164
+ Example apps:
165
+ * https://github.com/davidsulc/sugar_on_rails_basic
166
+ * https://github.com/davidsulc/dev_zone_basic_rails_app
153
167
 
154
168
  == USING A CONFIGURATION FILE
155
169
 
data/Rakefile CHANGED
@@ -18,7 +18,7 @@ Jeweler::Tasks.new do |gem|
18
18
  gem.homepage = "http://github.com/chicks/sugarcrm"
19
19
  gem.authors = ["Carl Hicks", "David Sulc"]
20
20
  gem.executables = ['sugarcrm']
21
- gem.files = FileList['./lib/**/*', './*'].exclude("*.lock").to_a
21
+ gem.files = FileList['./lib/**/*', './*'].exclude("*.lock", "*.tmproj").to_a
22
22
  end
23
23
  Jeweler::RubygemsDotOrgTasks.new
24
24
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.12
1
+ 0.9.13
@@ -145,7 +145,7 @@ module SugarCRM; module AttributeMethods
145
145
  # sets the id if it's a new record
146
146
  def save_modified_attributes!
147
147
  # Complain if we aren't valid
148
- raise InvalidRecord, errors.to_a.join(", ") if !valid?
148
+ raise InvalidRecord, @errors.full_messages.join(", ") unless valid?
149
149
  # Send the save request
150
150
  response = self.class.session.connection.set_entry(self.class._module.name, serialize_modified_attributes)
151
151
  # Complain if we don't get a parseable response back
@@ -1,11 +1,30 @@
1
1
  module SugarCRM; module AttributeValidations
2
2
  # Checks to see if we have all the neccessary attributes
3
3
  def valid?
4
- @errors = Set.new
4
+ @errors = ActiveSupport::HashWithIndifferentAccess.new
5
+
5
6
  self.class._module.required_fields.each do |attribute|
6
7
  valid_attribute?(attribute)
7
8
  end
8
- @errors.length == 0
9
+
10
+ # for rails compatibility
11
+ def @errors.full_messages
12
+ # After removing attributes without errors, flatten the error hash, repeating the name of the attribute before each message:
13
+ # e.g. {'name' => ['cannot be blank', 'is too long'], 'website' => ['is not valid']}
14
+ # will become 'name cannot be blank, name is too long, website is not valid
15
+ self.inject([]){|memo, obj| memo.concat(obj[1].inject([]){|m, o| m << "#{obj[0].to_s.humanize} #{o}" })}
16
+ end
17
+
18
+ # Rails needs each attribute to be present in the error hash (if the attribute has no error, it has [] as a value)
19
+ # Redefine the [] method for the errors hash to return [] instead of nil is the hash doesn't contain the key
20
+ class << @errors
21
+ alias :old_key_lookup :[]
22
+ def [](key)
23
+ old_key_lookup(key) || Array.new
24
+ end
25
+ end
26
+
27
+ @errors.size == 0
9
28
  end
10
29
 
11
30
  protected
@@ -21,7 +40,7 @@ module SugarCRM; module AttributeValidations
21
40
  validate_class_for(attribute, [Fixnum, Float])
22
41
  else
23
42
  if @attributes[attribute].blank?
24
- @errors.add "#{attribute} cannot be blank"
43
+ add_error(attribute, "cannot be blank")
25
44
  end
26
45
  end
27
46
  end
@@ -30,8 +49,14 @@ module SugarCRM; module AttributeValidations
30
49
  # returns true if they match, otherwise adds an entry to the @errors collection, and returns false
31
50
  def validate_class_for(attribute, class_array)
32
51
  return true if class_array.include? @attributes[attribute].class
33
- @errors.add "#{attribute} must be a #{class_array.join(" or ")} object (not #{@attributes[attribute].class})"
52
+ add_error(attribute, "must be a #{class_array.join(" or ")} object (not #{@attributes[attribute].class})")
34
53
  false
35
54
  end
36
55
 
56
+ # Add an error to the hash
57
+ def add_error(attribute, message)
58
+ @errors[attribute] ||= []
59
+ @errors[attribute] = @errors[attribute] << message unless @errors[attribute].include? message
60
+ @errors
61
+ end
37
62
  end; end
data/lib/sugarcrm/base.rb CHANGED
@@ -25,7 +25,7 @@ module SugarCRM; class Base
25
25
  attr :errors, true
26
26
 
27
27
  class << self # Class methods
28
- def find(*args)
28
+ def find(*args, &block)
29
29
  options = args.extract_options!
30
30
  options = {:order_by => 'date_entered'}.merge(options)
31
31
  validate_find_options(options)
@@ -35,39 +35,44 @@ module SugarCRM; class Base
35
35
  find_initial(options)
36
36
  when :last
37
37
  begin
38
- options[:order_by] = reverse_order_clause(options[:order_by])
38
+ options[:order_by] = reverse_order_clause(options[:order_by].to_s)
39
39
  rescue Exception => e
40
40
  raise
41
41
  end
42
42
  find_initial(options)
43
43
  when :all
44
- Array.wrap(find_every(options)).compact
44
+ Array.wrap(find_every(options, &block)).compact
45
45
  else
46
- find_from_ids(args, options)
46
+ find_from_ids(args, options, &block)
47
47
  end
48
48
  end
49
49
 
50
50
  # return the connection to the correct SugarCRM server (there can be several)
51
51
  def connection
52
- self.parent.session.connection
52
+ self.session.connection
53
+ end
54
+
55
+ def count(options={})
56
+ query = query_from_options(options)
57
+ connection.get_entries_count(self._module.name, query, options)['result_count'].to_i
53
58
  end
54
59
 
55
60
  # A convenience wrapper for <tt>find(:first, *args)</tt>. You can pass in all the
56
61
  # same arguments to this method as you can to <tt>find(:first)</tt>.
57
- def first(*args)
58
- find(:first, *args)
62
+ def first(*args, &block)
63
+ find(:first, *args, &block)
59
64
  end
60
65
 
61
66
  # A convenience wrapper for <tt>find(:last, *args)</tt>. You can pass in all the
62
67
  # same arguments to this method as you can to <tt>find(:last)</tt>.
63
- def last(*args)
64
- find(:last, *args)
68
+ def last(*args, &block)
69
+ find(:last, *args, &block)
65
70
  end
66
71
 
67
72
  # This is an alias for find(:all). You can pass in all the same arguments to this method as you can
68
73
  # to find(:all)
69
- def all(*args)
70
- find(:all, *args)
74
+ def all(*args, &block)
75
+ find(:all, *args, &block)
71
76
  end
72
77
 
73
78
  # Creates an object (or multiple objects) and saves it to SugarCRM if validations pass.
@@ -102,11 +107,11 @@ module SugarCRM; class Base
102
107
  object
103
108
  end
104
109
  end
105
-
106
110
  end
107
111
 
108
112
  # Creates an instance of a Module Class, i.e. Account, User, Contact, etc.
109
113
  def initialize(attributes={}, &block)
114
+ @errors = {}
110
115
  @modified_attributes = {}
111
116
  merge_attributes(attributes.with_indifferent_access)
112
117
  clear_association_cache
@@ -131,7 +136,7 @@ module SugarCRM; class Base
131
136
  # Saves the current object, checks that required fields are present.
132
137
  # returns true or false
133
138
  def save
134
- return false if !changed?
139
+ return false if !(new_record? || changed?)
135
140
  return false if !valid?
136
141
  begin
137
142
  save!
@@ -156,6 +161,12 @@ module SugarCRM; class Base
156
161
  params[:deleted]= {:name => "deleted", :value => "1"}
157
162
  @attributes[:deleted] = (self.class.connection.set_entry(self.class._module.name, params).class == Hash)
158
163
  end
164
+ alias :destroy :delete
165
+
166
+ # Returns if the record is persisted, i.e. it’s not a new record and it was not destroyed
167
+ def persisted?
168
+ !(new_record? || destroyed?)
169
+ end
159
170
 
160
171
  # Reloads the record from SugarCRM
161
172
  def reload!
@@ -178,16 +189,39 @@ module SugarCRM; class Base
178
189
  end
179
190
  alias :eql? :==
180
191
 
181
- def update_attribute(name, value)
192
+ def update_attribute!(name, value)
182
193
  self.send("#{name}=".to_sym, value)
183
- self.save
194
+ self.save!
184
195
  end
185
196
 
186
- def update_attributes(attributes)
197
+ def update_attribute(name, value)
198
+ begin
199
+ update_attribute!(name, value)
200
+ rescue
201
+ return false
202
+ end
203
+ true
204
+ end
205
+
206
+ def update_attributes!(attributes)
187
207
  attributes.each do |name, value|
188
208
  self.send("#{name}=".to_sym, value)
189
209
  end
190
- self.save
210
+ self.save!
211
+ end
212
+
213
+ def update_attributes(attributes)
214
+ begin
215
+ update_attributes!(attributes)
216
+ rescue
217
+ return false
218
+ end
219
+ true
220
+ end
221
+
222
+ # Returns the URL (in string format) where the module instance is available in CRM
223
+ def url
224
+ "#{SugarCRM.session.config[:base_url]}/index.php?module=#{self.class._module}&action=DetailView&record=#{self.id}"
191
225
  end
192
226
 
193
227
  # Delegates to id in order to allow two records of the same type and id to work with something like:
@@ -197,7 +231,7 @@ module SugarCRM; class Base
197
231
  end
198
232
 
199
233
  def pretty_print(pp)
200
- pp.text self.inspect, 0
234
+ pp.text self.inspect.to_s, 0
201
235
  end
202
236
 
203
237
  def attribute_methods_generated?
@@ -208,6 +242,31 @@ module SugarCRM; class Base
208
242
  self.class.association_methods_generated
209
243
  end
210
244
 
245
+ def to_key
246
+ new_record? ? nil : [ id ]
247
+ end
248
+
249
+ def to_param
250
+ id.to_s
251
+ end
252
+
253
+ def is_a?(klass)
254
+ superclasses.include? klass
255
+ end
256
+ alias :kind_of? :is_a?
257
+ alias :=== :is_a?
258
+
259
+ private
260
+ def superclasses
261
+ return @superclasses if @superclasses
262
+ @superclasses = [self.class]
263
+ current_class = self.class
264
+ while current_class.respond_to? :superclass
265
+ @superclasses << (current_class = current_class.superclass)
266
+ end
267
+ @superclasses
268
+ end
269
+
211
270
  Base.class_eval do
212
271
  extend FinderMethods::ClassMethods
213
272
  include AttributeMethods
@@ -21,6 +21,10 @@ module SugarCRM; class Request
21
21
  self
22
22
  end
23
23
 
24
+ def bytesize
25
+ self.to_s.bytesize
26
+ end
27
+
24
28
  def length
25
29
  self.to_s.length
26
30
  end
@@ -80,6 +80,7 @@ module SugarCRM; class Response
80
80
  # Takes a hash like { "first_name" => {"name" => "first_name", "value" => "John"}}
81
81
  # And flattens it into {"first_name" => "John"}
82
82
  def flatten(list)
83
+ raise ArgumentError, list[0]['value'] if list[0] && list[0]['name'] == 'warning'
83
84
  raise ArgumentError, 'method parameter must respond to #each_pair' unless list.respond_to? :each_pair
84
85
  flat_list = {}
85
86
  list.each_pair do |k,v|
@@ -11,7 +11,7 @@ module SugarCRM; class ConnectionPool
11
11
  # The mutex used to synchronize pool access
12
12
  @connection_mutex = Monitor.new
13
13
  @queue = @connection_mutex.new_cond
14
- @timeout = config_timeout || 5
14
+ @timeout = config_timeout || 10
15
15
 
16
16
  # default max pool size to 5
17
17
  @size = config_pool_size || default_pool_size
@@ -8,7 +8,7 @@ module SugarCRM; module FinderMethods
8
8
  result
9
9
  end
10
10
 
11
- def find_from_ids(ids, options)
11
+ def find_from_ids(ids, options, &block)
12
12
  expects_array = ids.first.kind_of?(Array)
13
13
  return ids.first if expects_array && ids.first.empty?
14
14
 
@@ -21,7 +21,7 @@ module SugarCRM; module FinderMethods
21
21
  result = find_one(ids.first, options)
22
22
  expects_array ? [ result ] : result
23
23
  else
24
- find_some(ids, options)
24
+ find_some(ids, options, &block)
25
25
  end
26
26
  end
27
27
 
@@ -34,7 +34,7 @@ module SugarCRM; module FinderMethods
34
34
  end
35
35
  end
36
36
 
37
- def find_some(ids, options)
37
+ def find_some(ids, options, &block)
38
38
  result = connection.get_entries(self._module.name, ids, {:fields => self._module.fields.keys})
39
39
 
40
40
  # Determine expected size from limit and offset, not just ids.size.
@@ -51,67 +51,73 @@ module SugarCRM; module FinderMethods
51
51
  end
52
52
 
53
53
  if result.size == expected_size
54
+ if block_given?
55
+ result.each{|r|
56
+ yield r
57
+ }
58
+ end
54
59
  result
55
60
  else
56
61
  raise RecordNotFound, "Couldn't find all #{name.pluralize} with IDs (#{ids_list})#{conditions} (found #{result.size} results, but was looking for #{expected_size})"
57
62
  end
58
63
  end
59
64
 
60
- def find_every(options)
61
- find_by_sql(options)
65
+ def find_every(options, &block)
66
+ find_by_sql(options, &block)
62
67
  end
63
-
64
- def find_by_sql(options)
65
- # SugarCRM REST API has a bug where, when :limit and :offset options are passed simultaneously, :limit is considered to be the smallest of the two, and :offset is the larger
66
- # in addition to allowing querying of large datasets while avoiding timeouts,
68
+
69
+ # the number of records we retrieve with each query
70
+ # it is kept small to avoid timeout issues
71
+ SLICE_SIZE = 5
72
+ SLICE_SIZE.freeze
73
+ # results accumulator stores the results we have fetched so far, recursively
74
+ def find_by_sql(options, results_accumulator=nil, &block)
75
+ # SugarCRM REST API has a bug where, when :limit and :offset options are passed simultaneously,
76
+ # :limit is considered to be the smallest of the two, and :offset is the larger
77
+ # In addition to allowing querying of large datasets while avoiding timeouts (by fetching results in small slices),
67
78
  # this implementation fixes the :limit - :offset bug so that it behaves correctly
79
+
80
+ offset = options[:offset].to_i >= 1 ? options[:offset].to_i : nil
81
+
82
+ # if many results are requested (i.e. multiple result slices), we call this function recursively
83
+ # this array keeps track of which slice we are retrieving (by updating the :offset and :limit options)
68
84
  local_options = {}
69
- options.keys.each{|k|
70
- local_options[k] = options[k]
71
- }
72
- local_options.delete(:offset) if local_options[:offset] == 0
73
-
74
- # store the number of records wanted by user, as we'll overwrite :limit option to obtain several slices of records (to avoid timeout issues)
75
- nb_to_fetch = local_options[:limit]
76
- nb_to_fetch = nb_to_fetch.to_i if nb_to_fetch
77
- offset_value = local_options[:offset] || 10 # arbitrary value, must be bigger than :limit used (see comment above)
78
- offset_value = offset_value.to_i
79
- offset_value.freeze
80
- initial_limit = nb_to_fetch.nil? ? offset_value : [offset_value, nb_to_fetch].min # how many records should be fetched on first pass
81
85
  # ensure results are ordered so :limit and :offset option behave in a deterministic fashion
82
- local_options = { :order_by => :id }.merge(local_options)
83
- local_options.update(:limit => initial_limit) # override original argument
84
-
85
- # get first slice of results
86
- # note: to work around a SugarCRM REST API bug, the :limit option must always be smaller than the :offset option
87
- # this is the reason this first query is separate (not in the loop): the initial query has a larger limit, so that we can then use the loop
88
- # with :limit always smaller than :offset
89
- results = connection.get_entry_list(self._module.name, query_from_options(local_options), local_options)
90
- return nil unless results
91
- results = Array.wrap(results)
92
-
93
- limit_value = [5, offset_value].min # arbitrary value, must be smaller than :offset used (see comment above)
94
- limit_value.freeze
95
- local_options = { :order_by => :id }.merge(local_options)
96
- local_options.update(:limit => limit_value)
97
-
98
- # a portion of the results has already been queried
99
- # update or set the :offset value to reflect this
100
- local_options[:offset] ||= results.size
101
- local_options[:offset] += offset_value
102
-
103
- # continue fetching results until we either
104
- # a) have as many results as the user wants (specified via the original :limit option)
105
- # b) there are no more results matching the criteria
106
- while result_slice = connection.get_entry_list(self._module.name, query_from_options(local_options), local_options)
107
- results.concat(Array.wrap(result_slice))
108
- # make sure we don't return more results than the user requested (via original :limit option)
109
- if nb_to_fetch && results.size >= nb_to_fetch
110
- return results.slice(0, nb_to_fetch)
111
- end
112
- local_options[:offset] += local_options[:limit] # update :offset as we get more records
86
+ local_options[:order_by] = :id unless options[:order_by]
87
+
88
+ # we must ensure limit <= offset (due to bug mentioned above)
89
+ if offset
90
+ local_options[:limit] = [offset.to_i, SLICE_SIZE].min
91
+ local_options[:offset] = offset if offset
92
+ else
93
+ local_options[:limit] = options[:limit] ? [options[:limit].to_i, SLICE_SIZE].min : SLICE_SIZE
94
+ end
95
+ local_options[:limit] = [local_options[:limit], options[:limit]].min if options[:limit] # don't retrieve more records than required
96
+ local_options = options.merge(local_options)
97
+
98
+ query = query_from_options(local_options)
99
+ result_slice = connection.get_entry_list(self._module.name, query, local_options)
100
+ return results_accumulator unless result_slice
101
+
102
+ result_slice_array = Array.wrap(result_slice)
103
+ if block_given?
104
+ result_slice_array.each{|r| yield r }
105
+ else
106
+ results_accumulator = [] unless results_accumulator
107
+ results_accumulator = results_accumulator.concat(result_slice_array)
108
+ end
109
+
110
+ # adjust options to take into account records that were already retrieved
111
+ updated_options = {:offset => options[:offset].to_i + result_slice_array.size}
112
+ updated_options[:limit] = (options[:limit] ? options[:limit] - result_slice_array.size : nil)
113
+ updated_options = options.merge(updated_options)
114
+
115
+ # have we retrieved all the records?
116
+ if (updated_options[:limit] && updated_options[:limit] < 1) || local_options[:limit] > result_slice_array.size
117
+ return results_accumulator
118
+ else
119
+ find_by_sql(updated_options, results_accumulator, &block)
113
120
  end
114
- results
115
121
  end
116
122
 
117
123
  def query_from_options(options)
@@ -16,7 +16,7 @@ module SugarCRM; class Session
16
16
 
17
17
  setup_connection
18
18
  register_namespace
19
- connect_and_add_session
19
+ connect(@config[:base_url], @config[:username], @config[:password], @config[:options])
20
20
  end
21
21
 
22
22
  # Creates a new session from the credentials present in a file
@@ -66,6 +66,7 @@ module SugarCRM; class Session
66
66
  SugarCRM::Module.deregister_all(self)
67
67
  @connection_pool = SugarCRM::ConnectionPool.new(self)
68
68
  SugarCRM::Module.register_all(self)
69
+ SugarCRM.add_session(self)
69
70
  load_extensions
70
71
  true
71
72
  end
@@ -195,11 +196,6 @@ module SugarCRM; class Session
195
196
  def load_extensions
196
197
  self.class.validate_path @extensions_path
197
198
  Dir[File.join(@extensions_path, '**', '*.rb').to_s].each { |f| load(f) }
198
- end
199
-
200
- def connect_and_add_session
201
- connect(@config[:base_url], @config[:username], @config[:password], @config[:options])
202
- SugarCRM.add_session(self)
203
199
  end
204
200
 
205
201
  # Returns hash containing only keys/values relating to connection pool options. These are removed from parameter hash.
data/sugarcrm.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{sugarcrm}
8
- s.version = "0.9.12"
8
+ s.version = "0.9.13"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Carl Hicks", "David Sulc"]
12
- s.date = %q{2011-03-02}
12
+ s.date = %q{2011-04-06}
13
13
  s.default_executable = %q{sugarcrm}
14
14
  s.email = %q{carl.hicks@gmail.com}
15
15
  s.executables = ["sugarcrm"]
@@ -78,12 +78,11 @@ Gem::Specification.new do |s|
78
78
  "./lib/sugarcrm/module.rb",
79
79
  "./lib/sugarcrm/module_methods.rb",
80
80
  "./lib/sugarcrm/session.rb",
81
- "./sugarcrm.gemspec",
82
- "./sugarcrm.tmproj"
81
+ "./sugarcrm.gemspec"
83
82
  ]
84
83
  s.homepage = %q{http://github.com/chicks/sugarcrm}
85
84
  s.require_paths = ["lib"]
86
- s.rubygems_version = %q{1.3.7}
85
+ s.rubygems_version = %q{1.6.2}
87
86
  s.summary = %q{A less clunky way to interact with SugarCRM via REST.}
88
87
  s.test_files = [
89
88
  "test/connection/test_get_available_modules.rb",
@@ -106,6 +105,7 @@ Gem::Specification.new do |s|
106
105
  "test/test_associations.rb",
107
106
  "test/test_connection.rb",
108
107
  "test/test_connection_pool.rb",
108
+ "test/test_finders.rb",
109
109
  "test/test_module.rb",
110
110
  "test/test_response.rb",
111
111
  "test/test_session.rb",
@@ -113,7 +113,6 @@ Gem::Specification.new do |s|
113
113
  ]
114
114
 
115
115
  if s.respond_to? :specification_version then
116
- current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
117
116
  s.specification_version = 3
118
117
 
119
118
  if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
@@ -18,13 +18,13 @@ class TestConnectionPool < ActiveSupport::TestCase
18
18
  end
19
19
 
20
20
  should "be able to specify its timeout" do
21
- assert_equal 5, SugarCRM.session.connection_pool.timeout # test default
21
+ default_timeout = SugarCRM.session.connection_pool.timeout
22
22
 
23
23
  config = SugarCRM.session.config
24
- sess = SugarCRM::Session.new(config[:base_url], config[:username], config[:password], {:connection_pool => {:wait_timeout => 3}})
24
+ sess = SugarCRM::Session.new(config[:base_url], config[:username], config[:password], {:connection_pool => {:wait_timeout => default_timeout+1}})
25
25
 
26
26
  begin
27
- assert_equal 3, sess.connection_pool.timeout
27
+ assert_equal default_timeout+1, sess.connection_pool.timeout
28
28
  ensure
29
29
  sess.disconnect!
30
30
  end