committee 1.15.0 → 5.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +5 -5
  2. data/bin/committee-stub +11 -38
  3. data/lib/committee/bin/committee_stub.rb +67 -0
  4. data/lib/committee/drivers/driver.rb +47 -0
  5. data/lib/committee/drivers/hyper_schema/driver.rb +105 -0
  6. data/lib/committee/drivers/hyper_schema/link.rb +68 -0
  7. data/lib/committee/drivers/hyper_schema/schema.rb +22 -0
  8. data/lib/committee/drivers/hyper_schema.rb +12 -0
  9. data/lib/committee/drivers/open_api_2/driver.rb +252 -0
  10. data/lib/committee/drivers/open_api_2/header_schema_builder.rb +33 -0
  11. data/lib/committee/drivers/open_api_2/link.rb +36 -0
  12. data/lib/committee/drivers/open_api_2/parameter_schema_builder.rb +83 -0
  13. data/lib/committee/drivers/open_api_2/schema.rb +26 -0
  14. data/lib/committee/drivers/open_api_2/schema_builder.rb +33 -0
  15. data/lib/committee/drivers/open_api_2.rb +13 -0
  16. data/lib/committee/drivers/open_api_3/driver.rb +51 -0
  17. data/lib/committee/drivers/open_api_3/schema.rb +41 -0
  18. data/lib/committee/drivers/open_api_3.rb +11 -0
  19. data/lib/committee/drivers/schema.rb +23 -0
  20. data/lib/committee/drivers.rb +84 -0
  21. data/lib/committee/errors.rb +17 -0
  22. data/lib/committee/middleware/base.rb +46 -29
  23. data/lib/committee/middleware/request_validation.rb +31 -49
  24. data/lib/committee/middleware/response_validation.rb +48 -25
  25. data/lib/committee/middleware/stub.rb +62 -37
  26. data/lib/committee/middleware.rb +11 -0
  27. data/lib/committee/request_unpacker.rb +58 -50
  28. data/lib/committee/schema_validator/hyper_schema/parameter_coercer.rb +79 -0
  29. data/lib/committee/schema_validator/hyper_schema/request_validator.rb +55 -0
  30. data/lib/committee/schema_validator/hyper_schema/response_generator.rb +102 -0
  31. data/lib/committee/schema_validator/hyper_schema/response_validator.rb +89 -0
  32. data/lib/committee/schema_validator/hyper_schema/router.rb +46 -0
  33. data/lib/committee/schema_validator/hyper_schema/string_params_coercer.rb +105 -0
  34. data/lib/committee/schema_validator/hyper_schema.rb +119 -0
  35. data/lib/committee/schema_validator/open_api_3/operation_wrapper.rb +139 -0
  36. data/lib/committee/schema_validator/open_api_3/request_validator.rb +52 -0
  37. data/lib/committee/schema_validator/open_api_3/response_validator.rb +29 -0
  38. data/lib/committee/schema_validator/open_api_3/router.rb +45 -0
  39. data/lib/committee/schema_validator/open_api_3.rb +120 -0
  40. data/lib/committee/schema_validator/option.rb +60 -0
  41. data/lib/committee/schema_validator.rb +23 -0
  42. data/lib/committee/test/methods.rb +68 -38
  43. data/lib/committee/test/schema_coverage.rb +101 -0
  44. data/lib/committee/utils.rb +28 -0
  45. data/lib/committee/validation_error.rb +5 -2
  46. data/lib/committee/version.rb +5 -0
  47. data/lib/committee.rb +31 -18
  48. data/test/bin/committee_stub_test.rb +57 -0
  49. data/test/bin_test.rb +25 -0
  50. data/test/committee_test.rb +77 -0
  51. data/test/drivers/hyper_schema/driver_test.rb +49 -0
  52. data/test/drivers/hyper_schema/link_test.rb +56 -0
  53. data/test/drivers/open_api_2/driver_test.rb +156 -0
  54. data/test/drivers/open_api_2/header_schema_builder_test.rb +26 -0
  55. data/test/drivers/open_api_2/link_test.rb +52 -0
  56. data/test/drivers/open_api_2/parameter_schema_builder_test.rb +195 -0
  57. data/test/drivers/open_api_3/driver_test.rb +84 -0
  58. data/test/drivers_test.rb +154 -0
  59. data/test/middleware/base_test.rb +96 -7
  60. data/test/middleware/request_validation_open_api_3_test.rb +626 -0
  61. data/test/middleware/request_validation_test.rb +423 -32
  62. data/test/middleware/response_validation_open_api_3_test.rb +291 -0
  63. data/test/middleware/response_validation_test.rb +125 -23
  64. data/test/middleware/stub_test.rb +81 -20
  65. data/test/request_unpacker_test.rb +126 -52
  66. data/test/schema_validator/hyper_schema/parameter_coercer_test.rb +111 -0
  67. data/test/schema_validator/hyper_schema/request_validator_test.rb +151 -0
  68. data/test/schema_validator/hyper_schema/response_generator_test.rb +142 -0
  69. data/test/{response_validator_test.rb → schema_validator/hyper_schema/response_validator_test.rb} +43 -6
  70. data/test/schema_validator/hyper_schema/router_test.rb +88 -0
  71. data/test/schema_validator/hyper_schema/string_params_coercer_test.rb +137 -0
  72. data/test/schema_validator/open_api_3/operation_wrapper_test.rb +218 -0
  73. data/test/schema_validator/open_api_3/request_validator_test.rb +110 -0
  74. data/test/schema_validator/open_api_3/response_validator_test.rb +92 -0
  75. data/test/test/methods_new_version_test.rb +97 -0
  76. data/test/test/methods_test.rb +334 -27
  77. data/test/test/schema_coverage_test.rb +216 -0
  78. data/test/test_helper.rb +108 -1
  79. data/test/validation_error_test.rb +3 -1
  80. metadata +190 -27
  81. data/lib/committee/query_params_coercer.rb +0 -45
  82. data/lib/committee/request_validator.rb +0 -44
  83. data/lib/committee/response_generator.rb +0 -35
  84. data/lib/committee/response_validator.rb +0 -59
  85. data/lib/committee/router.rb +0 -62
  86. data/test/query_params_coercer_test.rb +0 -70
  87. data/test/request_validator_test.rb +0 -103
  88. data/test/response_generator_test.rb +0 -61
  89. data/test/router_test.rb +0 -38
