1

我有一個Ruby on Rails應用程序,我正在處理這個應用程序,並且在功能測試中遇到了一些問題。特別是,在測試期間,我一直拒絕訪問通過具有類似憑據(相同角色等)的用戶登錄時可能在瀏覽器中訪問的頁面。例如,這裏是從控制器的測試代碼:在功能測試過程中驗證失敗

include Devise::TestHelpers 
include Authorization::TestHelper 
... 
setup do 
    @user = Factory(:user) 
    @user.roles << Factory(:refinery_role) 
    @user.roles << Factory(:agency_role) 
    @user.save 
    sign_in @user 

    @agency = AgencyOrganization.create :name => "Test Agency" 

    @adv1 = AdvertiserOrganization.create :name => "Test Advertiser", :parent => @agency 

    UserOrganization.create :user_id => @user.id, :organization_id => @agency.id 
end 

test "agency user can edit advertiser" do 
    assert @user.has_role? :agency #passes 
    should_be_allowed_to :update, :advertiser_organizations #passes 

    get :edit, {:id => @adv1.id}, {:agency_id => @agency.id} 

    assert_equal "/unauthorized", request.env['PATH_INFO'] #passes :'(
    assert_template :edit #fails 
    # and more tests we never get to 
end 

(顯然,這些都不是所有斷言我真要查,但他們表現出發生了什麼事情。)

對於它的價值,上面的測試失敗,提出瞭如下異常:

4) Failure: 
test_agency_user_can_edit_advertiser(AdvertiserOrganizationsControllerTest [/Users/gworley/.rvm/gems/[email protected]/gems/declarative_authorization-0.5.1/lib/declarative_authorization/maintenance.rb:170]: 
Exception raised: 
<#<Authorization::NotAuthorized: No matching rules found for update for #<Authorization::GuestUser:0x00000101cda2b0 @role_symbols=[:guest]> (roles [:guest], privileges [:update, :manage], context :advertiser_organizations).>>. 

同樣,正如我所說的,一切正常,當你實際運行的應用程序,它只是讓測試工作(雖然也許應用程序是唯一WO誰知道呢?)。

+0

簽署你怎麼了檢查用戶是否登錄?你爲什麼發送':agency_id'作爲會話變量? – Bohdan

+0

我想我不檢查,因爲他們應該已經在每次測試之前通過設置登錄,並且它可以在其他測試中工作,並且我有一個測試,只有當我在它之前執行'signout @ user'時纔會通過測試。至於':agency_id',用戶可能有多個代理機構,但他們應該只與一個機構進行交互,所以它似乎是一種傳遞信息的好方法。仍然在學習rails,所以這可能不是最好的方法。 –

+0

我們可以看到sign_in方法的定義嗎? – Jakobinsky

回答

1

這是一個在黑暗中拍攝,因爲我沒有在我的應用程序使用設計的,但我們使用的身份驗證系統具有這樣的特質,它只是在會話建立:user_id,它獲取重挫通過測試中的會話哈希。

我注意到你的測試方法是在會話中設置:agency_id

嘗試徹底刪除會話哈希,並查看您獲得的錯誤是否由一個關於缺席:agency_id而不是驗證錯誤取代,或者將Devise用於驗證的任何會話變量添加到哈希中。

+0

基於此,我查看了會話並在正常使用過程中看到了幾件事情,包括' 'warden.user.user.key'=> [「User」,「3」]'或類似的東西。把它放在會話中會使測試以一種新的有趣的方式失敗,這表明它實際上試圖訪問所需的控制器方法。還有一些驗證令牌沒有在測試中設置並存在於用戶會話中。 –

+0

經過一些更多的測試後,您確實幫我找到了答案:我需要在會話中手動設置「warden.user.user.key''的值,以便進行身份驗證。太感謝了! –

1

你缺少在設置request.env["devise.mapping"] = Devise.mappings[:user]

看一看的設計wiki以獲取更多信息。我個人會將這個登錄功能提取到一個單獨的模塊中,並根據請求包含它。即,login_user/login_agency_user

+0

我試過這個,但它似乎沒有任何區別(甚至在調整使用'@request ...'作爲維基建議後)。 –

+0

你仍然得到相同的錯誤? '/ Authorization :: GuestUser /' – Jakobinsky

+0

不,現在只是我仍然被重定向到'/未授權'。在我嘗試了你的建議之前,這實際上已經被別的東西修復了,但我忘記了更新顯示失敗的過去的部分。 –

0

是否認證(你是誰)或授權(什麼是你允許這樣做),這不成?如果授權失敗,那麼這可能是您使用的declarative_authorization gem的問題。如果這是一個認證問題,那麼這可能是Devise gem或Devise TestHelpers的問題。這similar question可能會有所幫助。如果實在不行的話,那也應該是可能的,踩滅認證這樣

before :each do 
    @current_user = Factory(:user) 
    controller.stub!(:current_user).and_return(@current_user) 
    controller.stub!(:user_signed_in?).and_return(:true) 
    controller.stub!(:authenticate_user!).and_return(:true) 
    end 
1

不要忘記設置Authorization.current_user或DA也不會知道是誰在

def current_user 
    @controller.current_user 
    end 
    def with_sign_in(u) 
    sign_in u 
    Authorization.current_user = current_user 
    yield 
    sign_out u 
    Authorization.current_user = nil 
    end