ddy_remote_resource 0.4.2
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.
- checksums.yaml +7 -0
 - data/.gitignore +22 -0
 - data/.rspec +2 -0
 - data/.ruby-gemset +1 -0
 - data/.ruby-version +1 -0
 - data/.travis.yml +3 -0
 - data/Gemfile +4 -0
 - data/LICENSE.txt +22 -0
 - data/README.md +182 -0
 - data/Rakefile +7 -0
 - data/lib/extensions/ethon/easy/queryable.rb +36 -0
 - data/lib/remote_resource.rb +64 -0
 - data/lib/remote_resource/base.rb +126 -0
 - data/lib/remote_resource/builder.rb +53 -0
 - data/lib/remote_resource/collection.rb +31 -0
 - data/lib/remote_resource/connection.rb +24 -0
 - data/lib/remote_resource/connection_options.rb +41 -0
 - data/lib/remote_resource/http_errors.rb +33 -0
 - data/lib/remote_resource/querying/finder_methods.rb +34 -0
 - data/lib/remote_resource/querying/persistence_methods.rb +38 -0
 - data/lib/remote_resource/request.rb +106 -0
 - data/lib/remote_resource/response.rb +69 -0
 - data/lib/remote_resource/response_handeling.rb +48 -0
 - data/lib/remote_resource/rest.rb +29 -0
 - data/lib/remote_resource/url_naming.rb +34 -0
 - data/lib/remote_resource/url_naming_determination.rb +39 -0
 - data/lib/remote_resource/version.rb +3 -0
 - data/remote_resource.gemspec +32 -0
 - data/spec/lib/extensions/ethon/easy/queryable_spec.rb +135 -0
 - data/spec/lib/remote_resource/base_spec.rb +388 -0
 - data/spec/lib/remote_resource/builder_spec.rb +245 -0
 - data/spec/lib/remote_resource/collection_spec.rb +148 -0
 - data/spec/lib/remote_resource/connection_options_spec.rb +124 -0
 - data/spec/lib/remote_resource/connection_spec.rb +61 -0
 - data/spec/lib/remote_resource/querying/finder_methods_spec.rb +105 -0
 - data/spec/lib/remote_resource/querying/persistence_methods_spec.rb +174 -0
 - data/spec/lib/remote_resource/request_spec.rb +594 -0
 - data/spec/lib/remote_resource/response_spec.rb +196 -0
 - data/spec/lib/remote_resource/rest_spec.rb +98 -0
 - data/spec/lib/remote_resource/url_naming_determination_spec.rb +225 -0
 - data/spec/lib/remote_resource/url_naming_spec.rb +72 -0
 - data/spec/lib/remote_resource/version_spec.rb +8 -0
 - data/spec/spec_helper.rb +4 -0
 - metadata +242 -0
 
| 
         @@ -0,0 +1,53 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RemoteResource
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Builder
         
     | 
| 
      
 3 
     | 
    
         
            +
                extend ActiveSupport::Concern
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                module ClassMethods
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                  def build_resource_from_response(response)
         
     | 
| 
      
 8 
     | 
    
         
            +
                    build_resource response.sanitized_response_body, response_hash(response)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                  def build_resource(collection, response_hash = {})
         
     | 
| 
      
 12 
     | 
    
         
            +
                    if collection.is_a? Hash
         
     | 
| 
      
 13 
     | 
    
         
            +
                      new collection.merge response_hash
         
     | 
| 
      
 14 
     | 
    
         
            +
                    end
         
     | 
| 
      
 15 
     | 
    
         
            +
                  end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                  def build_collection_from_response(response)
         
     | 
| 
      
 18 
     | 
    
         
            +
                    build_collection response.sanitized_response_body, response_hash(response)
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                  def build_collection(collection, response_hash = {})
         
     | 
| 
      
 22 
     | 
    
         
            +
                    if collection.is_a? Array
         
     | 
| 
      
 23 
     | 
    
         
            +
                      RemoteResource::Collection.new self, collection, response_hash
         
     | 
| 
      
 24 
     | 
    
         
            +
                    end
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  private
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                  def response_hash(response_object)
         
     | 
| 
      
 30 
     | 
    
         
            +
                    { _response: response_object }
         
     | 
| 
      
 31 
     | 
    
         
            +
                  end
         
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                def rebuild_resource_from_response(response)
         
     | 
| 
      
 35 
     | 
    
         
            +
                  rebuild_resource response.sanitized_response_body, response_hash(response)
         
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                def rebuild_resource(collection, response_hash = {})
         
     | 
