activesalesforce 0.4.3 → 0.4.4

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.
Files changed (26) hide show
  1. data/lib/asf_adapter.rb +41 -46
  2. data/lib/result_array.rb +34 -0
  3. data/lib/rforce.rb +90 -79
  4. data/test/unit/basic_test.rb +40 -4
  5. data/test/unit/profiler_results.txt +1072 -0
  6. data/test/unit/profiler_results_live.txt +1347 -0
  7. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_add_notes_to_contact.recording +1050 -1017
  8. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_assignment_rule_id.recording +1078 -0
  9. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_batch_insert.recording +674 -644
  10. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_count_contacts.recording +770 -708
  11. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_create_a_contact.recording +731 -706
  12. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_find_a_contact.recording +741 -716
  13. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_find_a_contact_by_first_name.recording +1026 -764
  14. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_find_a_contact_by_id.recording +791 -764
  15. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_find_addresses.recording +1297 -0
  16. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_get_created_by_from_contact.recording +2325 -2280
  17. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_master_detail.recording +1315 -1302
  18. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_read_all_content_columns.recording +691 -666
  19. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_save_a_contact.recording +741 -716
  20. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_use_default_rule.recording +1078 -0
  21. data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_use_update_mru.recording +1078 -0
  22. data/test/unit/recorded_test_case.rb +1 -4
  23. data/test/unit/test.html +157 -0
  24. data/test/unit/test.html~ +183 -0
  25. metadata +26 -18
  26. data/test/unit/recorded_results/AsfUnitTestsAsfScaffoldGeneratorTest.test_describe_layout.recording +0 -1789
data/lib/asf_adapter.rb CHANGED
@@ -30,15 +30,7 @@ require File.dirname(__FILE__) + '/asf_active_record'
30
30
  require File.dirname(__FILE__) + '/id_resolver'
31
31
  require File.dirname(__FILE__) + '/sid_authentication_filter'
32
32
  require File.dirname(__FILE__) + '/recording_binding'
33
-
34
-
35
- class ResultArray < Array
36
- attr_reader :actual_size
37
-
38
- def initialize(actual_size)
39
- @actual_size = actual_size
40
- end
41
- end
33
+ require File.dirname(__FILE__) + '/result_array'
42
34
 
43
35
 
44
36
  module ActiveRecord
@@ -262,11 +254,9 @@ module ActiveRecord
262
254
  end
263
255
 
264
256
  raw_table_name = sql.match(/FROM (\w+)/i)[1]
265
- table_name = raw_table_name.singularize
266
- entity_name = entity_name_from_table(table_name)
267
- entity_def = get_entity_def(entity_name)
257
+ table_name, columns, entity_def = lookup(raw_table_name)
268
258
 
269
- column_names = api_column_names(table_name)
259
+ column_names = columns.map { |column| column.api_name }
270
260
 
271
261
  # Always (unless COUNT*)'ing) select all columns (required for the AR attributes mechanism to work correctly
272
262
  soql = sql.sub(/SELECT .+ FROM/i, "SELECT #{column_names.join(', ')} FROM") unless selectCountMatch
@@ -274,13 +264,13 @@ module ActiveRecord
274
264
  soql.sub!(/\s+FROM\s+\w+/i, " FROM #{entity_def.api_name}")
275
265
 
276
266
  # Look for a LIMIT clause
277
- soql.sub!(/LIMIT\s+1/i, "")
267
+ limit = extract_sql_modifier(soql, "LIMIT")
278
268
 
279
269
  # Look for an OFFSET clause
280
- soql.sub!(/\d+\s+OFFSET\s+\d+/i, "")
270
+ offset = extract_sql_modifier(soql, "OFFSET")
281
271
 
282
272
  # Fixup column references to use api names
