diff --git a/lib/springboard/client/uri.rb b/lib/springboard/client/uri.rb index fe34946..3a256f7 100644 --- a/lib/springboard/client/uri.rb +++ b/lib/springboard/client/uri.rb @@ -10,7 +10,7 @@ class URI # # @return [URI] def self.parse(value) - return value if value.is_a?(self) + return value.dup if value.is_a?(self) new(::Addressable::URI.parse(value)) end @@ -30,6 +30,14 @@ def initialize(uri) @uri = uri end + ## + # Clones the URI object + # + # @return [URI] + def dup + self.class.new(@uri.dup) + end + ## # Returns a new URI with the given subpath appended to it. Ensures a single # forward slash between the URI's path and the given subpath. diff --git a/spec/springboard/client/resource_spec.rb b/spec/springboard/client/resource_spec.rb index d4622d3..9572022 100644 --- a/spec/springboard/client/resource_spec.rb +++ b/spec/springboard/client/resource_spec.rb @@ -48,6 +48,12 @@ it "should add bracket notation for array parameters" do expect(resource.__send__(method, :somearray => [1, 2, 3]).uri.to_s).to eq("/some/path?somearray[]=1&somearray[]=2&somearray[]=3") end + + it "should return a new resource without modifying the existing URI" do + new_resource = resource.query(per_page: 1) + expect(new_resource.uri.to_s).to eq("/some/path?per_page=1") + expect(resource.uri.to_s).to eq("/some/path") + end end describe "when called without arguments" do @@ -107,7 +113,7 @@ end end - %w{count each each_page}.each do |method| + %w{each each_page}.each do |method| describe method do it "should call the client's #{method} method with the resource's URI" do expect(client).to receive(method).with(resource.uri) @@ -134,6 +140,37 @@ end end + describe "count" do + let(:response_data) { + { + :status => 200, + :body => {total: 123}.to_json + } + } + + it "should call the client's count method with the resource's URI" do + expect(client).to receive('count').with(resource.uri) + resource.__send__('count') + end + + it "should set the per_page query string param to 1" do + request_stub = stub_request(:get, "#{base_url}/some/path?page=1&per_page=1").to_return(response_data) + resource.count + expect(request_stub).to have_been_requested + end + + it "should return the resource count" do + request_stub = stub_request(:get, "#{base_url}/some/path?page=1&per_page=1").to_return(response_data) + expect(resource.count).to eq(123) + end + + it "should not modify the original resource URI" do + request_stub = stub_request(:get, "#{base_url}/some/path?page=1&per_page=1").to_return(response_data) + resource.count + expect(resource.uri.to_s).to eq("/some/path") + end + end + describe "first" do let(:response_data) { { @@ -152,6 +189,12 @@ request_stub = stub_request(:get, "#{base_url}/some/path?page=1&per_page=1").to_return(response_data) expect(resource.first).to eq({"id" => "Me first!"}) end + + it "should not modify the original resource URI" do + request_stub = stub_request(:get, "#{base_url}/some/path?page=1&per_page=1").to_return(response_data) + resource.first + expect(resource.uri.to_s).to eq("/some/path") + end end describe "embed" do diff --git a/spec/springboard/client/uri_spec.rb b/spec/springboard/client/uri_spec.rb index 872ad74..1e760b0 100644 --- a/spec/springboard/client/uri_spec.rb +++ b/spec/springboard/client/uri_spec.rb @@ -12,10 +12,38 @@ end describe "parse" do - it "should return a URI based on the given string" do - uri = described_class.parse('/some_path') - expect(uri).to be_a(described_class) - expect(uri.to_s).to eq('/some_path') + describe "when called with a URI object" do + it "should return a cloned URI object" do + parsed_uri = described_class.parse(uri) + expect(uri.class).to eq(parsed_uri.class) + expect(uri.object_id).not_to eq(parsed_uri.object_id) + end + end + + describe "when called with a URI string" do + it "should return a URI based on the given string" do + uri = described_class.parse('/some_path') + expect(uri).to be_a(described_class) + expect(uri.to_s).to eq('/some_path') + end + end + end + + describe "dup" do + it "should return a duplicate URI object" do + dup_uri = uri.dup + expect(uri.class).to eq(dup_uri.class) + expect(uri.to_s).to eq(dup_uri.to_s) + expect(uri.object_id).not_to eq(dup_uri.object_id) + end + + describe "when mutating the copy" do + it "should not affect the original" do + dup_uri = uri.dup + dup_uri.query_values = {per_page: 1} + expect(uri.to_s).to eq('/relative/path') + expect(dup_uri.to_s).to eq('/relative/path?per_page=1') + end end end