input_sanitizer 0.1.10 → 0.2.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 80975685ea36b822133f114e4f25a86795ab1a84
4
+ data.tar.gz: fe52c7a9f8039a61e247cc7634a93d176de4ed32
5
+ SHA512:
6
+ metadata.gz: 3fd6f2abb6f51ddfc1e161568515dcb40800f3eb7c7a28962253040d1aa37052de7b3e15f1f6b0b5b739a54276b1d76b7f66f98289ad4052afb2fd84b264ddbb
7
+ data.tar.gz: cfc6ea3add9b7a3d9089e30830e53e1ffa00ec12daacb0d0ced5c6c8eedc05d22d112a2c29c3617c886ee57dd5559bea455901384b18ad78f7d437c681f9d38d
data/.travis.yml CHANGED
@@ -6,7 +6,7 @@ rvm:
6
6
  - 1.9.3
7
7
  - jruby-18mode
8
8
  - jruby-19mode
9
- - rbx-18mode
10
9
 
11
10
  # keeps failing
11
+ #- rbx-18mode
12
12
  #- rbx-19mode
@@ -1,4 +1,5 @@
1
1
  require 'time'
2
+ require 'date'
2
3
 
3
4
  module InputSanitizer
4
5
  class ConversionError < Exception
@@ -32,11 +33,18 @@ module InputSanitizer
32
33
  end
33
34
 
34
35
  class TimeConverter
35
- ISO_RE = /\A\d{4}-?\d{2}-?\d{2}([T ]?\d{2}(:?\d{2}(:?\d{2})?)?)?\Z/
36
+ ISO_RE = /\A\d{4}-?\d{2}-?\d{2}([T ]?\d{2}(:?\d{2}(:?\d{2}((\.)?\d{0,3}(Z)?)?)?)?)?\Z/
36
37
 
37
38
  def call(value)
38
- if value =~ ISO_RE
39
- strip_timezone(Time.parse(value))
39
+ case value
40
+ when Time
41
+ value.getutc
42
+ when String
43
+ if value =~ ISO_RE
44
+ strip_timezone(Time.parse(value))
45
+ else
46
+ raise ConversionError.new("invalid time")
47
+ end
40
48
  else
41
49
  raise ConversionError.new("invalid time")
42
50
  end
@@ -59,6 +67,8 @@ module InputSanitizer
59
67
  '0' => false,
60
68
  'yes' => true,
61
69
  'no' => false,
70
+ 1 => true,
71
+ 0 => false,
62
72
  }
63
73
 
64
74
  def call(value)
@@ -22,7 +22,10 @@ class InputSanitizer::Sanitizer
22
22
  self.class.fields.each do |field, hash|
23
23
  type = hash[:type]
24
24
  required = hash[:options][:required]
25
- clean_field(field, type, required)
25
+ collection = hash[:options][:collection]
26
+ namespace = hash[:options][:namespace]
27
+ default = hash[:options][:default]
28
+ clean_field(field, type, required, collection, namespace, default)
26
29
  end
27
30
  @performed = true
28
31
  @cleaned.freeze
@@ -73,6 +76,17 @@ class InputSanitizer::Sanitizer
73
76
  self.set_keys_to_type(keys, converter)
74
77
  end
75
78
 
79
+ def self.nested(*keys)
80
+ options = keys.pop
81
+ sanitizer = options.delete(:sanitizer)
82
+ keys.push(options)
83
+ raise "You did not define a sanitizer for nested value" if sanitizer == nil
84
+ converter = lambda { |value|
85
+ sanitizer.clean(value)
86
+ }
87
+ self.set_keys_to_type(keys, converter)
88
+ end
89
+
76
90
  protected
77
91
  def self.fields
78
92
  @fields ||= {}
@@ -91,13 +105,15 @@ class InputSanitizer::Sanitizer
91
105
  array.last.is_a?(Hash) ? array.last : {}
92
106
  end