| 
      
 39 
     | 
    
         
            +
                  if collection.is_a? Hash
         
     | 
| 
      
 40 
     | 
    
         
            +
                    self.attributes = collection.merge(response_hash)
         
     | 
| 
      
 41 
     | 
    
         
            +
                  else
         
     | 
| 
      
 42 
     | 
    
         
            +
                    self.attributes = response_hash
         
     | 
| 
      
 43 
     | 
    
         
            +
                  end and self
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                private
         
     | 
| 
      
 47 
     | 
    
         
            +
             
     | 
| 
      
 48 
     | 
    
         
            +
                def response_hash(response_object)
         
     | 
| 
      
 49 
     | 
    
         
            +
                  self.class.send :response_hash, response_object
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
              end
         
     | 
| 
      
 53 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,31 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RemoteResource
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Collection
         
     | 
| 
      
 3 
     | 
    
         
            +
                include Enumerable
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                delegate :[], :at, :reverse, :size, to: :to_a
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                attr_reader :resource_klass, :resources_collection, :_response
         
     | 
| 
      
 8 
     | 
    
         
            +
             
     | 
| 
      
 9 
     | 
    
         
            +
                def initialize(resource_klass, resources_collection, response_hash)
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @resource_klass       = resource_klass
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @resources_collection = resources_collection
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @response_hash        = response_hash
         
     | 
| 
      
 13 
     | 
    
         
            +
                  @_response            = response_hash[:_response]
         
     | 
| 
      
 14 
     | 
    
         
            +
                end
         
     | 
| 
      
 15 
     | 
    
         
            +
             
     | 
| 
      
 16 
     | 
    
         
            +
                def each
         
     | 
| 
      
 17 
     | 
    
         
            +
                  if resources_collection.is_a? Array
         
     | 
| 
      
 18 
     | 
    
         
            +
                    resources_collection.each { |element| yield resource_klass.new element.merge(@response_hash) }
         
     | 
| 
      
 19 
     | 
    
         
            +
                  end
         
     | 
| 
      
 20 
     | 
    
         
            +
                end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                def empty?
         
     | 
| 
      
 23 
     | 
    
         
            +
                  resources_collection.blank?
         
     | 
| 
      
 24 
     | 
    
         
            +
                end
         
     | 
| 
      
 25 
     | 
    
         
            +
             
     | 
| 
      
 26 
     | 
    
         
            +
                def success?
         
     | 
| 
      
 27 
     | 
    
         
            +
                  _response.success?
         
     | 
| 
      
 28 
     | 
    
         
            +
                end
         
     | 
| 
      
 29 
     | 
    
         
            +
             
     | 
| 
      
 30 
     | 
    
         
            +
              end
         
     | 
| 
      
 31 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,24 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RemoteResource
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Connection
         
     | 
| 
      
 3 
     | 
    
         
            +
                extend ActiveSupport::Concern
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                included do
         
     | 
| 
      
 6 
     | 
    
         
            +
                  class_attribute :content_type, :default_headers, :extra_headers, instance_accessor: false
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                  self.content_type    = '.json'
         
     | 
| 
      
 9 
     | 
    
         
            +
                  self.default_headers = { "Accept" => "application/json" }
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                module ClassMethods
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                  def connection
         
     | 
| 
      
 15 
     | 
    
         
            +
                    Typhoeus::Request
         
     | 
| 
      
 16 
     | 
    
         
            +
                  end
         
     | 
| 
      
 17 
     | 
    
         
            +
             
     | 
| 
      
 18 
     | 
    
         
            +
                  def headers
         
     | 
| 
      
 19 
     | 
    
         
            +
                    self.default_headers.merge self.extra_headers || {}
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
              end
         
     | 
| 
      
 24 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,41 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RemoteResource
         
     | 
| 
      
 2 
     | 
    
         
            +
              class ConnectionOptions
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                attr_reader :base_class
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                def initialize(base_class)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @base_class = base_class
         
     | 
| 
      
 8 
     | 
    
         
            +
                  self.send :initialize_connection_options
         
     | 
| 
      
 9 
     | 
    
         
            +
                end
         
     | 
| 
      
 10 
     | 
    
         
            +
             
     | 
| 
      
 11 
     | 
    
         
            +
                def merge(options = {})
         
     | 
| 
      
 12 
     | 
    
         
            +
                  options.each do |option, value|
         
     | 
| 
      
 13 
     | 
    
         
            +
                    self.public_send "#{option}=", value
         
     | 
