Remove allow_mass_assignment_of matcher (#1430)
This commit is contained in:
parent
e746f2e370
commit
33e1a1abbe
|
@ -26,7 +26,6 @@ require 'shoulda/matchers/active_model/numericality_matchers/comparison_matcher'
|
|||
require 'shoulda/matchers/active_model/numericality_matchers/odd_number_matcher'
|
||||
require 'shoulda/matchers/active_model/numericality_matchers/even_number_matcher'
|
||||
require 'shoulda/matchers/active_model/numericality_matchers/only_integer_matcher'
|
||||
require 'shoulda/matchers/active_model/allow_mass_assignment_of_matcher'
|
||||
require 'shoulda/matchers/active_model/errors'
|
||||
require 'shoulda/matchers/active_model/have_secure_password_matcher'
|
||||
|
||||
|
|
|
@ -1,161 +0,0 @@
|
|||
module Shoulda
|
||||
module Matchers
|
||||
module ActiveModel
|
||||
# The `allow_mass_assignment_of` matcher tests usage of Rails 3's
|
||||
# `attr_accessible` and `attr_protected` macros, asserting that an
|
||||
# attribute in your model is contained in either the whitelist or
|
||||
# blacklist and thus can or cannot be set via mass assignment.
|
||||
#
|
||||
# class Post
|
||||
# include ActiveModel::Model
|
||||
# include ActiveModel::MassAssignmentSecurity
|
||||
# attr_accessor :title
|
||||
#
|
||||
# attr_accessible :title
|
||||
# end
|
||||
#
|
||||
# class User
|
||||
# include ActiveModel::Model
|
||||
# include ActiveModel::MassAssignmentSecurity
|
||||
# attr_accessor :encrypted_password
|
||||
#
|
||||
# attr_protected :encrypted_password
|
||||
# end
|
||||
#
|
||||
# # RSpec
|
||||
# RSpec.describe Post, type: :model do
|
||||
# it { should allow_mass_assignment_of(:title) }
|
||||
# end
|
||||
#
|
||||
# RSpec.describe User, type: :model do
|
||||
# it { should_not allow_mass_assignment_of(:encrypted_password) }
|
||||
# end
|
||||
#
|
||||
# # Minitest (Shoulda)
|
||||
# class PostTest < ActiveSupport::TestCase
|
||||
# should allow_mass_assignment_of(:title)
|
||||
# end
|
||||
#
|
||||
# class UserTest < ActiveSupport::TestCase
|
||||
# should_not allow_mass_assignment_of(:encrypted_password)
|
||||
# end
|
||||
#
|
||||
# #### Optional qualifiers
|
||||
#
|
||||
# ##### as
|
||||
#
|
||||
# Use `as` if your mass-assignment rules apply only under a certain role
|
||||
# *(Rails >= 3.1 only)*.
|
||||
#
|
||||
# class Post
|
||||
# include ActiveModel::Model
|
||||
# include ActiveModel::MassAssignmentSecurity
|
||||
# attr_accessor :title
|
||||
#
|
||||
# attr_accessible :title, as: :admin
|
||||
# end
|
||||
#
|
||||
# # RSpec
|
||||
# RSpec.describe Post, type: :model do
|
||||
# it { should allow_mass_assignment_of(:title).as(:admin) }
|
||||
# end
|
||||
#
|
||||
# # Minitest (Shoulda)
|
||||
# class PostTest < ActiveSupport::TestCase
|
||||
# should allow_mass_assignment_of(:title).as(:admin)
|
||||
# end
|
||||
#
|
||||
# @return [AllowMassAssignmentOfMatcher]
|
||||
#
|
||||
def allow_mass_assignment_of(value)
|
||||
AllowMassAssignmentOfMatcher.new(value)
|
||||
end
|
||||
|
||||
# @private
|
||||
class AllowMassAssignmentOfMatcher
|
||||
attr_reader :failure_message, :failure_message_when_negated
|
||||
|
||||
def initialize(attribute)
|
||||
@attribute = attribute.to_s
|
||||
@options = {}
|
||||
end
|
||||
|
||||
def as(role)
|
||||
@options[:role] = role
|
||||
self
|
||||
end
|
||||
|
||||
def matches?(subject)
|
||||
@subject = subject
|
||||
if attr_mass_assignable?
|
||||
if whitelisting?
|
||||
@failure_message_when_negated = "#{@attribute} was made "\
|
||||
'accessible'
|
||||
elsif protected_attributes.empty?
|
||||
@failure_message_when_negated = 'no attributes were protected'
|
||||
else
|
||||
@failure_message_when_negated =
|
||||
"#{class_name} is protecting " <<
|
||||
"#{protected_attributes.to_a.to_sentence}, " <<
|
||||
"but not #{@attribute}."
|
||||
end
|
||||
true
|
||||
else
|
||||
@failure_message =
|
||||
if whitelisting?
|
||||
"Expected #{@attribute} to be accessible"
|
||||
else
|
||||
"Did not expect #{@attribute} to be protected"
|
||||
end
|
||||
false
|
||||
end
|
||||
end
|
||||
|
||||
def description
|
||||
[base_description, role_description].compact.join(' ')
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def base_description
|
||||
"allow mass assignment of #{@attribute}"
|
||||
end
|
||||
|
||||
def role_description
|
||||
if role != :default
|
||||
"as #{role}"
|
||||
end
|
||||
end
|
||||
|
||||
def role
|
||||
@options[:role] || :default
|
||||
end
|
||||
|
||||
def protected_attributes
|
||||
@_protected_attributes ||= (@subject.class.protected_attributes || [])
|
||||
end
|
||||
|
||||
def accessible_attributes
|
||||
@_accessible_attributes ||=
|
||||
(@subject.class.accessible_attributes || [])
|
||||
end
|
||||
|
||||
def whitelisting?
|
||||
authorizer.is_a?(::ActiveModel::MassAssignmentSecurity::WhiteList)
|
||||
end
|
||||
|
||||
def attr_mass_assignable?
|
||||
!authorizer.deny?(@attribute)
|
||||
end
|
||||
|
||||
def authorizer
|
||||
@subject.class.active_authorizer[role]
|
||||
end
|
||||
|
||||
def class_name
|
||||
@subject.class.name
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,123 +0,0 @@
|
|||
require 'unit_spec_helper'
|
||||
|
||||
describe Shoulda::Matchers::ActiveModel::AllowMassAssignmentOfMatcher, type: :model do
|
||||
if action_pack_lt_5?
|
||||
context '#description' do
|
||||
context 'without a role' do
|
||||
it 'includes the attribute name' do
|
||||
expect(described_class.new(:attr).description).
|
||||
to eq 'allow mass assignment of attr'
|
||||
end
|
||||
end
|
||||
|
||||
if active_model_3_1?
|
||||
context 'with a role' do
|
||||
it 'includes the attribute name and the role' do
|
||||
expect(described_class.new(:attr).as(:admin).description).
|
||||
to eq 'allow mass assignment of attr as admin'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'an attribute that is blacklisted from mass-assignment' do
|
||||
it 'rejects being mass-assignable' do
|
||||
model = define_model(:example, blacklisted: :string) do
|
||||
attr_protected :blacklisted
|
||||
end.new
|
||||
|
||||
expect(model).not_to allow_mass_assignment_of(:blacklisted)
|
||||
end
|
||||
end
|
||||
|
||||
context 'an attribute that is not whitelisted for mass-assignment' do
|
||||
it 'rejects being mass-assignable' do
|
||||
model = define_model(
|
||||
:example,
|
||||
not_whitelisted: :string,
|
||||
whitelisted: :string,
|
||||
) do
|
||||
attr_accessible :whitelisted
|
||||
end.new
|
||||
|
||||
expect(model).not_to allow_mass_assignment_of(:not_whitelisted)
|
||||
end
|
||||
end
|
||||
|
||||
context 'an attribute that is whitelisted for mass-assignment' do
|
||||
it 'accepts being mass-assignable' do
|
||||
expect(define_model(:example, whitelisted: :string) do
|
||||
attr_accessible :whitelisted
|
||||
end.new).to allow_mass_assignment_of(:whitelisted)
|
||||
end
|
||||
end
|
||||
|
||||
context 'an attribute not included in the mass-assignment blacklist' do
|
||||
it 'accepts being mass-assignable' do
|
||||
model = define_model(
|
||||
:example,
|
||||
not_blacklisted: :string,
|
||||
blacklisted: :string,
|
||||
) do
|
||||
attr_protected :blacklisted
|
||||
end.new
|
||||
|
||||
expect(model).to allow_mass_assignment_of(:not_blacklisted)
|
||||
end
|
||||
end
|
||||
|
||||
unless active_model_3_2? || active_model_4_0?
|
||||
context 'an attribute on a class with no protected attributes' do
|
||||
it 'accepts being mass-assignable' do
|
||||
expect(no_protected_attributes).to allow_mass_assignment_of(:attr)
|
||||
end
|
||||
|
||||
it 'assigns a negative failure message' do
|
||||
matcher = allow_mass_assignment_of(:attr)
|
||||
|
||||
expect(matcher.matches?(no_protected_attributes)).to eq true
|
||||
|
||||
expect(matcher.failure_message_when_negated).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
def no_protected_attributes
|
||||
define_model(:example, attr: :string).new
|
||||
end
|
||||
end
|
||||
|
||||
context 'an attribute on a class with all protected attributes' do
|
||||
it 'rejects being mass-assignable' do
|
||||
expect(all_protected_attributes).not_to allow_mass_assignment_of(:attr)
|
||||
end
|
||||
|
||||
def all_protected_attributes
|
||||
define_model(:example, attr: :string) do
|
||||
attr_accessible nil
|
||||
end.new
|
||||
end
|
||||
end
|
||||
|
||||
if active_model_3_1?
|
||||
context 'an attribute included in the mass-assignment whitelist for admin role only' do
|
||||
it 'rejects being mass-assignable' do
|
||||
expect(mass_assignable_as_admin).not_to allow_mass_assignment_of(:attr)
|
||||
end
|
||||
|
||||
it 'accepts being mass-assignable for admin' do
|
||||
expect(mass_assignable_as_admin).to allow_mass_assignment_of(:attr).as(:admin)
|
||||
end
|
||||
|
||||
def mass_assignable_as_admin
|
||||
define_model(:example, attr: :string) do
|
||||
attr_accessible :attr, as: :admin
|
||||
end.new
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def define_model(name, columns, &block)
|
||||
super(name, columns, whitelist_attributes: false, &block)
|
||||
end
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue