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.
- data/lib/asf_adapter.rb +41 -46
- data/lib/result_array.rb +34 -0
- data/lib/rforce.rb +90 -79
- data/test/unit/basic_test.rb +40 -4
- data/test/unit/profiler_results.txt +1072 -0
- data/test/unit/profiler_results_live.txt +1347 -0
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_add_notes_to_contact.recording +1050 -1017
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_assignment_rule_id.recording +1078 -0
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_batch_insert.recording +674 -644
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_count_contacts.recording +770 -708
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_create_a_contact.recording +731 -706
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_find_a_contact.recording +741 -716
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_find_a_contact_by_first_name.recording +1026 -764
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_find_a_contact_by_id.recording +791 -764
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_find_addresses.recording +1297 -0
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_get_created_by_from_contact.recording +2325 -2280
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_master_detail.recording +1315 -1302
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_read_all_content_columns.recording +691 -666
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_save_a_contact.recording +741 -716
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_use_default_rule.recording +1078 -0
- data/test/unit/recorded_results/AsfUnitTestsBasicTest.test_use_update_mru.recording +1078 -0
- data/test/unit/recorded_test_case.rb +1 -4
- data/test/unit/test.html +157 -0
- data/test/unit/test.html~ +183 -0
- metadata +26 -18
- 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
|
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 =
|
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
|
267
|
+
limit = extract_sql_modifier(soql, "LIMIT")
|
278
268
|
|
279
269
|
# Look for an OFFSET clause
|
280
|
-
soql
|
270
|
+
offset = extract_sql_modifier(soql, "OFFSET")
|
281
271
|
|
282
272
|
# Fixup column references to use api names
|
283
|
-
columns =
|
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]
|
352
|
-
|
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(
|
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]
|
381
|
-
|
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(
|
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
|
-
|
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
|
-
|
617
|
-
|
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" }' <<
|
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
|
-
|
666
|
-
|
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
|
data/lib/result_array.rb
ADDED
@@ -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
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
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
|
-
|
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
|
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
|
data/test/unit/basic_test.rb
CHANGED
@@ -17,10 +17,10 @@
|
|
17
17
|
|
18
18
|
require 'rubygems'
|
19
19
|
|
20
|
-
#require_gem 'activesalesforce', '>= 0.
|
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 :
|
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
|
|