| 
      
 14 
     | 
    
         
            +
                  end and self
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def to_hash
         
     | 
| 
      
 18 
     | 
    
         
            +
                  RemoteResource::Base::OPTIONS.each_with_object(Hash.new) do |option, hash|
         
     | 
| 
      
 19 
     | 
    
         
            +
                    hash[option] = self.public_send option
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
             
     | 
| 
      
 23 
     | 
    
         
            +
                def reload
         
     | 
| 
      
 24 
     | 
    
         
            +
                  initialize_connection_options
         
     | 
| 
      
 25 
     | 
    
         
            +
                end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                def reload!
         
     | 
| 
      
 28 
     | 
    
         
            +
                  reload and self
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                private
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                def initialize_connection_options
         
     | 
| 
      
 34 
     | 
    
         
            +
                  RemoteResource::Base::OPTIONS.each do |option|
         
     | 
| 
      
 35 
     | 
    
         
            +
                    self.class.send :attr_accessor, option
         
     | 
| 
      
 36 
     | 
    
         
            +
                    self.public_send "#{option}=", base_class.public_send(option)
         
     | 
| 
      
 37 
     | 
    
         
            +
                  end
         
     | 
| 
      
 38 
     | 
    
         
            +
                end
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
              end
         
     | 
| 
      
 41 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,33 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RemoteResource
         
     | 
| 
      
 2 
     | 
    
         
            +
              module HTTPErrors
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                private
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                def raise_http_errors(response)
         
     | 
| 
      
 7 
     | 
    
         
            +
                  case response.response_code
         
     | 
| 
      
 8 
     | 
    
         
            +
                  when 301, 302, 303, 307 then raise RemoteResource::HTTPRedirectionError, response
         
     | 
| 
      
 9 
     | 
    
         
            +
                  when 400 then raise RemoteResource::HTTPBadRequest, response
         
     | 
| 
      
 10 
     | 
    
         
            +
                  when 401 then raise RemoteResource::HTTPUnauthorized, response
         
     | 
| 
      
 11 
     | 
    
         
            +
                  when 403 then raise RemoteResource::HTTPForbidden, response
         
     | 
| 
      
 12 
     | 
    
         
            +
                  when 404 then raise RemoteResource::HTTPNotFound, response
         
     | 
| 
      
 13 
     | 
    
         
            +
                  when 405 then raise RemoteResource::HTTPMethodNotAllowed, response
         
     | 
| 
      
 14 
     | 
    
         
            +
                  when 406 then raise RemoteResource::HTTPNotAcceptable, response
         
     | 
| 
      
 15 
     | 
    
         
            +
                  when 408 then raise RemoteResource::HTTPRequestTimeout, response
         
     | 
| 
      
 16 
     | 
    
         
            +
                  when 409 then raise RemoteResource::HTTPConflict, response
         
     | 
| 
      
 17 
     | 
    
         
            +
                  when 410 then raise RemoteResource::HTTPGone, response
         
     | 
| 
      
 18 
     | 
    
         
            +
                  when 418 then raise RemoteResource::HTTPTeapot, response
         
     | 
| 
      
 19 
     | 
    
         
            +
                  when 444 then raise RemoteResource::HTTPNoResponse, response
         
     | 
| 
      
 20 
     | 
    
         
            +
                  when 494 then raise RemoteResource::HTTPRequestHeaderTooLarge, response
         
     | 
| 
      
 21 
     | 
    
         
            +
                  when 495 then raise RemoteResource::HTTPCertError, response
         
     | 
| 
      
 22 
     | 
    
         
            +
                  when 496 then raise RemoteResource::HTTPNoCert, response
         
     | 
| 
      
 23 
     | 
    
         
            +
                  when 497 then raise RemoteResource::HTTPToHTTPS, response
         
     | 
| 
      
 24 
     | 
    
         
            +
                  when 499 then raise RemoteResource::HTTPClientClosedRequest, response
         
     | 
| 
      
 25 
     | 
    
         
            +
                  when 400..499 then raise RemoteResource::HTTPClientError, response
         
     | 
| 
      
 26 
     | 
    
         
            +
                  when 500..599 then raise RemoteResource::HTTPServerError, response
         
     | 
| 
      
 27 
     | 
    
         
            +
                  else
         
     | 
| 
      
 28 
     | 
    
         
            +
                    raise RemoteResource::HTTPError, response
         
     | 
| 
      
 29 
     | 
    
         
            +
                  end
         
     | 
