restforce 2.5.4 → 3.0.0

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 (90) hide show
  1. checksums.yaml +5 -5
  2. data/.circleci/config.yml +56 -0
  3. data/.rubocop.yml +18 -3
  4. data/.rubocop_todo.yml +8 -8
  5. data/CHANGELOG.md +12 -3
  6. data/CONTRIBUTING.md +3 -3
  7. data/Gemfile +4 -2
  8. data/Guardfile +3 -1
  9. data/LICENSE +1 -1
  10. data/README.md +22 -16
  11. data/Rakefile +2 -1
  12. data/lib/restforce.rb +2 -0
  13. data/lib/restforce/abstract_client.rb +2 -0
  14. data/lib/restforce/attachment.rb +2 -0
  15. data/lib/restforce/client.rb +2 -0
  16. data/lib/restforce/collection.rb +3 -1
  17. data/lib/restforce/concerns/api.rb +11 -8
  18. data/lib/restforce/concerns/authentication.rb +2 -0
  19. data/lib/restforce/concerns/base.rb +2 -0
  20. data/lib/restforce/concerns/caching.rb +4 -2
  21. data/lib/restforce/concerns/canvas.rb +2 -0
  22. data/lib/restforce/concerns/connection.rb +26 -20
  23. data/lib/restforce/concerns/picklists.rb +7 -5
  24. data/lib/restforce/concerns/streaming.rb +2 -0
  25. data/lib/restforce/concerns/verbs.rb +3 -1
  26. data/lib/restforce/config.rb +3 -1
  27. data/lib/restforce/data/client.rb +2 -0
  28. data/lib/restforce/document.rb +2 -0
  29. data/lib/restforce/mash.rb +2 -0
  30. data/lib/restforce/middleware.rb +2 -0
  31. data/lib/restforce/middleware/authentication.rb +8 -6
  32. data/lib/restforce/middleware/authentication/password.rb +2 -0
  33. data/lib/restforce/middleware/authentication/token.rb +2 -0
  34. data/lib/restforce/middleware/authorization.rb +3 -1
  35. data/lib/restforce/middleware/caching.rb +3 -1
  36. data/lib/restforce/middleware/custom_headers.rb +2 -0
  37. data/lib/restforce/middleware/gzip.rb +5 -3
  38. data/lib/restforce/middleware/instance_url.rb +7 -3
  39. data/lib/restforce/middleware/logger.rb +2 -0
  40. data/lib/restforce/middleware/mashify.rb +2 -0
  41. data/lib/restforce/middleware/multipart.rb +7 -4
  42. data/lib/restforce/middleware/raise_error.rb +2 -0
  43. data/lib/restforce/patches/parts.rb +2 -0
  44. data/lib/restforce/signed_request.rb +2 -0
  45. data/lib/restforce/sobject.rb +2 -0
  46. data/lib/restforce/tooling/client.rb +2 -0
  47. data/lib/restforce/upload_io.rb +2 -0
  48. data/lib/restforce/version.rb +3 -1
  49. data/restforce.gemspec +17 -10
  50. data/spec/fixtures/sobject/sobject_describe_success_response.json +48 -1
  51. data/spec/integration/abstract_client_spec.rb +9 -6
  52. data/spec/integration/data/client_spec.rb +24 -5
  53. data/spec/spec_helper.rb +2 -0
  54. data/spec/support/client_integration.rb +2 -0
  55. data/spec/support/concerns.rb +2 -0
  56. data/spec/support/event_machine.rb +2 -0
  57. data/spec/support/fixture_helpers.rb +2 -0
  58. data/spec/support/matchers.rb +2 -0
  59. data/spec/support/middleware.rb +3 -1
  60. data/spec/support/mock_cache.rb +4 -2
  61. data/spec/unit/abstract_client_spec.rb +2 -0
  62. data/spec/unit/attachment_spec.rb +2 -0
  63. data/spec/unit/collection_spec.rb +5 -3
  64. data/spec/unit/concerns/api_spec.rb +30 -11
  65. data/spec/unit/concerns/authentication_spec.rb +4 -2
  66. data/spec/unit/concerns/base_spec.rb +2 -0
  67. data/spec/unit/concerns/caching_spec.rb +2 -0
  68. data/spec/unit/concerns/canvas_spec.rb +3 -1
  69. data/spec/unit/concerns/connection_spec.rb +5 -3
  70. data/spec/unit/concerns/streaming_spec.rb +3 -1
  71. data/spec/unit/config_spec.rb +10 -8
  72. data/spec/unit/data/client_spec.rb +2 -0
  73. data/spec/unit/document_spec.rb +2 -0
  74. data/spec/unit/mash_spec.rb +3 -1
  75. data/spec/unit/middleware/authentication/password_spec.rb +2 -0
  76. data/spec/unit/middleware/authentication/token_spec.rb +2 -0
  77. data/spec/unit/middleware/authentication_spec.rb +3 -1
  78. data/spec/unit/middleware/authorization_spec.rb +2 -0
  79. data/spec/unit/middleware/custom_headers_spec.rb +3 -1
  80. data/spec/unit/middleware/gzip_spec.rb +4 -2
  81. data/spec/unit/middleware/instance_url_spec.rb +2 -0
  82. data/spec/unit/middleware/logger_spec.rb +2 -0
  83. data/spec/unit/middleware/mashify_spec.rb +3 -1
  84. data/spec/unit/middleware/raise_error_spec.rb +2 -0
  85. data/spec/unit/signed_request_spec.rb +2 -0
  86. data/spec/unit/sobject_spec.rb +5 -3
  87. data/spec/unit/tooling/client_spec.rb +2 -0
  88. metadata +35 -19
  89. data/.travis.yml +0 -16
  90. data/Gemfile.travis +0 -8
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  module Concerns
3
5
  module Authentication
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  module Concerns
3
5
  module Base
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  module Concerns
3
5
  module Caching
