require 'core/spec_helper' class SimpleClient < ZendeskAPI::Client def build_connection "FOO" end end describe ZendeskAPI::Client do subject { client } context "#initialize" do it "should require a block" do expect { ZendeskAPI::Client.new }.to raise_error(ArgumentError) end it "should raise an exception when url isn't ssl" do expect do ZendeskAPI::Client.new do |config| config.url = "http://www.google.com" end end.to raise_error(ArgumentError) end it "should not raise an exception when url isn't ssl and allow_http is set to true" do expect do ZendeskAPI::Client.new do |config| config.allow_http = true config.url = "http://www.google.com/" end end.to_not raise_error end it "should handle valid url" do expect do ZendeskAPI::Client.new do |config| config.url = "https://example.zendesk.com/api/v2" end.to_not raise_error end end context "basic_auth" do subject do ZendeskAPI::Client.new do |config| config.url = "https://example.zendesk.com/api/v2" config.username = "hello" config.password = "token" end end it "should build basic auth middleware" do expect(subject.connection.builder.handlers.index(Faraday::Request::BasicAuthentication)).to_not be_nil end it "should not build token middleware" do expect(subject.connection.headers["Authorization"]).to be_nil end end context "access token" do subject do ZendeskAPI::Client.new do |config| config.url = "https://example.zendesk.com/api/v2" config.access_token = "hello" end end it "should not build basic auth middleware" do expect(subject.connection.builder.handlers.index(Faraday::Request::BasicAuthentication)).to be_nil end it "should build token middleware" do expect(subject.connection.headers["Authorization"]).to match(/Bearer/) end end context "#token" do let(:client) do ZendeskAPI::Client.new do |config| config.url = "https://example.zendesk.com/api/v2" config.username = username config.token = "token" end end subject { client.config } let(:username) { "hello" } context "with a username with /token" do let(:username) { "hello/token" } it "should not add /token to the username" do expect(subject.username).to eq("hello/token") end end context "with no password" do it "should build basic auth middleware" do expect(client.connection.builder.handlers.index(Faraday::Request::BasicAuthentication)).to_not be_nil end it "should not build token middleware" do expect(client.connection.builder.handlers.index(Faraday::Request::TokenAuthentication)).to be_nil end it "should copy token to password" do expect(subject.token).to eq(subject.password) end it "should add /token to the username" do expect(subject.username).to eq("hello/token") end end end context "#logger" do before(:each) do @client = ZendeskAPI::Client.new do |config| config.url = "https://example.zendesk.com/api/v2" config.logger = subject end stub_request(:get, %r{/bs$}).to_return(:status => 200) end context "with true value" do subject { true } it "should log in faraday" do expect(@client.connection.builder.handlers).to include(ZendeskAPI::Middleware::Response::Logger) end context "with a request" do it "should log" do expect(client.config.logger).to receive(:info).at_least(:once) @client.connection.get('/bs') end end end context "with false value" do subject { false } it "should not log" do expect(@client.connection.builder.handlers).to_not include(ZendeskAPI::Middleware::Response::Logger) end end context "with a nil value" do subject { nil } it "should log" do expect(@client.connection.builder.handlers).to include(ZendeskAPI::Middleware::Response::Logger) end end context "with a logger" do let(:out){ StringIO.new } subject { Logger.new(out) } it "should log" do expect(@client.connection.builder.handlers).to include(ZendeskAPI::Middleware::Response::Logger) end context "with a request" do it "should log to the subject" do expect(out).to receive(:write).at_least(:once) @client.connection.get('/bs') end end end end end context "#current_user" do before(:each) do stub_json_request(:get, %r{users/me}, json("user" => {})) end it "should be a user instance" do expect(client.current_user).to be_instance_of(ZendeskAPI::User) end end context "#connection" do it "should initially be false" do expect(subject.instance_variable_get(:@connection)).to be_falsey end it "connection should be initialized on first call to #connection" do expect(subject.connection).to be_instance_of(Faraday::Connection) end end context "resources" do it "should return an instance of ZendeskAPI::Collection if there is no method" do expect(subject.instance_variable_get(:@resource_cache)["tickets"]).to be_nil expect(subject.tickets).to be_instance_of(ZendeskAPI::Collection) expect(subject.instance_variable_get(:@resource_cache)["tickets"]).to_not be_empty expect(subject.instance_variable_get(:@resource_cache)["tickets"][:class]).to eq(ZendeskAPI::Ticket) expect(subject.instance_variable_get(:@resource_cache)["tickets"][:cache]).to be_instance_of(ZendeskAPI::LRUCache) expect(ZendeskAPI).to_not receive(:const_get) expect(subject.tickets).to be_instance_of(ZendeskAPI::Collection) end it "should not cache calls with different options" do expect(subject.search(:query => 'abc')).to_not eq(subject.search(:query => '123')) end it "should not cache calls with :reload => true options" do expect(subject.search(:query => 'abc')).to_not eq(subject.search(:query => 'abc', :reload => true)) end it "should not pass reload to the underlying collection" do collection = subject.search(:query => 'abc', :reload => true) expect(collection.options.key?(:reload)).to be(false) end it "should cache calls with the same options" do expect(subject.search(:query => 'abc')).to eq(subject.search(:query => 'abc')) end it "should respond_to? for valid resources" do expect(subject.respond_to?(:tickets)).to eq(true) end it "should respond_to? for valid cached resources" do subject.tickets expect(subject.respond_to?(:tickets)).to eq(true) end it "should respond_to? for actual instance methods" do expect(subject.respond_to?(:set_default_logger, true)).to eq(true) expect(subject.respond_to?(:set_default_logger)).to eq(false) end it "should not respond_to? invalid resources" do expect(subject.respond_to?(:nope)).to eq(false) end it "delegates voice correctly" do expect(subject.voice.greetings).to be_instance_of(ZendeskAPI::Collection) end it "looks in the appropriate namespaces" do expect(subject.greetings.association.options['class']).to eq(ZendeskAPI::Voice::Greeting) end it 'raises if the resource does not exist' do expect { subject.random_resource }.to raise_error(RuntimeError) end end it "can be subclassed" do client = SimpleClient.new do |config| config.allow_http = true end expect(client.config.allow_http).to eq(true) expect(client.connection).to eq("FOO") expect(client.connection.object_id).to eq(client.connection.object_id) # it's cached end context ZendeskAPI::Voice do it "defers to voice delegator" do expect(subject).to receive(:phone_numbers).once subject.voice.phone_numbers end it "manages namespace correctly" do expect(client.certification_addresses.path).to match(/channels\/voice\/certification_addresses/) expect(client.phone_numbers.path).to match(/channels\/voice\/phone_numbers/) expect(client.greetings.path).to match(/channels\/voice\/greetings/) expect(client.greeting_categories.path).to match(/channels\/voice\/greeting_categories/) end end end