sfdc 3.0.0 → 3.0.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.
Files changed (97) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +96 -0
  3. data/Gemfile +11 -0
  4. data/Guardfile +11 -0
  5. data/LICENSE +22 -0
  6. data/README.md +88 -98
  7. data/Rakefile +10 -0
  8. data/lib/sfdc.rb +1 -0
  9. data/lib/sfdc/abstract_client.rb +1 -1
  10. data/lib/sfdc/attachment.rb +0 -2
  11. data/lib/sfdc/concerns/api.rb +1 -2
  12. data/lib/sfdc/concerns/authentication.rb +1 -2
  13. data/lib/sfdc/concerns/base.rb +5 -7
  14. data/lib/sfdc/concerns/caching.rb +1 -3
  15. data/lib/sfdc/concerns/canvas.rb +0 -2
  16. data/lib/sfdc/concerns/connection.rb +2 -3
  17. data/lib/sfdc/concerns/picklists.rb +1 -4
  18. data/lib/sfdc/concerns/streaming.rb +2 -2
  19. data/lib/sfdc/concerns/verbs.rb +0 -2
  20. data/lib/sfdc/config.rb +1 -0
  21. data/lib/sfdc/middleware/authentication.rb +4 -2
  22. data/lib/sfdc/middleware/authentication/password.rb +2 -5
  23. data/lib/sfdc/middleware/authorization.rb +1 -5
  24. data/lib/sfdc/middleware/caching.rb +0 -2
  25. data/lib/sfdc/middleware/instance_url.rb +0 -4
  26. data/lib/sfdc/middleware/mashify.rb +1 -3
  27. data/lib/sfdc/middleware/multipart.rb +6 -4
  28. data/lib/sfdc/signed_request.rb +1 -1
  29. data/lib/sfdc/tooling/client.rb +4 -6
  30. data/lib/sfdc/version.rb +2 -2
  31. data/sfdc.gemspec +27 -0
  32. data/spec/fixtures/auth_error_response.json +4 -0
  33. data/spec/fixtures/auth_success_response.json +7 -0
  34. data/spec/fixtures/blob.jpg +0 -0
  35. data/spec/fixtures/expired_session_response.json +6 -0
  36. data/spec/fixtures/reauth_success_response.json +7 -0
  37. data/spec/fixtures/refresh_error_response.json +4 -0
  38. data/spec/fixtures/refresh_success_response.json +7 -0
  39. data/spec/fixtures/services_data_success_response.json +12 -0
  40. data/spec/fixtures/sobject/create_success_response.json +5 -0
  41. data/spec/fixtures/sobject/delete_error_response.json +1 -0
  42. data/spec/fixtures/sobject/describe_sobjects_success_response.json +31 -0
  43. data/spec/fixtures/sobject/list_sobjects_success_response.json +31 -0
  44. data/spec/fixtures/sobject/org_query_response.json +11 -0
  45. data/spec/fixtures/sobject/query_aggregate_success_response.json +23 -0
  46. data/spec/fixtures/sobject/query_empty_response.json +5 -0
  47. data/spec/fixtures/sobject/query_error_response.json +6 -0
  48. data/spec/fixtures/sobject/query_paginated_first_page_response.json +14 -0
  49. data/spec/fixtures/sobject/query_paginated_last_page_response.json +13 -0
  50. data/spec/fixtures/sobject/query_success_response.json +38 -0
  51. data/spec/fixtures/sobject/recent_success_response.json +18 -0
  52. data/spec/fixtures/sobject/search_error_response.json +6 -0
  53. data/spec/fixtures/sobject/search_success_response.json +16 -0
  54. data/spec/fixtures/sobject/sobject_describe_error_response.json +6 -0
  55. data/spec/fixtures/sobject/sobject_describe_success_response.json +1429 -0
  56. data/spec/fixtures/sobject/sobject_find_error_response.json +6 -0
  57. data/spec/fixtures/sobject/sobject_find_success_response.json +29 -0
  58. data/spec/fixtures/sobject/upsert_created_success_response.json +5 -0
  59. data/spec/fixtures/sobject/upsert_error_response.json +6 -0
  60. data/spec/fixtures/sobject/upsert_multiple_error_response.json +4 -0
  61. data/spec/fixtures/sobject/upsert_updated_success_response.json +0 -0
  62. data/spec/fixtures/sobject/write_error_response.json +6 -0
  63. data/spec/integration/abstract_client_spec.rb +306 -0
  64. data/spec/integration/data/client_spec.rb +90 -0
  65. data/spec/spec_helper.rb +20 -0
  66. data/spec/support/client_integration.rb +45 -0
  67. data/spec/support/concerns.rb +18 -0
  68. data/spec/support/event_machine.rb +14 -0
  69. data/spec/support/fixture_helpers.rb +45 -0
  70. data/spec/support/matchers.rb +11 -0
  71. data/spec/support/middleware.rb +76 -0
  72. data/spec/support/mock_cache.rb +13 -0
  73. data/spec/unit/abstract_client_spec.rb +11 -0
  74. data/spec/unit/attachment_spec.rb +15 -0
  75. data/spec/unit/collection_spec.rb +52 -0
  76. data/spec/unit/concerns/api_spec.rb +244 -0
  77. data/spec/unit/concerns/authentication_spec.rb +98 -0
  78. data/spec/unit/concerns/base_spec.rb +42 -0
  79. data/spec/unit/concerns/caching_spec.rb +29 -0
  80. data/spec/unit/concerns/canvas_spec.rb +30 -0
  81. data/spec/unit/concerns/connection_spec.rb +22 -0
  82. data/spec/unit/config_spec.rb +99 -0
  83. data/spec/unit/data/client_spec.rb +10 -0
  84. data/spec/unit/mash_spec.rb +36 -0
  85. data/spec/unit/middleware/authentication/password_spec.rb +31 -0
  86. data/spec/unit/middleware/authentication/token_spec.rb +24 -0
  87. data/spec/unit/middleware/authentication_spec.rb +67 -0
  88. data/spec/unit/middleware/authorization_spec.rb +11 -0
  89. data/spec/unit/middleware/gzip_spec.rb +66 -0
  90. data/spec/unit/middleware/instance_url_spec.rb +24 -0
  91. data/spec/unit/middleware/logger_spec.rb +19 -0
  92. data/spec/unit/middleware/mashify_spec.rb +11 -0
  93. data/spec/unit/middleware/raise_error_spec.rb +32 -0
  94. data/spec/unit/signed_request_spec.rb +24 -0
  95. data/spec/unit/sobject_spec.rb +86 -0
  96. data/spec/unit/tooling/client_spec.rb +7 -0
  97. metadata +225 -65
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
3
+
4
+ task :default => [:spec]
5
+
6
+ require 'rspec/core/rake_task'
7
+ desc "Run specs"
8
+ RSpec::Core::RakeTask.new do |t|
9
+ t.pattern = 'spec/**/*_spec.rb'
10
+ end
@@ -69,5 +69,6 @@ module Sfdc
69
69
  self