| 
      
 30 
     | 
    
         
            +
                end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
              end
         
     | 
| 
      
 33 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,34 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RemoteResource
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Querying
         
     | 
| 
      
 3 
     | 
    
         
            +
                module FinderMethods
         
     | 
| 
      
 4 
     | 
    
         
            +
                  extend ActiveSupport::Concern
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  module ClassMethods
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                    def find(id, connection_options = {})
         
     | 
| 
      
 9 
     | 
    
         
            +
                      connection_options.merge! no_params: true
         
     | 
| 
      
 10 
     | 
    
         
            +
                      response = RemoteResource::Request.new(self, :get, { id: id }, connection_options).perform
         
     | 
| 
      
 11 
     | 
    
         
            +
                      build_resource_from_response response
         
     | 
| 
      
 12 
     | 
    
         
            +
                    end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
      
 14 
     | 
    
         
            +
                    def find_by(params, connection_options = {})
         
     | 
| 
      
 15 
     | 
    
         
            +
                      response = RemoteResource::Request.new(self, :get, params, connection_options).perform
         
     | 
| 
      
 16 
     | 
    
         
            +
                      build_resource_from_response response
         
     | 
| 
      
 17 
     | 
    
         
            +
                    end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                    def all(connection_options = {})
         
     | 
| 
      
 20 
     | 
    
         
            +
                      connection_options.merge! collection: true
         
     | 
| 
      
 21 
     | 
    
         
            +
                      response = RemoteResource::Request.new(self, :get, {}, connection_options).perform
         
     | 
| 
      
 22 
     | 
    
         
            +
                      build_collection_from_response response
         
     | 
| 
      
 23 
     | 
    
         
            +
                    end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                    def where(params, connection_options = {})
         
     | 
| 
      
 26 
     | 
    
         
            +
                      connection_options.merge! collection: true
         
     | 
| 
      
 27 
     | 
    
         
            +
                      response = RemoteResource::Request.new(self, :get, params, connection_options).perform
         
     | 
| 
      
 28 
     | 
    
         
            +
                      build_collection_from_response response
         
     | 
| 
      
 29 
     | 
    
         
            +
                    end
         
     | 
| 
      
 30 
     | 
    
         
            +
                  end
         
     | 
| 
      
 31 
     | 
    
         
            +
             
     | 
| 
      
 32 
     | 
    
         
            +
                end
         
     | 
| 
      
 33 
     | 
    
         
            +
              end
         
     | 
| 
      
 34 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,38 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RemoteResource
         
     | 
| 
      
 2 
     | 
    
         
            +
              module Querying
         
     | 
| 
      
 3 
     | 
    
         
            +
                module PersistenceMethods
         
     | 
| 
      
 4 
     | 
    
         
            +
                  extend ActiveSupport::Concern
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                  module ClassMethods
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
                    def create(attributes = {}, connection_options = {})
         
     | 
| 
      
 9 
     | 
    
         
            +
                      resource = new attributes
         
     | 
| 
      
 10 
     | 
    
         
            +
                      response = RemoteResource::Request.new(self, :post, attributes, connection_options).perform
         
     | 
| 
      
 11 
     | 
    
         
            +
                      resource.handle_response response
         
     | 
| 
      
 12 
     | 
    
         
            +
                    end
         
     | 
| 
      
 13 
     | 
    
         
            +
                  end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                  def update_attributes(attributes = {}, connection_options = {})
         
     | 
| 
      
 16 
     | 
    
         
            +
                    rebuild_resource attributes
         
     | 
| 
      
 17 
     | 
    
         
            +
                    attributes.reverse_merge! id: id
         
     | 
| 
      
 18 
     | 
    
         
            +
                    create_or_update attributes, connection_options
         
     | 
| 
      
 19 
     | 
    
         
            +
                    success? ? self : false
         
     | 
| 
      
 20 
     | 
    
         
            +
                  end
         
     | 
| 
      
 21 
     | 
    
         
            +
             
     | 
| 
      
 22 
     | 
    
         
            +
                  def save(connection_options = {})
         
     | 
| 
      
 23 
     | 
    
         
            +
                    create_or_update self.attributes, connection_options
         
     | 
| 
      
 24 
     | 
    
         
            +
                    success? ? self : false
         
     | 
| 
      
 25 
     | 
    
         
            +
                  end
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
                  def create_or_update(attributes = {}, connection_options = {})
         
     | 
| 
      
 28 
     | 
    
         
            +
                    if attributes.has_key? :id
         
     | 
