From: Petr Blaho <pblaho(a)redhat.com>
https://www.aeolusproject.org/redmine/issues/3422
Adds rspec tests for Provider Accounts API - index action
Moves some shared examples to spec/support/shared_example_for_api.rb
and require them in spec_helper.rb
---
.../provider_accounts_controller_spec.rb | 284 +++++++++++++++-----
src/spec/controllers/providers_controller_spec.rb | 34 ---
src/spec/factories/credential.rb | 8 +
src/spec/factories/provider_account.rb | 8 +
src/spec/spec_helper.rb | 1 +
src/spec/support/shared_examples_for_api.rb | 49 ++++
6 files changed, 277 insertions(+), 107 deletions(-)
create mode 100644 src/spec/support/shared_examples_for_api.rb
diff --git a/src/spec/controllers/provider_accounts_controller_spec.rb
b/src/spec/controllers/provider_accounts_controller_spec.rb
index fe0ad13..a88bd25 100644
--- a/src/spec/controllers/provider_accounts_controller_spec.rb
+++ b/src/spec/controllers/provider_accounts_controller_spec.rb
@@ -18,95 +18,233 @@ require 'spec_helper'
describe ProviderAccountsController do
- fixtures :all
- before(:each) do
- @tuser = FactoryGirl.create :tuser
- @provider_account = FactoryGirl.create :mock_provider_account
- @provider = @provider_account.provider
-
- @admin_permission = Permission.create :role => Role.find(:first, :conditions =>
['name = ?', 'base.provider.admin']),
- :permission_object => @provider,
- :entity =>
FactoryGirl.create(:provider_admin_user).entity
- @admin = @admin_permission.user
+ render_views
+
+ shared_examples_for "having XML with provider accounts" do
+ # TODO: implement more attributes checks
+ subject { Nokogiri::XML(response.body) }
+ context "list of provider accounts" do
+ #let(:xml_provider_accounts) {
[subject['provider_accounts']['provider_account']].flatten.compact }
+ let(:xml_provider_accounts) {
subject.xpath('//provider_accounts/provider_account') }
+ context "number of provider accounts" do
+ it { xml_provider_accounts.size.should be_eql(number_of_provider_accounts) }
+ end
+ it "should have correct provider accounts" do
+ provider_accounts.each do |provider_account|
+ xml_provider_account =
xml_provider_accounts.xpath("//provider_account[(a)id=\"#{provider_account.id}\"]")
+ xml_provider_account.xpath('name').text.should
be_eql(provider_account.name.to_s)
+ xml_provider_account.xpath('(a)href').text.should
be_eql(api_provider_account_url(provider_account))
+ end
+ end
+ it "should have not incorrect provider accounts" do
+ other_provider_accounts.each do |provider_account|
+ xml_provider_account =
xml_provider_accounts.xpath("//provider_account[(a)id=\"#{provider_account.id}\"]")
+ xml_provider_account.should be_empty
+ end
+ end
+ end
end
- it "shows provider accounts as XML list" do
- mock_warden(@admin)
- get :index, :format => :xml
- response.should be_success
+ context "UI" do
- # it should have not provider accounts credentials
- resp = Hash.from_xml(response.body)
-
resp['provider_accounts']['provider_account']['provider_credentials'].should
be_nil
- end
+ fixtures :all
+ before(:each) do
+ @tuser = FactoryGirl.create :tuser
+ @provider_account = FactoryGirl.create :mock_provider_account
+ @provider = @provider_account.provider
- it "doesn't allow to save provider's account if not valid
credentials" do
- mock_warden(@admin)
- post :create, :provider_account => {:provider_id => @provider.id,
:credentials_hash => {}}, :provider_id => @provider.id
- response.should be_success
- response.should render_template("new")
- request.flash[:error].should == "Cannot add the provider account."
- end
+ @admin_permission = Permission.create :role => Role.find(:first, :conditions
=> ['name = ?', 'base.provider.admin']),
+ :permission_object => @provider,
+ :entity => FactoryGirl.create(:provider_admin_user).entity
+ @admin = @admin_permission.user
+ end
- it "should permit users with account modify permission to access edit cloud
account interface" do
- mock_warden(@admin)
- get :edit, :provider_id => @provider, :id => @provider_account.id
- response.should be_success
- response.should render_template("edit")
- end
+ it "shows provider accounts as XML list" do
+ mock_warden(@admin)
+ get :index, :format => :xml
+ response.should be_success
- it "should allow users with account modify password to update a cloud
account" do
- mock_warden(@admin)
- @provider_account.credentials_hash = {:username => 'mockuser2', :password
=> "foobar"}
- @provider_account.stub!(:valid_credentials?).and_return(true)
- @provider_account.quota = Quota.new
- @provider_account.save.should be_true
- post :update, :id => @provider_account.id, :provider_account => {
:credentials_hash => {:username => 'mockuser', :password =>
'mockpassword'} }
- response.should redirect_to edit_provider_path((a)provider_account.provider_id,
:details_tab => 'accounts')
-
ProviderAccount.find((a)provider_account.id).credentials_hash['password'].should ==
"mockpassword"
- end
+ # it should have not provider accounts credentials
+ resp = Hash.from_xml(response.body)
+
resp['provider_accounts']['provider_account']['provider_credentials'].should
be_nil
+ end
- it "should allow users with account modify permission to delete a cloud
account" do
- mock_warden(@admin)
- lambda do
- post :multi_destroy, :provider_id => @provider_account.provider_id,
:accounts_selected => [@provider_account.id]
- end.should change(ProviderAccount, :count).by(-1)
- response.should redirect_to edit_provider_path((a)provider_account.provider_id,
:details_tab => 'accounts')
- ProviderAccount.find_by_id((a)provider_account.id).should be_nil
- end
+ it "doesn't allow to save provider's account if not valid
credentials" do
+ mock_warden(@admin)
+ post :create, :provider_account => {:provider_id => @provider.id,
:credentials_hash => {}}, :provider_id => @provider.id
+ response.should be_success
+ response.should render_template("new")
+ request.flash[:error].should == "Cannot add the provider account."
+ end
- describe "should deny access to users without account modify permission" do
- before do
- mock_warden(@tuser)
+ it "should permit users with account modify permission to access edit cloud
account interface" do
+ mock_warden(@admin)
+ get :edit, :provider_id => @provider, :id => @provider_account.id
+ response.should be_success
+ response.should render_template("edit")
end
- it "for edit" do
- get :edit, :provider_id => @provider_account.provider_id, :id =>
@provider_account.id
- response.should render_template('layouts/error')
+ it "should allow users with account modify password to update a cloud
account" do
+ mock_warden(@admin)
+ @provider_account.credentials_hash = {:username => 'mockuser2',
:password => "foobar"}
+ @provider_account.stub!(:valid_credentials?).and_return(true)
+ @provider_account.quota = Quota.new
+ @provider_account.save.should be_true
+ post :update, :id => @provider_account.id, :provider_account => {
:credentials_hash => {:username => 'mockuser', :password =>
'mockpassword'} }
+ response.should redirect_to edit_provider_path((a)provider_account.provider_id,
:details_tab => 'accounts')
+
ProviderAccount.find((a)provider_account.id).credentials_hash['password'].should ==
"mockpassword"
end
- it "for update" do
- post :update, :id => @provider_account.id, :provider_account => { :password
=> 'foobar' }
- response.should render_template('layouts/error')
+ it "should allow users with account modify permission to delete a cloud
account" do
+ mock_warden(@admin)
+ lambda do
+ post :multi_destroy, :provider_id => @provider_account.provider_id,
:accounts_selected => [@provider_account.id]
+ end.should change(ProviderAccount, :count).by(-1)
+ response.should redirect_to edit_provider_path((a)provider_account.provider_id,
:details_tab => 'accounts')
+ ProviderAccount.find_by_id((a)provider_account.id).should be_nil
end
- it "for destroy" do
- post :destroy, :id => @provider_account.id
- response.should render_template('layouts/error')
+ describe "should deny access to users without account modify permission"
do
+ before do
+ mock_warden(@tuser)
+ end
+
+ it "for edit" do
+ get :edit, :provider_id => @provider_account.provider_id, :id =>
@provider_account.id
+ response.should render_template('layouts/error')
+ end
+
+ it "for update" do
+ post :update, :id => @provider_account.id, :provider_account => { :password
=> 'foobar' }
+ response.should render_template('layouts/error')
+ end
+
+ it "for destroy" do
+ post :destroy, :id => @provider_account.id
+ response.should render_template('layouts/error')
+ end
end
- end
- it "should provide ui to create new account" do
- mock_warden(@admin)
- get :new, :provider_id => @provider.id
- response.should be_success
- response.should render_template("new")
- end
+ it "should provide ui to create new account" do
+ mock_warden(@admin)
+ get :new, :provider_id => @provider.id
+ response.should be_success
+ response.should render_template("new")
+ end
- it "should fail to grant access to account UIs for unauthenticated user" do
- mock_warden(nil)
- get :new
- response.should_not be_success
- end
+ it "should fail to grant access to account UIs for unauthenticated user"
do
+ mock_warden(nil)
+ get :new
+ response.should_not be_success
+ end
+
+ end # UI
+
+ context "API" do
+
+ context "when requesting XML" do
+
+ before(:each) do
+ accept_xml
+ end
+
+ context "when using admin credentials" do
+
+ before(:each) do
+ user = FactoryGirl.create(:admin_permission).user
+ mock_warden(user)
+ end
+
+ describe "#index" do
+
+ context "with parent provider specified" do
+ before(:each) do
+ # call these to create them in database
+ provider_accounts
+ other_provider_accounts
+
+ get :index, :provider_id => provider.id
+ end
+
+ let(:provider) { FactoryGirl.create(:mock_provider) }
+ let(:other_provider) { FactoryGirl.create(:mock_provider) }
+ let(:other_provider_accounts) do
+ 3.times do
+ pa = FactoryGirl.build(:mock_provider_account_seq, :provider =>
other_provider)
+ pa.stub!(:validate_credentials).and_return(true)
+ pa.save
+ end
+ other_provider.provider_accounts
+ end
+
+ context "when there are 3 provider accounts for specified provider"
do
+
+ let(:provider_accounts) do
+ 3.times do
+ pa = FactoryGirl.build(:mock_provider_account_seq, :provider =>
provider)
+ pa.stub!(:validate_credentials).and_return(true)
+ pa.save
+ end
+ provider.provider_accounts
+ end
+
+ it_behaves_like "http OK"
+ it_behaves_like "responding with XML"
+
+ context "XML body" do
+ let(:number_of_provider_accounts) { 3 }
+ it_behaves_like "having XML with provider accounts"
+ end
+ end
+
+ end
+
+ context "with parent provider not specified" do
+
+ before(:each) do
+ # call these to create them in database
+ provider_accounts
+ other_provider_accounts
+
+ get :index
+ end
+
+ let(:provider) { FactoryGirl.create(:mock_provider) }
+ let(:other_provider) { FactoryGirl.create(:mock_provider) }
+ let(:other_provider_accounts) { [] }
+
+ context "when there are 3 provider accounts for specified provider"
do
+
+ let(:provider_accounts) do
+ 3.times do
+ pa = FactoryGirl.build(:mock_provider_account_seq, :provider =>
provider)
+ pa.stub!(:validate_credentials).and_return(true)
+ pa.save
+ end
+
+ 3.times do
+ pa = FactoryGirl.build(:mock_provider_account_seq, :provider =>
other_provider)
+ pa.stub!(:validate_credentials).and_return(true)
+ pa.save
+ end
+ other_provider.provider_accounts + provider.provider_accounts
+ end
+
+ it_behaves_like "http OK"
+ it_behaves_like "responding with XML"
+
+ context "XML body" do
+ let(:number_of_provider_accounts) { 6 }
+ it_behaves_like "having XML with provider accounts"
+ end
+ end
+
+ end
+ end # #index
+ end
+
+ end
+
+ end
end
diff --git a/src/spec/controllers/providers_controller_spec.rb
b/src/spec/controllers/providers_controller_spec.rb
index 38228fb..1e93205 100644
--- a/src/spec/controllers/providers_controller_spec.rb
+++ b/src/spec/controllers/providers_controller_spec.rb
@@ -20,40 +20,6 @@ describe ProvidersController do
render_views
- shared_examples_for "http OK" do
- context "response status code" do
- subject { response.status }
- it { should be_eql(200) }
- end
- end
-
- shared_examples_for "http Bad Request" do
- context "response status code" do
- subject { response.status }
- it { should be_eql(400) }
- end
- end
-
- shared_examples_for "http Not Found" do
- context "response status code" do
- subject { response.status }
- it { should be_eql(404) }
- end
- end
-
- shared_examples_for "responding with XML" do
- context "response" do
- subject { response }
-
- it { should have_content_type("application/xml") }
-
- context "body" do
- subject { response.body }
- it { should be_xml }
- end
- end
- end
-
shared_examples_for "having XML with providers" do
# TODO: implement more attributes checks
subject { Nokogiri::XML(response.body) }
diff --git a/src/spec/factories/credential.rb b/src/spec/factories/credential.rb
index bdee71f..1c8d75f 100644
--- a/src/spec/factories/credential.rb
+++ b/src/spec/factories/credential.rb
@@ -58,4 +58,12 @@ FactoryGirl.define do
credential_definition {
CredentialDefinition.find_by_name('password',:conditions => {:provider_type_id
=> ProviderType.find_by_deltacloud_driver('mock')})}
end
+ factory :username_credential_seq, :parent => :username_credential do |ucs|
+ ucs.sequence(:value) { |n| "mockuser#{n}" }
+ end
+
+ factory :password_credential_seq, :parent => :password_credential do |pcs|
+ pcs.sequence(:value) { |n| "mockpassword#{n}" }
+ end
+
end
diff --git a/src/spec/factories/provider_account.rb
b/src/spec/factories/provider_account.rb
index 93afc12..b5b9b5a 100644
--- a/src/spec/factories/provider_account.rb
+++ b/src/spec/factories/provider_account.rb
@@ -37,6 +37,14 @@ FactoryGirl.define do
end
end
+ factory :mock_provider_account_seq, :parent => :provider_account do
+ association :provider, :factory => :mock_provider2
+ after_build do |acc|
+ acc.credentials << Factory.build(:username_credential_seq)
+ acc.credentials << Factory.build(:password_credential_seq)
+ end
+ end
+
factory :ec2_provider_account, :parent => :provider_account do
association :provider, :factory => :ec2_provider
after_build do |acc|
diff --git a/src/spec/spec_helper.rb b/src/spec/spec_helper.rb
index ffaf879..44b734b 100644
--- a/src/spec/spec_helper.rb
+++ b/src/spec/spec_helper.rb
@@ -26,6 +26,7 @@ else
require 'vcr_setup_norec'
end
+Dir[File.dirname(__FILE__) + '/support/*.rb'].each {|file| require file }
Dir[File.dirname(__FILE__) + '/matchers/*.rb'].each {|file| require file }
module RequestContentTypeHelper
diff --git a/src/spec/support/shared_examples_for_api.rb
b/src/spec/support/shared_examples_for_api.rb
new file mode 100644
index 0000000..03c5ec6
--- /dev/null
+++ b/src/spec/support/shared_examples_for_api.rb
@@ -0,0 +1,49 @@
+#
+# 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.
+#
+
+shared_examples_for "http OK" do
+ context "response status code" do
+ subject { response.status }
+ it { should be_eql(200) }
+ end
+end
+
+shared_examples_for "http Bad Request" do
+ context "response status code" do
+ subject { response.status }
+ it { should be_eql(400) }
+ end
+end
+
+shared_examples_for "http Not Found" do
+ context "response status code" do
+ subject { response.status }
+ it { should be_eql(404) }
+ end
+end
+
+shared_examples_for "responding with XML" do
+ context "response" do
+ subject { response }
+
+ it { should have_content_type("application/xml") }
+
+ context "body" do
+ subject { response.body }
+ it { should be_xml }
+ end
+ end
+end
--
1.7.7.6