@@ -0,0 +1,154 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
4
+
5
+ describe Committee::Drivers do
6
+ DRIVERS = [
7
+ :hyper_schema,
8
+ :open_api_2,
9
+ :open_api_3,
10
+ ].freeze
11
+
12
+ it "gets driver with .driver_from_name" do
13
+ DRIVERS.each do |name|
14
+ driver = Committee::Drivers.driver_from_name(name)
15
+ assert_kind_of Committee::Drivers::Driver, driver
16
+ end
17
+ end
18
+
19
+ it "raises an ArgumentError for an unknown driver with .driver_from_name" do
20
+ e = assert_raises(ArgumentError) do
21
+ Committee::Drivers.driver_from_name(:blueprint)
22
+ end
23
+ assert_equal %{Committee: unknown driver "blueprint".}, e.message
24
+ end
25
+
26
+ describe 'load_from_file(schema_path)' do
27
+ it 'loads OpenAPI2' do
28
+ s = Committee::Drivers.load_from_file(open_api_2_schema_path)
29
+ assert_kind_of Committee::Drivers::Schema, s
30
+ assert_kind_of Committee::Drivers::OpenAPI2::Schema, s
31
+ end
32
+
33
+ it 'loads Hyper-Schema' do
34
+ s = Committee::Drivers.load_from_file(hyper_schema_schema_path)
35
+ assert_kind_of Committee::Drivers::Schema, s
36
+ assert_kind_of Committee::Drivers::HyperSchema::Schema, s
37
+ end
38
+
39
+ it 'loads OpenAPI 3' do
40
+ s = Committee::Drivers.load_from_file(open_api_3_schema_path, parser_options:{strict_reference_validation: true})
41
+ assert_kind_of Committee::Drivers::Schema, s
42
+ assert_kind_of Committee::Drivers::OpenAPI3::Schema, s
43
+ end
44
+
45
+ it 'load OpenAPI 3 (patch version 3.0.1)' do
46
+ s = Committee::Drivers.load_from_file(open_api_3_0_1_schema_path, parser_options:{strict_reference_validation: true})
47
+ assert_kind_of Committee::Drivers::Schema, s
48
+ assert_kind_of Committee::Drivers::OpenAPI3::Schema, s
49
+ end
50
+
51
+ it 'fails to load OpenAPI 3 with invalid reference' do
52
+ parser_options = { strict_reference_validation: true }
53
+ assert_raises(OpenAPIParser::MissingReferenceError) do
54
+ Committee::Drivers.load_from_file(open_api_3_invalid_reference_path, parser_options: parser_options)
55
+ end
56
+ end
57
+
58
+ # This test can be removed when the test above (raising on invalid reference) becomes default behavior?
59
+ it 'allows loading OpenAPI 3 with invalid reference as existing behavior' do
60
+ s = Committee::Drivers.load_from_file(open_api_3_invalid_reference_path, parser_options:{strict_reference_validation: false})
61
+ assert_kind_of Committee::Drivers::OpenAPI3::Schema, s
62
+ end
63
+
64
+ it 'errors on an unsupported file extension' do
65
+ e = assert_raises(StandardError) do
66
+ Committee::Drivers.load_from_file('test.xml', parser_options:{strict_reference_validation: true})
67
+ end
68
+ assert_equal "Committee only supports the following file extensions: '.json', '.yaml', '.yml'", e.message
69
+ end
70
+ end
71
+
72
+ describe 'load_from_json(schema_path)' do
73
+ it 'loads OpenAPI2' do
74
+ s = Committee::Drivers.load_from_json(open_api_2_schema_path, parser_options:{strict_reference_validation: true})
75
+ assert_kind_of Committee::Drivers::Schema, s
76
+ assert_kind_of Committee::Drivers::OpenAPI2::Schema, s
77
+ end
78
+
79
+ it 'loads Hyper-Schema' do
80
+ s = Committee::Drivers.load_from_json(hyper_schema_schema_path, parser_options:{strict_reference_validation: true})
81
+ assert_kind_of Committee::Drivers::Schema, s
82
+ assert_kind_of Committee::Drivers::HyperSchema::Schema, s
83
+ end
84
+ end
85
+
86
+ describe 'load_from_yaml(schema_path)' do
87
+ it 'loads OpenAPI3' do
88
+ s = Committee::Drivers.load_from_yaml(open_api_3_schema_path, parser_options:{strict_reference_validation: true})
89
+ assert_kind_of Committee::Drivers::Schema, s
90
+ assert_kind_of Committee::Drivers::OpenAPI3::Schema, s
91
+ end
92
+ end
93
+
94
+ describe 'load_from_data(schema_path)' do
95
+ it 'loads OpenAPI3' do
96
+ s = Committee::Drivers.load_from_data(open_api_3_data, parser_options:{strict_reference_validation: false})
97
+ assert_kind_of Committee::Drivers::Schema, s
98
+ assert_kind_of Committee::Drivers::OpenAPI3::Schema, s
99
+ end
100
+
101
+ it 'loads OpenAPI2' do
102
+ s = Committee::Drivers.load_from_data(open_api_2_data)
103
+ assert_kind_of Committee::Drivers::Schema, s
104
+ assert_kind_of Committee::Drivers::OpenAPI2::Schema, s
105
+ end
106
+
107
+ it 'loads Hyper-Schema' do
108
+ s = Committee::Drivers.load_from_data(hyper_schema_data)
109
+ assert_kind_of Committee::Drivers::Schema, s
110
+ assert_kind_of Committee::Drivers::HyperSchema::Schema, s
111
+ end
112
+ end
113
+ end
114
+
115
+ describe Committee::Drivers::Driver do
116
+ DRIVER_METHODS = {
117
+ default_allow_get_body: [],
118
+ default_coerce_form_params: [],
119
+ default_path_params: [],
120
+ default_query_params: [],
121
+ name: [],
122
+ parse: [nil],
123
+ schema_class: [],
124
+ }
125
+
126
+ it "has a set of abstract methods" do
127
+ driver = Committee::Drivers::Driver.new
128
+ DRIVER_METHODS.each do |name, args|
129
+ e = assert_raises do
130
+ driver.send(name, *args)
131
+ end
132
+ assert_equal "needs implementation", e.message,
133
+ "Incorrect error message while sending #{name}: #{e.message}"
134
+ end
135
+ end
136
+ end
137
+
138
+ describe Committee::Drivers::Schema do
139
+ SCHEMA_METHODS = {
140
+ driver: [],
141
+ build_router: [validator_option: nil, prefix: nil]
142
+ }
143
+
144
+ it "has a set of abstract methods" do
145
+ schema = Committee::Drivers::Schema.new
146
+ SCHEMA_METHODS.each do |name, args|
147
+ e = assert_raises do
148
+ schema.send(name, *args)
149
+ end
150
+ assert_equal "needs implementation", e.message,
151
+ "Incorrect error message while sending #{name}: #{e.message}"
152
+ end
153
+ end
154
+ end
@@ -1,4 +1,6 @@
1
- require_relative "../test_helper"
1
+ # frozen_string_literal: true
2
+
3
+ require "test_helper"
2
4
 