| 
      
 29 
     | 
    
         
            +
                      response = RemoteResource::Request.new(self, :patch, attributes, connection_options).perform
         
     | 
| 
      
 30 
     | 
    
         
            +
                    else
         
     | 
| 
      
 31 
     | 
    
         
            +
                      response = RemoteResource::Request.new(self, :post, attributes, connection_options).perform
         
     | 
| 
      
 32 
     | 
    
         
            +
                    end
         
     | 
| 
      
 33 
     | 
    
         
            +
                    handle_response response
         
     | 
| 
      
 34 
     | 
    
         
            +
                  end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                end
         
     | 
| 
      
 37 
     | 
    
         
            +
              end
         
     | 
| 
      
 38 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,106 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RemoteResource
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Request
         
     | 
| 
      
 3 
     | 
    
         
            +
                include RemoteResource::HTTPErrors
         
     | 
| 
      
 4 
     | 
    
         
            +
             
     | 
| 
      
 5 
     | 
    
         
            +
                attr_reader :resource, :rest_action, :attributes
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def initialize(resource, rest_action, attributes = {}, connection_options = {})
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @resource           = resource
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @rest_action        = rest_action.to_sym
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @attributes         = attributes
         
     | 
| 
      
 11 
     | 
    
         
            +
                  @connection_options = connection_options
         
     | 
| 
      
 12 
     | 
    
         
            +
                  @original_connection_options = connection_options.dup
         
     | 
| 
      
 13 
     | 
    
         
            +
                end
         
     | 
| 
      
 14 
     | 
    
         
            +
             
     | 
| 
      
 15 
     | 
    
         
            +
                def connection
         
     | 
| 
      
 16 
     | 
    
         
            +
                  resource_klass.connection
         
     | 
| 
      
 17 
     | 
    
         
            +
                end
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                def connection_options
         
     | 
| 
      
 20 
     | 
    
         
            +
                  @connection_options.reverse_merge! threaded_connection_options
         
     | 
| 
      
 21 
     | 
    
         
            +
                  @connection_options.reverse_merge! resource.connection_options.to_hash
         
     | 
| 
      
 22 
     | 
    
         
            +
                end
         
     | 
| 
      
 23 
     | 
    
         
            +
             
     | 
| 
      
 24 
     | 
    
         
            +
                def original_connection_options
         
     | 
| 
      
 25 
     | 
    
         
            +
                  @original_connection_options.reverse_merge! threaded_connection_options
         
     | 
| 
      
 26 
     | 
    
         
            +
                end
         
     | 
| 
      
 27 
     | 
    
         
            +
             
     | 
| 
      
 28 
     | 
    
         
            +
                def perform
         
     | 
| 
      
 29 
     | 
    
         
            +
                  case rest_action
         
     | 
| 
      
 30 
     | 
    
         
            +
                  when :get
         
     | 
| 
      
 31 
     | 
    
         
            +
                    response = connection.public_send rest_action, determined_request_url, params: determined_params, headers: determined_headers
         
     | 
| 
      
 32 
     | 
    
         
            +
                  when :put, :patch, :post
         
     | 
| 
      
 33 
     | 
    
         
            +
                    response = connection.public_send rest_action, determined_request_url, body: determined_attributes, headers: determined_headers
         
     | 
| 
      
 34 
     | 
    
         
            +
                  else
         
     | 
| 
      
 35 
     | 
    
         
            +
                    raise RemoteResource::RESTActionUnknown, "for action: '#{rest_action}'"
         
     | 
| 
      
 36 
     | 
    
         
            +
                  end
         
     | 
| 
      
 37 
     | 
    
         
            +
             
     | 
| 
      
 38 
     | 
    
         
            +
                  if response.success? || response.response_code == 422
         
     | 
| 
      
 39 
     | 
    
         
            +
                    RemoteResource::Response.new response, connection_options
         
     | 
| 
      
 40 
     | 
    
         
            +
                  else
         
     | 
| 
      
 41 
     | 
    
         
            +
                    raise_http_errors response
         
     | 
| 
      
 42 
     | 
    
         
            +
                  end
         
     | 
| 
      
 43 
     | 
    
         
            +
                end
         
     | 
| 
      
 44 
     | 
    
         
            +
             
     | 
| 
      
 45 
     | 
    
         
            +
                def determined_request_url
         
     | 
| 
      
 46 
     | 
    
         
            +
                  id           = attributes[:id].presence
         
     | 
| 
      
 47 
     | 
    
         
            +
                  base_url     = original_connection_options[:base_url].presence || determined_url_naming.base_url(id)
         
     | 