93
107
 
94
- def clean_field(field, type, required)
108
+ def clean_field(field, type, required, collection, namespace, default)
95
109
  if @data.has_key?(field)
96
110
  begin
97
- @cleaned[field] = convert(field, type)
111
+ @cleaned[field] = convert(field, type, collection, namespace)
98
112
  rescue InputSanitizer::ConversionError => ex
99
113
  add_error(field, :invalid_value, @data[field], ex.message)
100
114
  end
115
+ elsif default
116
+ @cleaned[field] = converter(type).call(default)
101
117
  elsif required
102
118
  add_missing(field)
103
119
  end
@@ -116,8 +132,22 @@ class InputSanitizer::Sanitizer
116
132
  add_error(field, :missing, nil, nil)
117
133
  end
118
134
 
119
- def convert(field, type)
120
- converter(type).call(@data[field])
135
+ def convert(field, type, collection, namespace)
136
+ if collection
137
+ @data[field].map { |v|
138
+ convert_single(type, v, namespace)
139
+ }
140
+ else
141
+ convert_single(type, @data[field], namespace)
142
+ end
143
+ end
144
+
145
+ def convert_single(type, value, namespace)
146
+ if namespace
147
+ { namespace => converter(type).call(value[namespace]) }
148
+ else
149
+ converter(type).call(value)
150
+ end
121
151
  end
122
152
 
123
153
  def converter(type)
@@ -1,3 +1,3 @@
1
1
  module InputSanitizer
2
- VERSION = "0.1.10"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -81,14 +81,27 @@ describe InputSanitizer::TimeConverter do
81
81
  converter.call("2012-05-15 13:42:54").should == t
82
82
  converter.call("2012-05-15T13:42:54").should == t
83
83
  converter.call("20120515134254").should == t
84
+ end
85
+
86
+ it "works with miliseconds" do
87
+ t = Time.utc(2012, 5, 15, 13, 42, 54)
88
+ converter.call("2012-05-15 13:42:54.000").should == t
89
+ converter.call("2012-05-15T13:42:54.000").should == t
90
+ converter.call("20120515134254000").should == t
91
+ end
84
92
 
93
+ it "works with Z at the end" do
94
+ t = Time.utc(2012, 5, 15, 13, 42, 54)
95
+ converter.call("2012-05-15 13:42:54.000Z").should == t
96
+ converter.call("2012-05-15T13:42:54.000Z").should == t
97
+ converter.call("2012-05-15T13:42:54Z").should == t
98
+ converter.call("20120515134254000Z").should == t
85
99
  end
86
100
 
87
101
  it "does not require time part" do
88
102
  converter.call("2012-05-15 13:42").should == Time.utc(2012, 5, 15, 13, 42)
89
103
  converter.call("2012-05-15 13").should == Time.utc(2012, 5, 15, 13)
90
104
  converter.call("2012-05-15").should == Time.utc(2012, 5, 15)
91
-
92
105
  end
93
106
 
94
107
  it "raises error if can format is wrong" do
@@ -98,4 +111,9 @@ describe InputSanitizer::TimeConverter do
98
111
  it "raises error if date is wrong" do
99
112
  lambda { converter.call("2012-02-32") }.should raise_error(InputSanitizer::ConversionError)
100
113
  end
114
+
115
+ it "allows the instance of Time" do
116
+ t = Time.now
117
+ converter.call(t).should == t.utc
118
+ end
101
119
  end
@@ -1,11 +1,19 @@
1
1
  require 'spec_helper'
2
2
 
3
+ class NestedSanitizer < InputSanitizer::Sanitizer
4
+ integer :foo
5
+ end
6
+
3
7
  class BasicSanitizer < InputSanitizer::Sanitizer
4
8
  string :x, :y, :z
9
+ integer :namespaced, :namespace => :value
10
+ integer :array, :collection => true
11
+ integer :namespaced_array, :collection => true, :namespace => :value
5
12
  integer :num
