require "spec_helper" describe Shelly::Client do before do ENV['SHELLY_URL'] = nil @client = Shelly::Client.new("bob@example.com", "secret") RestClient::Request.stub!(:execute) end describe "#api_url" do context "env SHELLY_URL is not set" do it "should return default API URL" do ENV['SHELLY_URL'].should be_nil @client.api_url.should == "https://admin.winniecloud.com/apiv2" end end context "env variable SHELLY_URL is set" do it "should return value of env variable SHELLY_URL" do ENV['SHELLY_URL'] = "https://example.com/api" @client.api_url.should == "https://example.com/api" end end end describe "#request" do it "should make a request to given URL" do RestClient::Request.should_receive(:execute).with( request_parameters("/account", :get) ) @client.request("/account", :get) end it "should include provided parameters in the request" do RestClient::Request.should_receive(:execute).with( request_parameters("/account", :post, {:name => "test"}) ) @client.request("/account", :post, :name => "test") end it "should include user credentials in the request parameters" do @client = Shelly::Client.new("megan-fox@example.com", "secret") RestClient::Request.should_receive(:execute).with( request_parameters("/account", :get, {:email => "megan-fox@example.com", :password => "secret"}) ) @client.request("/account", :get) end it "should not include user credentials when they are blank" do @client = Shelly::Client.new RestClient::Request.should_receive(:execute).with( :method => :get, :url => "https://admin.winniecloud.com/apiv2/account", :headers => {:accept => :json, :content_type => :json, "shelly-version" => Shelly::VERSION}, :payload => "{}" ) @client.request("/account", :get) end it "should pass response to process_response method" do response = mock(RestClient::Response) request = mock(RestClient::Request) @client.should_receive(:process_response).with(response) RestClient::Request.should_receive(:execute).with( request_parameters("/account", :get) ).and_yield(response, request) @client.request("/account", :get) end def request_parameters(path, method, payload = {}) {:method => method, :url => "https://admin.winniecloud.com/apiv2#{path}", :headers => {:accept => :json, :content_type => :json, "shelly-version" => Shelly::VERSION}, :payload => ({:email => "bob@example.com", :password => "secret"}.merge(payload)).to_json} end end describe "#process_response" do before do @response = mock(RestClient::Response, :code => 200, :body => "{}", :return! => nil) @request = mock(RestClient::Request) RestClient::Request.stub(:execute).and_yield(@response, @request) end it "should not follow redirections" do @response.should_receive(:return!) @client.get('/account') end context "on 302 response code" do it "should raise UnauthorizedException" do @response.stub(:code).and_return(302) lambda { @client.get("/account") }.should raise_error(Shelly::Client::UnauthorizedException) end end context "on 406 response code" do it "should raise UnauthorizedException" do exception = RestClient::RequestFailed.new exception.stub(:http_code).and_return(406) @response.should_receive(:return!).and_raise(exception) lambda { @client.get("/account") }.should raise_error(Shelly::Client::UnauthorizedException) end end %w(404 422 500).each do |code| context "on #{code} response code" do it "should raise APIError" do @response.stub(:code).and_return(code.to_i) @response.stub(:body).and_return({"message" => "random error happened"}.to_json) lambda { @client.post("/api/apps/flower/command", :body => "puts User.count") }.should raise_error(Shelly::Client::APIError, "random error happened") end end end context "on unsupported response code" do it "should raise UnsupportedResponseException exception" do exception = RestClient::RequestFailed.new exception.stub(:http_code).and_return(409) @response.should_receive(:return!).and_raise(exception) lambda { @client.get("/account") }.should raise_error(Shelly::Client::UnsupportedResponseException) end end end describe "#get" do it "should make GET request to given path" do @client.should_receive(:request).with("/account", :get) @client.get("/account") end end describe "#post" do it "should make POST request to given path with parameters" do @client.should_receive(:request).with("/account", :post, :name => "pink-one") @client.post("/account", :name => "pink-one") end end end