Skip to content

Commit

Permalink
Merge f64846b into 61a8a68
Browse files Browse the repository at this point in the history
  • Loading branch information
dstotz committed Aug 29, 2018
2 parents 61a8a68 + f64846b commit 57fa82b
Show file tree
Hide file tree
Showing 7 changed files with 202 additions and 81 deletions.
7 changes: 3 additions & 4 deletions lib/springboard/client.rb
Expand Up @@ -30,7 +30,7 @@ class Client
DEFAULT_CONNECT_TIMEOUT = 10

##
# @return [Addressable::URI] The client's base URI
# @return [URI] The client's base URI
attr_reader :base_uri

##
Expand Down Expand Up @@ -80,7 +80,7 @@ def auth(opts={})
unless opts[:username] && opts[:password]
raise "Must specify :username and :password"
end
body = ::Addressable::URI.form_encode \
body = ::URI.encode_www_form \
:auth_key => opts[:username],
:password => opts[:password]
response = post '/auth/identity/callback', body,
Expand Down Expand Up @@ -236,8 +236,7 @@ def raise_on_fail(response)

def prepare_uri(uri)
uri = URI.parse(uri)
uri.path = uri.path.gsub(/^#{base_uri.path}/, '')
uri
uri.to_s.gsub(/^#{base_uri.to_s}|^#{base_uri.path}/, '')
end

def new_response(patron_response)
Expand Down
17 changes: 13 additions & 4 deletions lib/springboard/client/resource.rb
Expand Up @@ -21,7 +21,7 @@ class Resource
#
# @return [Addressable::URI]
attr_reader :uri

##
# The underlying Springboard Client.
#
Expand All @@ -31,9 +31,9 @@ class Resource
##
# @param [Springboard::Client] client
# @param [Addressable::URI, #to_s] uri
def initialize(client, uri)
def initialize(client, uri_or_path)
@client = client
@uri = URI.join('/', uri.to_s)
@uri = normalize_uri(uri_or_path)
end

##
Expand Down Expand Up @@ -171,7 +171,7 @@ def clone(uri=nil)
#
# @return [Resource]
def embed(*embeds)
embeds = (query['_include'] || []) + embeds
embeds = (query['_include[]'] || []) + embeds
query('_include' => embeds)
end

Expand All @@ -195,6 +195,15 @@ def exists?

private

##
# Normalizes the URI or path given to a URI
def normalize_uri(uri_or_path)
uri = URI.parse(uri_or_path)
return uri if uri.to_s.start_with?(client.base_uri.to_s)
path = uri_or_path.to_s.start_with?('/') ? uri_or_path : "/#{uri_or_path}"
URI.parse("#{client.base_uri}#{path}")
end

##
# Calls a client method, passing the URI as the first argument.
def call_client(method, *args, &block)
Expand Down
76 changes: 44 additions & 32 deletions lib/springboard/client/uri.rb
@@ -1,25 +1,17 @@
require 'addressable/uri'
require 'uri'

module Springboard
class Client
##
# A wrapper around Addressable::URI
# A wrapper around URI
class URI
##
# Returns a URI object based on the parsed string.
#
# @return [URI]
def self.parse(value)
return value.dup if value.is_a?(self)
new(::Addressable::URI.parse(value))
end

##
# Joins several URIs together.
#
# @return [URI]
def self.join(*args)
new(::Addressable::URI.join(*args))
new(::URI.parse(value.to_s))
end

##
Expand All @@ -46,59 +38,79 @@ def dup
def subpath(subpath)
uri = dup
uri.path = "#{path}/" unless path.end_with?('/')
uri.join subpath.to_s.gsub(/^\//, '')
uri.path = uri.path + ::URI.encode(subpath.to_s.gsub(/^\//, ''))
uri
end

##
# Merges the given hash of query string parameters and values with the URI's
# existing query string parameters (if any).
def merge_query_values!(values)
self.springboard_query_values = (self.query_values || {}).merge(normalize_query_hash(values))
old_query_values = self.query_values || {}
self.query_values = old_query_values.merge(normalize_query_hash(values))
end

##
# Checks if supplied URI matches current URI
#
# @return [boolean]
def ==(other_uri)
return false unless other_uri.is_a?(self.class)
uri == other_uri.__send__(:uri)
end

##
# Overwrites the query using the supplied query values
def query_values=(values)
self.query = ::URI.encode_www_form(normalize_query_hash(values).sort)
end

##
# Returns a hash of query string parameters and values
#
# @return [hash]
def query_values
return nil if query.nil?
::URI.decode_www_form(query).each_with_object({}) do |(k, v), hash|
if k.end_with?('[]')
hash[k] = Array(hash[k]) + [v]
else
hash[k] = v
end
end
end

private

attr_reader :uri

def springboard_query_values=(values)
retval = self.query_values = normalize_query_hash(values)
# Hack to strip digits from Addressable::URI's subscript notation
self.query = self.query.gsub(/\[\d+\]=/, '[]=')
retval
end

def self.delegate_and_wrap(*methods)
methods.each do |method|
define_method(method) do |*args, &block|
result = @uri.__send__(method, *args, &block)
if result.is_a?(Addressable::URI)
self.class.new(result)
else
result
end
@uri.__send__(method, *args, &block)
end
end
end

delegate_and_wrap(
:join, :path, :path=, :form_encode, :to_s,
:query_values, :query_values=, :query, :query=
:path, :path=, :to_s, :query, :query=
)

def normalize_query_hash(hash)
hash.inject({}) do |copy, (k, v)|
copy[k.to_s] = case v
when Hash then normalize_query_hash(v)
when true, false then v.to_s
else v end
k = "#{k}[]" if v.is_a?(Array) && !k.to_s.end_with?('[]')
copy[k.to_s] = normalized_query_hash_values(v)
copy
end
end

def normalized_query_hash_values(value)
case value
when Hash then normalize_query_hash(value)
when true, false then value.to_s
when Array then value.uniq
else value end
end
end
end
end

0 comments on commit 57fa82b

Please sign in to comment.