6
13
  date :birthday
7
14
  time :updated_at
8
15
  custom :cust1, :cust2, :converter => lambda { |v| v.reverse }
16
+ nested :stuff, :sanitizer => NestedSanitizer, :collection => true, :namespace => :nested
9
17
  end
10
18
 
11
19
  class BrokenCustomSanitizer < InputSanitizer::Sanitizer
@@ -28,12 +36,17 @@ class RequiredCustom < BasicSanitizer
28
36
  custom :c1, :required => true, :converter => lambda { |v| v }
29
37
  end
30
38
 
39
+ class DefaultParameters < BasicSanitizer
40
+ integer :funky_number, :default => 5
41
+ custom :fixed_stuff, :converter => lambda {|v| v }, :default => "default string"
42
+ end
43
+
31
44
  describe InputSanitizer::Sanitizer do
32
45
  let(:sanitizer) { BasicSanitizer.new(@params) }
33
46
 
34
47
  describe ".clean" do
35
48
  it "returns cleaned data" do
36
- clean_data = mock()
49
+ clean_data = double
37
50
  BasicSanitizer.any_instance.should_receive(:cleaned).and_return(clean_data)
38
51
  BasicSanitizer.clean({}).should be(clean_data)
39
52
  end
@@ -83,6 +96,30 @@ describe InputSanitizer::Sanitizer do
83
96
  cleaned.should_not have_key(:d)
84
97
  end
85
98
 
99
+ it "preserves namespace" do
100
+ value = { :value => 5 }
101
+ @params = { :namespaced => value }
102
+
103
+ cleaned[:namespaced].should eq(value)
104
+ end
105
+
106
+ it "maps values for collection fields" do
107
+ numbers = [3, 5, 6]
108
+ @params = { :array => numbers }
109
+
110
+ cleaned[:array].should eq(numbers)
111
+ end
112
+
113
+ it "maps values for collection fields with namespace" do
114
+ numbers = [
115
+ { :value => 2 },
116
+ { :value => 5 }
117
+ ]
118
+ @params = { :namespaced_array => numbers }
119
+
120
+ cleaned[:namespaced_array].should eq(numbers)
121
+ end
122
+
86
123
  it "silently discards cast errors" do
87
124
  @params = {:num => "f"}
88
125
 
@@ -106,6 +143,32 @@ describe InputSanitizer::Sanitizer do
106
143
  cleaned[:is_nice].should == 42
107
144
  end
108
145
 
146
+ context "when sanitizer is initialized with default values" do
147
+ context "when paremeters are not overwriten" do
148
+ let(:sanitizer) { DefaultParameters.new({}) }
149
+
150
+ it "returns default value for non custom key" do
151
+ sanitizer.cleaned[:funky_number].should == 5
152
+ end
153
+
154
+ it "returns default value for custom key" do
155
+ sanitizer.cleaned[:fixed_stuff].should == "default string"
156
+ end
157
+ end
158
+
159
+ context "when parameters are overwriten" do
160
+ let(:sanitizer) { DefaultParameters.new({ :funky_number => 2, :fixed_stuff => "fixed" }) }
161
+
162
+ it "returns default value for non custom key" do
163
+ sanitizer.cleaned[:funky_number].should == 2
164
+ end
165
+
166
+ it "returns default value for custom key" do
167
+ sanitizer.cleaned[:fixed_stuff].should == "fixed"
168
+ end
169
+ end
170
+ end
171
+
109
172
  end
110
173
 
111
174
  describe ".custom" do
@@ -126,6 +189,25 @@ describe InputSanitizer::Sanitizer do
126
189
  end
127
190
  end
128
191
 
