[PATCH conductor 3/5] Rspec tests for Provider Accounts API - index action

pblaho at redhat.com pblaho at redhat.com
Mon Jul 2 15:51:55 UTC 2012


From: Petr Blaho <pblaho at 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[@id=\"#{provider_account.id}\"]")
+          xml_provider_account.xpath('name').text.should be_eql(provider_account.name.to_s)
+          xml_provider_account.xpath('@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[@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(@provider_account.provider_id, :details_tab => 'accounts')
-    ProviderAccount.find(@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(@provider_account.provider_id, :details_tab => 'accounts')
-    ProviderAccount.find_by_id(@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(@provider_account.provider_id, :details_tab => 'accounts')
+      ProviderAccount.find(@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(@provider_account.provider_id, :details_tab => 'accounts')
+      ProviderAccount.find_by_id(@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




More information about the aeolus-devel mailing list