| 
      
 48 
     | 
    
         
            +
                  content_type = connection_options[:content_type]
         
     | 
| 
      
 49 
     | 
    
         
            +
             
     | 
| 
      
 50 
     | 
    
         
            +
                  "#{base_url}#{content_type}"
         
     | 
| 
      
 51 
     | 
    
         
            +
                end
         
     | 
| 
      
 52 
     | 
    
         
            +
             
     | 
| 
      
 53 
     | 
    
         
            +
                def determined_params
         
     | 
| 
      
 54 
     | 
    
         
            +
                  no_params     = connection_options[:no_params].eql? true
         
     | 
| 
      
 55 
     | 
    
         
            +
                  no_attributes = connection_options[:no_attributes].eql? true
         
     | 
| 
      
 56 
     | 
    
         
            +
                  params        = connection_options[:params].presence || {}
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                  if no_params
         
     | 
| 
      
 59 
     | 
    
         
            +
                    nil
         
     | 
| 
      
 60 
     | 
    
         
            +
                  elsif no_attributes
         
     | 
| 
      
 61 
     | 
    
         
            +
                    params
         
     | 
| 
      
 62 
     | 
    
         
            +
                  else
         
     | 
| 
      
 63 
     | 
    
         
            +
                    attributes.merge! params
         
     | 
| 
      
 64 
     | 
    
         
            +
                  end
         
     | 
| 
      
 65 
     | 
    
         
            +
                end
         
     | 
| 
      
 66 
     | 
    
         
            +
             
     | 
| 
      
 67 
     | 
    
         
            +
                def determined_attributes
         
     | 
| 
      
 68 
     | 
    
         
            +
                  no_attributes = connection_options[:no_attributes].eql? true
         
     | 
| 
      
 69 
     | 
    
         
            +
                  root_element  = connection_options[:root_element].presence
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
                  if no_attributes
         
     | 
| 
      
 72 
     | 
    
         
            +
                    {}
         
     | 
| 
      
 73 
     | 
    
         
            +
                  elsif root_element
         
     | 
| 
      
 74 
     | 
    
         
            +
                    pack_up_attributes attributes, root_element
         
     | 
| 
      
 75 
     | 
    
         
            +
                  else
         
     | 
| 
      
 76 
     | 
    
         
            +
                    attributes
         
     | 
| 
      
 77 
     | 
    
         
            +
                  end
         
     | 
| 
      
 78 
     | 
    
         
            +
                end
         
     | 
| 
      
 79 
     | 
    
         
            +
             
     | 
| 
      
 80 
     | 
    
         
            +
                def determined_headers
         
     | 
| 
      
 81 
     | 
    
         
            +
                  headers = original_connection_options[:headers].presence || {}
         
     | 
| 
      
 82 
     | 
    
         
            +
             
     | 
| 
      
 83 
     | 
    
         
            +
                  (connection_options[:default_headers].presence ||
         
     | 
| 
      
 84 
     | 
    
         
            +
                      resource.connection_options.headers.merge(headers)).reverse_merge RemoteResource::Base.global_headers
         
     | 
| 
      
 85 
     | 
    
         
            +
                end
         
     | 
| 
      
 86 
     | 
    
         
            +
             
     | 
| 
      
 87 
     | 
    
         
            +
                private
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
      
 89 
     | 
    
         
            +
                def threaded_connection_options
         
     | 
| 
      
 90 
     | 
    
         
            +
                  resource.try(:threaded_connection_options) || {}
         
     | 
| 
      
 91 
     | 
    
         
            +
                end
         
     | 
| 
      
 92 
     | 
    
         
            +
             
     | 
| 
      
 93 
     | 
    
         
            +
                def determined_url_naming
         
     | 
| 
      
 94 
     | 
    
         
            +
                  RemoteResource::UrlNamingDetermination.new resource_klass, original_connection_options
         
     | 
| 
      
 95 
     | 
    
         
            +
                end
         
     | 
| 
      
 96 
     | 
    
         
            +
             
     | 
| 
      
 97 
     | 
    
         
            +
                def resource_klass
         
     | 
| 
      
 98 
     | 
    
         
            +
                  resource.is_a?(Class) ? resource : resource.class
         
     | 
| 
      
 99 
     | 
    
         
            +
                end
         
     | 
| 
      
 100 
     | 
    
         
            +
             
     | 
| 
      
 101 
     | 
    
         
            +
                def pack_up_attributes(attributes, root_element)
         
     | 
