Skip to content

Commit

Permalink
Add basic support for GlobalId
Browse files Browse the repository at this point in the history
  • Loading branch information
yuki24 committed Aug 25, 2019
1 parent 55e8a81 commit 9e09bbb
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 2 deletions.
2 changes: 2 additions & 0 deletions hyperclient.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,6 @@ Gem::Specification.new do |gem|
gem.add_dependency 'faraday_hal_middleware'
gem.add_dependency 'faraday_middleware'
gem.add_dependency 'net-http-digest_auth'

gem.add_development_dependency 'globalid'
end
9 changes: 8 additions & 1 deletion lib/hyperclient.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,23 @@
require 'hyperclient/resource'
require 'hyperclient/resource_collection'
require 'hyperclient/version'
require 'hyperclient/railtie' if defined?(Rails)

# Public: Hyperclient namespace.
#
module Hyperclient
URL_TO_ENDPOINT_MAPPING = { }

# Public: Convenience method to create new EntryPoints.
#
# url - A String with the url of the API.
#
# Returns a Hyperclient::EntryPoint
def self.new(url, &block)
Hyperclient::EntryPoint.new(url, &block)
URL_TO_ENDPOINT_MAPPING[url] = Hyperclient::EntryPoint.new(url, &block)
end

def self.lookup_entry_point(uri)
URL_TO_ENDPOINT_MAPPING[uri] || raise(ArgumentError, "Entry point not registered for #{uri}")
end
end
56 changes: 56 additions & 0 deletions lib/hyperclient/global_id.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# frozen_string_literal: true

require 'delegate'
require 'globalid'

module Hyperclient
module GlobalId
class Locator
def locate(gid)
Hyperclient
.lookup_entry_point(gid.params['endpoint'])
.public_send(gid.params['key'], gid.params.except('endpoint', 'key'))
end
end

class Serializable < SimpleDelegator
def id
_url
end
end

private_constant :Serializable

def self.app_name
"#{GlobalID.app}-hyperclient"
end

def self.setup!
::Hyperclient::Link.include ::GlobalID::Identification
::Hyperclient::Link.prepend ::Hyperclient::GlobalId

::GlobalID::Locator.use app_name, ::Hyperclient::GlobalId::Locator.new
end

def to_global_id(options = {})
GlobalID.create(Serializable.new(self), default_global_id_options.merge(options))
end
alias to_gid to_global_id

def to_signed_global_id(options = {})
SignedGlobalID.create(Serializable.new(self), default_global_id_options.merge(options))
end
alias to_sgid to_signed_global_id

private

def default_global_id_options
{
app: ::Hyperclient::GlobalId.app_name,
endpoint: @entry_point._url,
key: @key,
**@uri_variables || {},
}
end
end
end
11 changes: 11 additions & 0 deletions lib/hyperclient/railtie.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module Hyperclient
class Railtie < ::Rails::Railtie #:nodoc:
initializer 'hyperclient.client.attach_log_subscriber' do
ActiveSupport.on_load(:active_job) do
require 'hyperclient/global_id'

::Hyperclient::GlobalId.setup!
end
end
end
end
31 changes: 30 additions & 1 deletion test/hyperclient/link_test.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
require_relative '../test_helper'
require 'hyperclient'
require 'hyperclient/global_id'

module Hyperclient
describe Link do
Expand Down Expand Up @@ -350,5 +351,33 @@ module Hyperclient
end
end
end

describe 'GlobalId Support' do
describe '#to_global_id' do
before do
Hyperclient::GlobalId.setup!
Hyperclient::URL_TO_ENDPOINT_MAPPING[entry_point._url] = entry_point
end

it "serializes the object with entry point, key and uri_variables if present" do
link = Link.new('key', { 'href' => "http://api.example.org/key" }, entry_point)

stub_request(entry_point.connection) do |stub|
stub.get('http://api.example.org/') { [200, {}, { '_links' => { 'key' => { 'href' => 'http://api.example.org/key' } } }] }
end

actual = GlobalID.find(link.to_global_id)

actual._url.must_equal(link._url)
end

it "raises an exception when the hypermedia URL is missing" do
link_without_href = Link.new('key', { }, entry_point)
message = "Unable to create a Global ID for Hyperclient::GlobalId::Serializable without a model id."

-> { link_without_href.to_global_id }.must_raise(URI::GID::MissingModelIdError, message)
end
end
end
end
end
end

0 comments on commit 9e09bbb

Please sign in to comment.