require 'core/spec_helper' describe ZendeskAPI::Association do let(:instance) { ZendeskAPI::TestResource.new(client, :id => 1) } let(:child) { ZendeskAPI::TestResource::TestChild.new(client, :id => 1, :test_resource_id => 2) } describe "setting/getting" do context "has" do before do ZendeskAPI::TestResource.associations.clear ZendeskAPI::TestResource.has :child, :class => ZendeskAPI::TestResource::TestChild end it "should not try and fetch nil child" do instance.child_id = nil expect(instance.child).to be_nil end it "should cache an set object" do instance.child = child expect(instance.child).to eq(child) end it "should set id on set if it was there" do instance.child_id = nil instance.child = child expect(instance.child_id).to eq(child.id) end it "should build a object set via hash" do instance.child = {:id => 2} expect(instance.child.id).to eq(2) end it "should build a object set via id" do instance.child = 2 expect(instance.child.id).to eq(2) end it "should not fetch an unknown object" do expect(instance.child).to be_nil end it "should fetch an object known by id" do stub_json_request(:get, %r{test_resources/1/child/5}, json(:test_child => {:id => 5})) instance.child_id = 5 expect(instance.child.id).to eq(5) end it "should handle client errors" do stub_request(:get, %r{test_resources/1/child/5}).to_return(:status => 500) instance.child_id = 5 expect { silence_logger { instance.child } }.to_not raise_error end it "should handle resource not found errors" do stub_request(:get, %r{test_resources/1/child/5}).to_return(:status => 404) instance.child_id = 5 silence_logger{ expect(instance.child).to be_nil } end it "is not used when not used" do expect(instance.child_used?).to eq(false) end it "is used when used" do instance.child = child expect(instance.child_used?).to eq(true) end end context "has_many" do it "should cache a set object" do instance.children = [child] expect(instance.children.map(&:id)).to eq([1]) expect(instance.children).to be_instance_of(ZendeskAPI::Collection) end it "should set ids" do instance.children_ids = [] instance.children = [child] expect(instance.children_ids).to eq([child.id]) expect(instance.children).to be_instance_of(ZendeskAPI::Collection) end it "should build and cache objects set via hash" do instance.children = [{:id => 2}] expect(instance.children.map(&:id)).to eq([2]) expect(instance.children).to be_instance_of(ZendeskAPI::Collection) end it "should build a object set via id" do instance.children = [2] expect(instance.children.map(&:id)).to eq([2]) expect(instance.children).to be_instance_of(ZendeskAPI::Collection) end it "should fetch unknown objects" do stub_json_request(:get, %r{test_resources/1/children}, json(:test_children => [{:id => 2}, {:id => 3}])) expect(instance.children.map(&:id)).to eq([2,3]) expect(instance.children).to be_instance_of(ZendeskAPI::Collection) end it "should not change objects" do child = 'foo' children = [child] instance.children = children expect(children[0]).to eq('foo') end it "is not used when not used" do expect(instance.children_used?).to eq(false) end it "is used when used" do instance.children = [child] expect(instance.children_used?).to eq(true) end end end context "class only" do subject { described_class.new(:class => ZendeskAPI::TestResource) } it "should generate resource path" do expect(subject.generate_path).to eq("test_resources") end context "with an instance" do it "should generate a specific resource path" do expect(subject.generate_path(instance)).to eq("test_resources/1") end context "with_id => false" do it "should generate general resource path" do expect(subject.generate_path(instance, :with_id => false)).to eq("test_resources") end end context "with an instance that is a new record" do it "should generate general resource path" do expect(subject.generate_path(ZendeskAPI::TestResource.new(client))).to eq("test_resources") end end end context "with a specified path" do before(:each) { subject.options[:path] = "blergh" } it "should generate general resource path" do expect(subject.generate_path).to eq("blergh") end end context "with a passed in id" do it "should generate specific resource path" do opts = { :id => 1 } expect(subject.generate_path(opts)).to eq("test_resources/1") expect(opts).to be_empty end end end context "class with a specified parent" do subject { described_class.new(:class => ZendeskAPI::TestResource::TestChild, :parent => instance, :name => :children) } it "should generate nested resource path" do expect(subject.generate_path).to eq("test_resources/1/children") end context "with an instance" do it "should generate a specific nested resource path" do expect(subject.generate_path(child)).to eq("test_resources/1/children/1") end context "with_id => false" do it "should generate nested resource path" do expect(subject.generate_path(child, :with_id => false)).to eq("test_resources/1/children") end end end context "with a specified path" do before(:each) { subject.options[:path] = "blergh" } it "should generate nested resource path" do expect(subject.generate_path).to eq("test_resources/1/blergh") end end context "with a path on the association" do before(:each) do association = ZendeskAPI::TestResource.associations.detect {|a| a[:name] == :children} association[:path] = "blergh" end it "should generate nested resource path" do expect(subject.generate_path).to eq("test_resources/1/blergh") end end context "with no association" do before(:each) do ZendeskAPI::TestResource.associations.clear end it "should generate nested resource path" do expect(subject.generate_path).to eq("test_resources/1/test_children") end end end context "class with a parent id" do subject { described_class.new(:class => ZendeskAPI::TestResource::TestChild, :name => :children) } it "should raise an error if not passed an instance or id" do expect { subject.generate_path }.to raise_error(ArgumentError) end it "should generate specific nested resource path" do expect(subject.generate_path(child)).to eq("test_resources/2/children/1") end context "with parent id passed in" do it "should generate nested resource path" do opts = { :test_resource_id => 3 } expect(subject.generate_path(opts)).to eq("test_resources/3/children") expect(opts).to be_empty end end end context "with a singular resource" do subject { described_class.new(:class => ZendeskAPI::SingularTestResource) } context "with an instance" do it "should not generate a specific resource path" do expect(subject.generate_path(ZendeskAPI::SingularTestResource.new(client, :id => 1))).to eq("singular_test_resources") end end end end