@@ -6,9 +8,9 @@ module Restforce
6
8
  # block - A query/describe/etc.
7
9
  #
8
10
  # Returns the result of the block
9
- def without_caching(&block)
11
+ def without_caching
10
12
  options[:use_cache] = false
11
- block.call
13
+ yield
12
14
  ensure
13
15
  options.delete(:use_cache)
14
16
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  module Concerns
3
5
  module Canvas
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  module Concerns
3
5
  module Connection
@@ -13,7 +15,7 @@ module Restforce
13
15
  def middleware
14
16
  connection.builder
15
17
  end
16
- alias_method :builder, :middleware
18
+ alias builder middleware
17
19
 
18
20
  private
19
21
 
@@ -22,40 +24,44 @@ module Restforce
22
24
  @connection ||= Faraday.new(options[:instance_url],
23
25
  connection_options) do |builder|
24
26
  # Parses JSON into Hashie::Mash structures.
25
- unless (options[:mashify] == false)
26
- builder.use Restforce::Middleware::Mashify, self, options
27
+ unless options[:mashify] == false
28
+ builder.use Restforce::Middleware::Mashify, self, options
27
29
  end
28
30
 
29
31
  # Handles multipart file uploads for blobs.
30
- builder.use Restforce::Middleware::Multipart
32
+ builder.use Restforce::Middleware::Multipart
31
33
  # Converts the request into JSON.
32
- builder.request :json
34
+ builder.request :json
33
35
  # Handles reauthentication for 403 responses.
34
36
  if authentication_middleware
35
- builder.use authentication_middleware, self, options
37
+ builder.use authentication_middleware, self, options
36
38
  end
37
39
  # Sets the oauth token in the headers.
38
- builder.use Restforce::Middleware::Authorization, self, options
40
+ builder.use Restforce::Middleware::Authorization, self, options
39
41
  # Ensures the instance url is set.
40
- builder.use Restforce::Middleware::InstanceURL, self, options
42
+ builder.use Restforce::Middleware::InstanceURL, self, options
41
43
  # Caches GET requests.
42
- builder.use Restforce::Middleware::Caching, cache, options if cache
44
+ builder.use Restforce::Middleware::Caching, cache, options if cache
43
45
  # Follows 30x redirects.
44
- builder.use FaradayMiddleware::FollowRedirects
46
+ builder.use FaradayMiddleware::FollowRedirects
45
47
  # Raises errors for 40x responses.
