From 46f5722ef83d3d3603e23ac9525c49f4ed43621a Mon Sep 17 00:00:00 2001 From: Thom May Date: Wed, 25 Jan 2017 15:51:46 +0000 Subject: Make it easier to have a versioned factory classes providing an API should include VersionedAPI, whilst the factory class includes VersionedAPIFactory. Signed-off-by: Thom May --- spec/unit/http/api_versions_spec.rb | 69 ++++++++++++++++++++++ spec/unit/mixin/versioned_api_spec.rb | 107 ++++++++++++++++++++++++++++++++++ spec/unit/server_api_versions_spec.rb | 44 ++++++++++++++ 3 files changed, 220 insertions(+) create mode 100644 spec/unit/http/api_versions_spec.rb create mode 100644 spec/unit/mixin/versioned_api_spec.rb create mode 100644 spec/unit/server_api_versions_spec.rb (limited to 'spec') diff --git a/spec/unit/http/api_versions_spec.rb b/spec/unit/http/api_versions_spec.rb new file mode 100644 index 0000000000..79c97a1b69 --- /dev/null +++ b/spec/unit/http/api_versions_spec.rb @@ -0,0 +1,69 @@ +# +# Copyright:: Copyright 2017, 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 "spec_helper" + +describe Chef::HTTP::APIVersions do + class TestVersionClient < Chef::HTTP + use Chef::HTTP::APIVersions + end + + before do + Chef::ServerAPIVersions.instance.reset! + end + + let(:method) { "GET" } + let(:url) { "http://dummy.com" } + let(:headers) { {} } + let(:data) { false } + + let(:request) {} + let(:return_value) { "200" } + + # Test Variables + let(:response_body) { "Thanks for checking in." } + let(:response_headers) do + { + "x-ops-server-api-version" => { "min_version" => 0, "max_version" => 2 }, + } + end + + let(:response) do + m = double("HttpResponse", :body => response_body) + allow(m).to receive(:key?).with("x-ops-server-api-version").and_return(true) + allow(m).to receive(:[]) do |key| + response_headers[key] + end + + m + end + + let(:middleware) do + client = TestVersionClient.new(url) + client.middlewares[0] + end + + def run_api_version_handler + middleware.handle_request(method, url, headers, data) + middleware.handle_response(response, request, return_value) + end + + it "correctly stores server api versions" do + run_api_version_handler + expect(Chef::ServerAPIVersions.instance.min_server_version).to eq(0) + end +end diff --git a/spec/unit/mixin/versioned_api_spec.rb b/spec/unit/mixin/versioned_api_spec.rb new file mode 100644 index 0000000000..4f2418ca24 --- /dev/null +++ b/spec/unit/mixin/versioned_api_spec.rb @@ -0,0 +1,107 @@ +# +# Copyright:: Copyright 2015-2017, 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 "spec_helper" +require "chef/mixin/versioned_api" + +describe Chef::Mixin::VersionedAPI do + let(:dummy_class) { Class.new { extend Chef::Mixin::VersionedAPI } } + + it "allows a class to declare the minimum supported API version" do + dummy_class.minimum_api_version 3 + expect(dummy_class.minimum_api_version).to eq(3) + end +end + +describe Chef::Mixin::VersionedAPIFactory do + class V1Class; extend Chef::Mixin::VersionedAPI; minimum_api_version 1; end + class V2Class; extend Chef::Mixin::VersionedAPI; minimum_api_version 2; end + class V3Class; extend Chef::Mixin::VersionedAPI; minimum_api_version 3; end + + let(:factory_class) { Class.new { extend Chef::Mixin::VersionedAPIFactory } } + + before do + Chef::ServerAPIVersions.instance.reset! + end + + describe "#add_versioned_api_class" do + it "adds a target class" do + factory_class.add_versioned_api_class V1Class + expect(factory_class.versioned_interfaces).to eq([V1Class]) + end + + it "can be called many times" do + factory_class.add_versioned_api_class V1Class + factory_class.add_versioned_api_class V2Class + expect(factory_class.versioned_interfaces).to eq([V1Class, V2Class]) + end + end + + describe "#versioned_api_class" do + describe "with no known versions" do + it "with one class it returns that class" do + factory_class.add_versioned_api_class V2Class + expect(factory_class.versioned_api_class.minimum_api_version).to eq(2) + end + + it "with many classes it returns the highest minimum version" do + factory_class.add_versioned_api_class V1Class + factory_class.add_versioned_api_class V2Class + factory_class.add_versioned_api_class V3Class + expect(factory_class.versioned_api_class.minimum_api_version).to eq(3) + end + end + + describe "with a known version" do + it "with one class it returns that class" do + Chef::ServerAPIVersions.instance.set_versions({ "min_version" => 0, "max_version" => 2 }) + factory_class.add_versioned_api_class V2Class + expect(factory_class.versioned_api_class.minimum_api_version).to eq(2) + end + + it "with a maximum version it returns the highest possible versioned class" do + Chef::ServerAPIVersions.instance.set_versions({ "min_version" => 0, "max_version" => 2 }) + factory_class.add_versioned_api_class V1Class + factory_class.add_versioned_api_class V2Class + factory_class.add_versioned_api_class V3Class + expect(factory_class.versioned_api_class.minimum_api_version).to eq(2) + end + end + + it "with no classes it returns nil" do + expect(factory_class.versioned_api_class).to be_nil + end + end + + describe "#new" do + it "creates an instance of the versioned class" do + factory_class.add_versioned_api_class V2Class + expect { factory_class.new }.to_not raise_error + expect(factory_class.new.class).to eq(V2Class) + end + end + + describe "#def_versioned_delegator" do + it "delegates the method to the correct class" do + factory_class.add_versioned_api_class V2Class + factory_class.def_versioned_delegator("test_method") + expect(V2Class).to receive(:test_method).with("test message").and_return(true) + + factory_class.test_method("test message") + end + end +end diff --git a/spec/unit/server_api_versions_spec.rb b/spec/unit/server_api_versions_spec.rb new file mode 100644 index 0000000000..43445eb825 --- /dev/null +++ b/spec/unit/server_api_versions_spec.rb @@ -0,0 +1,44 @@ +# +# Copyright:: Copyright 2017, 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 "spec_helper" + +describe Chef::ServerAPIVersions do + before do + Chef::ServerAPIVersions.instance.reset! + end + + describe "#min_server_version" do + it "returns nil if no versions have been recorded" do + expect(Chef::ServerAPIVersions.instance.min_server_version).to be_nil + end + it "returns the correct value" do + Chef::ServerAPIVersions.instance.set_versions({ "min_version" => 0, "max_version" => 2 }) + expect(Chef::ServerAPIVersions.instance.min_server_version).to eq(0) + end + end + + describe "#max_server_version" do + it "returns nil if no versions have been recorded" do + expect(Chef::ServerAPIVersions.instance.max_server_version).to be_nil + end + it "returns the correct value" do + Chef::ServerAPIVersions.instance.set_versions({ "min_version" => 0, "max_version" => 2 }) + expect(Chef::ServerAPIVersions.instance.max_server_version).to eq(2) + end + end +end -- cgit v1.2.1