70
70
  end
71
71
  end
72
+
72
73
  Object.send :include, Sfdc::CoreExtensions unless Object.respond_to? :tap
73
74
  end
@@ -6,4 +6,4 @@ module Sfdc
6
6
  include Sfdc::Concerns::Caching
7
7
  include Sfdc::Concerns::API
8
8
  end
9
- end
9
+ end
@@ -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
@@ -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
- private
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: Force an authentication
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
@@ -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
- # opts - A hash of options to be passed in (default: {}).
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(opts = {})
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! opts
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
- private
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
@@ -1,12 +1,10 @@
1
1
  module Sfdc
2
2
  module Concerns
3
3
  module Canvas
4
-
5
4
  def decode_signed_request(signed_request)
6
5
  raise 'client_secret not set.' unless options[:client_secret]
7
6
  SignedRequest.decode(signed_request, options[:client_secret])
8
7
  end
9
-
10
8
  end
11
9
  end
12
10
  end
@@ -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
- private
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
- private
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
@@ -1,7 +1,6 @@
1
1
  module Sfdc
2
2
  module Concerns
3
3
  module Verbs
4
-
5
4
  # Internal: Define methods to handle a verb.
6
5
  #
7
6
  # verbs - A list of verbs to define methods for.
@@ -62,7 +61,6 @@ module Sfdc
62
61
  send(verb, *args, &block)
63
62
  end
64
63
  end
65
-
66
64
  end
67
65
  end
68
66
  end
@@ -56,6 +56,7 @@ module Sfdc
56
56
  end
57
57
 
58
58
  private
59
+
59
60
  attr_reader :default
60
61
  alias_method :default_provided?, :default
61
62
 
@@ -62,10 +62,12 @@ module Sfdc
62
62
  end
63
63
  end
64
64
 
65
- private
65
+ private
66
+
66
67
  def faraday_options
67
68
  { :url => "https://#{@options[:host]}",
68
- :proxy => @options[:proxy_uri] }.reject { |k, v| v.nil? }
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
- @app.call env
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
- false
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
@@ -29,6 +29,7 @@ module Sfdc
29
29
  end
30
30
 
31
31
  private
32
+
32
33
  attr_reader :client_secret, :signature, :payload
33
34
 
34
35
  def split_components(signed_request)
@@ -43,6 +44,5 @@ module Sfdc
43
44
  def digest
44
45
  OpenSSL::Digest::Digest.new('sha256')
45
46
  end
46
-
47
47
  end
48
48
  end
@@ -1,13 +1,11 @@
1
1
  module Sfdc
2
2
  module Tooling
3
3
  class Client < AbstractClient
4
-
5
4
  private
6
5
 
7
- def api_path(path)
8
- super("tooling/#{path}")
9
- end
10
-
6
+ def api_path(path)
7
+ super("tooling/#{path}")
8
+ end
11
9
  end
12
10
  end
13
- end
11
+ end
@@ -1,3 +1,3 @@
1
1
  module Sfdc
2
- VERSION = '3.0.0'
3
- end
2
+ VERSION = '3.0.1'
3
+ end
@@ -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