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 => @age开发者_运维问答ncy.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?).
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.
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. i.e, login_user
/ login_agency_user
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
精彩评论