46
- builder.use Restforce::Middleware::RaiseError
48
+ builder.use Restforce::Middleware::RaiseError
47
49
  # Parses returned JSON response into a hash.
48
50
  builder.response :json, content_type: /\bjson$/
49
51
  # Compress/Decompress the request/response
50
- builder.use Restforce::Middleware::Gzip, self, options
52
+ unless adapter == :httpclient
53
+ builder.use Restforce::Middleware::Gzip, self, options
54
+ end
51
55
  # Inject custom headers into requests
52
- builder.use Restforce::Middleware::CustomHeaders, self, options
56
+ builder.use Restforce::Middleware::CustomHeaders, self, options
53
57
  # Log request/responses
54
- builder.use Restforce::Middleware::Logger,
55
- Restforce.configuration.logger,
56
- options if Restforce.log?
58
+ if Restforce.log?
59
+ builder.use Restforce::Middleware::Logger,
60
+ Restforce.configuration.logger,
61
+ options
62
+ end
57
63
 
58
- builder.adapter adapter
64
+ builder.adapter adapter
59
65
  end
60
66
  end
61
67
 
@@ -67,10 +73,10 @@ module Restforce
67
73
  def connection_options
68
74
  { request: {
69
75
  timeout: options[:timeout],
70
- open_timeout: options[:timeout] },
76
+ open_timeout: options[:timeout]
77
+ },
71
78
  proxy: options[:proxy_uri],
72
- ssl: options[:ssl]
73
- }
79
+ ssl: options[:ssl] }
74
80
  end
75
81
 
76
82
  # Internal: Returns true if the middlware stack includes the
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  module Concerns
3
5
  module Picklists
@@ -26,8 +28,6 @@ module Restforce
26
28
  PicklistValues.new(describe(sobject)['fields'], field, options)
27
29
  end
28
30
 
29
- private
30
-
31
31
  class PicklistValues < Array
32
32
  def initialize(fields, field, options = {})
33
33
  @fields = fields
@@ -60,7 +60,9 @@ module Restforce
60
60
 
61
61
  def controlling_picklist
62
62
  @_controlling_picklist ||= controlling_field['picklistValues'].
63
- find { |picklist_entry| picklist_entry['value'] == @valid_for }
63
+ find do |picklist_entry|
64
+ picklist_entry['value'] == @valid_for
65
+ end
64
66
  end
65
67
 
66
68
  def index
@@ -81,8 +83,8 @@ module Restforce
81
83
  # cribesobjects_describesobjectresult.htm
82
84
  def valid?(picklist_entry)
83
85
  valid_for = picklist_entry['validFor'].ljust(16, 'A').unpack('m').first.
84
- unpack('q*')
85
- (valid_for[index >> 3] & (0x80 >> index % 8)) != 0
86
+ unpack('C*')
87
+ (valid_for[index >> 3] & (0x80 >> index % 8)).positive?
86
88
  end
87
89
  end
88
90
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  module Concerns
3
5
  module Streaming
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  module Concerns
3
5
  module Verbs
@@ -34,7 +36,7 @@ module Restforce
34
36
  begin
35
37
  connection.send(verb, *args, &block)
36
38
  rescue Restforce::UnauthorizedError
37
- if retries > 0
39
+ if retries.positive?
38
40
  retries -= 1
39
41
  connection.url_prefix = options[:instance_url]
40
42
  retry
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'logger'
2
4
 
3
5
  module Restforce
@@ -60,7 +62,7 @@ module Restforce
60
62
  private
61
63
 
62
64
  attr_reader :default
63
- alias_method :default_provided?, :default
65
+ alias default_provided? default
64
66
 
65
67
  def write_attribute
66
68
  configuration.send :attr_accessor, name
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  module Data
3
5
  class Client < AbstractClient
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  class Document < Restforce::SObject
3
5
  # Public: Returns the body of the document.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'hashie/mash'
2
4
 
3
5
  module Restforce
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  # Base class that all middleware can extend. Provides some convenient helper
3
5
  # functions.
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  # Faraday middleware that allows for on the fly authentication of requests.
3
5
  # When a request fails (a status of 401 is returned), the middleware
@@ -31,9 +33,7 @@ module Restforce
31
33
  @options[:instance_url] = response.body['instance_url']