192
+ describe ".nested" do
193
+ let(:sanitizer) { BasicSanitizer.new(@params) }
194
+ let(:cleaned) { sanitizer.cleaned }
195
+
196
+ it "sanitizes nested values" do
197
+ nested = [
198
+ { :nested => { :foo => "5" } },
199
+ { :nested => { :foo => 8 } },
200
+ ]
201
+ @params = { :stuff => nested }
202
+
203
+ expected = [
204
+ { :nested => { :foo => 5 } },
205
+ { :nested => { :foo => 8 } },
206
+ ]
207
+ cleaned[:stuff].should eq(expected)
208
+ end
209
+ end
210
+
129
211
  describe ".converters" do
130
212
  let(:sanitizer) { InputSanitizer::Sanitizer }
131
213
 
data/spec/spec_helper.rb CHANGED
@@ -1,7 +1,9 @@
1
1
  require 'bundler'
2
2
  Bundler.setup(:test)
3
3
 
4
- require 'simplecov'
5
- SimpleCov.start unless ENV['CI'] == 'true'
4
+ unless ENV['CI']
5
+ require 'simplecov'
6
+ SimpleCov.start
7
+ end
6
8
 
7
9
  require 'input_sanitizer'
metadata CHANGED
@@ -1,8 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: input_sanitizer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.10
5
- prerelease:
4
+ version: 0.2.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Tomek Paczkowski
@@ -11,38 +10,34 @@ authors:
11
10
  autorequire:
12
11
  bindir: bin
13
12
  cert_chain: []
14
- date: 2013-05-13 00:00:00.000000000 Z
13
+ date: 2013-12-11 00:00:00.000000000 Z
15
14
  dependencies:
16
15
  - !ruby/object:Gem::Dependency
17
16
  name: rspec
18
17
  requirement: !ruby/object:Gem::Requirement
19
- none: false
20
18
  requirements:
21
- - - ! '>='
19
+ - - '>='
22
20
  - !ruby/object:Gem::Version
23
21
  version: '0'
24
22
  type: :development
25
23
  prerelease: false
26
24
  version_requirements: !ruby/object:Gem::Requirement
27
- none: false
28
25
  requirements:
29
- - - ! '>='
26
+ - - '>='
30
27
  - !ruby/object:Gem::Version
31
28
  version: '0'
32
29
  - !ruby/object:Gem::Dependency
33
30
  name: simplecov
34
31
  requirement: !ruby/object:Gem::Requirement
35
- none: false
36
32
  requirements:
37
- - - ! '>='
33
+ - - '>='
38
34
  - !ruby/object:Gem::Version
39
35
  version: '0'
40
36
  type: :development
41
37
  prerelease: false
42
38
  version_requirements: !ruby/object:Gem::Requirement
43
- none: false
44
39
  requirements:
45
- - - ! '>='
40
+ - - '>='
46
41
  - !ruby/object:Gem::Version
47
42
  version: '0'
48
43
  description: Gem to sanitize hash of incoming data
@@ -75,27 +70,26 @@ files:
75
70
  - spec/spec_helper.rb
76
71
  homepage: ''
77
72
  licenses: []
73
+ metadata: {}
78
74
  post_install_message:
79
75
  rdoc_options: []
80
76
  require_paths:
81
77
  - lib
82
78
  required_ruby_version: !ruby/object:Gem::Requirement
83
- none: false
84
79
  requirements:
85
- - - ! '>='
80
+ - - '>='
86
81
  - !ruby/object:Gem::Version
87
82
  version: '0'
88
83
  required_rubygems_version: !ruby/object:Gem::Requirement
89
- none: false
90
84
  requirements:
91
- - - ! '>='
85
+ - - '>='
92
86
  - !ruby/object:Gem::Version
93
87
  version: '0'
94
88
  requirements: []
95
89
  rubyforge_project:
96
- rubygems_version: 1.8.23
90
+ rubygems_version: 2.0.14
97
91
  signing_key:
98
- specification_version: 3
92
+ specification_version: 4
99
93
  summary: Gem to sanitize hash of incoming data
100
94
  test_files:
101
95
  - spec/default_converters_spec.rb