restforce 2.5.4 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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