paramoid 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/lib/paramoid/base.rb +49 -21
- data/lib/paramoid/controller.rb +3 -0
- data/lib/paramoid/list.rb +11 -2
- data/lib/paramoid/object.rb +87 -9
- data/lib/paramoid/version.rb +3 -1
- data/lib/paramoid.rb +0 -1
- data/spec/paramoid/base_spec.rb +11 -6
- data/spec/paramoid/complex_spec.rb +168 -0
- data/spec/paramoid/controller_spec.rb +5 -2
- data/spec/paramoid/object_spec.rb +28 -8
- data/spec/spec_helper.rb +1 -0
- data/spec/support/params.rb +35 -0
- metadata +12 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81d4e4ce0a1c77990eeadd7e01f7450307bab477bfdbd4d307f7240521ceab3a
|
4
|
+
data.tar.gz: cbc6586cd42d5aa4c96ef197d689b24add85b79d3841835a85b6f85ef54a8c51
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c42ab24874cbd59db1f5891e7cd96e57ab6151d4e916b0bcd33289aefe97b326d77d4301337471555dcba9ca7c2814a7aa0cf7ecf8b0bb1e414ca3430aabf491
|
7
|
+
data.tar.gz: fa359b7d150eaa6f22c7bcbfea4b8760a51c1e140be713d31e98ba057c47a8af470ed161af4cb3683008c22ffb0afaf732826ef32f64ea07bf202520ff9fb2ef
|
data/lib/paramoid/base.rb
CHANGED
@@ -1,51 +1,83 @@
|
|
1
1
|
module Paramoid
|
2
|
+
# The base class for Paramoid.
|
3
|
+
# @example
|
4
|
+
# class MyParamoidSanitizer < Paramoid::Base
|
5
|
+
# def initialize(user = nil)
|
6
|
+
# param :name, as: :first_name
|
7
|
+
# param :age, transformer: ->(age) { age.to_i }
|
8
|
+
# group :address do
|
9
|
+
# param :street
|
10
|
+
# param :city
|
11
|
+
# param :state
|
12
|
+
# param :zip
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
# end
|
2
16
|
class Base
|
3
17
|
# @param [ActionController::Parameters] params
|
4
18
|
def sanitize(params)
|
5
19
|
params = params.permit(*permitted_params)
|
6
|
-
|
7
|
-
|
20
|
+
context.transform_params!(params)
|
21
|
+
context.apply_defaults!(params)
|
8
22
|
ensure_required_params!(params)
|
9
23
|
end
|
10
24
|
|
25
|
+
def permitted_params
|
26
|
+
scalar_params.to_params
|
27
|
+
end
|
28
|
+
|
11
29
|
protected
|
12
30
|
|
13
31
|
# @param [Symbol] name
|
14
32
|
# @param [Symbol] as
|
15
33
|
# @param [Lambda | NilClass] transformer
|
16
|
-
def group
|
17
|
-
|
18
|
-
|
19
|
-
context << data
|
20
|
-
return unless block_given?
|
34
|
+
def group(name, as: nil, transformer: nil, &block)
|
35
|
+
_nest_rule(name, as: as, transformer: transformer, nesting_type: :object, &block)
|
36
|
+
end
|
21
37
|
|
22
|
-
|
23
|
-
|
24
|
-
yield
|
25
|
-
@context = old_context
|
38
|
+
def list(name, as: nil, transformer: nil, &block)
|
39
|
+
_nest_rule(name, as: as, transformer: transformer, nesting_type: :list, &block)
|
26
40
|
end
|
27
41
|
|
28
|
-
alias list
|
29
|
-
alias array! group!
|
42
|
+
alias array list
|
30
43
|
|
31
44
|
# @param [Array<Symbol>] names
|
32
|
-
def params
|
33
|
-
names.each { |name| param
|
45
|
+
def params(*names, required: false)
|
46
|
+
names.each { |name| param name, required: required }
|
34
47
|
end
|
35
48
|
|
36
|
-
def param
|
49
|
+
def param(name, as: nil, transformer: nil, default: nil, required: false)
|
37
50
|
key = as || name
|
38
51
|
data = Object.new(name, key, nested: nil, default: default, transformer: transformer, required: required)
|
39
52
|
context << data
|
40
53
|
end
|
41
54
|
|
42
|
-
def default
|
55
|
+
def default(name, value)
|
43
56
|
data = Object.new(name, name, nested: nil, default: value)
|
44
57
|
context << data
|
45
58
|
end
|
46
59
|
|
60
|
+
alias param! param
|
61
|
+
alias params! params
|
62
|
+
alias group! group
|
63
|
+
alias default! default
|
64
|
+
alias array! array
|
65
|
+
alias list! list
|
66
|
+
|
47
67
|
private
|
48
68
|
|
69
|
+
def _nest_rule(name, nesting_type:, as: nil, transformer: nil)
|
70
|
+
key = as || name
|
71
|
+
data = Object.new(name, key, nested: List.new, nesting_type: nesting_type, transformer: transformer)
|
72
|
+
context << data
|
73
|
+
return unless block_given?
|
74
|
+
|
75
|
+
old_context = context
|
76
|
+
@context = data
|
77
|
+
yield
|
78
|
+
@context = old_context
|
79
|
+
end
|
80
|
+
|
49
81
|
def context
|
50
82
|
@context ||= scalar_params
|
51
83
|
end
|
@@ -68,10 +100,6 @@ module Paramoid
|
|
68
100
|
@transformers ||= {}.with_indifferent_access
|
69
101
|
end
|
70
102
|
|
71
|
-
def permitted_params
|
72
|
-
scalar_params.to_params
|
73
|
-
end
|
74
|
-
|
75
103
|
def transformed_keys
|
76
104
|
@transformed_keys ||= scalar_params
|
77
105
|
end
|
data/lib/paramoid/controller.rb
CHANGED
data/lib/paramoid/list.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Paramoid
|
2
4
|
class List < Array
|
3
5
|
def to_params
|
@@ -12,13 +14,20 @@ module Paramoid
|
|
12
14
|
end
|
13
15
|
end
|
14
16
|
|
17
|
+
def apply_defaults!(params)
|
18
|
+
each do |params_data|
|
19
|
+
params = params_data.apply_defaults! params
|
20
|
+
end
|
21
|
+
params
|
22
|
+
end
|
23
|
+
|
15
24
|
def to_defaults
|
16
25
|
inject({}) { |a, b| a.merge!(b.to_defaults) }
|
17
26
|
end
|
18
27
|
|
19
|
-
def ensure_required_params!(params)
|
28
|
+
def ensure_required_params!(params, path: [])
|
20
29
|
each do |params_data|
|
21
|
-
params_data.ensure_required_params! params
|
30
|
+
params_data.ensure_required_params! params, path: path
|
22
31
|
end
|
23
32
|
end
|
24
33
|
end
|
data/lib/paramoid/object.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
module Paramoid
|
2
|
+
# rubocop:disable Metrics/ClassLength
|
2
3
|
class Object
|
3
4
|
# @return [Symbol] the parameter name
|
4
5
|
attr_reader :name
|
@@ -19,19 +20,18 @@ module Paramoid
|
|
19
20
|
# @param [Object] default
|
20
21
|
# @param [Lambda, NilClass] transformer
|
21
22
|
# @param [TrueClass, FalseClass] required
|
22
|
-
def initialize(name, alias_name, nested: nil, transformer: nil, default: nil, required: false)
|
23
|
+
def initialize(name, alias_name, nested: nil, nesting_type: nil, transformer: nil, default: nil, required: false)
|
23
24
|
@name = name
|
24
25
|
@alias = alias_name
|
25
26
|
@nested = nested
|
26
27
|
@default = default
|
27
28
|
@transformer = transformer
|
28
29
|
@required = required
|
30
|
+
@nesting_type = nesting_type
|
29
31
|
end
|
30
32
|
|
31
33
|
# @param [Array, Hash] params
|
32
34
|
def transform_params!(params)
|
33
|
-
return if @alias == @name
|
34
|
-
|
35
35
|
if params.is_a?(Array)
|
36
36
|
params.each { |param| transform_params!(param) }
|
37
37
|
return
|
@@ -39,6 +39,8 @@ module Paramoid
|
|
39
39
|
|
40
40
|
return unless params.key?(@name)
|
41
41
|
|
42
|
+
params[@name] = @transformer.call(params[@name]) if @transformer.respond_to?(:call)
|
43
|
+
|
42
44
|
@nested.transform_params!(params[@name]) if nested?
|
43
45
|
params[@alias] = params.delete(@name) unless @alias == @name
|
44
46
|
end
|
@@ -51,6 +53,7 @@ module Paramoid
|
|
51
53
|
end
|
52
54
|
end
|
53
55
|
|
56
|
+
# @return [Hash] the required params
|
54
57
|
def to_required_params
|
55
58
|
if nested?
|
56
59
|
@nested.to_required_params
|
@@ -59,21 +62,83 @@ module Paramoid
|
|
59
62
|
end
|
60
63
|
end
|
61
64
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
65
|
+
# @param [Hash] params
|
66
|
+
# @param [Array<Symbol>] path
|
67
|
+
# @raise [ActionController::ParameterMissing] if one of the required params is missing
|
68
|
+
def ensure_required_params!(params, path: [])
|
69
|
+
if params.is_a?(Array)
|
70
|
+
params.flatten.each do |param|
|
71
|
+
ensure_required_params!(param, path: path)
|
72
|
+
end
|
73
|
+
return params
|
74
|
+
end
|
75
|
+
|
76
|
+
current_path = [*path, @name]
|
77
|
+
|
78
|
+
_raise_on_missing_parameter!(params, output_key, current_path) if @required
|
79
|
+
|
80
|
+
return params unless nested?
|
81
|
+
|
82
|
+
ensure_required_nested_params!(params, current_path)
|
83
|
+
end
|
84
|
+
|
85
|
+
def ensure_required_nested_params!(params, current_path)
|
86
|
+
return params if current_path.size > 1 && params.nil?
|
87
|
+
|
88
|
+
@nested.ensure_required_params!(params ? params[output_key] : nil, path: current_path)
|
89
|
+
|
90
|
+
params
|
91
|
+
end
|
92
|
+
|
93
|
+
# @param [Hash] params
|
94
|
+
# @return [Hash] the params with the default values
|
95
|
+
def apply_defaults!(params)
|
96
|
+
return apply_nested_defaults!(params) if nested?
|
97
|
+
|
98
|
+
return params unless @default
|
99
|
+
|
100
|
+
return params if @nesting_type == :list && !params
|
101
|
+
|
102
|
+
params ||= {}
|
103
|
+
apply_scalar_defaults!(params)
|
104
|
+
|
105
|
+
params
|
106
|
+
end
|
107
|
+
|
108
|
+
def apply_scalar_defaults!(params)
|
109
|
+
if params.is_a?(Array)
|
110
|
+
params.map! { |param| apply_scalar_defaults!(param) }
|
111
|
+
else
|
112
|
+
params[output_key] ||= @default
|
66
113
|
end
|
114
|
+
params
|
115
|
+
end
|
116
|
+
|
117
|
+
def apply_nested_defaults!(params)
|
118
|
+
return params unless params
|
67
119
|
|
68
|
-
@
|
120
|
+
params ||= @nesting_type == :list ? [] : {}
|
69
121
|
|
122
|
+
return apply_nested_param_default_when_available!(params, output_key) unless params.is_a?(Array)
|
123
|
+
|
124
|
+
params.map! do |param|
|
125
|
+
apply_nested_param_default_when_available!(param, output_key)
|
126
|
+
end
|
70
127
|
params
|
71
128
|
end
|
72
129
|
|
130
|
+
def apply_nested_param_default_when_available!(param, key)
|
131
|
+
return param unless param[key]
|
132
|
+
|
133
|
+
result = @nested.apply_defaults!(param[key])
|
134
|
+
param[key] = result if result
|
135
|
+
param
|
136
|
+
end
|
137
|
+
|
73
138
|
def to_defaults
|
74
139
|
if nested?
|
75
140
|
nested_defaults = @nested.to_defaults
|
76
|
-
(nested_defaults.present? ? { output_key =>
|
141
|
+
(nested_defaults.present? ? { output_key => nested_defaults } : {}).with_indifferent_access
|
77
142
|
else
|
78
143
|
(@default ? { output_key => @default } : {}).with_indifferent_access
|
79
144
|
end
|
@@ -90,5 +155,18 @@ module Paramoid
|
|
90
155
|
def nested?
|
91
156
|
!@nested.nil?
|
92
157
|
end
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
def _raise_on_missing_parameter!(params, key, current_path)
|
162
|
+
return if params.nil?
|
163
|
+
return if _param_exist?(params, key)
|
164
|
+
|
165
|
+
raise ActionController::ParameterMissing, current_path.join('.')
|
166
|
+
end
|
167
|
+
|
168
|
+
def _param_exist?(params, key)
|
169
|
+
params&.key?(key) && !params[key].nil?
|
170
|
+
end
|
93
171
|
end
|
94
172
|
end
|
data/lib/paramoid/version.rb
CHANGED
data/lib/paramoid.rb
CHANGED
data/spec/paramoid/base_spec.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
5
|
+
# rubocop:disable Metrics/BlockLength
|
3
6
|
describe PersonParamsSanitizer, type: :controller do
|
4
7
|
let(:params) do
|
5
8
|
ActionController::Parameters.new(params_hash)
|
@@ -15,8 +18,7 @@ describe PersonParamsSanitizer, type: :controller do
|
|
15
18
|
current_user_id: 2,
|
16
19
|
first_name: 'John',
|
17
20
|
last_name: 'Doe',
|
18
|
-
|
19
|
-
# email: 'Hello@MyCustomMAIL.COM',
|
21
|
+
email: 'Hello@MyCustomMAIL.COM',
|
20
22
|
role: 'some_role',
|
21
23
|
unwanted: 'hello',
|
22
24
|
an_object_filtered: { name: 'value' },
|
@@ -38,13 +40,12 @@ describe PersonParamsSanitizer, type: :controller do
|
|
38
40
|
end
|
39
41
|
|
40
42
|
it 'keeps only allowed params' do
|
41
|
-
expect(sanitized).to eq(
|
43
|
+
expect(sanitized.to_unsafe_h).to eq(
|
42
44
|
{
|
43
45
|
'current_user_id' => 2,
|
44
46
|
'first_name' => 'John',
|
45
47
|
'last_name' => 'Doe',
|
46
|
-
|
47
|
-
# 'email' => 'hello@mycustommail.com',
|
48
|
+
'email' => 'hello@mycustommail.com',
|
48
49
|
'some_default' => 1,
|
49
50
|
'an_array_unfiltered' => [1, 2, 3, 4, 5]
|
50
51
|
}
|
@@ -56,7 +57,10 @@ describe PersonParamsSanitizer, type: :controller do
|
|
56
57
|
{}
|
57
58
|
end
|
58
59
|
it 'raises an error' do
|
59
|
-
expect { sanitized }.to raise_error(
|
60
|
+
expect { sanitized }.to raise_error(
|
61
|
+
ActionController::ParameterMissing,
|
62
|
+
/param is missing or the value is empty( or invalid)?: current_user_id/
|
63
|
+
)
|
60
64
|
end
|
61
65
|
end
|
62
66
|
|
@@ -78,3 +82,4 @@ describe PersonParamsSanitizer, type: :controller do
|
|
78
82
|
end
|
79
83
|
end
|
80
84
|
end
|
85
|
+
# rubocop:enable Metrics/BlockLength
|
@@ -0,0 +1,168 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
# rubocop:disable Metrics/BlockLength
|
6
|
+
describe ComplexParamsSanitizer, type: :controller do
|
7
|
+
let(:params) do
|
8
|
+
ActionController::Parameters.new(params_hash)
|
9
|
+
end
|
10
|
+
|
11
|
+
subject { described_class.new(user) }
|
12
|
+
let(:sanitized) { subject.sanitize(params) }
|
13
|
+
|
14
|
+
describe 'when params are valid' do
|
15
|
+
let(:user) { double(admin?: false) }
|
16
|
+
let(:params_hash) do
|
17
|
+
{
|
18
|
+
|
19
|
+
unwanted: 1,
|
20
|
+
name: 'some_name',
|
21
|
+
buyer: {
|
22
|
+
payment_method: {
|
23
|
+
id: 1
|
24
|
+
}
|
25
|
+
}
|
26
|
+
}
|
27
|
+
end
|
28
|
+
let(:params) do
|
29
|
+
ActionController::Parameters.new(params_hash)
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'filters out unwanted params' do
|
33
|
+
expect(sanitized).not_to have_key(:unwanted)
|
34
|
+
end
|
35
|
+
|
36
|
+
it 'has the default values of existing objects' do
|
37
|
+
expect(sanitized.to_unsafe_h).to eq(
|
38
|
+
{
|
39
|
+
'buyer' => { 'payment_method' => { 'uuid' => 1 } },
|
40
|
+
'total' => 0,
|
41
|
+
'name' => 'some_name'
|
42
|
+
}
|
43
|
+
)
|
44
|
+
end
|
45
|
+
|
46
|
+
context 'when a nested object has at least a value' do
|
47
|
+
let(:params_hash) do
|
48
|
+
{
|
49
|
+
|
50
|
+
unwanted: 1,
|
51
|
+
name: 'some_name',
|
52
|
+
buyer: {
|
53
|
+
payment_method: {
|
54
|
+
id: 1
|
55
|
+
}
|
56
|
+
},
|
57
|
+
person: {},
|
58
|
+
items: [{}, { sub_items: [{ id: 5 }] }]
|
59
|
+
}
|
60
|
+
end
|
61
|
+
it 'has the default value for those' do
|
62
|
+
expect(sanitized.to_unsafe_h).to eq(
|
63
|
+
{
|
64
|
+
'buyer' => { 'payment_method' => { 'uuid' => 1 } },
|
65
|
+
'total' => 0,
|
66
|
+
'name' => 'some_name',
|
67
|
+
'items' => [
|
68
|
+
{ 'price' => 0 },
|
69
|
+
{ 'price' => 0, 'sub_items' => [{ 'price' => 0, 'id' => 5 }] }
|
70
|
+
],
|
71
|
+
'person_attributes' => { 'role' => :user }
|
72
|
+
}
|
73
|
+
)
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'and the required parameter is missing' do
|
77
|
+
let(:params_hash) do
|
78
|
+
{
|
79
|
+
|
80
|
+
unwanted: 1,
|
81
|
+
name: 'some_name',
|
82
|
+
buyer: {
|
83
|
+
payment_method: {
|
84
|
+
id: 1
|
85
|
+
}
|
86
|
+
},
|
87
|
+
person: {},
|
88
|
+
items: [{}, { sub_items: [{ price: 5 }] }]
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'raises an error' do
|
93
|
+
expect { sanitized }.to raise_error(
|
94
|
+
ActionController::ParameterMissing,
|
95
|
+
/param is missing or the value is empty( or invalid)?: items.sub_items.id/
|
96
|
+
)
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe 'when params all parameters are set' do
|
103
|
+
let(:user) { double(admin?: true) }
|
104
|
+
let(:params_hash) do
|
105
|
+
{
|
106
|
+
name: 'some_name',
|
107
|
+
unwanted: 1,
|
108
|
+
buyer: {
|
109
|
+
payment_method: {
|
110
|
+
id: 1
|
111
|
+
}
|
112
|
+
},
|
113
|
+
items: [{ id: 5, name: 'some_name', discount: 10 }],
|
114
|
+
total: 100,
|
115
|
+
person: { id: 1, full_name: 'some_name' }
|
116
|
+
|
117
|
+
}
|
118
|
+
end
|
119
|
+
let(:params) do
|
120
|
+
ActionController::Parameters.new(params_hash)
|
121
|
+
end
|
122
|
+
|
123
|
+
it 'returns permitted params' do
|
124
|
+
expect(subject.permitted_params).to eq(
|
125
|
+
[
|
126
|
+
:total, :name,
|
127
|
+
{ buyer: [{ payment_method: [:id] }],
|
128
|
+
items: [:id, :name, :price, :discount, { sub_items: [:id, :price] }],
|
129
|
+
person: %i[id full_name role] }
|
130
|
+
]
|
131
|
+
)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'has the default values correctly nested' do
|
135
|
+
expect(sanitized.to_unsafe_h).to eq(
|
136
|
+
{
|
137
|
+
'buyer' => { 'payment_method' => { 'uuid' => 1 } },
|
138
|
+
'items' => [
|
139
|
+
{ 'price' => 0, 'name' => 'some_name', 'discount' => 0.1, 'id' => 5 }
|
140
|
+
],
|
141
|
+
'total' => 100,
|
142
|
+
'name' => 'some_name',
|
143
|
+
'person_attributes' => { 'role' => :admin, 'id' => 1, 'full_name' => 'some_name' }
|
144
|
+
}
|
145
|
+
)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
describe 'when required params are missing' do
|
150
|
+
let(:user) { double(admin?: false) }
|
151
|
+
let(:params_hash) do
|
152
|
+
{
|
153
|
+
name: 'some_name',
|
154
|
+
buyer: {
|
155
|
+
payment_method: {}
|
156
|
+
}
|
157
|
+
}
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'raises an error' do
|
161
|
+
expect { sanitized }.to raise_error(
|
162
|
+
ActionController::ParameterMissing,
|
163
|
+
/param is missing or the value is empty( or invalid)?: buyer.payment_method.id/
|
164
|
+
)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
# rubocop:enable Metrics/BlockLength
|
@@ -1,13 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
5
|
+
# rubocop:disable Metrics/BlockLength
|
3
6
|
describe 'controllers' do
|
4
7
|
let(:params_hash) do
|
5
8
|
{
|
6
9
|
current_user_id: 2,
|
7
10
|
first_name: 'John',
|
8
11
|
last_name: 'Doe',
|
9
|
-
|
10
|
-
# email: 'Hello@MyCustomMAIL.COM',
|
12
|
+
email: 'Hello@MyCustomMAIL.COM',
|
11
13
|
role: 'some_role',
|
12
14
|
unwanted: 'hello',
|
13
15
|
an_object_filtered: { name: 'value' },
|
@@ -41,3 +43,4 @@ describe 'controllers' do
|
|
41
43
|
end
|
42
44
|
end
|
43
45
|
end
|
46
|
+
# rubocop:enable Metrics/BlockLength
|
@@ -1,5 +1,8 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'spec_helper'
|
2
4
|
|
5
|
+
# rubocop:disable Metrics/BlockLength
|
3
6
|
describe Paramoid::Object do
|
4
7
|
let(:name) { :some_param }
|
5
8
|
let(:alias_name) { :some_param }
|
@@ -27,6 +30,7 @@ describe Paramoid::Object do
|
|
27
30
|
end
|
28
31
|
end
|
29
32
|
|
33
|
+
# FIXME: deprecate to_defaults
|
30
34
|
describe '#to_defaults' do
|
31
35
|
it 'returns an empty value' do
|
32
36
|
expect(subject.to_defaults).to eq({})
|
@@ -94,30 +98,46 @@ describe Paramoid::Object do
|
|
94
98
|
expect do
|
95
99
|
subject.ensure_required_params!(params)
|
96
100
|
end.to raise_error(ActionController::ParameterMissing,
|
97
|
-
|
101
|
+
/param is missing or the value is empty( or invalid)?: some_param/)
|
98
102
|
end
|
99
103
|
end
|
100
104
|
|
101
105
|
context 'when it\'s nested' do
|
102
106
|
let(:nested) { described_class.new(:nested, nil, required: true) }
|
103
107
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
108
|
+
context 'and some_param is present, but nested is required' do
|
109
|
+
let(:params_hash) { { 'not_this_param' => 'some_value', 'some_param' => {} } }
|
110
|
+
|
111
|
+
it 'raises an error' do
|
112
|
+
expect do
|
113
|
+
subject.ensure_required_params!(params)
|
114
|
+
end.to raise_error(ActionController::ParameterMissing,
|
115
|
+
/param is missing or the value is empty( or invalid)?: some_param.nested/)
|
116
|
+
end
|
109
117
|
end
|
110
118
|
|
111
|
-
context 'and
|
119
|
+
context 'and some_param is required' do
|
112
120
|
let(:required) { true }
|
113
121
|
|
114
122
|
it 'raises an error on the parent param' do
|
115
123
|
expect do
|
116
124
|
subject.ensure_required_params!(params)
|
117
125
|
end.to raise_error(ActionController::ParameterMissing,
|
118
|
-
|
126
|
+
/param is missing or the value is empty( or invalid)?: some_param/)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
|
130
|
+
context 'when params is nil' do
|
131
|
+
let(:params) { nil }
|
132
|
+
|
133
|
+
it 'skips the check' do
|
134
|
+
expect do
|
135
|
+
subject.ensure_required_params!(params)
|
136
|
+
end.not_to raise_error(ActionController::ParameterMissing,
|
137
|
+
'param is missing or the value is empty: some_param.nested')
|
119
138
|
end
|
120
139
|
end
|
121
140
|
end
|
122
141
|
end
|
123
142
|
end
|
143
|
+
# rubocop:enable Metrics/BlockLength
|
data/spec/spec_helper.rb
CHANGED
data/spec/support/params.rb
CHANGED
@@ -21,3 +21,38 @@ class PersonParamsSanitizer < Paramoid::Base
|
|
21
21
|
end
|
22
22
|
end
|
23
23
|
end
|
24
|
+
|
25
|
+
class ComplexParamsSanitizer < Paramoid::Base
|
26
|
+
def initialize(user = nil)
|
27
|
+
group :person, as: :person_attributes do
|
28
|
+
params :id, :full_name
|
29
|
+
|
30
|
+
if user.admin?
|
31
|
+
param :role, default: :admin
|
32
|
+
else
|
33
|
+
default :role, :user
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
group :buyer do
|
38
|
+
group :payment_method do
|
39
|
+
param :id, required: true, as: :uuid
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
array :items do
|
44
|
+
params :id, :name
|
45
|
+
|
46
|
+
default :price, 0
|
47
|
+
param :discount, transformer: ->(data) { data&.to_f / 100 } if user.admin?
|
48
|
+
|
49
|
+
array :sub_items do
|
50
|
+
param :id, required: true
|
51
|
+
default :price, 0
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
default :total, 0
|
56
|
+
param :name, required: true
|
57
|
+
end
|
58
|
+
end
|
metadata
CHANGED
@@ -1,11 +1,11 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paramoid
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mònade
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
date: 2022-05-28 00:00:00.000000000 Z
|
@@ -19,7 +19,7 @@ dependencies:
|
|
19
19
|
version: '5'
|
20
20
|
- - "<"
|
21
21
|
- !ruby/object:Gem::Version
|
22
|
-
version: '
|
22
|
+
version: '9'
|
23
23
|
type: :runtime
|
24
24
|
prerelease: false
|
25
25
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -29,7 +29,7 @@ dependencies:
|
|
29
29
|
version: '5'
|
30
30
|
- - "<"
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version: '
|
32
|
+
version: '9'
|
33
33
|
- !ruby/object:Gem::Dependency
|
34
34
|
name: activesupport
|
35
35
|
requirement: !ruby/object:Gem::Requirement
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
version: '5'
|
40
40
|
- - "<"
|
41
41
|
- !ruby/object:Gem::Version
|
42
|
-
version: '
|
42
|
+
version: '9'
|
43
43
|
type: :runtime
|
44
44
|
prerelease: false
|
45
45
|
version_requirements: !ruby/object:Gem::Requirement
|
@@ -49,7 +49,7 @@ dependencies:
|
|
49
49
|
version: '5'
|
50
50
|
- - "<"
|
51
51
|
- !ruby/object:Gem::Version
|
52
|
-
version: '
|
52
|
+
version: '9'
|
53
53
|
- !ruby/object:Gem::Dependency
|
54
54
|
name: rspec
|
55
55
|
requirement: !ruby/object:Gem::Requirement
|
@@ -93,6 +93,7 @@ files:
|
|
93
93
|
- lib/paramoid/object.rb
|
94
94
|
- lib/paramoid/version.rb
|
95
95
|
- spec/paramoid/base_spec.rb
|
96
|
+
- spec/paramoid/complex_spec.rb
|
96
97
|
- spec/paramoid/controller_spec.rb
|
97
98
|
- spec/paramoid/object_spec.rb
|
98
99
|
- spec/spec_helper.rb
|
@@ -102,7 +103,7 @@ homepage: https://rubygems.org/gems/paramoid
|
|
102
103
|
licenses:
|
103
104
|
- MIT
|
104
105
|
metadata: {}
|
105
|
-
post_install_message:
|
106
|
+
post_install_message:
|
106
107
|
rdoc_options: []
|
107
108
|
require_paths:
|
108
109
|
- lib
|
@@ -110,19 +111,20 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
110
111
|
requirements:
|
111
112
|
- - ">="
|
112
113
|
- !ruby/object:Gem::Version
|
113
|
-
version:
|
114
|
+
version: 3.0.0
|
114
115
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
115
116
|
requirements:
|
116
117
|
- - ">="
|
117
118
|
- !ruby/object:Gem::Version
|
118
119
|
version: '0'
|
119
120
|
requirements: []
|
120
|
-
rubygems_version: 3.
|
121
|
-
signing_key:
|
121
|
+
rubygems_version: 3.4.6
|
122
|
+
signing_key:
|
122
123
|
specification_version: 4
|
123
124
|
summary: Getting paranoid about your Rails application params? Try paramoid!
|
124
125
|
test_files:
|
125
126
|
- spec/paramoid/base_spec.rb
|
127
|
+
- spec/paramoid/complex_spec.rb
|
126
128
|
- spec/paramoid/controller_spec.rb
|
127
129
|
- spec/paramoid/object_spec.rb
|
128
130
|
- spec/spec_helper.rb
|