3
5
  describe Committee::Middleware::Base do
4
6
  include Rack::Test::Methods
@@ -7,8 +9,10 @@ describe Committee::Middleware::Base do
7
9
  @app
8
10
  end
9
11
 
10
- it "accepts schema hash" do
11
- @app = new_rack_app(schema: JSON.parse(File.read("./test/data/schema.json")))
12
+ it "accepts just a schema object" do
13
+ @app = new_rack_app(
14
+ schema: hyper_schema
15
+ )
12
16
  params = {
13
17
  "name" => "cloudnasium"
14
18
  }
@@ -17,20 +21,105 @@ describe Committee::Middleware::Base do
17
21
  assert_equal 200, last_response.status
18
22
  end
19
23
 
20
- it "accepts schema object" do
21
- schema = JsonSchema.parse!(JSON.parse(File.read("./test/data/schema.json")))
22
- @app = new_rack_app(schema: schema)
24
+ it "accepts just a OpenAPI3 schema object" do
25
+ @app = new_rack_app(schema: open_api_3_schema)
23
26
  params = {
24
- "name" => "cloudnasium"
27
+ "name" => "cloudnasium"
25
28
  }
26
29
  header "Content-Type", "application/json"
27
30
  post "/apps", JSON.generate(params)
28
31
  assert_equal 200, last_response.status
