https://www.aeolusproject.org/redmine/issues/3234
This commit adds rspec tests for index action of Providers API
This adds custom matchers for rspec and modifies spec_helper.rb file to
load them.
---
src/spec/controllers/provider_controller_spec.rb | 143 ++++++++++++++++++---
src/spec/matchers/be_xml.rb | 34 +++++
src/spec/matchers/have_content_type.rb | 60 +++++++++
src/spec/spec_helper.rb | 2 +
4 files changed, 218 insertions(+), 21 deletions(-)
create mode 100644 src/spec/matchers/be_xml.rb
create mode 100644 src/spec/matchers/have_content_type.rb
diff --git a/src/spec/controllers/provider_controller_spec.rb
b/src/spec/controllers/provider_controller_spec.rb
index 3098523..d0a7a23 100644
--- a/src/spec/controllers/provider_controller_spec.rb
+++ b/src/spec/controllers/provider_controller_spec.rb
@@ -18,35 +18,136 @@ require 'spec_helper'
describe ProvidersController do
- fixtures :all
- before(:each) do
- @admin_permission = FactoryGirl.create :provider_admin_permission
- @provider = @admin_permission.permission_object
- @admin = @admin_permission.user
- mock_warden(@admin)
+ render_views
+
+ shared_examples_for "responding with XML" do
+ context "response" do
+ subject { response }
+
+ it { should be_success }
+ it { should have_content_type("application/xml") }
+
+ context "body" do
+ subject { response.body }
+ it { should be_xml }
+ end
+ end
end
- describe "provide ui to view realms" do
- before do
- get :show, :id => @provider.id, :details_tab => 'realms', :format
=> :js
+ shared_examples_for "having XML with providers" do
+ # TODO: implement more attributes checks
+ subject { Hash.from_xml(response.body) }
+ context "list of providers" do
+ let(:xml_providers) {
[subject['providers']['provider']].flatten.compact }
+ context "number of providers" do
+ it { xml_providers.size.should be_eql(number_of_providers) }
+ end
+ it "should have correct providers" do
+ providers.each do |provider|
+ xml_provider = xml_providers.find{|xp| xp['name'] == provider.name}
+ xml_provider['id'].should be_eql(provider.id.to_s)
+ xml_provider['href'].should be_eql(api_provider_url(provider))
+ end
+ end
end
-
- it { response.should be_success }
- it { assigns[:realm_names].size.should == @provider.realms.size }
- it { response.should render_template(:partial => "providers/_realms") }
end
- describe "check availability" do
- context "when provider is not accessible" do
+ context "UI" do
+
+ fixtures :all
+ before(:each) do
+ @admin_permission = FactoryGirl.create :provider_admin_permission
+ @provider = @admin_permission.permission_object
+ @admin = @admin_permission.user
+ mock_warden(@admin)
+ end
+
+ describe "provide ui to view realms" do
before do
- @provider.update_attribute(:url, "invalid_url")
+ get :show, :id => @provider.id, :details_tab => 'realms', :format
=> :js
+ end
+
+ it { response.should be_success }
+ it { assigns[:realm_names].size.should == @provider.realms.size }
+ it { response.should render_template(:partial => "providers/_realms")
}
+ end
+
+ describe "check availability" do
+ context "when provider is not accessible" do
+ before do
+ @provider.update_attribute(:url, "invalid_url")
+ end
+
+ it "should update availability status on test connection" do
+ @provider.available.should_not be_false
+ get :edit, :id => @provider.id, :test_provider => true
+ @provider.reload
+ @provider.available.should be_false
+ end
+ end
+ end
+
+ end
+
+ context "API" do
+ context "when requesting XML" do
+
+ before(:each) do
+ accept_xml
end
- it "should update availability status on test connection" do
- @provider.available.should_not be_false
- get :edit, :id => @provider.id, :test_provider => true
- @provider.reload
- @provider.available.should be_false
+ context "when using admin credentials" do
+ before(:each) do
+ user = FactoryGirl.create(:admin_permission).user
+ mock_warden(user)
+ end
+
+ describe "#index" do
+
+ before(:each) do
+ ProvidersController.stub(:load_providers).and_return(providers)
+ get :index
+ end
+
+ context "when there are 3 providers" do
+
+ let(:providers) { 3.times{ FactoryGirl.create(:mock_provider) }; Provider.all
}
+
+ it_behaves_like "responding with XML"
+
+ context "XML body" do
+ let(:number_of_providers) { 3 }
+ it_behaves_like "having XML with providers"
+ end
+
+ end
+
+ context "when there is 1 provider" do
+
+ let(:providers) { FactoryGirl.create(:mock_provider); Provider.all }
+
+ it_behaves_like "responding with XML"
+
+ context "XML body" do
+ let(:number_of_providers) { 1 }
+ it_behaves_like "having XML with providers"
+ end
+
+ end
+
+ context "when there are no providers" do
+
+ let(:providers) { Provider.all }
+
+ it_behaves_like "responding with XML"
+
+ context "XML body" do
+ let(:number_of_providers) { 0 }
+ it_behaves_like "having XML with providers"
+ end
+
+ end
+ end
end
end
end
diff --git a/src/spec/matchers/be_xml.rb b/src/spec/matchers/be_xml.rb
new file mode 100644
index 0000000..f35e681
--- /dev/null
+++ b/src/spec/matchers/be_xml.rb
@@ -0,0 +1,34 @@
+#
+# Copyright 2011 Red Hat, Inc.
+#
+# 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.
+#
+
+RSpec::Matchers.define :be_xml do
+
+ match do |body|
+ begin
+ Hash.from_xml(body)
+ rescue REXML::ParseException
+ false
+ end
+ end
+
+ failure_message_for_should do |body|
+ "#{body.inspect} should be XML"
+ end
+
+ failure_message_for_should_not do |body|
+ "#{body.inspect} should not be XML"
+ end
+end
diff --git a/src/spec/matchers/have_content_type.rb
b/src/spec/matchers/have_content_type.rb
new file mode 100644
index 0000000..bc39ede
--- /dev/null
+++ b/src/spec/matchers/have_content_type.rb
@@ -0,0 +1,60 @@
+# Copyright (c) 2012 James Conroy-Finn
+#
+# Permission is hereby granted, free of charge, to any person obtaining
+# a copy of this software and associated documentation files (the
+# "Software"), to deal in the Software without restriction, including
+# without limitation the rights to use, copy, modify, merge, publish,
+# distribute, sublicense, and/or sell copies of the Software, and to permit
+# persons to whom the Software is furnished to do so, subject to the
+# following conditions:
+#
+# The above copyright notice and this permission notice shall be included
+# in all copies or substantial portions of the Software.
+#
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+# IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+# CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT
+# OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR
+# THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+#
+# Original source:
https://gist.github.com/917903
+
+RSpec::Matchers.define :have_content_type do |content_type|
+ CONTENT_HEADER_MATCHER = /^(.*?)(?:; charset=(.*))?$/
+
+ chain :with_charset do |charset|
+ @charset = charset
+ end
+
+ match do |response|
+ _, content, charset = *content_type_header.match(CONTENT_HEADER_MATCHER).to_a
+
+ if @charset
+ @charset == charset && content == content_type
+ else
+ content == content_type
+ end
+ end
+
+ failure_message_for_should do |response|
+ if @charset
+ "Content type #{content_type_header.inspect} should match
#{content_type.inspect} with charset #{@charset}"
+ else
+ "Content type #{content_type_header.inspect} should match
#{content_type.inspect}"
+ end
+ end
+
+ failure_message_for_should_not do |model|
+ if @charset
+ "Content type #{content_type_header.inspect} should not match
#{content_type.inspect} with charset #{@charset}"
+ else
+ "Content type #{content_type_header.inspect} should not match
#{content_type.inspect}"
+ end
+ end
+
+ def content_type_header
+ response.headers['Content-Type']
+ end
+end
diff --git a/src/spec/spec_helper.rb b/src/spec/spec_helper.rb
index 00cb1fd..2ea9093 100644
--- a/src/spec/spec_helper.rb
+++ b/src/spec/spec_helper.rb
@@ -26,6 +26,8 @@ else
require 'vcr_setup_norec'
end
+Dir[File.dirname(__FILE__) + '/matchers/*.rb'].each {|file| require file }
+
module RequestContentTypeHelper
def accept_all
@request.env["HTTP_ACCEPT"] = "*/*"
--
1.7.7.6