32
34
  @options[:oauth_token] = response.body['access_token']
33
35
 
34
- if @options[:authentication_callback]
35
- @options[:authentication_callback].call(response.body)
36
- end
36
+ @options[:authentication_callback]&.call(response.body)
37
37
 
38
38
  response.body
39
39
  end
@@ -50,9 +50,11 @@ module Restforce
50
50
  builder.use Restforce::Middleware::Mashify, nil, @options
51
51
  builder.response :json
52
52
 
53
- builder.use Restforce::Middleware::Logger,
54
- Restforce.configuration.logger,
55
- @options if Restforce.log?
53
+ if Restforce.log?
54
+ builder.use Restforce::Middleware::Logger,
55
+ Restforce.configuration.logger,
56
+ @options
57
+ end
56
58
 
57
59
  builder.adapter @options[:adapter]
58
60
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  # Authentication middleware used if username and password flow is used
3
5
  class Middleware::Authentication::Password < Restforce::Middleware::Authentication
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  # Authentication middleware used if oauth_token and refresh_token are set
3
5
  class Middleware::Authentication::Token < Restforce::Middleware::Authentication
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  # Piece of middleware that simply injects the OAuth token into the request
3
5
  # headers.
4
6
  class Middleware::Authorization < Restforce::Middleware
5
- AUTH_HEADER = 'Authorization'.freeze
7
+ AUTH_HEADER = 'Authorization'
6
8
 
7
9
  def call(env)
8
10
  env[:request_headers][AUTH_HEADER] = %(OAuth #{token})
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  class Middleware::Caching < FaradayMiddleware::Caching
3
5
  def call(env)
@@ -6,7 +8,7 @@ module Restforce
6
8
  end
7
9
 
8
10
  def expire(key)
9
- cache.delete(key) if cache
11
+ cache&.delete(key)
10
12
  end
11
13
 
12
14
  # We don't want to cache requests for different clients, so append the
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  # Middleware that allows you to specify custom request headers
3
5
  # when initializing Restforce client
@@ -1,11 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'zlib'
2
4
 
3
5
  module Restforce
4
6
  # Middleware to uncompress GZIP compressed responses from Salesforce.
5
7
  class Middleware::Gzip < Restforce::Middleware
6
- ACCEPT_ENCODING_HEADER = 'Accept-Encoding'.freeze
7
- CONTENT_ENCODING_HEADER = 'Content-Encoding'.freeze
8
- ENCODING = 'gzip'.freeze
8
+ ACCEPT_ENCODING_HEADER = 'Accept-Encoding'
9
+ CONTENT_ENCODING_HEADER = 'Content-Encoding'
10
+ ENCODING = 'gzip'
9
11
 
10
12
  def call(env)
11
13
  env[:request_headers][ACCEPT_ENCODING_HEADER] = ENCODING if @options[:compress]
@@ -1,16 +1,20 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  # Middleware which asserts that the instance_url is always set
3
5
  class Middleware::InstanceURL < Restforce::Middleware
4
6
  def call(env)
5
7
  # If the connection url_prefix isn't set, we must not be authenticated.
6
- raise Restforce::UnauthorizedError,
7
- 'Connection prefix not set' unless url_prefix_set?
8
+ unless url_prefix_set?
9
+ raise Restforce::UnauthorizedError,
10
+ 'Connection prefix not set'
11
+ end
8
12
 
9
13
  @app.call(env)
10
14
  end
11
15
 
12
16
  def url_prefix_set?
13
- !!(connection.url_prefix && connection.url_prefix.host)
17
+ !!(connection.url_prefix&.host)
14
18
  end
15
19
  end
16
20
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'forwardable'
2
4
 
3
5
  module Restforce
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  # Middleware the converts sobject records from JSON into Restforce::SObject objects
3
5
  # and collections of records into Restforce::Collection objects.
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  class Middleware::Multipart < Faraday::Request::UrlEncoded
3
- self.mime_type = 'multipart/form-data'.freeze
4
- DEFAULT_BOUNDARY = "--boundary_string".freeze
5
- JSON_CONTENT_TYPE = { "Content-Type" => "application/json" }
5
+ self.mime_type = 'multipart/form-data'
6
+ DEFAULT_BOUNDARY = "--boundary_string"
7
+ JSON_CONTENT_TYPE = { "Content-Type" => "application/json" }.freeze
6
8
 
7
9
  def call(env)
8
10
  match_content_type(env) do |params|
@@ -46,9 +48,10 @@ module Restforce
46
48
 
47
49
  # Files
48
50
  params.each do |k, v|
51
+ next unless v.respond_to? :content_type
49
52
  parts << Faraday::Parts::Part.new(boundary,
50
53
  k.to_s,
51
- v) if v.respond_to? :content_type
54
+ v)
52
55
  end
