soapforce 0.1.1
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/.gitignore +18 -0
- data/.travis.yml +9 -0
- data/Gemfile +8 -0
- data/LICENSE.txt +22 -0
- data/README.md +145 -0
- data/Rakefile +9 -0
- data/lib/soapforce.rb +12 -0
- data/lib/soapforce/client.rb +333 -0
- data/lib/soapforce/configuration.rb +20 -0
- data/lib/soapforce/query_result.rb +42 -0
- data/lib/soapforce/sobject.rb +52 -0
- data/lib/soapforce/version.rb +3 -0
- data/resources/partner.wsdl.xml +3657 -0
- data/soapforce.gemspec +33 -0
- data/spec/fixtures/create_response.xml +11 -0
- data/spec/fixtures/delete_response.xml +11 -0
- data/spec/fixtures/describe_global_response.xml +55 -0
- data/spec/fixtures/describe_s_object_response.xml +9 -0
- data/spec/fixtures/describe_s_objects_response.xml +9 -0
- data/spec/fixtures/get_user_info_response.xml +32 -0
- data/spec/fixtures/login_response.xml +39 -0
- data/spec/fixtures/org_id_response.xml +17 -0
- data/spec/fixtures/query_all_response.xml +26 -0
- data/spec/fixtures/query_more_response.xml +26 -0
- data/spec/fixtures/query_response.xml +26 -0
- data/spec/fixtures/retrieve_response.xml +14 -0
- data/spec/fixtures/search_response.xml +8 -0
- data/spec/fixtures/update_response.xml +11 -0
- data/spec/fixtures/upsert_response.xml +17 -0
- data/spec/lib/client_spec.rb +301 -0
- data/spec/lib/configuration_spec.rb +28 -0
- data/spec/lib/query_result_spec.rb +79 -0
- data/spec/lib/sobject_spec.rb +44 -0
- data/spec/spec_helper.rb +21 -0
- data/spec/support/fixture_helpers.rb +58 -0
- data/test.rb +58 -0
- metadata +167 -0
data/soapforce.gemspec
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'soapforce/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = "soapforce"
|
8
|
+
gem.version = Soapforce::VERSION
|
9
|
+
gem.authors = ["Joe Heth"]
|
10
|
+
gem.email = ["joeheth@gmail.com"]
|
11
|
+
gem.description = %q{A ruby client for the Salesforce SOAP API based on Savon.}
|
12
|
+
gem.summary = %q{Wraps Savon with helper methods and custom types for interacting with the Salesforce SOAP API.}
|
13
|
+
gem.homepage = "https://github.com/TinderBox/soapforce"
|
14
|
+
|
15
|
+
ignores = File.readlines('.gitignore').grep(/\S+/).map(&:chomp)
|
16
|
+
dotfiles = %w[.gitignore .travis.yml]
|
17
|
+
|
18
|
+
all_files_without_ignores = Dir['**/*'].reject { |f|
|
19
|
+
File.directory?(f) || ignores.any? { |i| File.fnmatch(i, f) }
|
20
|
+
}
|
21
|
+
|
22
|
+
gem.files = (all_files_without_ignores + dotfiles).sort
|
23
|
+
|
24
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
25
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
26
|
+
gem.require_paths = ["lib"]
|
27
|
+
|
28
|
+
gem.add_dependency("savon", "~>2.3.0")
|
29
|
+
|
30
|
+
gem.add_development_dependency 'rspec', '~> 2.14.0'
|
31
|
+
gem.add_development_dependency 'webmock', '~> 1.13.0'
|
32
|
+
gem.add_development_dependency 'simplecov', '~> 0.7.1'
|
33
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com">
|
3
|
+
<soapenv:Body>
|
4
|
+
<createResponse>
|
5
|
+
<result>
|
6
|
+
<id>006A000000LbiizIAB</id>
|
7
|
+
<success>true</success>
|
8
|
+
</result>
|
9
|
+
</createResponse>
|
10
|
+
</soapenv:Body>
|
11
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com">
|
3
|
+
<soapenv:Body>
|
4
|
+
<deleteResponse>
|
5
|
+
<result>
|
6
|
+
<id>006A000000LbiizIAB</id>
|
7
|
+
<success>true</success>
|
8
|
+
</result>
|
9
|
+
</deleteResponse>
|
10
|
+
</soapenv:Body>
|
11
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,55 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
3
|
+
<soapenv:Body>
|
4
|
+
<describeGlobalResponse>
|
5
|
+
<result>
|
6
|
+
<encoding>UTF-8</encoding>
|
7
|
+
<maxBatchSize>200</maxBatchSize>
|
8
|
+
<sobjects>
|
9
|
+
<activateable>false</activateable>
|
10
|
+
<createable>true</createable>
|
11
|
+
<custom>false</custom>
|
12
|
+
<customSetting>false</customSetting>
|
13
|
+
<deletable>true</deletable>
|
14
|
+
<deprecatedAndHidden>false</deprecatedAndHidden>
|
15
|
+
<feedEnabled>true</feedEnabled>
|
16
|
+
<keyPrefix>001</keyPrefix>
|
17
|
+
<label>Account</label>
|
18
|
+
<labelPlural>Accounts</labelPlural>
|
19
|
+
<layoutable>true</layoutable>
|
20
|
+
<mergeable>true</mergeable>
|
21
|
+
<name>Account</name>
|
22
|
+
<queryable>true</queryable>
|
23
|
+
<replicateable>true</replicateable>
|
24
|
+
<retrieveable>true</retrieveable>
|
25
|
+
<searchable>true</searchable>
|
26
|
+
<triggerable>true</triggerable>
|
27
|
+
<undeletable>true</undeletable>
|
28
|
+
<updateable>true</updateable>
|
29
|
+
</sobjects>
|
30
|
+
<sobjects>
|
31
|
+
<activateable>false</activateable>
|
32
|
+
<createable>true</createable>
|
33
|
+
<custom>false</custom>
|
34
|
+
<customSetting>false</customSetting>
|
35
|
+
<deletable>true</deletable>
|
36
|
+
<deprecatedAndHidden>false</deprecatedAndHidden>
|
37
|
+
<feedEnabled>false</feedEnabled>
|
38
|
+
<keyPrefix>02Z</keyPrefix>
|
39
|
+
<label>Account Contact Role</label>
|
40
|
+
<labelPlural>Account Contact Role</labelPlural>
|
41
|
+
<layoutable>false</layoutable>
|
42
|
+
<mergeable>false</mergeable>
|
43
|
+
<name>AccountContactRole</name>
|
44
|
+
<queryable>true</queryable>
|
45
|
+
<replicateable>true</replicateable>
|
46
|
+
<retrieveable>true</retrieveable>
|
47
|
+
<searchable>false</searchable>
|
48
|
+
<triggerable>false</triggerable>
|
49
|
+
<undeletable>false</undeletable>
|
50
|
+
<updateable>true</updateable>
|
51
|
+
</sobjects>
|
52
|
+
</result>
|
53
|
+
</describeGlobalResponse>
|
54
|
+
</soapenv:Body>
|
55
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
2
|
+
<soapenv:Body>
|
3
|
+
<describeSObjectResponse>
|
4
|
+
<result>
|
5
|
+
</result>
|
6
|
+
</describeSObjectResponse>
|
7
|
+
</soapenv:Body>
|
8
|
+
</soapenv:Envelope>
|
9
|
+
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
2
|
+
<soapenv:Body>
|
3
|
+
<describeSObjectsResponse>
|
4
|
+
<result>
|
5
|
+
</result>
|
6
|
+
</describeSObjectsResponse>
|
7
|
+
</soapenv:Body>
|
8
|
+
</soapenv:Envelope>
|
9
|
+
|
@@ -0,0 +1,32 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
3
|
+
<soapenv:Body>
|
4
|
+
<getUserInfoResponse>
|
5
|
+
<result>
|
6
|
+
<accessibilityMode>false</accessibilityMode>
|
7
|
+
<currencySymbol>$</currencySymbol>
|
8
|
+
<orgAttachmentFileSizeLimit>5242880</orgAttachmentFileSizeLimit>
|
9
|
+
<orgDefaultCurrencyIsoCode>USD</orgDefaultCurrencyIsoCode>
|
10
|
+
<orgDisallowHtmlAttachments>false</orgDisallowHtmlAttachments>
|
11
|
+
<orgHasPersonAccounts>false</orgHasPersonAccounts>
|
12
|
+
<organizationId>00DA0000000YpZ4MAK</organizationId>
|
13
|
+
<organizationMultiCurrency>false</organizationMultiCurrency>
|
14
|
+
<organizationName>Developer</organizationName>
|
15
|
+
<profileId>00eA0000000AAAAIA2</profileId>
|
16
|
+
<roleId xsi:nil="true"/>
|
17
|
+
<sessionSecondsValid>7200</sessionSecondsValid>
|
18
|
+
<userDefaultCurrencyIsoCode xsi:nil="true"/>
|
19
|
+
<userEmail>johndoe@email.com</userEmail>
|
20
|
+
<userFullName>John Doe</userFullName>
|
21
|
+
<userId>005A000000AAAAY</userId>
|
22
|
+
<userLanguage>en_US</userLanguage>
|
23
|
+
<userLocale>en_US</userLocale>
|
24
|
+
<userName>john.doe@email.com</userName>
|
25
|
+
<userTimeZone>America/Panama</userTimeZone>
|
26
|
+
<userType>Standard</userType>
|
27
|
+
<userUiSkin>Theme3</userUiSkin>
|
28
|
+
</result>
|
29
|
+
</getUserInfoResponse>
|
30
|
+
</soapenv:Body>
|
31
|
+
</soapenv:Envelope>
|
32
|
+
|
@@ -0,0 +1,39 @@
|
|
1
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
2
|
+
<soapenv:Body>
|
3
|
+
<loginResponse>
|
4
|
+
<result>
|
5
|
+
<metadataServerUrl>https://na7.salesforce.com/services/Soap/m/28.0/00DA0000000YpZ4</metadataServerUrl>
|
6
|
+
<passwordExpired>false</passwordExpired>
|
7
|
+
<sandbox>false</sandbox>
|
8
|
+
<serverUrl>https://na7.salesforce.com/services/Soap/u/28.0/00DA0000000YpZ4</serverUrl>
|
9
|
+
<sessionId>00DA0000000YpZ4!ARAAQEH.613sgjdpLDPsev9EBTxM0PMhEzbaCE505DYFCSm8tBkdDBl.NFsmPEISjp7Ccd.t9BTTFa1DRmtbxkikZPI8FqDj</sessionId>
|
10
|
+
<userId>005A000000AAAAAIAY</userId>
|
11
|
+
<userInfo>
|
12
|
+
<accessibilityMode>false</accessibilityMode>
|
13
|
+
<currencySymbol>$</currencySymbol>
|
14
|
+
<orgAttachmentFileSizeLimit>5242880</orgAttachmentFileSizeLimit>
|
15
|
+
<orgDefaultCurrencyIsoCode>USD</orgDefaultCurrencyIsoCode>
|
16
|
+
<orgDisallowHtmlAttachments>false</orgDisallowHtmlAttachments>
|
17
|
+
<orgHasPersonAccounts>false</orgHasPersonAccounts>
|
18
|
+
<organizationId>00DA0000000YpZ4MAK</organizationId>
|
19
|
+
<organizationMultiCurrency>false</organizationMultiCurrency>
|
20
|
+
<organizationName>Developer</organizationName>
|
21
|
+
<profileId>00eA0000000AAAAAA2</profileId>
|
22
|
+
<roleId xsi:nil="true"/>
|
23
|
+
<sessionSecondsValid>7200</sessionSecondsValid>
|
24
|
+
<userDefaultCurrencyIsoCode xsi:nil="true"/>
|
25
|
+
<userEmail>john.doe@email.com</userEmail>
|
26
|
+
<userFullName>John Doe</userFullName>
|
27
|
+
<userId>005A000000AAAAAIAY</userId>
|
28
|
+
<userLanguage>en_US</userLanguage>
|
29
|
+
<userLocale>en_US</userLocale>
|
30
|
+
<userName>john.doe@email.com</userName>
|
31
|
+
<userTimeZone>America/Panama</userTimeZone>
|
32
|
+
<userType>Standard</userType>
|
33
|
+
<userUiSkin>Theme3</userUiSkin>
|
34
|
+
</userInfo>
|
35
|
+
</result>
|
36
|
+
</loginResponse>
|
37
|
+
</soapenv:Body>
|
38
|
+
</soapenv:Envelope>
|
39
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sf="urn:sobject.partner.soap.sforce.com">
|
3
|
+
<soapenv:Body>
|
4
|
+
<queryResponse>
|
5
|
+
<result xsi:type="QueryResult">
|
6
|
+
<done>true</done>
|
7
|
+
<queryLocator xsi:nil="true"/>
|
8
|
+
<records xsi:type="sf:sObject">
|
9
|
+
<sf:type>Organization</sf:type>
|
10
|
+
<sf:Id>00DA0000000YpZ4MAK</sf:Id>
|
11
|
+
<sf:Id>00DA0000000YpZ4MAK</sf:Id>
|
12
|
+
</records>
|
13
|
+
<size>1</size>
|
14
|
+
</result>
|
15
|
+
</queryResponse>
|
16
|
+
</soapenv:Body>
|
17
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sf="urn:sobject.partner.soap.sforce.com">
|
3
|
+
<soapenv:Body>
|
4
|
+
<queryAllResponse>
|
5
|
+
<result xsi:type="QueryResult">
|
6
|
+
<done>true</done>
|
7
|
+
<queryLocator xsi:nil="true"/>
|
8
|
+
<records xsi:type="sf:sObject">
|
9
|
+
<sf:type>Opportunity</sf:type>
|
10
|
+
<sf:Id>006A000000LZhwNIAT</sf:Id>
|
11
|
+
<sf:Id>006A000000LZhwNIAT</sf:Id>
|
12
|
+
<sf:Name>Opportunity 1</sf:Name>
|
13
|
+
<sf:StageName>Prospecting</sf:StageName>
|
14
|
+
</records>
|
15
|
+
<records xsi:type="sf:sObject">
|
16
|
+
<sf:type>Opportunity</sf:type>
|
17
|
+
<sf:Id>006A000000LaF4xIAF</sf:Id>
|
18
|
+
<sf:Id>006A000000LaF4xIAF</sf:Id>
|
19
|
+
<sf:Name>Opportunity 2</sf:Name>
|
20
|
+
<sf:StageName>Value Proposition</sf:StageName>
|
21
|
+
</records>
|
22
|
+
<size>2</size>
|
23
|
+
</result>
|
24
|
+
</queryAllResponse>
|
25
|
+
</soapenv:Body>
|
26
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sf="urn:sobject.partner.soap.sforce.com">
|
3
|
+
<soapenv:Body>
|
4
|
+
<queryMoreResponse>
|
5
|
+
<result xsi:type="QueryResult">
|
6
|
+
<done>true</done>
|
7
|
+
<queryLocator xsi:nil="true"/>
|
8
|
+
<records xsi:type="sf:sObject">
|
9
|
+
<sf:type>Opportunity</sf:type>
|
10
|
+
<sf:Id>006A000000LZhwNIAT</sf:Id>
|
11
|
+
<sf:Id>006A000000LZhwNIAT</sf:Id>
|
12
|
+
<sf:Name>Opportunity 1</sf:Name>
|
13
|
+
<sf:StageName>Prospecting</sf:StageName>
|
14
|
+
</records>
|
15
|
+
<records xsi:type="sf:sObject">
|
16
|
+
<sf:type>Opportunity</sf:type>
|
17
|
+
<sf:Id>006A000000LaF4xIAF</sf:Id>
|
18
|
+
<sf:Id>006A000000LaF4xIAF</sf:Id>
|
19
|
+
<sf:Name>Opportunity 2</sf:Name>
|
20
|
+
<sf:StageName>Value Proposition</sf:StageName>
|
21
|
+
</records>
|
22
|
+
<size>2</size>
|
23
|
+
</result>
|
24
|
+
</queryMoreResponse>
|
25
|
+
</soapenv:Body>
|
26
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,26 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:sf="urn:sobject.partner.soap.sforce.com">
|
3
|
+
<soapenv:Body>
|
4
|
+
<queryResponse>
|
5
|
+
<result xsi:type="QueryResult">
|
6
|
+
<done>true</done>
|
7
|
+
<queryLocator xsi:nil="true"/>
|
8
|
+
<records xsi:type="sf:sObject">
|
9
|
+
<sf:type>Opportunity</sf:type>
|
10
|
+
<sf:Id>006A000000LZhwNIAT</sf:Id>
|
11
|
+
<sf:Id>006A000000LZhwNIAT</sf:Id>
|
12
|
+
<sf:Name>Opportunity 1</sf:Name>
|
13
|
+
<sf:StageName>Prospecting</sf:StageName>
|
14
|
+
</records>
|
15
|
+
<records xsi:type="sf:sObject">
|
16
|
+
<sf:type>Opportunity</sf:type>
|
17
|
+
<sf:Id>006A000000LaF4xIAF</sf:Id>
|
18
|
+
<sf:Id>006A000000LaF4xIAF</sf:Id>
|
19
|
+
<sf:Name>Opportunity 2</sf:Name>
|
20
|
+
<sf:StageName>Value Proposition</sf:StageName>
|
21
|
+
</records>
|
22
|
+
<size>2</size>
|
23
|
+
</result>
|
24
|
+
</queryResponse>
|
25
|
+
</soapenv:Body>
|
26
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com" xmlns:sf="urn:sobject.partner.soap.sforce.com" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
3
|
+
<soapenv:Body>
|
4
|
+
<retrieveResponse>
|
5
|
+
<result xsi:type="sf:sObject">
|
6
|
+
<sf:type>Opportunity</sf:type>
|
7
|
+
<sf:Id>006A000000LbkT5IAJ</sf:Id>
|
8
|
+
<sf:Name>SOAPForce Opportunity</sf:Name>
|
9
|
+
<sf:Description xsi:nil="true"/>
|
10
|
+
<sf:StageName>Prospecting</sf:StageName>
|
11
|
+
</result>
|
12
|
+
</retrieveResponse>
|
13
|
+
</soapenv:Body>
|
14
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com">
|
3
|
+
<soapenv:Body>
|
4
|
+
<updateResponse>
|
5
|
+
<result>
|
6
|
+
<id>006A000000LbiizIAB</id>
|
7
|
+
<success>true</success>
|
8
|
+
</result>
|
9
|
+
</updateResponse>
|
10
|
+
</soapenv:Body>
|
11
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
2
|
+
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="urn:partner.soap.sforce.com">
|
3
|
+
<soapenv:Body>
|
4
|
+
<upsertResponse>
|
5
|
+
<result>
|
6
|
+
<created>true</created>
|
7
|
+
<id>006A000000LbiizIAB</id>
|
8
|
+
<success>true</success>
|
9
|
+
</result>
|
10
|
+
<result>
|
11
|
+
<created>false</created>
|
12
|
+
<id>006A000000LbiizIAB</id>
|
13
|
+
<success>true</success>
|
14
|
+
</result>
|
15
|
+
</upsertResponse>
|
16
|
+
</soapenv:Body>
|
17
|
+
</soapenv:Envelope>
|
@@ -0,0 +1,301 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Soapforce::Client do
|
4
|
+
let(:endpoint) { 'https://na15.salesforce.com' }
|
5
|
+
|
6
|
+
describe "#operations" do
|
7
|
+
it "should return list of operations from the wsdl" do
|
8
|
+
subject.operations.should be_a(Array)
|
9
|
+
subject.operations.should include(:login, :logout, :query, :create)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "#login" do
|
14
|
+
it "authenticates with username and password_and_token" do
|
15
|
+
|
16
|
+
body = "<tns:login><tns:username>testing</tns:username><tns:password>password_and_token</tns:password></tns:login>"
|
17
|
+
stub = stub_login_request({with_body: body})
|
18
|
+
stub.to_return(:status => 200, :body => fixture("login_response")) #, :headers => {})
|
19
|
+
|
20
|
+
subject.login(username: 'testing', password: 'password_and_token')
|
21
|
+
end
|
22
|
+
|
23
|
+
it "authenticates with session_id and instance_url" do
|
24
|
+
|
25
|
+
body = "<tns:getUserInfo></tns:getUserInfo>"
|
26
|
+
stub = stub_login_request({
|
27
|
+
server_url: 'https://na15.salesforce.com',
|
28
|
+
headers: {session_id: 'abcde12345'},
|
29
|
+
with_body: body}
|
30
|
+
)
|
31
|
+
stub.to_return(:status => 200, :body => fixture("get_user_info_response"))
|
32
|
+
|
33
|
+
user_info = subject.login(session_id: 'abcde12345', server_url: 'https://na15.salesforce.com')
|
34
|
+
|
35
|
+
user_info[:user_email].should == "johndoe@email.com"
|
36
|
+
user_info[:user_full_name].should == "John Doe"
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should raise arugment error when no parameters are passed" do
|
40
|
+
expect { subject.login(session_id: 'something') }.to raise_error(ArgumentError)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "list_sobjects" do
|
45
|
+
it "should return array of object names" do
|
46
|
+
|
47
|
+
body = "<tns:describeGlobal></tns:describeGlobal>"
|
48
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'describe_global_response'})
|
49
|
+
|
50
|
+
subject.list_sobjects.should == ['Account', 'AccountContactRole']
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "org_id" do
|
55
|
+
it "should return organization id" do
|
56
|
+
|
57
|
+
body = "<tns:query><tns:queryString>select id from Organization</tns:queryString></tns:query>"
|
58
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'org_id_response'})
|
59
|
+
|
60
|
+
subject.org_id.should == "00DA0000000YpZ4MAK"
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "#descibeSObject" do
|
65
|
+
|
66
|
+
it "supports single sobject name" do
|
67
|
+
|
68
|
+
body = "<tns:describeSObject><tns:sObjectType>Opportunity</tns:sObjectType></tns:describeSObject>"
|
69
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'describe_s_object_response'})
|
70
|
+
|
71
|
+
subject.describe("Opportunity")
|
72
|
+
|
73
|
+
# Hit cache.
|
74
|
+
subject.describe("Opportunity")
|
75
|
+
end
|
76
|
+
|
77
|
+
it "supports array of sobject names" do
|
78
|
+
|
79
|
+
body = "<tns:describeSObjects><tns:sObjectType>Account</tns:sObjectType><tns:sObjectType>Opportunity</tns:sObjectType></tns:describeSObjects>"
|
80
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'describe_s_objects_response'})
|
81
|
+
|
82
|
+
subject.describe(["Account", "Opportunity"])
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe "#retrieve" do
|
87
|
+
|
88
|
+
it "should retrieve object by id" do
|
89
|
+
fields = {:fields => [{:name => "Id"},{:name => "Name"},{:name => "Description"},{:name => "StageName"}]}
|
90
|
+
# retrieve calls describe to get the list of available fields.
|
91
|
+
subject.should_receive(:describe).with("Opportunity").and_return(fields)
|
92
|
+
|
93
|
+
body = "<tns:retrieve><tns:fieldList>Id,Name,Description,StageName</tns:fieldList><tns:sObjectType>Opportunity</tns:sObjectType><tns:ids>006A000000LbkT5IAJ</tns:ids></tns:retrieve>"
|
94
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'retrieve_response'})
|
95
|
+
|
96
|
+
sobject = subject.retrieve("Opportunity", "006A000000LbkT5IAJ")
|
97
|
+
|
98
|
+
sobject.should be_a(Soapforce::SObject)
|
99
|
+
sobject.type.should == "Opportunity"
|
100
|
+
sobject.Id.should == "006A000000LbkT5IAJ"
|
101
|
+
sobject.Name.should == "SOAPForce Opportunity"
|
102
|
+
sobject.Description.should be_nil
|
103
|
+
sobject.StageName.should == "Prospecting"
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
describe "#find" do
|
108
|
+
it "should retrieve object by id" do
|
109
|
+
|
110
|
+
fields = {:fields => [{:name => "Id"},{:name => "Name"},{:name => "Description"},{:name => "StageName"}]}
|
111
|
+
# retrieve calls describe to get the list of available fields.
|
112
|
+
subject.should_receive(:describe).with("Opportunity").and_return(fields)
|
113
|
+
|
114
|
+
body = "<tns:retrieve><tns:fieldList>Id,Name,Description,StageName</tns:fieldList><tns:sObjectType>Opportunity</tns:sObjectType><tns:ids>006A000000LbkT5IAJ</tns:ids></tns:retrieve>"
|
115
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'retrieve_response'})
|
116
|
+
|
117
|
+
sobject = subject.find("Opportunity", "006A000000LbkT5IAJ")
|
118
|
+
|
119
|
+
sobject.should be_a(Soapforce::SObject)
|
120
|
+
sobject.type.should == "Opportunity"
|
121
|
+
sobject.Id.should == "006A000000LbkT5IAJ"
|
122
|
+
sobject.Name.should == "SOAPForce Opportunity"
|
123
|
+
sobject.Description.should be_nil
|
124
|
+
sobject.StageName.should == "Prospecting"
|
125
|
+
end
|
126
|
+
|
127
|
+
end
|
128
|
+
|
129
|
+
describe "#find_by_field" do
|
130
|
+
|
131
|
+
it "should retrieve object by string field" do
|
132
|
+
fields = {:fields => [{:name => "Id"},{:name => "Name"},{:name => "Description"},{:name => "StageName"}]}
|
133
|
+
# retrieve calls describe to get the list of available fields.
|
134
|
+
subject.should_receive(:describe).exactly(2).with("Opportunity").and_return(fields)
|
135
|
+
|
136
|
+
body = "<tns:query><tns:queryString>Select Id, Name, Description, StageName From Opportunity Where StageName = 'Prospecting'</tns:queryString></tns:query>"
|
137
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'query_response'})
|
138
|
+
|
139
|
+
subject.find_by_field("Opportunity", "Prospecting", "StageName")
|
140
|
+
end
|
141
|
+
|
142
|
+
it "should retrieve object by number field" do
|
143
|
+
fields = {:fields => [{:name => "Id"},{:name => "Name"},{:name => "Description"},{:name => "Amount", :type => "double"}]}
|
144
|
+
# retrieve calls describe to get the list of available fields.
|
145
|
+
subject.should_receive(:describe).exactly(2).with("Opportunity").and_return(fields)
|
146
|
+
|
147
|
+
body = "<tns:query><tns:queryString>Select Id, Name, Description, Amount From Opportunity Where Amount = 0.0</tns:queryString></tns:query>"
|
148
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'query_response'})
|
149
|
+
|
150
|
+
subject.find_by_field("Opportunity", 0.0, "Amount")
|
151
|
+
end
|
152
|
+
|
153
|
+
end
|
154
|
+
|
155
|
+
describe "#find_where" do
|
156
|
+
|
157
|
+
let(:fields) { {:fields => [{:name => "Id"},{:name => "Name"},{:name => "Description"},{:name => "StageName"}]} }
|
158
|
+
let(:body) { "<tns:query><tns:queryString>Select Id, Name, Description, StageName From Opportunity Where Id = '006A000000LbkT5IAJ' AND Amount = 0.0</tns:queryString></tns:query>" }
|
159
|
+
|
160
|
+
after(:each) do
|
161
|
+
@result.should be_a(Soapforce::QueryResult)
|
162
|
+
@result.size.should == 2
|
163
|
+
@result.first.Name == "Opportunity 1"
|
164
|
+
@result.last.Name == "Opportunity 2"
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should retrieve records from hash conditions" do
|
168
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'query_response'})
|
169
|
+
# retrieve calls describe to get the list of available fields.
|
170
|
+
subject.should_receive(:describe).with("Opportunity").and_return(fields)
|
171
|
+
|
172
|
+
@result = subject.find_where("Opportunity", {Id: "006A000000LbkT5IAJ", Amount: 0.0})
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should retrieve records from hash condition using IN clause" do
|
176
|
+
body = "<tns:query><tns:queryString>Select Id, Name, Description, StageName From Opportunity Where Id IN ('006A000000LbkT5IAJ', '006A000000AbkTcIAQ')</tns:queryString></tns:query>"
|
177
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'query_response'})
|
178
|
+
|
179
|
+
# retrieve calls describe to get the list of available fields.
|
180
|
+
subject.should_receive(:describe).with("Opportunity").and_return(fields)
|
181
|
+
|
182
|
+
@result = subject.find_where("Opportunity", {Id: ["006A000000LbkT5IAJ", "006A000000AbkTcIAQ"]})
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should retrieve records from string condition" do
|
186
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'query_response'})
|
187
|
+
# retrieve calls describe to get the list of available fields.
|
188
|
+
subject.should_receive(:describe).with("Opportunity").and_return(fields)
|
189
|
+
|
190
|
+
@result = subject.find_where("Opportunity", "Id = '006A000000LbkT5IAJ' AND Amount = 0.0")
|
191
|
+
end
|
192
|
+
|
193
|
+
it "should retrieve records from string condition and specify fields" do
|
194
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'query_response'})
|
195
|
+
subject.should_not_receive(:describe)
|
196
|
+
|
197
|
+
@result = subject.find_where("Opportunity", "Id = '006A000000LbkT5IAJ' AND Amount = 0.0", ["Id", "Name", "Description", "StageName"])
|
198
|
+
end
|
199
|
+
|
200
|
+
end
|
201
|
+
|
202
|
+
describe "query methods" do
|
203
|
+
|
204
|
+
after(:each) do
|
205
|
+
@result.should be_a(Soapforce::QueryResult)
|
206
|
+
@result.size.should == 2
|
207
|
+
@result.first.Name == "Opportunity 1"
|
208
|
+
@result.last.Name == "Opportunity 2"
|
209
|
+
end
|
210
|
+
|
211
|
+
it "#query" do
|
212
|
+
body = "<tns:query><tns:queryString>Select Id, Name, StageName from Opportunity</tns:queryString></tns:query>"
|
213
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'query_response'})
|
214
|
+
|
215
|
+
@result = subject.query("Select Id, Name, StageName from Opportunity")
|
216
|
+
end
|
217
|
+
|
218
|
+
it "#query_all" do
|
219
|
+
body = "<tns:queryAll><tns:queryString>Select Id, Name, StageName from Opportunity</tns:queryString></tns:queryAll>"
|
220
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'query_all_response'})
|
221
|
+
|
222
|
+
@result = subject.query_all("Select Id, Name, StageName from Opportunity")
|
223
|
+
end
|
224
|
+
|
225
|
+
it "#query_more" do
|
226
|
+
body = "<tns:queryMore><tns:queryLocator>some_locator_string</tns:queryLocator></tns:queryMore>"
|
227
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'query_more_response'})
|
228
|
+
|
229
|
+
@result = subject.query_more("some_locator_string")
|
230
|
+
end
|
231
|
+
|
232
|
+
end
|
233
|
+
|
234
|
+
describe "#search" do
|
235
|
+
|
236
|
+
it "should return search results" do
|
237
|
+
|
238
|
+
sosl = "FIND 'Name*' IN ALL FIELDS RETURNING Account (Id, Name), Contact, Opportunity, Lead"
|
239
|
+
|
240
|
+
body = "<tns:search><tns:searchString>#{sosl}</tns:searchString></tns:search>"
|
241
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'search_response'})
|
242
|
+
|
243
|
+
subject.search(sosl)
|
244
|
+
end
|
245
|
+
|
246
|
+
end
|
247
|
+
|
248
|
+
describe "#create" do
|
249
|
+
it "should create new object" do
|
250
|
+
|
251
|
+
body = "<tns:create><tns:sObjects><ins0:type>Opportunity</ins0:type><tns:Name>SOAPForce Opportunity</tns:Name><tns:CloseDate>2013-08-12</tns:CloseDate><tns:StageName>Prospecting</tns:StageName></tns:sObjects></tns:create>"
|
252
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'create_response'})
|
253
|
+
|
254
|
+
params = { Name: "SOAPForce Opportunity", CloseDate: '2013-08-12', StageName: 'Prospecting' }
|
255
|
+
response = subject.create("Opportunity", params)
|
256
|
+
|
257
|
+
response[:success].should be_true
|
258
|
+
response[:id].should == "006A000000LbiizIAB"
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
describe "#update" do
|
263
|
+
it "should update existing object" do
|
264
|
+
|
265
|
+
body = "<tns:update><tns:sObjects><ins0:type>Opportunity</ins0:type><ins0:Id>003ABCDE</ins0:Id><tns:Name>SOAPForce Opportunity</tns:Name><tns:CloseDate>2013-08-12</tns:CloseDate><tns:StageName>Closed Won</tns:StageName></tns:sObjects></tns:update>"
|
266
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'update_response'})
|
267
|
+
|
268
|
+
params = { Id: '003ABCDE', Name: "SOAPForce Opportunity", CloseDate: '2013-08-12', StageName: 'Closed Won' }
|
269
|
+
response = subject.update("Opportunity", params)
|
270
|
+
|
271
|
+
response[:success].should be_true
|
272
|
+
response[:id].should == "006A000000LbiizIAB"
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
describe "#upsert" do
|
277
|
+
it "should insert new and update existing objects" do
|
278
|
+
|
279
|
+
body = "<tns:upsert><tns:externalIDFieldName>External_Id__c</tns:externalIDFieldName><tns:sObjects><ins0:type>Opportunity</ins0:type><tns:Name>New Opportunity</tns:Name><tns:CloseDate>2013-08-12</tns:CloseDate><tns:StageName>Prospecting</tns:StageName></tns:sObjects><tns:sObjects><ins0:type>Opportunity</ins0:type><ins0:Id>003ABCDE</ins0:Id><tns:Name>Existing Opportunity</tns:Name><tns:CloseDate>2013-08-12</tns:CloseDate><tns:StageName>Closed Won</tns:StageName></tns:sObjects></tns:upsert>"
|
280
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'upsert_response'})
|
281
|
+
|
282
|
+
objects = [
|
283
|
+
{ Name: "New Opportunity", CloseDate: '2013-08-12', StageName: 'Prospecting' },
|
284
|
+
{ Id: '003ABCDE', Name: "Existing Opportunity", CloseDate: '2013-08-12', StageName: 'Closed Won' }
|
285
|
+
]
|
286
|
+
subject.upsert("Opportunity", "External_Id__c", objects)
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
describe "#delete" do
|
291
|
+
it "should delete existing objects" do
|
292
|
+
body = "<tns:delete><tns:ids>003ABCDE</tns:ids></tns:delete>"
|
293
|
+
stub = stub_api_request(endpoint, {with_body: body, fixture: 'delete_response'})
|
294
|
+
response = subject.delete("003ABCDE")
|
295
|
+
|
296
|
+
response[:success].should be_true
|
297
|
+
response[:id].should == "006A000000LbiizIAB"
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
end
|