diff --git a/hactor.gemspec b/hactor.gemspec index 0a3c5e9..d8ace5f 100644 --- a/hactor.gemspec +++ b/hactor.gemspec @@ -18,4 +18,5 @@ Gem::Specification.new do |gem| gem.require_paths = ["lib"] gem.add_development_dependency 'rspec' gem.add_dependency 'faraday' + gem.add_dependency 'addressable' end diff --git a/lib/hactor/hal/link.rb b/lib/hactor/hal/link.rb index 3c1d8b7..361bbb6 100644 --- a/lib/hactor/hal/link.rb +++ b/lib/hactor/hal/link.rb @@ -1,15 +1,30 @@ require 'ostruct' +require 'addressable/template' module Hactor module HAL class Link < OpenStruct - attr_reader :rel, :parent_resource + attr_reader :rel, :parent_resource, :template_class def initialize(obj, options) + @href = obj[:href] @rel = options.fetch(:rel) @parent_resource = options.fetch(:context) + @template_class = options[:template_class] || Addressable::Template super(obj) end + + def href(variables={}) + if templated? + template_class.new(@href).expand(variables).to_s + else + @href + end + end + + def templated? + !!templated + end end end end diff --git a/lib/hactor/http/client.rb b/lib/hactor/http/client.rb index bb759a2..385a9e5 100644 --- a/lib/hactor/http/client.rb +++ b/lib/hactor/http/client.rb @@ -17,7 +17,7 @@ def follow(link, options = {}) actor = options[:actor] || Hactor::NullActor.new variables = options[:expand_with] - href = variables ? link.expand_with(variables) : link.href + href = variables ? link.href(variables) : link.href url = context_url.merge(href) get(url: url, actor: actor) diff --git a/spec/hactor/hal/link_spec.rb b/spec/hactor/hal/link_spec.rb new file mode 100644 index 0000000..57a947e --- /dev/null +++ b/spec/hactor/hal/link_spec.rb @@ -0,0 +1,33 @@ +require 'spec_helper' +require 'hactor/hal/link' + +describe Hactor::HAL::Link do + context "templated link" do + let(:template_class) { mock } + let(:template) { mock } + let(:href) { stub } + let(:link) do + Hactor::HAL::Link.new({ + href: href, + templated: true + },{ + rel: stub, + context: stub, + template_class: template_class + }) + end + + describe "#href" do + it "expands using the variables passed in" do + sentinel, variables = stub, stub + + template_class.should_receive(:new).with(href). + and_return(template) + template.should_receive(:expand).with(variables). + and_return(stub(to_s: sentinel)) + + link.href(variables).should == sentinel + end + end + end +end diff --git a/spec/hactor/http/client_spec.rb b/spec/hactor/http/client_spec.rb index c551be7..64f0a31 100644 --- a/spec/hactor/http/client_spec.rb +++ b/spec/hactor/http/client_spec.rb @@ -57,7 +57,7 @@ it "should apply the variables to the template and follow resulting URI" do variables = stub - link.should_receive(:expand_with).with(variables).and_return(uri) + link.should_receive(:href).with(variables).and_return(uri) context_url.should_receive(:merge).with(uri).and_return(resolved_uri) client.follow(link, context_url: context_url, actor: actor, expand_with: variables)