简体   繁体   中英

Authentication failing during functional tests

I have a Ruby on Rails app that I'm working on and I'm having some problems with my functional tests. In particular, I keep getting denied access during my tests to pages that are possible to access in the browser when logged in through a user with similar credentials (same roles, etc.). For example, here's code from a test for a controller:

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

(Obviously those aren't all assertions I really want to check, but they demonstrate what's going on.)

For what it's worth, the above test fails with the follow exception raised:

 4) Failure: test_agency_user_can_edit_advertiser(AdvertiserOrganizationsControllerTest [/Users/gworley/.rvm/gems/ruby-1.9.2-p180@portal/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).>>.

Again, as I said, everything works when you're actually running the app, it's just getting tests to work (although maybe the app is only working by accident, who knows?).

You are missing in the setup request.env["devise.mapping"] = Devise.mappings[:user]

Have a look at the Devise wiki for more information. Personally I would extract this login functionality into a separate module and include it on request. ie, login_user / login_agency_user

This is a shot in the dark because I'm not using Devise in my app, but the authentication system we use has this idiosyncrasy that it's just setting up the :user_id in the session, which gets clobbered by the session hash in the test.

I noticed your test method is setting :agency_id in the session.

Try removing the session hash entirely and seeing if the error you get is replaced by one about the absence of :agency_id rather than an authentication error, or else add whatever session variable that Devise uses for authentication to the hash.

Don't forget to set Authorization.current_user or DA won't know who's signed in

  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

Is it authentication (who are you) or authorization (what are you allowed to do) which fails? If authorization fails, then it is maybe a problem with the declarative_authorization gem you use. If it is an authentication problem, then it is probably a problem with the Devise gem or the Devise TestHelpers. This similar question may be helpful. If nothing works, then it should also be possible to stub out authentication like this

  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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM