Reputation: 68
Given a simple User model, in Rails 4 with name, email, and an admin boolean, what's the best approach to testing mass assignment using RSpec?
Here's the UsersController:
def create
@user = User.new user_params
...snip
end
private
def user_params
params.require(:user).permit(:name, :email)
end
and two different tries at testing this:
in user_spec.rb
describe "accessible attributes" do
describe "should not allow access to admin" do
before do
@user.admin = "1"
@user.save
end
it { should_not be_admin }
end
end
or in users_controller_spec.rb
it 'should only allow name and email to be set' do
@controller.user_params.keys.should eq(['name', 'email')
end
Neither work - the former just creates a user with admin set to true (failing the test) - presumably this bypasses strong_parameters. The latter works, but only if the user_params method is not private. (The official docs recommend setting it to private. Note - watching for a MassAssignment error in the user_spec doesn't work either (no error is raised).
Note - actually setting the user to admin in a view correctly works - the admin attribute is filtered out and all is happy, but would really like to see this working properly in a test.
An alternative suggest is to use the shoulda-matchers gem with the user_spec.rb:
describe User do
...
it { should_not allow_mass_assignment_of(:admin) }
...
end
(this doesn't work either), giving:
Failure/Error: it { should_not allow_mass_assignment_of(:admin) }
NoMethodError:
undefined method `active_authorizer' for #<Class:0x007f93c9840648>
(I assume this error is due to the fact shoulda-matchers isn't Rails 4 compatible yet).
Thanks in advance!
Upvotes: 1
Views: 1743
Reputation: 4459
it "should not allow mass assignment" do
raw_parameters = { :admin => 1 }
parameters = ActionController::Parameters.new(raw_parameters)
expect {@user.update_attributes(parameters)}.should raise_error
end
In order to test mass assignment you should simulate passing parameters from controller.
https://github.com/rails/strong_parameters#use-outside-of-controllers
Upvotes: 2