committee 0.4.14 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,83 +0,0 @@
1
- module Committee
2
- module Validation
3
- def check_format!(format, value, identifier)
4
- return if !format
5
- return if check_format(format, value, identifier)
6
-
7
- description = case identifier
8
- when String
9
- %{Invalid format for key "#{identifier}": expected "#{value}" to be "#{format}".}
10
- when Array
11
- %{Invalid format at "#{identifier.join(":")}": expected "#{value}" to be "#{format}".}
12
- end
13
-
14
- raise InvalidFormat, description
15
- end
16
-
17
- def check_format(format, value, identifier)
18
- case format
19
- when "date-time"
20
- value =~ /^(\d{4})-(\d{2})-(\d{2})T(\d{2})\:(\d{2})\:(\d{2})(\.\d{1,})?(Z|[+-](\d{2})\:(\d{2}))$/
21
- when "email"
22
- value =~ /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,4}$/i
23
- when "uuid"
24
- value =~ /^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/
25
- else
26
- true
27
- end
28
- end
29
-
30
- def check_type!(allowed_types, value, identifier)
31
- return if check_type(allowed_types, value, identifier)
32
-
33
- description = case identifier
34
- when String
35
- %{Invalid type for key "#{identifier}": expected #{value.inspect} to be #{allowed_types}.}
36
- when Array
37
- %{Invalid type at "#{identifier.join(":")}": expected #{value.inspect} to be #{allowed_types}.}
38
- end
39
-
40
- raise InvalidType, description
41
- end
42
-
43
- def check_type(allowed_types, value, identifier)
44
- types = case value
45
- when NilClass
46
- ["null"]
47
- when TrueClass, FalseClass
48
- ["boolean"]
49
- when Bignum, Fixnum
50
- ["integer", "number"]
51
- when Float
52
- ["number"]
53
- when Hash
54
- ["object"]
55
- when String
56
- ["string"]
57
- when Array
58
- ["array"]
59
- else
60
- ["unknown"]
61
- end
62
-
63
- !(allowed_types & types).empty?
64
- end
65
-
66
- def check_pattern!(pattern, value, identifier)
67
- return if check_pattern(pattern, value, identifier)
68
-
69
- description = case identifier
70
- when String
71
- %{Invalid pattern for key "#{identifier}": expected #{value} to match "#{pattern}".}
72
- when Array
73
- %{Invalid pattern at "#{identifier.join(":")}": expected #{value} to match "#{pattern}".}
74
- end
75
-
76
- raise InvalidPattern, description
77
- end
78
-
79
- def check_pattern(pattern, value, identifier)
80
- !pattern || value =~ Regexp.new(pattern)
81
- end
82
- end
83
- end
@@ -1,127 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- describe Committee::ParamValidator do
4
- before do
5
- @schema = Committee::Schema.new(File.read("./test/data/schema.json"))
6
- # POST /account/app-transfers
7
- @link_schema = @schema["app-transfer"]["links"][0]
8
- end
9
-
10
- it "passes through a valid request" do
11
- params = {
12
- "app" => "heroku-api",
13
- "recipient" => "owner@heroku.com",
14
- }
15
- validate(params, @schema, @link_schema)
16
- end
17
-
18
- it "detects a missing parameter" do
19
- e = assert_raises(Committee::InvalidParams) do
20
- validate({}, @schema, @link_schema)
21
- end
22
- message = "Require params: app, recipient."
23
- assert_equal message, e.message
24
- end
25
-
26
- it "doesn't error on an extraneous parameter with allow_extra" do
27
- params = {
28
- "app" => "heroku-api",
29
- "cloud" => "production",
30
- "recipient" => "owner@heroku.com",
31
- }
32
- validate(params, @schema, @link_schema, allow_extra: true)
33
- end
34
-
35
- it "detects a parameter of the wrong type" do
36
- params = {
37
- "app" => "heroku-api",
38
- "recipient" => 123,
39
- }
40
- e = assert_raises(Committee::InvalidType) do
41
- validate(params, @schema, @link_schema)
42
- end
43
- message = %{Invalid type for key "recipient": expected 123 to be ["string"].}
44
- assert_equal message, e.message
45
- end
46
-
47
- it "detects a parameter of the wrong format" do
48
- params = {
49
- "app" => "heroku-api",
50
- "recipient" => "not-email",
51
- }
52
- e = assert_raises(Committee::InvalidFormat) do
53
- validate(params, @schema, @link_schema)
54
- end
55
- message = %{Invalid format for key "recipient": expected "not-email" to be "email".}
56
- assert_equal message, e.message
57
- end
58
-
59
- it "detects a parameter of the wrong pattern" do
60
- params = {
61
- "name" => "%@!"
62
- }
63
- link_schema = @schema["app"]["links"][0]
64
- e = assert_raises(Committee::InvalidPattern) do
65
- validate(params, @schema, link_schema)
66
- end
67
- message = %{Invalid pattern for key "name": expected %@! to match "(?-mix:^[a-z][a-z0-9-]{3,30}$)".}
68
- assert_equal message, e.message
69
- end
70
-
71
- describe "complex arrays" do
72
- it "passes an array parameter" do
73
- params = {
74
- "updates" => [
75
- { "name" => "bamboo", "state" => "private" },
76
- { "name" => "cedar", "state" => "public" },
77
- ]
78
- }
79
- link_schema = @schema["stack"]["links"][2]
80
- validate(params, @schema, link_schema)
81
- end
82
-
83
- it "detects an array item with a parameter of the wrong type" do
84
- params = {
85
- "updates" => [
86
- { "name" => "bamboo", "state" => 123 },
87
- ]
88
- }
89
- link_schema = @schema["stack"]["links"][2]
90
- e = assert_raises(Committee::InvalidType) do
91
- validate(params, @schema, link_schema)
92
- end
93
- message = %{Invalid type for key "state": expected 123 to be ["string"].}
94
- assert_equal message, e.message
95
- end
96
- end
97
-
98
- describe "simple arrays" do
99
- it "passes an array parameter" do
100
- params = {
101
- "password" => "1234",
102
- "flags" => [ "vip", "customer" ]
103
- }
104
- link_schema = @schema["account"]["links"][1]
105
- validate(params, @schema, link_schema)
106
- end
107
-
108
- it "detects an array item with a parameter of the wrong type" do
109
- params = {
110
- "password" => "1234",
111
- "flags" => [ "vip", "customer", 999 ]
112
- }
113
- link_schema = @schema["account"]["links"][1]
114
- e = assert_raises(Committee::InvalidType) do
115
- validate(params, @schema, link_schema)
116
- end
117
- message = %{Invalid type for key "flags": expected 999 to be ["string"].}
118
- assert_equal message, e.message
119
- end
120
- end
121
-
122
- private
123
-
124
- def validate(params, schema, link_schema, options = {})
125
- Committee::ParamValidator.new(params, schema, link_schema, options).call
126
- end
127
- end
@@ -1,55 +0,0 @@
1
- require "benchmark"
2
- require_relative "../test_helper"
3
-
4
- describe Committee::Middleware::RequestValidation do
5
- include Rack::Test::Methods
6
-
7
- def app
8
- @app
9
- end
10
-
11
- N = 50000
12
-
13
- it "is reasonably quick" do
14
- params = MultiJson.encode({
15
- "app" => "heroku-api",
16
- "recipient" => "owner@heroku.com",
17
- })
18
-
19
- Benchmark.benchmark(Benchmark::CAPTION, 7, Benchmark::FORMAT, ">overhead:") do |x|
20
- raw = x.report("raw") do
21
- N.times do
22
- @app = new_rack_app(raw: true)
23
- header "Content-Type", "application/json"
24
- post "/account/app-transfers", params
25
- end
26
- end
27
-
28
- rich = x.report("rich") do
29
- N.times do
30
- @app = new_rack_app
31
- header "Content-Type", "application/json"
32
- post "/account/app-transfers", params
33
- end
34
- end
35
-
36
- puts "average overhead = #{(rich.real - raw.real) / N}"
37
- end
38
- end
39
-
40
- private
41
-
42
- def new_rack_app(options = {})
43
- Rack::Builder.new {
44
- unless options.delete(:raw)
45
- options = {
46
- schema: File.read("./test/data/schema.json")
47
- }.merge(options)
48
- use Committee::Middleware::RequestValidation, options
49
- end
50
- run lambda { |_|
51
- [200, {}, []]
52
- }
53
- }
54
- end
55
- end
data/test/schema_test.rb DELETED
@@ -1,36 +0,0 @@
1
- require_relative "test_helper"
2
-
3
- describe Committee::Schema do
4
- before do
5
- data = File.read("./test/data/schema.json")
6
- @schema = Committee::Schema.new(data)
7
- end
8
-
9
- it "is enumerable" do
10
- arr = @schema.to_a
11
- assert_equal "account", arr[0][0]
12
- assert arr[0][1].is_a?(Hash)
13
- end
14
-
15
- it "can lookup definitions" do
16
- expected = {
17
- "default" => nil,
18
- "description" => "slug size in bytes of app",
19
- "example" => 0,
20
- "readOnly" => true,
21
- "type" => ["number", "null"]
22
- }
23
- assert_equal expected, @schema.find("#/definitions/app/definitions/slug_size")
24
- end
25
-
26
- it "raises error on a non-existent definition" do
27
- assert_raises(Committee::ReferenceNotFound) do
28
- @schema.find("/schema/app#/definitions/bad_field")
29
- end
30
- end
31
-
32
- it "materializes regexes" do
33
- definition = @schema.find("#/definitions/app/definitions/git_url")
34
- assert definition["pattern"].is_a?(Regexp)
35
- end
36
- end