stronger_parameters 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 7f1ac00b775682d4c9c6afb626ba93e34c5592d5
4
+ data.tar.gz: a91d5b4d4d1ca33e232b71761cfce8698f70e989
5
+ SHA512:
6
+ metadata.gz: ddb1bc2266c76e9796903d0f5610878ab6435ae0a99191bebb94e462ecd710deb5b3c4ab3e5b6d5ee4c1101d124015102c9900eb21eceddd71e49a8f18c8b76a
7
+ data.tar.gz: f64f92a712ab52389c838315cc71dc6d9b3f292adfd9a8638213a6d84187762f5c2dd372e838c98a08dd38c7bd3564d45a19b9a98d5961138485bd341b481b48
data/README.md ADDED
@@ -0,0 +1,157 @@
1
+ # stronger_parameters
2
+
3
+ This is an extension of `strong_parameters` with added type checking.
4
+
5
+ ## Simple types
6
+ You can specify simple types like this:
7
+
8
+ ```ruby
9
+ params.permit(
10
+ :id => Parameters.id,
11
+ :name => Parameters.string
12
+ )
13
+ ```
14
+
15
+ ## Arrays
16
+ You can specify arrays like this:
17
+
18
+ ```ruby
19
+ params.permit(
20
+ :id => Parameters.array(Parameters.id)
21
+ )
22
+ ```
23
+
24
+ This will allow an array of id parameters that all are IDs.
25
+
26
+ ## Nested Parameters
27
+
28
+ ```ruby
29
+ params.permit(
30
+ :name => Parameters.string,
31
+ :emails => Parameters.array(Parameters.string),
32
+ :friends => Parameters.array(
33
+ Parameters.map(
34
+ :name => Parameters.string,
35
+ :family => Parameters.map(
36
+ :name => Parameters.string
37
+ )
38
+ :hobbies => Parameters.array(Parameters.string)
39
+ )
40
+ )
41
+ )
42
+ ```
43
+
44
+ This will allow parameters like this:
45
+
46
+ ```json
47
+ {
48
+ "name": "Mick",
49
+ "emails": ["mick@zendesk.com", "mick@staugaard.com"],
50
+ "friends": [
51
+ {"name": "Morten", "family": {"name": "Primdahl"}, "hobbies": ["work", "art"]},
52
+ {"name": "Eric", "family": {"name": "Chapweske"}, "hobbies": ["boating", "whiskey"]}
53
+ ]
54
+ }
55
+ ```
56
+
57
+ ### ActiveModel Nested Attributes
58
+
59
+ ```ruby
60
+ params.require(:author).permit(
61
+ :name => Parameters.string,
62
+ :books_attributes => Parameters.array(
63
+ Parameters.map(
64
+ :title => Parameters.string,
65
+ :id => Parameters.id,
66
+ :_destroy => Parameters.boolean
67
+ )
68
+ )
69
+ )
70
+ ```
71
+
72
+ This will allow parameters like this:
73
+
74
+ ```json
75
+ {
76
+ "author": {
77
+ "name": "Eric Chapweske",
78
+ "books_attributes": [
79
+ {"title": "Boatin' and Drinkin'", "id": 234, "_destroy": true},
80
+ {"title": "Advanced Boatin' and Drinkin'", "id": 567}
81
+ ]
82
+ }
83
+ }
84
+ ```
85
+
86
+ ## Combining Requirements
87
+
88
+ If you want to permit a parameter to be one of multiple types, you can use the `|` operator:
89
+
90
+ ```ruby
91
+ params.require(:ticket).permit(
92
+ :status => Parameters.id | Parameters.enum('open', 'closed')
93
+ )
94
+ ```
95
+
96
+ This will allow these parameter sets:
97
+
98
+ ```json
99
+ {
100
+ "ticket": {
101
+ "status": 123
102
+ }
103
+ }
104
+ ```
105
+ ```json
106
+ {
107
+ "ticket": {
108
+ "status": "open"
109
+ }
110
+ }
111
+ ```
112
+
113
+ You can use the `&` operator to apply further restrictions on the type:
114
+
115
+ ```ruby
116
+ params.require(:user).permit(
117
+ :age => Parameters.integer & Parameters.gte(0)
118
+ )
119
+ ```
120
+
121
+ This requires the parameter to be an integer greater than or equal to 0.
122
+
123
+ ### Combining Requirements in Arrays
124
+
125
+ You can also use the `|` and `&` operators in arrays:
126
+
127
+ ```ruby
128
+ params.require(:group).permit(
129
+ :users => Parameters.array(Parameters.id | Parameters.string)
130
+ )
131
+ ```
132
+
133
+ This will permit these parameters:
134
+ ```json
135
+ {
136
+ "group": {
137
+ "users": [123, "mick@zendesk.com", 345, 676, "morten@zendesk.com"]
138
+ }
139
+ }
140
+ ```
141
+
142
+ ## Types
143
+
144
+ | Syntax | (Simplified) Definition |
145
+ |--------------------------------|-------------------------------------------------------------------------|
146
+ | Parameters.string | value.is_a?(String) |
147
+ | Parameters.integer | value.is_a?(Fixnum) |
148
+ | Parameters.enum('asc', 'desc') | ['asc', 'desc'].include?(value) |
149
+ | Parameters.lt(10) | value < 10 |
150
+ | Parameters.lte(10) | value <= 10 |
151
+ | Parameters.gt(0) | value > 0 |
152
+ | Parameters.gte(0) | value >= 0 |
153
+ | Parameters.integer32 | Parameters.integer & Parameters.lte(2 ** 31) & Parameters.gte(-2 ** 31) |
154
+ | Parameters.integer64 | Parameters.integer & Parameters.lte(2 ** 63) & Parameters.gte(-2 ** 63) |
155
+ | Parameters.id | Parameters.integer & Parameters.lte(2 ** 31) & Parameters.gte(0) |
156
+ | Parameters.bigid | Parameters.integer & Parameters.lte(2 ** 63) & Parameters.gte(0) |
157
+ | Parameters.boolean | Parameters.enum(true, false, 'true', 'false', 1, 0) |
@@ -0,0 +1,6 @@
1
+ require 'stronger_parameters/version'
2
+ require 'action_pack'
3
+ require 'strong_parameters' if ActionPack::VERSION::MAJOR == 3
4
+ require 'stronger_parameters/railtie'
5
+ require 'stronger_parameters/parameters'
6
+ require 'stronger_parameters/constraints'
@@ -0,0 +1,84 @@
1
+ require 'stronger_parameters/errors'
2
+
3
+ module StrongerParameters
4
+ class Constraint
5
+ def value(v)
6
+ v
7
+ end
8
+
9
+ def |(other)
10
+ OrConstraint.new(self, other)
11
+ end
12
+
13
+ def &(other)
14
+ AndConstraint.new(self, other)
15
+ end
16
+
17
+ def ==(other)
18
+ self.class == other.class
19
+ end
20
+ end
21
+
22
+ class OrConstraint < Constraint
23
+ attr_reader :constraints
24
+
25
+ def initialize(*constraints)
26
+ @constraints = constraints
27
+ end
28
+
29
+ def value(v)
30
+ exception = nil
31
+
32
+ constraints.each do |c|
33
+ begin
34
+ return c.value(v)
35
+ rescue InvalidParameter => e
36
+ exception ||= e
37
+ end
38
+ end
39
+
40
+ raise exception
41
+ end
42
+
43
+ def |(other)
44
+ constraints << other
45
+ self
46
+ end
47
+
48
+ def ==(other)
49
+ super && constraints == other.constraints
50
+ end
51
+ end
52
+
53
+ class AndConstraint < Constraint
54
+ attr_reader :constraints
55
+
56
+ def initialize(*constraints)
57
+ @constraints = constraints
58
+ end
59
+
60
+ def value(v)
61
+ constraints.each do |c|
62
+ v = c.value(v)
63
+ end
64
+ v
65
+ end
66
+
67
+ def &(other)
68
+ constraints << other
69
+ self
70
+ end
71
+
72
+ def ==(other)
73
+ super && constraints == other.constraints
74
+ end
75
+ end
76
+ end
77
+
78
+ require 'stronger_parameters/constraints/string_constraint'
79
+ require 'stronger_parameters/constraints/fixnum_constraint'
80
+ require 'stronger_parameters/constraints/boolean_constraint'
81
+ require 'stronger_parameters/constraints/array_constraint'
82
+ require 'stronger_parameters/constraints/hash_constraint'
83
+ require 'stronger_parameters/constraints/enumeration_constraint'
84
+ require 'stronger_parameters/constraints/comparison_constraints'
@@ -0,0 +1,25 @@
1
+ require 'stronger_parameters/constraints'
2
+
3
+ module StrongerParameters
4
+ class ArrayConstraint < Constraint
5
+ attr_reader :item_constraint
6
+
7
+ def initialize(item_constraint)
8
+ @item_constraint = item_constraint
9
+ end
10
+
11
+ def value(v)
12
+ if v.is_a?(Array)
13
+ return v.map do |item|
14
+ item_constraint.value(item)
15
+ end
16
+ end
17
+
18
+ raise InvalidParameter.new(v, "must be an array")
19
+ end
20
+
21
+ def ==(other)
22
+ super && item_constraint == other.item_constraint
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,20 @@
1
+ require 'stronger_parameters/constraints'
2
+
3
+ module StrongerParameters
4
+ class BooleanConstraint < Constraint
5
+ TRUE_VALUES = [true, 'true', '1', 1].freeze
6
+ FALSE_VALUES = [false, 'false', '0', 0].freeze
7
+
8
+ def value(v)
9
+ if TRUE_VALUES.include?(v)
10
+ return true
11
+ end
12
+
13
+ if FALSE_VALUES.include?(v)
14
+ return false
15
+ end
16
+
17
+ raise InvalidParameter.new(v, "must be either true or false")
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,47 @@
1
+ require 'stronger_parameters/constraints'
2
+
3
+ module StrongerParameters
4
+ class ComparisonConstraints < Constraint
5
+ attr_reader :limit
6
+
7
+ def initialize(limit)
8
+ @limit = limit
9
+ end
10
+
11
+ def ==(other)
12
+ super && limit == other.limit
13
+ end
14
+ end
15
+
16
+ class LessThanConstraint < ComparisonConstraints
17
+ def value(v)
18
+ return v if v < limit
19
+
20
+ raise InvalidParameter.new(v, "must be less than #{limit}")
21
+ end
22
+ end
23
+
24
+ class LessThanOrEqualConstraint < ComparisonConstraints
25
+ def value(v)
26
+ return v if v <= limit
27
+
28
+ raise InvalidParameter.new(v, "must be less than or equal to #{limit}")
29
+ end
30
+ end
31
+
32
+ class GreaterThanConstraint < ComparisonConstraints
33
+ def value(v)
34
+ return v if v > limit
35
+
36
+ raise InvalidParameter.new(v, "must be greater than #{limit}")
37
+ end
38
+ end
39
+
40
+ class GreaterThanOrEqualConstraint < ComparisonConstraints
41
+ def value(v)
42
+ return v if v >= limit
43
+
44
+ raise InvalidParameter.new(v, "must be greater than or equal to #{limit}")
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,21 @@
1
+ require 'stronger_parameters/constraints'
2
+
3
+ module StrongerParameters
4
+ class EnumerationConstraint < Constraint
5
+ attr_reader :allowed
6
+
7
+ def initialize(*allowed)
8
+ @allowed = allowed
9
+ end
10
+
11
+ def value(v)
12
+ return v if allowed.include?(v)
13
+
14
+ raise InvalidParameter.new(v, "must be one of these: #{allowed.to_sentence}")
15
+ end
16
+
17
+ def ==(other)
18
+ super && allowed == other.allowed
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ require 'stronger_parameters/constraints'
2
+
3
+ module StrongerParameters
4
+ class FixnumConstraint < Constraint
5
+ def value(v)
6
+ if v.is_a?(Fixnum)
7
+ return v
8
+ elsif v.is_a?(String) && v =~ /^\d+$/
9
+ return v.to_i
10
+ end
11
+
12
+ raise InvalidParameter.new(v, 'must be an integer')
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,28 @@
1
+ require 'stronger_parameters/constraints'
2
+
3
+ module StrongerParameters
4
+ class HashConstraint < Constraint
5
+ attr_reader :constraints
6
+
7
+ def initialize(constraints)
8
+ @constraints = constraints.with_indifferent_access
9
+ end
10
+
11
+ def value(v)
12
+ if v.is_a?(Hash)
13
+ return ActionController::Parameters.new(v).permit(constraints)
14
+ end
15
+
16
+ raise InvalidParameter.new(v, "must be a hash")
17
+ end
18
+
19
+ def merge(other)
20
+ other_constraints = other.is_a?(HashConstraint) ? other.constraints : other
21
+ self.class.new(constraints.merge(other_constraints))
22
+ end
23
+
24
+ def ==(other)
25
+ super && constraints == other.constraints
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,27 @@
1
+ require 'stronger_parameters/constraints'
2
+
3
+ module StrongerParameters
4
+ class StringConstraint < Constraint
5
+ attr_reader :maximum_length
6
+
7
+ def initialize(options = {})
8
+ @maximum_length = options[:maximum_length] || options[:max_length]
9
+ end
10
+
11
+ def value(v)
12
+ if v.is_a?(String)
13
+ if maximum_length && v.bytesize > maximum_length
14
+ raise InvalidParameter.new(v, "can not be longer than #{maximum_length} bytes")
15
+ end
16
+
17
+ return v
18
+ end
19
+
20
+ raise InvalidParameter.new(v, 'must be a string')
21
+ end
22
+
23
+ def ==(other)
24
+ super && maximum_length == other.maximum_length
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,19 @@
1
+ module StrongerParameters
2
+ class InvalidParameter < StandardError
3
+ attr_accessor :key, :value, :message
4
+
5
+ def initialize(value, message)
6
+ @value = value
7
+ @message = message
8
+ super(message)
9
+ end
10
+
11
+ def to_s
12
+ if key.present?
13
+ "found invalid value for #{key}. Value #{super}"
14
+ else
15
+ "found invalid value. Value #{super}"
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,136 @@
1
+ require 'action_pack'
2
+
3
+ if ActionPack::VERSION::MAJOR == 3
4
+ require 'action_controller/parameters'
5
+ else
6
+ require 'action_controller/metal/strong_parameters'
7
+ end
8
+
9
+ require 'stronger_parameters/constraints'
10
+ require 'stronger_parameters/errors'
11
+
12
+ module StrongerParameters
13
+ module Parameters
14
+ extend ActiveSupport::Concern
15
+
16
+ included do
17
+ alias_method_chain :hash_filter, :stronger_parameters
18
+ cattr_accessor :action_on_invalid_parameters, :instance_accessor => false
19
+ end
20
+
21
+ module ClassMethods
22
+ def anything
23
+ Constraint.new
24
+ end
25
+
26
+ def string(options = {})
27
+ StringConstraint.new(options)
28
+ end
29
+
30
+ def integer
31
+ @integer ||= FixnumConstraint.new
32
+ end
33
+
34
+ def lt(limit)
35
+ LessThanConstraint.new(limit)
36
+ end
37
+
38
+ def lte(limit)
39
+ LessThanOrEqualConstraint.new(limit)
40
+ end
41
+
42
+ def gt(limit)
43
+ GreaterThanConstraint.new(limit)
44
+ end
45
+
46
+ def gte(limit)
47
+ GreaterThanOrEqualConstraint.new(limit)
48
+ end
49
+
50
+ def integer32
51
+ integer & lte(2 ** 31) & gte(-2 ** 31)
52
+ end
53
+
54
+ def integer64
55
+ integer & lte(2 ** 63) & gte(-2 ** 63)
56
+ end
57
+
58
+ def id
59
+ integer & lte(2 ** 31) & gte(0)
60
+ end
61
+
62
+ def bigid
63
+ integer & lte(2 ** 63) & gte(0)
64
+ end
65
+
66
+ def enumeration(*allowed)
67
+ EnumerationConstraint.new(*allowed)
68
+ end
69
+ alias_method :enum, :enumeration
70
+
71
+ def boolean
72
+ BooleanConstraint.new
73
+ end
74
+
75
+ def array(item_constraint)
76
+ ArrayConstraint.new(item_constraint)
77
+ end
78
+
79
+ def map(constraints)
80
+ HashConstraint.new(constraints)
81
+ end
82
+ end
83
+
84
+ def hash_filter_with_stronger_parameters(params, filter)
85
+ stronger_filter = ActiveSupport::HashWithIndifferentAccess.new
86
+ other_filter = ActiveSupport::HashWithIndifferentAccess.new
87
+
88
+ filter.each do |k,v|
89
+ if v.is_a?(Constraint)
90
+ stronger_filter[k] = v
91
+ else
92
+ other_filter[k] = v
93
+ end
94
+ end
95
+
96
+ hash_filter_without_stronger_parameters(params, other_filter)
97
+
98
+ slice(*stronger_filter.keys).each do |key, value|
99
+ if value.nil?
100
+ params[key] = nil
101
+ next
102
+ end
103
+
104
+ constraint = stronger_filter[key]
105
+ begin
106
+ params[key] = constraint.value(value)
107
+ rescue InvalidParameter => e
108
+ e.key = key
109
+
110
+ name = "invalid_parameter.action_controller"
111
+ ActiveSupport::Notifications.publish(name, :key => key, :value => value, :message => e.message)
112
+
113
+ params[key] = value
114
+
115
+ raise unless self.class.action_on_invalid_parameters == :log
116
+ end
117
+ end
118
+ end
119
+
120
+ end
121
+
122
+ module ControllerSupport
123
+ extend ActiveSupport::Concern
124
+
125
+ Parameters = ActionController::Parameters
126
+
127
+ included do
128
+ rescue_from(StrongerParameters::InvalidParameter) do |e|
129
+ render :text => "Invalid parameter: #{e.key} #{e.message}", :status => :bad_request
130
+ end
131
+ end
132
+ end
133
+ end
134
+
135
+ ActionController::Parameters.send :include, StrongerParameters::Parameters
136
+ ActionController::Base.send :include, StrongerParameters::ControllerSupport
@@ -0,0 +1,11 @@
1
+ require 'rails/railtie'
2
+
3
+ module StrongParameters
4
+ class Railtie < ::Rails::Railtie
5
+ initializer "stronger_parameters.config", :before => "action_controller.set_configs" do |app|
6
+ ActionController::Parameters.action_on_invalid_parameters = app.config.action_controller.delete(:action_on_invalid_parameters) do
7
+ (Rails.env.test? || Rails.env.development?) ? :log : false
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module StrongerParameters
2
+ VERSION = '1.0.0'
3
+ end
@@ -0,0 +1,12 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe 'array parameter constraints' do
4
+ subject { ActionController::Parameters.array(ActionController::Parameters.string) }
5
+
6
+ permits ['a', 'b']
7
+
8
+ rejects 'abc'
9
+ rejects 123
10
+ rejects [123, 456]
11
+ rejects ['abc', 123]
12
+ end
@@ -0,0 +1,17 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe 'boolean parameter constraints' do
4
+ subject { ActionController::Parameters.boolean }
5
+
6
+ permits true, :as => true
7
+ permits 'true', :as => true
8
+ permits 1, :as => true
9
+ permits '1', :as => true
10
+
11
+ permits false, :as => false
12
+ permits 'false', :as => false
13
+ permits 0, :as => false
14
+ permits '0', :as => false
15
+
16
+ rejects 'foo'
17
+ end
@@ -0,0 +1,35 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe 'comparison parameter constraints' do
4
+ describe 'less-than types' do
5
+ subject { ActionController::Parameters.lt(2) }
6
+
7
+ permits 1
8
+ rejects 2
9
+ rejects 3
10
+ end
11
+
12
+ describe 'less-than-or-equal types' do
13
+ subject { ActionController::Parameters.lte(2) }
14
+
15
+ permits 1
16
+ permits 2
17
+ rejects 3
18
+ end
19
+
20
+ describe 'greater-than types' do
21
+ subject { ActionController::Parameters.gt(2) }
22
+
23
+ rejects 1
24
+ rejects 2
25
+ permits 3
26
+ end
27
+
28
+ describe 'greater-than-or-equal types' do
29
+ subject { ActionController::Parameters.gte(2) }
30
+
31
+ rejects 1
32
+ permits 2
33
+ permits 3
34
+ end
35
+ end
@@ -0,0 +1,26 @@
1
+ require_relative 'test_helper'
2
+
3
+ class BooksController < ActionController::Base
4
+ def create
5
+ params.require(:book).permit(:id => Parameters.integer)
6
+
7
+ head :ok
8
+ end
9
+ end
10
+
11
+ describe BooksController do
12
+ it 'rejects invalid params' do
13
+ post :create, { :magazine => { :name => 'Mjallo!' } }
14
+ assert_response :bad_request
15
+ response.body.must_equal 'Required parameter missing: book'
16
+
17
+ post :create, { :book => { :id => 'Mjallo!' } }
18
+ assert_response :bad_request
19
+ response.body.must_equal 'Invalid parameter: id must be an integer'
20
+ end
21
+
22
+ it 'permits valid params' do
23
+ post :create, { :book => { :id => '123' } }
24
+ assert_response :ok
25
+ end
26
+ end
@@ -0,0 +1,12 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe 'enum parameter constraints' do
4
+ subject { ActionController::Parameters.enumeration('abc', 123) }
5
+
6
+ permits 'abc'
7
+ permits 123
8
+
9
+ rejects 'abcd'
10
+ rejects '123'
11
+ rejects 1234
12
+ end
@@ -0,0 +1,13 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe 'integer parameter constraints' do
4
+ subject { ActionController::Parameters.integer }
5
+
6
+ permits 123
7
+ permits '123', :as => 123
8
+
9
+ rejects 'abc'
10
+ rejects Date.today
11
+ rejects Time.now
12
+
13
+ end
@@ -0,0 +1,28 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe 'array parameter constraints' do
4
+ subject do
5
+ ActionController::Parameters.map(
6
+ :id => ActionController::Parameters.integer,
7
+ :name => ActionController::Parameters.string
8
+ )
9
+ end
10
+
11
+ def self.permits(value, options = {})
12
+ options[:as] ||= value
13
+ options[:as] = options[:as].with_indifferent_access
14
+
15
+ super(value, options)
16
+ end
17
+
18
+ permits(:id => 1, :name => 'Mick')
19
+ permits({:id => '1', :name => 'Mick'}, :as => {:id => 1, :name => 'Mick'})
20
+ permits(:id => 1)
21
+ permits({:id => '1'}, :as => {:id => 1})
22
+ permits(:name => 'Mick')
23
+
24
+ rejects(:id => 1, :name => 123)
25
+ rejects(:id => 'Mick', :name => 'Mick')
26
+ rejects(123)
27
+ rejects('abc')
28
+ end
@@ -0,0 +1,22 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe 'operator parameter constraints' do
4
+ describe 'OR types' do
5
+ subject { ActionController::Parameters.integer | ActionController::Parameters.string }
6
+
7
+ permits 'abc'
8
+ permits '123', :as => 123
9
+
10
+ rejects Date.today
11
+ rejects Time.now
12
+ end
13
+
14
+ describe 'AND types' do
15
+ subject { ActionController::Parameters.string & ActionController::Parameters.integer }
16
+
17
+ permits '123', :as => 123
18
+
19
+ rejects 123
20
+ rejects 'abc'
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ require_relative 'test_helper'
2
+
3
+ describe 'string parameter constraints' do
4
+ subject { ActionController::Parameters.string }
5
+
6
+ permits 'abc'
7
+
8
+ rejects 123
9
+ rejects Date.today
10
+ rejects Time.now
11
+
12
+ it 'rejects strings that are too long' do
13
+ assert_rejects(:value) { params(:value => '123').permit(:value => ActionController::Parameters.string(:max_length => 2)) }
14
+ end
15
+ end
@@ -0,0 +1,72 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+
3
+ require 'test/unit'
4
+ require 'rails'
5
+ require 'action_controller'
6
+ require 'rails/test_help'
7
+
8
+ class FakeApplication < Rails::Application; end
9
+
10
+ Rails.application = FakeApplication
11
+ Rails.configuration.action_controller = ActiveSupport::OrderedOptions.new
12
+ Rails.configuration.secret_key_base = 'secret_key_base'
13
+
14
+ require 'action_pack'
15
+ require 'strong_parameters' if ActionPack::VERSION::MAJOR == 3
16
+
17
+ module ActionController
18
+ SharedTestRoutes = ActionDispatch::Routing::RouteSet.new
19
+ SharedTestRoutes.draw do
20
+ get ':controller(/:action)'
21
+ post ':controller(/:action)'
22
+ put ':controller(/:action)'
23
+ delete ':controller(/:action)'
24
+ end
25
+
26
+ class Base
27
+ include ActionController::Testing
28
+ include SharedTestRoutes.url_helpers
29
+
30
+ rescue_from(ActionController::ParameterMissing) do |e|
31
+ render :text => "Required parameter missing: #{e.param}", :status => :bad_request
32
+ end
33
+ end
34
+
35
+ class ActionController::TestCase
36
+ setup do
37
+ @routes = SharedTestRoutes
38
+ end
39
+ end
40
+ end
41
+
42
+ require 'stronger_parameters'
43
+ require 'minitest/rails'
44
+ require 'minitest/autorun'
45
+
46
+ class MiniTest::Spec
47
+ def params(hash)
48
+ ActionController::Parameters.new(hash)
49
+ end
50
+
51
+ def assert_rejects(key, &block)
52
+ err = block.must_raise StrongerParameters::InvalidParameter
53
+ err.key.must_equal key.to_s
54
+ end
55
+
56
+ def self.permits(value, options = {})
57
+ type_casted = options.fetch(:as, value)
58
+
59
+ it "permits #{value.inspect} as #{type_casted.inspect}" do
60
+ permitted = params(:value => value).permit(:value => subject)
61
+ permitted[:value].must_equal type_casted
62
+ end
63
+ end
64
+
65
+ def self.rejects(value, options = {})
66
+ key = options.fetch(:key, :value)
67
+
68
+ it "rejects #{value.inspect}" do
69
+ assert_rejects(key) { params(:value => value).permit(:value => subject) }
70
+ end
71
+ end
72
+ end
metadata ADDED
@@ -0,0 +1,190 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stronger_parameters
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Mick Staugaard
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-11-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: guard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: guard-minitest
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: minitest-rails
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: appraisal
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: actionpack
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - '>'
116
+ - !ruby/object:Gem::Version
117
+ version: '2'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - '>'
123
+ - !ruby/object:Gem::Version
124
+ version: '2'
125
+ description:
126
+ email:
127
+ - mick@zendesk.com
128
+ executables: []
129
+ extensions: []
130
+ extra_rdoc_files: []
131
+ files:
132
+ - lib/stronger_parameters/constraints/array_constraint.rb
133
+ - lib/stronger_parameters/constraints/boolean_constraint.rb
134
+ - lib/stronger_parameters/constraints/comparison_constraints.rb
135
+ - lib/stronger_parameters/constraints/enumeration_constraint.rb
136
+ - lib/stronger_parameters/constraints/fixnum_constraint.rb
137
+ - lib/stronger_parameters/constraints/hash_constraint.rb
138
+ - lib/stronger_parameters/constraints/string_constraint.rb
139
+ - lib/stronger_parameters/constraints.rb
140
+ - lib/stronger_parameters/errors.rb
141
+ - lib/stronger_parameters/parameters.rb
142
+ - lib/stronger_parameters/railtie.rb
143
+ - lib/stronger_parameters/version.rb
144
+ - lib/stronger_parameters.rb
145
+ - test/array_contraints_test.rb
146
+ - test/boolean_constraints_test.rb
147
+ - test/comparison_constraints_test.rb
148
+ - test/controller_test.rb
149
+ - test/enum_constraints_test.rb
150
+ - test/fixnum_constraints_test.rb
151
+ - test/hash_constraint_test.rb
152
+ - test/operator_constraints_test.rb
153
+ - test/string_constraints_test.rb
154
+ - test/test_helper.rb
155
+ - README.md
156
+ homepage: https://github.com/zendesk/stronger_parameters
157
+ licenses:
158
+ - Apache License Version 2.0
159
+ metadata: {}
160
+ post_install_message:
161
+ rdoc_options: []
162
+ require_paths:
163
+ - lib
164
+ required_ruby_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - '>='
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ required_rubygems_version: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - '>='
172
+ - !ruby/object:Gem::Version
173
+ version: '0'
174
+ requirements: []
175
+ rubyforge_project:
176
+ rubygems_version: 2.0.14
177
+ signing_key:
178
+ specification_version: 4
179
+ summary: Type checking and type casting of parameters for Action Pack
180
+ test_files:
181
+ - test/array_contraints_test.rb
182
+ - test/boolean_constraints_test.rb
183
+ - test/comparison_constraints_test.rb
184
+ - test/controller_test.rb
185
+ - test/enum_constraints_test.rb
186
+ - test/fixnum_constraints_test.rb
187
+ - test/hash_constraint_test.rb
188
+ - test/operator_constraints_test.rb
189
+ - test/string_constraints_test.rb
190
+ - test/test_helper.rb