29
32
  end
30
33
 
34
+ it "doesn't accept a schema string" do
35
+ @app = new_rack_app(
36
+ schema: JSON.dump(hyper_schema_data)
37
+ )
38
+ params = {
39
+ "name" => "cloudnasium"
40
+ }
41
+ header "Content-Type", "application/json"
42
+
43
+ e = assert_raises(ArgumentError) do
44
+ post "/apps", JSON.generate(params)
45
+ end
46
+
47
+ assert_equal "Committee: schema expected to be an instance " +
48
+ "of Committee::Drivers::Schema.", e.message
49
+ end
50
+
51
+ it "doesn't accept a schema hash" do
52
+ @app = new_rack_app(
53
+ schema: hyper_schema_data
54
+ )
55
+ params = {
56
+ "name" => "cloudnasium"
57
+ }
58
+ header "Content-Type", "application/json"
59
+
60
+ e = assert_raises(ArgumentError) do
61
+ post "/apps", JSON.generate(params)
62
+ end
63
+
64
+ assert_equal "Committee: schema expected to be an instance " +
65
+ "of Committee::Drivers::Schema.", e.message
66
+ end
67
+
68
+ it "doesn't accept a JsonSchema::Schema object" do
69
+ @app = new_rack_app(
70
+ schema: JsonSchema.parse!(hyper_schema_data)
71
+ )
72
+ params = {
73
+ "name" => "cloudnasium"
74
+ }
75
+ header "Content-Type", "application/json"
76
+
77
+ e = assert_raises(ArgumentError) do
78
+ post "/apps", JSON.generate(params)
79
+ end
80
+
81
+ assert_equal "Committee: schema expected to be an instance " +
82
+ "of Committee::Drivers::Schema.", e.message
83
+ end
84
+
85
+ it "doesn't accept other schema types" do
86
+ @app = new_rack_app(
87
+ schema: 7,
88
+ )
89
+ e = assert_raises(ArgumentError) do
90
+ post "/apps"
91
+ end
92
+ assert_equal "Committee: schema expected to be an instance of Committee::Drivers::Schema.", e.message
93
+ end
94
+
95
+ it "errors when no schema is specified" do
96
+ @app = new_rack_app
97
+ e = assert_raises(ArgumentError) do
98
+ post "/apps"
99
+ end
100
+
101
+ assert_equal "Committee: need option `schema` or `schema_path`", e.message
102
+ end
103
+
104
+ describe 'initialize option' do
105
+ it "accepts OpenAPI3 parser config of strict_reference_validation and raises" do
106
+ assert_raises(OpenAPIParser::MissingReferenceError) do
107
+ Committee::Middleware::Base.new(nil, schema_path: open_api_3_invalid_reference_path, strict_reference_validation: true)
108
+ end
109
+ end
110
+
111
+ it "does not raise by default even with invalid reference OpenAPI3 specification" do
112
+ b = Committee::Middleware::Base.new(nil, schema_path: open_api_3_invalid_reference_path, strict_reference_validation: false)
113
+ assert_kind_of Committee::Drivers::OpenAPI3::Schema, b.instance_variable_get(:@schema)
114
+ end
115
+ end
116
+
31
117
  private
32
118
 
33
119
  def new_rack_app(options = {})
120
+ # TODO: delete when 5.0.0 released because default value changed
121
+ options[:parse_response_by_content_type] = true if options[:parse_response_by_content_type] == nil
122
+
34
123
  Rack::Builder.new {
35
124
  use Committee::Middleware::RequestValidation, options
36
125
  run lambda { |_|