| 
      
 102 
     | 
    
         
            +
                  Hash[root_element.to_s, attributes]
         
     | 
| 
      
 103 
     | 
    
         
            +
                end
         
     | 
| 
      
 104 
     | 
    
         
            +
             
     | 
| 
      
 105 
     | 
    
         
            +
              end
         
     | 
| 
      
 106 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,69 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RemoteResource
         
     | 
| 
      
 2 
     | 
    
         
            +
              class Response
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                attr_reader :original_response, :original_request
         
     | 
| 
      
 5 
     | 
    
         
            +
                private :original_response, :original_request
         
     | 
| 
      
 6 
     | 
    
         
            +
             
     | 
| 
      
 7 
     | 
    
         
            +
                def initialize(response, connection_options = {})
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @original_response  = response
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @original_request   = response.request
         
     | 
| 
      
 10 
     | 
    
         
            +
                  @connection_options = connection_options
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
             
     | 
| 
      
 13 
     | 
    
         
            +
                def success?
         
     | 
| 
      
 14 
     | 
    
         
            +
                  original_response.success?
         
     | 
| 
      
 15 
     | 
    
         
            +
                end
         
     | 
| 
      
 16 
     | 
    
         
            +
             
     | 
| 
      
 17 
     | 
    
         
            +
                def unprocessable_entity?
         
     | 
| 
      
 18 
     | 
    
         
            +
                  response_code == 422
         
     | 
| 
      
 19 
     | 
    
         
            +
                end
         
     | 
| 
      
 20 
     | 
    
         
            +
             
     | 
| 
      
 21 
     | 
    
         
            +
                def response_body
         
     | 
| 
      
 22 
     | 
    
         
            +
                  original_response.body
         
     | 
| 
      
 23 
     | 
    
         
            +
                end
         
     | 
| 
      
 24 
     | 
    
         
            +
             
     | 
| 
      
 25 
     | 
    
         
            +
                def response_code
         
     | 
| 
      
 26 
     | 
    
         
            +
                  original_response.response_code
         
     | 
| 
      
 27 
     | 
    
         
            +
                end
         
     | 
| 
      
 28 
     | 
    
         
            +
             
     | 
| 
      
 29 
     | 
    
         
            +
                def sanitized_response_body
         
     | 
| 
      
 30 
     | 
    
         
            +
                  return empty_hash if response_body.blank?
         
     | 
| 
      
 31 
     | 
    
         
            +
                  return empty_hash if parsed_response_body.blank?
         
     | 
| 
      
 32 
     | 
    
         
            +
             
     | 
| 
      
 33 
     | 
    
         
            +
                  unpacked_parsed_response_body
         
     | 
| 
      
 34 
     | 
    
         
            +
                end
         
     | 
| 
      
 35 
     | 
    
         
            +
             
     | 
| 
      
 36 
     | 
    
         
            +
                def error_messages_response_body
         
     | 
| 
      
 37 
     | 
    
         
            +
                  return empty_hash if response_body.blank?
         
     | 
| 
      
 38 
     | 
    
         
            +
                  return empty_hash if parsed_response_body.blank?
         
     | 
| 
      
 39 
     | 
    
         
            +
             
     | 
| 
      
 40 
     | 
    
         
            +
                  return parsed_response_body["errors"]          if parsed_response_body.try :has_key?, "errors"
         
     | 
| 
      
 41 
     | 
    
         
            +
                  return unpacked_parsed_response_body["errors"] if unpacked_parsed_response_body.try :has_key?, "errors"
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                  empty_hash
         
     | 
| 
      
 44 
     | 
    
         
            +
                end
         
     | 
| 
      
 45 
     | 
    
         
            +
             
     | 
| 
      
 46 
     | 
    
         
            +
                def parsed_response_body
         
     | 
| 
      
 47 
     | 
    
         
            +
                  @parsed_response_body ||= JSON.parse response_body
         
     | 
| 
      
 48 
     | 
    
         
            +
                rescue JSON::ParserError
         
     | 
| 
      
 49 
     | 
    
         
            +
                  nil
         
     | 
| 
      
 50 
     | 
    
         
            +
                end
         
     | 
| 
      
 51 
     | 
    
         
            +
             
     | 
| 
      
 52 
     | 
    
         
            +
                private
         
     | 
| 
      
 53 
     | 
    
         
            +
             
     | 
| 
      
 54 
     | 
    
         
            +
                def empty_hash
         
     | 
| 
      
 55 
     | 
    
         
            +
                  {}
         
     | 