283
- columns = columns_map(table_name)
273
+ columns = entity_def.column_name_to_column
284
274
  soql.gsub!(/((?:\w+\.)?\w+)(?=\s*(?:=|!=|<|>|<=|>=)\s*(?:'[^']*'|NULL|TRUE|FALSE))/mi) do |column_name|
285
275
  # strip away any table alias
286
276
  column_name.sub!(/\w+\./, '')
@@ -295,12 +285,14 @@ module ActiveRecord
295
285
  soql.sub!(/#{raw_table_name}\./i, "#{entity_def.api_name}.")
296
286
 
297
287
  @connection.batch_size = @batch_size if @batch_size
288
+ @connection.batch_size = limit if limit
289
+
298
290
  @batch_size = nil
299
291
 
300
292
  queryResult = get_result(@connection.query(:queryString => soql), :query)
301
293
  records = queryResult[:records]
302
294
 
303
- result = ResultArray.new(queryResult[:size].to_i)
295
+ result = ActiveSalesforce::ResultArray.new(queryResult[:size].to_i)
304
296
  return result unless records
305
297
 
306
298
  records = [ records ] unless records.is_a?(Array)
@@ -324,7 +316,10 @@ module ActiveRecord
324
316
  end
325
317
  end
326
318
 
327
- result << row
319
+ result << row
320
+
321
+ # Insure that only LIMIT rows are returned
322
+ break if limit and result.length >= limit
328
323
  end
329
324
 
330
325
  if selectCountMatch
@@ -348,9 +343,8 @@ module ActiveRecord
348
343
  def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
349
344
  log(sql, name) {
350
345
  # Convert sql to sobject
351
- table_name = sql.match(/INSERT\s+INTO\s+(\w+)\s+/i)[1].singularize
352
- entity_name = entity_name_from_table(table_name)
353
- columns = columns_map(table_name)
346
+ table_name, columns, entity_def = lookup(sql.match(/INSERT\s+INTO\s+(\w+)\s+/i)[1])
347
+ columns = entity_def.column_name_to_column
354
348
 
355
349
  # Extract array of column names
356
350
  names = sql.match(/\((.+)\)\s+VALUES/i)[1].scan(/\w+/i)
@@ -363,7 +357,7 @@ module ActiveRecord
363
357
 
364
358
  fields = get_fields(columns, names, values, :createable)
365
359
 
366
- sobject = create_sobject(entity_name, nil, fields)
360
+ sobject = create_sobject(entity_def.api_name, nil, fields)
367
361
 
368
362
  # Track the id to be able to update it when the create() is actually executed
369
363
  id = String.new
@@ -377,9 +371,8 @@ module ActiveRecord
377
371
  def update(sql, name = nil) #:nodoc:
378
372
  log(sql, name) {
379
373
  # Convert sql to sobject
380
- table_name = sql.match(/UPDATE\s+(\w+)\s+/i)[1].singularize
381
- entity_name = entity_name_from_table(table_name)
382
- columns = columns_map(table_name)
374
+ table_name, columns, entity_def = lookup(sql.match(/UPDATE\s+(\w+)\s+/i)[1])
375
+ columns = entity_def.column_name_to_column
383
376
 
384
377
  match = sql.match(/SET\s+(.+)\s+WHERE/mi)[1]
385
378
  names = match.scan(/(\w+)\s*=\s*('|NULL|TRUE|FALSE)/i)
@@ -392,7 +385,7 @@ module ActiveRecord
392
385
 
393
386
  id = sql.match(/WHERE\s+id\s*=\s*'(\w+)'/i)[1]
394
387
 
395
- sobject = create_sobject(entity_name, id, fields)
388
+ sobject = create_sobject(entity_def.api_name, id, fields)
396
389
 
397
390
  @command_boxcar << ActiveSalesforce::BoxcarCommand::Update.new(self, sobject)
398
391
  }
@@ -468,6 +461,17 @@ module ActiveRecord
468
461
  end
469
462
 
470
463
 
464
+ def extract_sql_modifier(soql, modifier)
465
+ value = soql.match(/\s+#{modifier}\s+(\d+)/i)
466
+ if value
467
+ value = value[1].to_i
468
+ soql.sub!(/\s+#{modifier}\s+\d+/i, "")
469
+ end
470
+
471
+ value
472
+ end
473
+
474
+
471
475
  def get_result(response, method)
472
476
  responseName = (method.to_s + "Response").to_sym
473
477
  finalResponse = response[responseName]
@@ -538,7 +542,7 @@ module ActiveRecord
538
542
  key_prefix = metadata[:keyPrefix]
539
543
 
540
544
  entity_def = ActiveSalesforce::EntityDefinition.new(self, entity_name,
541
- cached_columns, cached_relationships, custom, key_prefix)
545
+ cached_columns, cached_relationships, custom, key_prefix)
542
546
 
543
547
  @entity_def_map[entity_name] = entity_def
544
548
  @keyprefix_to_entity_def_map[key_prefix] = entity_def
@@ -613,19 +617,8 @@ module ActiveRecord
613
617
 
614
618
 
615
619
  def columns(table_name, name = nil)
616
- entity_name = entity_name_from_table(table_name)
617
- get_entity_def(entity_name).columns
618
- end
619
-
620
-
621
- def columns_map(table_name, name = nil)
622
- entity_name = entity_name_from_table(table_name)
623
- get_entity_def(entity_name).column_name_to_column
624
- end
625
-
626
-
627
- def entity_name_from_table(table_name)
628
- return table_name.singularize.camelize
620
+ table_name, columns, entity_def = lookup(table_name)
621
+ entity_def.columns
629
622
  end
630
623
 
631
624
 
@@ -640,11 +633,9 @@ module ActiveRecord
640
633
 
641
634
 
642
635
  def create_sobject(entity_name, id, fields)
643
- entity_def = get_entity_def(entity_name)
644
-
645
636
  sobj = []
646
637
 
647
- sobj << 'type { :xmlns => "urn:sobject.partner.soap.sforce.com" }' << entity_def.api_name
638
+ sobj << 'type { :xmlns => "urn:sobject.partner.soap.sforce.com" }' << entity_name
648
639
  sobj << 'Id { :xmlns => "urn:sobject.partner.soap.sforce.com" }' << id if id
649
640
 
650
641
  # now add any changed fields
@@ -660,10 +651,14 @@ module ActiveRecord
660
651
  def column_names(table_name)
661
652
  columns(table_name).map { |column| column.name }
662
653
  end
654
+
663
655
 
664
-
665
- def api_column_names(table_name)
666
- columns(table_name).map { |column| column.api_name }
656
+ def lookup(raw_table_name)
657
+ table_name = raw_table_name.singularize
658
+ entity_def = get_entity_def(table_name.camelize)
659
+ columns = entity_def.columns
660
+
661
+ [table_name, columns, entity_def]
667
662
  end
668
663
 
669
664
  end
@@ -0,0 +1,34 @@
1
+ =begin
2
+ ActiveSalesforce
3
+ Copyright 2006 Doug Chasman
4
+
5
+ Licensed under the Apache License, Version 2.0 (the "License");
6
+ you may not use this file except in compliance with the License.
7
+ You may obtain a copy of the License at
8
+
9
+ http://www.apache.org/licenses/LICENSE-2.0
10
+
11
+ Unless required by applicable law or agreed to in writing, software
12
+ distributed under the License is distributed on an "AS IS" BASIS,
13
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ See the License for the specific language governing permissions and
15
+ limitations under the License.
16
+ =end
17
+
18
+ require 'rubygems'
19
+ require_gem 'rails', ">= 1.0.0"
20
+
21
+ require 'pp'
22
+
23
+
24
+ module ActiveSalesforce
25
+
26
+ class ResultArray < Array
27
+ attr_reader :actual_size
28
+
29
+ def initialize(actual_size)
30
+ @actual_size = actual_size
31
+ end
32
+ end
33
+
34
+ end
data/lib/rforce.rb CHANGED
@@ -1,24 +1,24 @@
1
1
  =begin
2
- RForce v0.1
3
- Copyright (c) 2005 Ian Dees
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in
13
- all copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
2
+ RForce v0.1
3
+ Copyright (c) 2005 Ian Dees
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
22
22
  =end
23
23
 
24
24
  # RForce is a simple Ruby binding to the SalesForce CRM system.
@@ -59,7 +59,7 @@ require_gem 'builder'
59
59
 
60
60
 
61
61
  module RForce
62
-
62
+
63
63
  #Allows indexing hashes like method calls: hash.key
64
64
  #to supplement the traditional way of indexing: hash[key]
65
65
  module FlashHash
@@ -67,50 +67,50 @@ module RForce
67
67
  self[method]
68
68
  end
69
69
  end
70
-
70
+
71
71
  #Turns an XML response from the server into a Ruby
72
72
  #object whose methods correspond to nested XML elements.
73
73
  class SoapResponse
74
74
  include FlashHash
75
-
75
+
76
76
  #Parses an XML string into structured data.
77
77
  def initialize(content)
78
78
  document = REXML::Document.new content
79
79
  node = REXML::XPath.first document, '//soapenv:Body'
80
80
  @parsed = SoapResponse.parse node
81
81
  end
82
-
82
+
83
83
  #Allows this object to act like a hash (and therefore
84
84
  #as a FlashHash via the include above).
85
85
  def [](symbol)
86
86
  @parsed[symbol]
87
87
  end
88
-
88
+
89
89
  #Digests an XML DOM node into nested Ruby types.
90
90
  def SoapResponse.parse(node)
91
91
  #Convert text nodes into simple strings.
92
92
  return node.text unless node.has_elements?
93
-
93
+
94
94
  #Convert nodes with children into FlashHashes.
95
95
  elements = {}
96
96
  class << elements
97
97
  include FlashHash
98
98
  end
99
-
99
+
100
100
  #Add all the element's children to the hash.
101
101
  node.each_element do |e|
102
102
  name = e.name.to_sym
103
-
103
+
104
104
  case elements[name]
105
105
  #The most common case: unique child element tags.
106
106
  when NilClass: elements[name] = parse(e)
107
-
107
+
108
108
  #Non-unique child elements become arrays:
109
-
109
+
110
110
  #We've already created the array: just
111
111
  #add the element.
112
112
  when Array: elements[name] << parse(e)
113
-
113
+
114
114
  #We haven't created the array yet: do so,
115
115
  #then put the existing element in, followed
116
116
  #by the new one.
@@ -119,17 +119,17 @@ module RForce
119
119
  elements[name] << parse(e)
120
120
  end
121
121
  end
122
-
122
+
123
123
  return elements
124
124
  end
125
125
  end
126
126
 
127
-
127
+
128
128
  #Implements the connection to the SalesForce server.
129
129
  class Binding
130
130
  DEFAULT_BATCH_SIZE = 10
131
- attr_accessor :batch_size, :url
132
-
131
+ attr_accessor :batch_size, :url, :assignment_rule_id, :use_default_rule, :update_mru
132
+
133
133
  #Fill in the guts of this typical SOAP envelope
134
134
  #with the session ID and the body of the SOAP request.
135
135
  Envelope = <<-HERE
@@ -144,60 +144,66 @@ module RForce
144
144
  <QueryOptions>
145
145
  <batchSize>%d</batchSize>
146
146
  </QueryOptions>
147
+ %s
147
148
  </env:Header>
148
149
  <env:Body>
149
150
  %s
150
151
  </env:Body>
151
152
  </env:Envelope>
152
153
  HERE
154
+
155
+ AssignmentRuleHeaderUsingRuleId = "<AssignmentRuleHeader><assignment_rule_id>%s</assignment_rule_id></AssignmentRuleHeader>"
156
+ AssignmentRuleHeaderUsingDefaultRule = "<AssignmentRuleHeader><use_default_rule>true</use_default_rule></AssignmentRuleHeader>"
157
+ MruHeader = "<MruHeader><update_mru>true</update_mru></MruHeader>"
153
158
 
154
-
159
+
155
160
  #Connect to the server securely.
156
161
  def initialize(url, sid)
157
162
  init_server(url)
158
-
163
+
159
164
  @session_id = sid
160
165
  @batch_size = DEFAULT_BATCH_SIZE
161
166
  end
162
-
163
-
167
+
168
+
164
169
  def show_debug
165
170
  $DEBUG or ENV['SHOWSOAP']
166
171
  end
167
-
172
+
168
173
 
169
174
  def init_server(url)
170
175
  @url = URI.parse(url)
171
176
  @server = Net::HTTP.new(@url.host, @url.port)
172
177
  @server.use_ssl = @url.scheme == 'https'
173
178
  @server.verify_mode = OpenSSL::SSL::VERIFY_NONE
174
-
175
- # run ruby with -d to see SOAP wiredumps.
179
+
180
+ # run ruby with -d or env variable SHOWSOAP=true to see SOAP wiredumps.
176
181
  @server.set_debug_output $stderr if show_debug
177
182
  end
178
-
179
-
183
+
184
+
180
185
  #Log in to the server and remember the session ID
181
186
  #returned to us by SalesForce.
182
187
  def login(user, password)
183
- puts "\n\nIn login(#{user})\n\n"
184
-
185
188
  @user = user
186
189
  @password = password
187
-
190
+
188
191
  response = call_remote(:login, [:username, user, :password, password])
189
-
190
- raise "Incorrect user name / password [#{response.fault}]" unless response.loginResponse
191
-
192
+
193
+ unless response.loginResponse
194
+ pp response
195
+ raise "Incorrect user name / password [#{response.fault}]"
196
+ end
197
+
192
198
  result = response[:loginResponse][:result]
193
199
  @session_id = result[:sessionId]
194
-
200
+
195
201
  init_server(result[:serverUrl])
196
-
202
+
197
203
  response
198
204
  end
199
205
 
200
-
206
+
201
207
  #Call a method on the remote server. Arguments can be
202
208
  #a hash or (if order is important) an array of alternating
203
209
  #keys and values.
@@ -206,58 +212,63 @@ module RForce
206
212
  expanded = ''
207
213
  @builder = Builder::XmlMarkup.new(:target => expanded)
208
214
  expand({method => args}, 'urn:partner.soap.sforce.com')
215
+
216
+ extra_headers = ""
217
+ extra_headers << (AssignmentRuleHeaderUsingRuleId % assignment_rule_id) if assignment_rule_id
218
+ extra_headers << AssignmentRuleHeaderUsingDefaultRule if use_default_rule
219
+ extra_headers << MruHeader if update_mru
209
220
 
210
221
  #Fill in the blanks of the SOAP envelope with our
211
222
  #session ID and the expanded XML of our request.
212
- request = (Envelope % [@session_id, @batch_size, expanded])
213
-
223
+ request = (Envelope % [@session_id, @batch_size, extra_headers, expanded])
224
+
214
225
  # reset the batch size for the next request
215
226
  @batch_size = DEFAULT_BATCH_SIZE
216
-
227
+
217
228
  # gzip request
218
229
  request = encode(request)
219
-
230
+
220
231
  headers = {
221
232
  'Connection' => 'Keep-Alive',
222
233
  'Content-Type' => 'text/xml',
223
234
  'SOAPAction' => '""',
224
- 'User-Agent' => 'ActiveSalesforce RForce'
235
+ 'User-Agent' => 'ActiveSalesforce'
225
236
  }
226
237
 
227
238
  unless show_debug
228
239
  headers['Accept-Encoding'] = 'gzip'
229
240
  headers['Content-Encoding'] = 'gzip'
230
241
  end
231
-
242
+
232
243
  #Send the request to the server and read the response.
233
- response = @server.post2(@url.path, request, headers)
234
-
244
+ response = @server.post2(@url.path, request.lstrip, headers)
245
+
235
246
  # decode if we have encoding
236
247
  content = decode(response)
237
-
248
+
238
249
  # Check to see if INVALID_SESSION_ID was raised and try to relogin in
239
250
  if method != :login and @session_id and response =~ /<faultcode>sf\:INVALID_SESSION_ID<\/faultcode>/
240
251
  puts "\n\nSession timeout error - auto relogin activated"
241
-
252
+
242
253
  login(@user, @password)
243
-
254
+
244
255
  #Send the request to the server and read the response.
245
256
  response = @server.post2(@url.path, request, headers)
246
-
257
+
247
258
  content = decode(response)
248
259
  end
249
-
260
+
250
261
  SoapResponse.new(content)
251
262
  end
252
263
 
253
-
264
+
254
265
  # decode gzip
255
266
  def decode(response)
256
267
  encoding = response['Content-Encoding']
257
-
268
+
258
269
  # return body if no encoding
259
270
  if !encoding then return response.body end
260
-
271
+
261
272
  # decode gzip
262
273
  case encoding.strip
263
274
  when 'gzip':
@@ -273,7 +284,7 @@ module RForce
273
284
  end
274
285
  end
275
286
 
276
-
287
+
277
288
  # encode gzip
278
289
  def encode(request)
279
290
  return request if show_debug
@@ -287,28 +298,28 @@ module RForce
287
298
  gzw.close
288
299
  end
289
300
  end
290
-
291
-
301
+
302
+
292
303
  #Turns method calls on this object into remote SOAP calls.
293
304
  def method_missing(method, *args)
294
305
  unless args.size == 1 && [Hash, Array].include?(args[0].class)
295
306
  raise 'Expected 1 Hash or Array argument'
296
307
  end
297
-
308
+
298
309
  call_remote method, args[0]
299
310
  end
300
311
 
301
-
312
+
302
313
  #Expand Ruby data structures into XML.
303
314
  def expand(args, xmlns = nil)
304
315
  #Nest arrays: [:a, 1, :b, 2] => [[:a, 1], [:b, 2]]
305
316
  if (args.class == Array)
306
317
  args.each_index{|i| args[i, 2] = [args[i, 2]]}
307
318
  end
308
-
319
+
309
320
  args.each do |key, value|
310
321
  attributes = xmlns ? {:xmlns => xmlns} : {}
311
-
322
+
312
323
  #If the XML tag requires attributes,
313
324
  #the tag name will contain a space
314
325
  #followed by a string representation
@@ -318,16 +329,16 @@ module RForce
318
329
  #becomes <sObject xsi:type="Opportunity>...</sObject>
319
330
  if key.is_a? String
320
331
  key, modifier = key.split(' ', 2)
321
-
332
+
322
333
  attributes.merge!(eval(modifier)) if modifier
323
334
  end
324
-
335
+
325
336
  #Create an XML element and fill it with this
326
337
  #value's sub-items.
327
338
  case value
328
339
  when Hash, Array
329
340
  @builder.tag!(key, attributes) do expand value; end
330
-
341
+
331
342
  when String
332
343
  @builder.tag!(key, attributes) { @builder.text! value }
333
344
  end
@@ -17,10 +17,10 @@
17
17
 
18
18
  require 'rubygems'
19
19
 
20
- #require_gem 'activesalesforce', '>= 0.2.6'
21
- require 'activesalesforce'
20
+ #require_gem 'activesalesforce', '>= 0.4.3'
21
+ require File.dirname(__FILE__) + '/../../lib/activesalesforce'
22
22
 
23
- require 'recorded_test_case'
23
+ require File.dirname(__FILE__) + '/recorded_test_case'
24
24
  require 'pp'
25
25
 
26
26
 
@@ -30,6 +30,9 @@ end
30
30
  class Department < ActiveRecord::Base
31
31
  end
32
32
 
33
+ class Address < ActiveRecord::Base
34
+ end
35
+
33
36
 
34
37
  module Asf
35
38
  module UnitTests
@@ -42,7 +45,7 @@ module Asf
42
45
  def initialize(test_method_name)
43
46
  super(test_method_name)
44
47
 
45
- #force_recording :test_batch_insert
48
+ #force_recording :test_master_detail
46
49
  end
47
50
 
48
51
  def setup
@@ -51,6 +54,9 @@ module Asf
51
54
  super
52
55
 
53
56
  @contact = Contact.new
57
+
58
+ reset_header_options
59
+
54
60
  contact.first_name = 'DutchTestFirstName'
55
61
  contact.last_name = 'DutchTestLastName'
56
62
  contact.home_phone = '555-555-1212'
@@ -60,10 +66,19 @@ module Asf
60
66
  end
61
67
 
62
68
  def teardown
69
+ reset_header_options
70
+
63
71
  contact.destroy if contact
64
72
 
65
73
  super
66
74
  end
75
+
76
+ def reset_header_options
77
+ binding = Contact.connection.binding
78
+ binding.assignment_rule_id = nil
79
+ binding.use_default_rule = false
80
+ binding.update_mru = false
81
+ end
67
82
 
68
83
 
69
84
  def test_create_a_contact
@@ -101,6 +116,23 @@ module Asf
101
116
  user = contact.created_by
102
117
  assert_equal contact.created_by_id, user.id
103
118
  end
119
+
120
+ def test_use_update_mru
121
+ Contact.connection.binding.update_mru = true
122
+ contact.save
123
+ end
124
+
125
+ def test_use_default_rule
126
+ Contact.connection.binding.use_default_rule = true
127
+ contact.save
128
+ end
129
+
130
+ def test_assignment_rule_id
131
+ Contact.connection.binding.assignment_rule_id = "1234567890"
132
+ contact.save
133
+ end
134
+
135
+
104
136
 
105
137
  def test_add_notes_to_contact
106
138
  n1 = Note.new(:title => "My Title", :body => "My Body")
@@ -155,6 +187,10 @@ module Asf
155
187
  c1.destroy
156
188
  end
157
189
  end
190
+
191
+ def test_find_addresses
192
+ adresses = Address.find(:all)
193
+ end
158
194
 
159
195
  end
160
196