53
56
 
54
57
  parts << Faraday::Parts::EpiloguePart.new(boundary)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  class Middleware::RaiseError < Faraday::Response::Middleware
3
5
  def on_complete(env)
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Faraday
2
4
  module Parts
3
5
  module Part
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'openssl'
2
4
  require 'base64'
3
5
  require 'json'
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  class SObject < Restforce::Mash
3
5
  def sobject_type
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
4
  module Tooling
3
5
  class Client < AbstractClient
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'faraday/upload_io'
2
4
 
3
5
  module Restforce
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Restforce
2
- VERSION = '2.5.4'.freeze
4
+ VERSION = '3.0.0'
3
5
  end
@@ -1,24 +1,30 @@
1
- # -*- encoding: utf-8 -*-
1
+ # frozen_string_literal: true
2
+
2
3
  require File.expand_path('../lib/restforce/version', __FILE__)
3
4
 
4
5
  Gem::Specification.new do |gem|
5
6
  gem.authors = ["Eric J. Holmes", "Tim Rogers"]
6
7
  gem.email = ["eric@ejholmes.net", "tim@gocardless.com"]
7
- gem.description = %q{A lightweight ruby client for the Salesforce REST API.}
8
- gem.summary = %q{A lightweight ruby client for the Salesforce REST API.}
8
+ gem.description = 'A lightweight ruby client for the Salesforce REST API.'
9
+ gem.summary = 'A lightweight ruby client for the Salesforce REST API.'
9
10
  gem.homepage = "http://restforce.org/"
10
11
  gem.license = "MIT"
11
12
 
12
- gem.files = `git ls-files`.split($\)
13
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
14
15
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
15
16
  gem.name = "restforce"
16
17
  gem.require_paths = ["lib"]
17
18
  gem.version = Restforce::VERSION
18
19
 
19
- gem.required_ruby_version = '>= 2.0'
20
+ gem.metadata = {
21
+ 'source_code_uri' => 'https://github.com/restforce/restforce',
22
+ 'changelog_uri' => 'https://github.com/restforce/restforce/blob/master/CHANGELOG.md'
23
+ }
24
+
25
+ gem.required_ruby_version = '>= 2.3'
20
26
 
21
- gem.add_dependency 'faraday', ['>= 0.9.0', '<= 1.0']
27
+ gem.add_dependency 'faraday', '<= 1.0', '>= 0.9.0'
22
28
  gem.add_dependency 'faraday_middleware', ['>= 0.8.8', '<= 1.0']
23
29
 
24
30
  gem.add_dependency 'json', '>= 1.7.5'
@@ -26,8 +32,9 @@ Gem::Specification.new do |gem|
26
32
  gem.add_dependency 'hashie', ['>= 1.2.0', '< 4.0']
27
33
 
28
34
  gem.add_development_dependency 'rspec', '~> 2.14.0'
29
- gem.add_development_dependency 'webmock', '~> 1.13.0'
30
- gem.add_development_dependency 'simplecov', '~> 0.7.1'
31
- gem.add_development_dependency 'rubocop', '~> 0.31.0'
35
+ gem.add_development_dependency 'webmock', '~> 3.4.0'
36
+ gem.add_development_dependency 'simplecov', '~> 0.15.0'
37
+ gem.add_development_dependency 'rubocop', '~> 0.50.0'
38
+ gem.add_development_dependency 'rspec_junit_formatter', '~> 0.3.0'
32
39
  gem.add_development_dependency 'faye' unless RUBY_PLATFORM == 'java'
33
40
  end