| 
      
 56 
     | 
    
         
            +
                end
         
     | 
| 
      
 57 
     | 
    
         
            +
             
     | 
| 
      
 58 
     | 
    
         
            +
                def unpacked_parsed_response_body
         
     | 
| 
      
 59 
     | 
    
         
            +
                  root_element = @connection_options[:root_element].presence
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
                  if root_element
         
     | 
| 
      
 62 
     | 
    
         
            +
                    parsed_response_body[root_element.to_s]
         
     | 
| 
      
 63 
     | 
    
         
            +
                  else
         
     | 
| 
      
 64 
     | 
    
         
            +
                    parsed_response_body
         
     | 
| 
      
 65 
     | 
    
         
            +
                  end
         
     | 
| 
      
 66 
     | 
    
         
            +
                end
         
     | 
| 
      
 67 
     | 
    
         
            +
             
     | 
| 
      
 68 
     | 
    
         
            +
              end
         
     | 
| 
      
 69 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -0,0 +1,48 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            module RemoteResource
         
     | 
| 
      
 2 
     | 
    
         
            +
              class ResponseHandeling
         
     | 
| 
      
 3 
     | 
    
         
            +
             
     | 
| 
      
 4 
     | 
    
         
            +
                attr_reader :resource, :response, :connection_options
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
                def initialize(resource, response, connection_options = {})
         
     | 
| 
      
 7 
     | 
    
         
            +
                  @resource           = resource
         
     | 
| 
      
 8 
     | 
    
         
            +
                  @response           = response
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @connection_options = connection_options
         
     | 
| 
      
 10 
     | 
    
         
            +
                end
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
                def perform
         
     | 
| 
      
 13 
     | 
    
         
            +
                  if response.success?
         
     | 
| 
      
 14 
     | 
    
         
            +
                    if resource.respond_to? :new
         
     | 
| 
      
 15 
     | 
    
         
            +
                      resource.build_resource_from_response response
         
     | 
| 
      
 16 
     | 
    
         
            +
                    else
         
     | 
| 
      
 17 
     | 
    
         
            +
                      resource
         
     | 
| 
      
 18 
     | 
    
         
            +
                    end
         
     | 
| 
      
 19 
     | 
    
         
            +
                  elsif errors?
         
     | 
| 
      
 20 
     | 
    
         
            +
                    if resource.respond_to? :new
         
     | 
| 
      
 21 
     | 
    
         
            +
                      #
         
     | 
| 
      
 22 
     | 
    
         
            +
                    else
         
     | 
| 
      
 23 
     | 
    
         
            +
                      # assign response
         
     | 
| 
      
 24 
     | 
    
         
            +
                      resource.assign_errors response.parsed_response_body, root_element
         
     | 
| 
      
 25 
     | 
    
         
            +
                    end
         
     | 
| 
      
 26 
     | 
    
         
            +
                  else
         
     | 
| 
      
 27 
     | 
    
         
            +
                    # nil
         
     | 
| 
      
 28 
     | 
    
         
            +
                  end
         
     | 
| 
      
 29 
     | 
    
         
            +
                end
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
                def errors?
         
     | 
| 
      
 32 
     | 
    
         
            +
                  parsed_response_body = response.parsed_response_body
         
     | 
| 
      
 33 
     | 
    
         
            +
             
     | 
| 
      
 34 
     | 
    
         
            +
                  if parsed_response_body
         
     | 
| 
      
 35 
     | 
    
         
            +
                    parsed_response_body.has_key?("errors") || parsed_response_body.fetch(root_element.to_s, nil).has_key?("errors")
         
     | 
| 
      
 36 
     | 
    
         
            +
                  else
         
     | 
| 
      
 37 
     | 
    
         
            +
                    false
         
     | 
| 
      
 38 
     | 
    
         
            +
                  end
         
     | 
| 
      
 39 
     | 
    
         
            +
                end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
                private
         
     | 
| 
      
 42 
     | 
    
         
            +
             
     | 
| 
      
 43 
     | 
    
         
            +
                def root_element
         
     | 
| 
      
 44 
     | 
    
         
            +
                  connection_options[:root_element].presence || resource.connection_options.root_element.presence
         
     | 
| 
      
 45 
     | 
    
         
            +
                end
         
     | 
| 
      
 46 
     | 
    
         
            +
             
     | 
| 
      
 47 
     | 
    
         
            +
              end
         
     | 
| 
      
 48 
     | 
    
         
            +
            end
         
     |