summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authordanielsdeleo <dan@getchef.com>2015-03-31 12:19:05 -0700
committerdanielsdeleo <dan@getchef.com>2015-04-01 13:35:01 -0700
commitaab0ccb5d41913e050707bd6b40e5b820649c566 (patch)
tree0eb3839f664afb6f5eade15e32f85313cf41defa /spec
parent8b42ac0374fb075fbcb21df73742e81e69d9bf6f (diff)
downloadchef-aab0ccb5d41913e050707bd6b40e5b820649c566.tar.gz
Extract socketless client and add specs
Diffstat (limited to 'spec')
-rw-r--r--spec/unit/http/socketless_chef_zero_client_spec.rb174
1 files changed, 174 insertions, 0 deletions
diff --git a/spec/unit/http/socketless_chef_zero_client_spec.rb b/spec/unit/http/socketless_chef_zero_client_spec.rb
new file mode 100644
index 0000000000..963cc9e8c4
--- /dev/null
+++ b/spec/unit/http/socketless_chef_zero_client_spec.rb
@@ -0,0 +1,174 @@
+#--
+# Author:: Daniel DeLeo (<dan@chef.io>)
+# Copyright:: Copyright (c) 2015 Chef Software, Inc.
+# License:: Apache License, Version 2.0
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+require 'chef/http/socketless_chef_zero_client'
+
+describe Chef::HTTP::SocketlessChefZeroClient do
+
+ let(:relative_url) { "" }
+ let(:uri_str) { "chefzero://localhost:1/#{relative_url}" }
+ let(:uri) { URI(uri_str) }
+
+ subject(:zero_client) { Chef::HTTP::SocketlessChefZeroClient.new(uri) }
+
+ it "has a host" do
+ expect(zero_client.host).to eq("localhost")
+ end
+
+ it "has a port" do
+ expect(zero_client.port).to eq(1)
+ end
+
+ describe "converting requests to rack format" do
+
+ let(:expected_rack_req) do
+ {
+ "SCRIPT_NAME" => "",
+ "SERVER_NAME" => "localhost",
+ "REQUEST_METHOD" => method.to_s.upcase,
+ "PATH_INFO" => uri.path,
+ "QUERY_STRING" => uri.query,
+ "SERVER_PORT" => uri.port,
+ "HTTP_HOST" => "localhost:#{uri.port}",
+ "rack.url_scheme" => "chefzero",
+ }
+ end
+
+ context "when the request has no body" do
+
+ let(:method) { :GET }
+ let(:relative_url) { "clients" }
+ let(:headers) { { "Accept" => "application/json" } }
+ let(:body) { false }
+ let(:expected_body_str) { "" }
+
+ let(:rack_req) { zero_client.req_to_rack(method, uri, body, headers) }
+
+ it "creates a rack request env" do
+ # StringIO doesn't implement == in a way that we can compare, so we
+ # check rack.input individually and then iterate over everything else
+ expect(rack_req["rack.input"].string).to eq(expected_body_str)
+ expected_rack_req.each do |key, value|
+ expect(rack_req[key]).to eq(value)
+ end
+ end
+
+ end
+
+ context "when the request has a body" do
+
+ let(:method) { :PUT }
+ let(:relative_url) { "clients/foo" }
+ let(:headers) { { "Accept" => "application/json" } }
+ let(:body) { "bunch o' JSON" }
+ let(:expected_body_str) { "bunch o' JSON" }
+
+ let(:rack_req) { zero_client.req_to_rack(method, uri, body, headers) }
+
+ it "creates a rack request env" do
+ # StringIO doesn't implement == in a way that we can compare, so we
+ # check rack.input individually and then iterate over everything else
+ expect(rack_req["rack.input"].string).to eq(expected_body_str)
+ expected_rack_req.each do |key, value|
+ expect(rack_req[key]).to eq(value)
+ end
+ end
+
+ end
+
+ end
+
+ describe "converting responses to Net::HTTP objects" do
+
+ let(:net_http_response) { zero_client.to_net_http(code, headers, body) }
+
+ context "when the request was successful (2XX)" do
+
+ let(:code) { 200 }
+ let(:headers) { { "Content-Type" => "Application/JSON" } }
+ let(:body) { [ "bunch o' JSON" ] }
+
+ it "creates a Net::HTTP success response object" do
+ expect(net_http_response).to be_a_kind_of(Net::HTTPOK)
+ expect(net_http_response.read_body).to eq("bunch o' JSON")
+ expect(net_http_response["content-type"]).to eq("Application/JSON")
+ end
+
+ it "does not fail when calling read_body with a block" do
+ expect(net_http_response.read_body {|chunk| chunk }).to eq("bunch o' JSON")
+ end
+
+ end
+
+ context "when the requested object doesn't exist (404)" do
+
+ let(:code) { 404 }
+ let(:headers) { { "Content-Type" => "Application/JSON" } }
+ let(:body) { [ "nope" ] }
+
+ it "creates a Net::HTTPNotFound response object" do
+ expect(net_http_response).to be_a_kind_of(Net::HTTPNotFound)
+ end
+ end
+
+ end
+
+ describe "request-response round trip" do
+
+ let(:method) { :GET }
+ let(:relative_url) { "clients" }
+ let(:headers) { { "Accept" => "application/json" } }
+ let(:body) { false }
+
+ let(:expected_rack_req) do
+ {
+ "SCRIPT_NAME" => "",
+ "SERVER_NAME" => "localhost",
+ "REQUEST_METHOD" => method.to_s.upcase,
+ "PATH_INFO" => uri.path,
+ "QUERY_STRING" => uri.query,
+ "SERVER_PORT" => uri.port,
+ "HTTP_HOST" => "localhost:#{uri.port}",
+ "rack.url_scheme" => "chefzero",
+ "rack.input" => an_instance_of(StringIO),
+ }
+ end
+
+
+ let(:response_code) { 200 }
+ let(:response_headers) { { "Content-Type" => "Application/JSON" } }
+ let(:response_body) { [ "bunch o' JSON" ] }
+
+ let(:rack_response) { [ response_code, response_headers, response_body ] }
+
+ let(:response) { zero_client.request(method, uri, body, headers) }
+
+ before do
+ expect(ChefZero::SocketlessServerMap).to receive(:request).with(1, expected_rack_req).and_return(rack_response)
+ end
+
+ it "makes a rack request to Chef Zero and returns the response as a Net::HTTP object" do
+ _client, net_http_response = response
+ expect(net_http_response).to be_a_kind_of(Net::HTTPOK)
+ expect(net_http_response.code).to eq("200")
+ expect(net_http_response.body).to eq("bunch o' JSON")
+ end
+
+ end
+
+end