sfdc 3.0.0 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +96 -0
- data/Gemfile +11 -0
- data/Guardfile +11 -0
- data/LICENSE +22 -0
- data/README.md +88 -98
- data/Rakefile +10 -0
- data/lib/sfdc.rb +1 -0
- data/lib/sfdc/abstract_client.rb +1 -1
- data/lib/sfdc/attachment.rb +0 -2
- data/lib/sfdc/concerns/api.rb +1 -2
- data/lib/sfdc/concerns/authentication.rb +1 -2
- data/lib/sfdc/concerns/base.rb +5 -7
- data/lib/sfdc/concerns/caching.rb +1 -3
- data/lib/sfdc/concerns/canvas.rb +0 -2
- data/lib/sfdc/concerns/connection.rb +2 -3
- data/lib/sfdc/concerns/picklists.rb +1 -4
- data/lib/sfdc/concerns/streaming.rb +2 -2
- data/lib/sfdc/concerns/verbs.rb +0 -2
- data/lib/sfdc/config.rb +1 -0
- data/lib/sfdc/middleware/authentication.rb +4 -2
- data/lib/sfdc/middleware/authentication/password.rb +2 -5
- data/lib/sfdc/middleware/authorization.rb +1 -5
- data/lib/sfdc/middleware/caching.rb +0 -2
- data/lib/sfdc/middleware/instance_url.rb +0 -4
- data/lib/sfdc/middleware/mashify.rb +1 -3
- data/lib/sfdc/middleware/multipart.rb +6 -4
- data/lib/sfdc/signed_request.rb +1 -1
- data/lib/sfdc/tooling/client.rb +4 -6
- data/lib/sfdc/version.rb +2 -2
- data/sfdc.gemspec +27 -0
- data/spec/fixtures/auth_error_response.json +4 -0
- data/spec/fixtures/auth_success_response.json +7 -0
- data/spec/fixtures/blob.jpg +0 -0
- data/spec/fixtures/expired_session_response.json +6 -0
- data/spec/fixtures/reauth_success_response.json +7 -0
- data/spec/fixtures/refresh_error_response.json +4 -0
- data/spec/fixtures/refresh_success_response.json +7 -0
- data/spec/fixtures/services_data_success_response.json +12 -0
- data/spec/fixtures/sobject/create_success_response.json +5 -0
- data/spec/fixtures/sobject/delete_error_response.json +1 -0
- data/spec/fixtures/sobject/describe_sobjects_success_response.json +31 -0
- data/spec/fixtures/sobject/list_sobjects_success_response.json +31 -0
- data/spec/fixtures/sobject/org_query_response.json +11 -0
- data/spec/fixtures/sobject/query_aggregate_success_response.json +23 -0
- data/spec/fixtures/sobject/query_empty_response.json +5 -0
- data/spec/fixtures/sobject/query_error_response.json +6 -0
- data/spec/fixtures/sobject/query_paginated_first_page_response.json +14 -0
- data/spec/fixtures/sobject/query_paginated_last_page_response.json +13 -0
- data/spec/fixtures/sobject/query_success_response.json +38 -0
- data/spec/fixtures/sobject/recent_success_response.json +18 -0
- data/spec/fixtures/sobject/search_error_response.json +6 -0
- data/spec/fixtures/sobject/search_success_response.json +16 -0
- data/spec/fixtures/sobject/sobject_describe_error_response.json +6 -0
- data/spec/fixtures/sobject/sobject_describe_success_response.json +1429 -0
- data/spec/fixtures/sobject/sobject_find_error_response.json +6 -0
- data/spec/fixtures/sobject/sobject_find_success_response.json +29 -0
- data/spec/fixtures/sobject/upsert_created_success_response.json +5 -0
- data/spec/fixtures/sobject/upsert_error_response.json +6 -0
- data/spec/fixtures/sobject/upsert_multiple_error_response.json +4 -0
- data/spec/fixtures/sobject/upsert_updated_success_response.json +0 -0
- data/spec/fixtures/sobject/write_error_response.json +6 -0
- data/spec/integration/abstract_client_spec.rb +306 -0
- data/spec/integration/data/client_spec.rb +90 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/support/client_integration.rb +45 -0
- data/spec/support/concerns.rb +18 -0
- data/spec/support/event_machine.rb +14 -0
- data/spec/support/fixture_helpers.rb +45 -0
- data/spec/support/matchers.rb +11 -0
- data/spec/support/middleware.rb +76 -0
- data/spec/support/mock_cache.rb +13 -0
- data/spec/unit/abstract_client_spec.rb +11 -0
- data/spec/unit/attachment_spec.rb +15 -0
- data/spec/unit/collection_spec.rb +52 -0
- data/spec/unit/concerns/api_spec.rb +244 -0
- data/spec/unit/concerns/authentication_spec.rb +98 -0
- data/spec/unit/concerns/base_spec.rb +42 -0
- data/spec/unit/concerns/caching_spec.rb +29 -0
- data/spec/unit/concerns/canvas_spec.rb +30 -0
- data/spec/unit/concerns/connection_spec.rb +22 -0
- data/spec/unit/config_spec.rb +99 -0
- data/spec/unit/data/client_spec.rb +10 -0
- data/spec/unit/mash_spec.rb +36 -0
- data/spec/unit/middleware/authentication/password_spec.rb +31 -0
- data/spec/unit/middleware/authentication/token_spec.rb +24 -0
- data/spec/unit/middleware/authentication_spec.rb +67 -0
- data/spec/unit/middleware/authorization_spec.rb +11 -0
- data/spec/unit/middleware/gzip_spec.rb +66 -0
- data/spec/unit/middleware/instance_url_spec.rb +24 -0
- data/spec/unit/middleware/logger_spec.rb +19 -0
- data/spec/unit/middleware/mashify_spec.rb +11 -0
- data/spec/unit/middleware/raise_error_spec.rb +32 -0
- data/spec/unit/signed_request_spec.rb +24 -0
- data/spec/unit/sobject_spec.rb +86 -0
- data/spec/unit/tooling/client_spec.rb +7 -0
- metadata +225 -65
data/Rakefile
ADDED
data/lib/sfdc.rb
CHANGED
data/lib/sfdc/abstract_client.rb
CHANGED
data/lib/sfdc/attachment.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
module Sfdc
|
2
2
|
class Attachment < Sfdc::SObject
|
3
|
-
|
4
3
|
# Public: Returns the body of the attachment.
|
5
4
|
#
|
6
5
|
# Examples
|
@@ -18,6 +17,5 @@ module Sfdc
|
|
18
17
|
return true if self.Body?
|
19
18
|
raise 'You need to query the Body for the record first.'
|
20
19
|
end
|
21
|
-
|
22
20
|
end
|
23
21
|
end
|
data/lib/sfdc/concerns/api.rb
CHANGED
@@ -300,7 +300,7 @@ module Sfdc
|
|
300
300
|
api_get(field ? "sobjects/#{sobject}/#{field}/#{id}" : "sobjects/#{sobject}/#{id}").body
|
301
301
|
end
|
302
302
|
|
303
|
-
|
303
|
+
private
|
304
304
|
|
305
305
|
# Internal: Returns a path to an api endpoint
|
306
306
|
#
|
@@ -316,7 +316,6 @@ module Sfdc
|
|
316
316
|
def exceptions
|
317
317
|
[Faraday::Error::ClientError]
|
318
318
|
end
|
319
|
-
|
320
319
|
end
|
321
320
|
end
|
322
321
|
end
|
@@ -2,7 +2,7 @@ module Sfdc
|
|
2
2
|
module Concerns
|
3
3
|
module Authentication
|
4
4
|
|
5
|
-
# Public:
|
5
|
+
# Public: Sfdc an authentication
|
6
6
|
def authenticate!
|
7
7
|
raise AuthenticationError, 'No authentication middleware present' unless authentication_middleware
|
8
8
|
middleware = authentication_middleware.new nil, self, options
|
@@ -34,7 +34,6 @@ module Sfdc
|
|
34
34
|
options[:client_id] &&
|
35
35
|
options[:client_secret]
|
36
36
|
end
|
37
|
-
|
38
37
|
end
|
39
38
|
end
|
40
39
|
end
|
data/lib/sfdc/concerns/base.rb
CHANGED
@@ -1,12 +1,11 @@
|
|
1
1
|
module Sfdc
|
2
2
|
module Concerns
|
3
3
|
module Base
|
4
|
-
|
5
4
|
attr_reader :options
|
6
5
|
|
7
6
|
# Public: Creates a new client instance
|
8
7
|
#
|
9
|
-
#
|
8
|
+
# options - A hash of options to be passed in (default: {}).
|
10
9
|
# :username - The String username to use (required for password authentication).
|
11
10
|
# :password - The String password to use (required for password authentication).
|
12
11
|
# :security_token - The String security token to use (required for password authentication).
|
@@ -40,10 +39,10 @@ module Sfdc
|
|
40
39
|
#
|
41
40
|
# :authentication_callback
|
42
41
|
# - A Proc that is called with the response body after a successful authentication.
|
43
|
-
def initialize(
|
44
|
-
raise ArgumentError, 'Please specify a hash of options' unless opts.is_a?(Hash)
|
42
|
+
def initialize(options = {})
|
45
43
|
@options = Hash[Sfdc.configuration.options.map { |option| [option, Sfdc.configuration.send(option)] }]
|
46
|
-
@options.merge!
|
44
|
+
@options.merge!(options)
|
45
|
+
|
47
46
|
yield builder if block_given?
|
48
47
|
end
|
49
48
|
|
@@ -55,7 +54,6 @@ module Sfdc
|
|
55
54
|
def inspect
|
56
55
|
"#<#{self.class} @options=#{@options.inspect}>"
|
57
56
|
end
|
58
|
-
|
59
57
|
end
|
60
58
|
end
|
61
|
-
end
|
59
|
+
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Sfdc
|
2
2
|
module Concerns
|
3
3
|
module Caching
|
4
|
-
|
5
4
|
# Public: Runs the block with caching disabled.
|
6
5
|
#
|
7
6
|
# block - A query/describe/etc.
|
@@ -14,13 +13,12 @@ module Sfdc
|
|
14
13
|
options.delete(:use_cache)
|
15
14
|
end
|
16
15
|
|
17
|
-
|
16
|
+
private
|
18
17
|
|
19
18
|
# Internal: Cache to use for the caching middleware
|
20
19
|
def cache
|
21
20
|
options[:cache]
|
22
21
|
end
|
23
|
-
|
24
22
|
end
|
25
23
|
end
|
26
24
|
end
|
data/lib/sfdc/concerns/canvas.rb
CHANGED
@@ -1,7 +1,6 @@
|
|
1
1
|
module Sfdc
|
2
2
|
module Concerns
|
3
3
|
module Connection
|
4
|
-
|
5
4
|
# Public: The Faraday::Builder instance used for the middleware stack. This
|
6
5
|
# can be used to insert an custom middleware.
|
7
6
|
#
|
@@ -14,9 +13,10 @@ module Sfdc
|
|
14
13
|
def middleware
|
15
14
|
connection.builder
|
16
15
|
end
|
16
|
+
|
17
17
|
alias_method :builder, :middleware
|
18
18
|
|
19
|
-
|
19
|
+
private
|
20
20
|
|
21
21
|
# Internal: Internal faraday connection where all requests go through
|
22
22
|
def connection
|
@@ -68,7 +68,6 @@ module Sfdc
|
|
68
68
|
def mashify?
|
69
69
|
middleware.handlers.index(Sfdc::Middleware::Mashify)
|
70
70
|
end
|
71
|
-
|
72
71
|
end
|
73
72
|
end
|
74
73
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Sfdc
|
2
2
|
module Concerns
|
3
3
|
module Picklists
|
4
|
-
|
5
4
|
# Public: Get the available picklist values for a picklist or multipicklist field.
|
6
5
|
#
|
7
6
|
# sobject - The String name of the sobject.
|
@@ -27,7 +26,7 @@ module Sfdc
|
|
27
26
|
PicklistValues.new(describe(sobject)['fields'], field, options)
|
28
27
|
end
|
29
28
|
|
30
|
-
|
29
|
+
private
|
31
30
|
|
32
31
|
class PicklistValues < Array
|
33
32
|
|
@@ -82,9 +81,7 @@ module Sfdc
|
|
82
81
|
valid_for = picklist_entry['validFor'].ljust(16, 'A').unpack('m').first.unpack('q*')
|
83
82
|
(valid_for[index >> 3] & (0x80 >> index % 8)) != 0
|
84
83
|
end
|
85
|
-
|
86
84
|
end
|
87
|
-
|
88
85
|
end
|
89
86
|
end
|
90
87
|
end
|
@@ -1,7 +1,6 @@
|
|
1
1
|
module Sfdc
|
2
2
|
module Concerns
|
3
3
|
module Streaming
|
4
|
-
|
5
4
|
# Public: Subscribe to a PushTopic
|
6
5
|
#
|
7
6
|
# channels - The name of the PushTopic channel(s) to subscribe to.
|
@@ -15,17 +14,18 @@ module Sfdc
|
|
15
14
|
# Public: Faye client to use for subscribing to PushTopics
|
16
15
|
def faye
|
17
16
|
raise 'Instance URL missing. Call .authenticate! first.' unless options[:instance_url]
|
17
|
+
|
18
18
|
@faye ||= Faye::Client.new("#{options[:instance_url]}/cometd/#{options[:api_version]}").tap do |client|
|
19
19
|
client.bind 'transport:down' do
|
20
20
|
Sfdc.log "[COMETD DOWN]"
|
21
21
|
client.set_header 'Authorization', "OAuth #{authenticate!.access_token}"
|
22
22
|
end
|
23
|
+
|
23
24
|
client.bind 'transport:up' do
|
24
25
|
Sfdc.log "[COMETD UP]"
|
25
26
|
end
|
26
27
|
end
|
27
28
|
end
|
28
|
-
|
29
29
|
end
|
30
30
|
end
|
31
31
|
end
|
data/lib/sfdc/concerns/verbs.rb
CHANGED
data/lib/sfdc/config.rb
CHANGED
@@ -62,10 +62,12 @@ module Sfdc
|
|
62
62
|
end
|
63
63
|
end
|
64
64
|
|
65
|
-
|
65
|
+
private
|
66
|
+
|
66
67
|
def faraday_options
|
67
68
|
{ :url => "https://#{@options[:host]}",
|
68
|
-
:proxy => @options[:proxy_uri]
|
69
|
+
:proxy => @options[:proxy_uri]
|
70
|
+
}.reject { |k, v| v.nil? }
|
69
71
|
end
|
70
72
|
end
|
71
73
|
end
|
@@ -1,20 +1,17 @@
|
|
1
1
|
module Sfdc
|
2
|
-
|
3
2
|
# Authentication middleware used if username and password flow is used
|
4
3
|
class Middleware::Authentication::Password < Sfdc::Middleware::Authentication
|
5
|
-
|
6
4
|
def params
|
7
5
|
{ :grant_type => 'password',
|
8
6
|
:client_id => @options[:client_id],
|
9
7
|
:client_secret => @options[:client_secret],
|
10
8
|
:username => @options[:username],
|
11
|
-
:password => password
|
9
|
+
:password => password
|
10
|
+
}
|
12
11
|
end
|
13
12
|
|
14
13
|
def password
|
15
14
|
"#{@options[:password]}#{@options[:security_token]}"
|
16
15
|
end
|
17
|
-
|
18
16
|
end
|
19
|
-
|
20
17
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module Sfdc
|
2
|
-
|
3
|
-
# Piece of middleware that simply injects the OAuth token into the request
|
4
|
-
# headers.
|
2
|
+
# Middleware that simply injects the OAuth token into the request headers.
|
5
3
|
class Middleware::Authorization < Sfdc::Middleware
|
6
4
|
AUTH_HEADER = 'Authorization'.freeze
|
7
5
|
|
@@ -13,7 +11,5 @@ module Sfdc
|
|
13
11
|
def token
|
14
12
|
@options[:oauth_token]
|
15
13
|
end
|
16
|
-
|
17
14
|
end
|
18
|
-
|
19
15
|
end
|
@@ -1,6 +1,5 @@
|
|
1
1
|
module Sfdc
|
2
2
|
class Middleware::Caching < FaradayMiddleware::Caching
|
3
|
-
|
4
3
|
def call(env)
|
5
4
|
expire(cache_key(env)) unless use_cache?
|
6
5
|
super
|
@@ -19,6 +18,5 @@ module Sfdc
|
|
19
18
|
def use_cache?
|
20
19
|
!@options.has_key?(:use_cache) || @options[:use_cache]
|
21
20
|
end
|
22
|
-
|
23
21
|
end
|
24
22
|
end
|
@@ -1,8 +1,6 @@
|
|
1
1
|
module Sfdc
|
2
|
-
|
3
2
|
# Middleware which asserts that the instance_url is always set
|
4
3
|
class Middleware::InstanceURL < Sfdc::Middleware
|
5
|
-
|
6
4
|
def call(env)
|
7
5
|
# If the connection url_prefix isn't set, we must not be authenticated.
|
8
6
|
raise Sfdc::UnauthorizedError, 'Connection prefix not set' unless url_prefix_set?
|
@@ -12,7 +10,5 @@ module Sfdc
|
|
12
10
|
def url_prefix_set?
|
13
11
|
!!(connection.url_prefix && connection.url_prefix.host)
|
14
12
|
end
|
15
|
-
|
16
13
|
end
|
17
|
-
|
18
14
|
end
|
@@ -2,7 +2,6 @@ module Sfdc
|
|
2
2
|
# Middleware the converts sobject records from JSON into Sfdc::SObject objects
|
3
3
|
# and collections of records into Sfdc::Collection objects.
|
4
4
|
class Middleware::Mashify < Sfdc::Middleware
|
5
|
-
|
6
5
|
def call(env)
|
7
6
|
@env = env
|
8
7
|
response = @app.call(env)
|
@@ -12,7 +11,6 @@ module Sfdc
|
|
12
11
|
|
13
12
|
def body
|
14
13
|
@env[:body]
|
15
|
-
end
|
16
|
-
|
14
|
+
end
|
17
15
|
end
|
18
16
|
end
|
@@ -10,7 +10,8 @@ module Sfdc
|
|
10
10
|
env[:request_headers][CONTENT_TYPE] += ";boundary=#{env[:request][:boundary]}"
|
11
11
|
env[:body] = create_multipart(env, params)
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
|
+
@app.call(env)
|
14
15
|
end
|
15
16
|
|
16
17
|
def process_request?(env)
|
@@ -28,17 +29,17 @@ module Sfdc
|
|
28
29
|
return true if (val.respond_to?(:content_type) || has_multipart?(val))
|
29
30
|
end
|
30
31
|
end
|
31
|
-
|
32
|
+
|
33
|
+
return false
|
32
34
|
end
|
33
35
|
|
34
36
|
def create_multipart(env, params)
|
35
37
|
boundary = env[:request][:boundary]
|
38
|
+
|
36
39
|
parts = []
|
37
40
|
|
38
|
-
# Fields
|
39
41
|
parts << Faraday::Parts::Part.new(boundary, 'entity_content', params.reject { |k,v| v.respond_to? :content_type }.to_json)
|
40
42
|
|
41
|
-
# Files
|
42
43
|
params.each do |k,v|
|
43
44
|
parts << Faraday::Parts::Part.new(boundary, k.to_s, v) if v.respond_to? :content_type
|
44
45
|
end
|
@@ -47,6 +48,7 @@ module Sfdc
|
|
47
48
|
|
48
49
|
body = Faraday::CompositeReadIO.new(parts)
|
49
50
|
env[:request_headers]['Content-Length'] = body.length.to_s
|
51
|
+
|
50
52
|
return body
|
51
53
|
end
|
52
54
|
end
|
data/lib/sfdc/signed_request.rb
CHANGED
data/lib/sfdc/tooling/client.rb
CHANGED
data/lib/sfdc/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Sfdc
|
2
|
-
VERSION = '3.0.
|
3
|
-
end
|
2
|
+
VERSION = '3.0.1'
|
3
|
+
end
|
data/sfdc.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/sfdc/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = "sfdc"
|
6
|
+
s.version = Sfdc::VERSION
|
7
|
+
s.authors = ["Bruce Yue"]
|
8
|
+
s.email = ["bruce.yue@outlook.com"]
|
9
|
+
s.description = "A lightweight ruby client for the Salesforce REST api."
|
10
|
+
s.summary = "A lightweight ruby client for the Salesforce REST api."
|
11
|
+
s.homepage = "http://www.sharealltech.com"
|
12
|
+
|
13
|
+
s.files = Dir["./**/*"].reject { |file| file =~ /\.\/(bin|example|log|pkg|script|spec|test|vendor)/ }
|
14
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
15
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
|
18
|
+
s.add_dependency 'faraday', '~> 0.8.4'
|
19
|
+
s.add_dependency 'faraday_middleware', '>= 0.8.8'
|
20
|
+
s.add_dependency 'json', ['>= 1.7.5', '< 1.9.0']
|
21
|
+
s.add_dependency 'hashie', ['>= 1.2.0', '< 2.1']
|
22
|
+
|
23
|
+
s.add_development_dependency 'rspec', '~> 2.14.0'
|
24
|
+
s.add_development_dependency 'webmock', '~> 1.13.0'
|
25
|
+
s.add_development_dependency 'simplecov', '~> 0.7.1'
|
26
|
+
s.add_development_dependency 'faye' unless RUBY_PLATFORM == 'java'
|
27
|
+
end
|