apipie-rails 1.2.0 → 1.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/.rubocop_todo.yml +22 -12
- data/CHANGELOG.md +14 -0
- data/README.rst +6 -3
- data/lib/apipie/application.rb +3 -5
- data/lib/apipie/dsl_definition.rb +5 -4
- data/lib/apipie/errors.rb +14 -0
- data/lib/apipie/extractor/collector.rb +1 -2
- data/lib/apipie/extractor/recorder.rb +26 -2
- data/lib/apipie/extractor.rb +6 -3
- data/lib/apipie/generator/swagger/config.rb +3 -1
- data/lib/apipie/generator/swagger/method_description/api_schema_service.rb +6 -3
- data/lib/apipie/generator/swagger/param_description/builder.rb +1 -1
- data/lib/apipie/static_dispatcher.rb +1 -1
- data/lib/apipie/validator.rb +20 -6
- data/lib/apipie/version.rb +1 -1
- data/spec/controllers/users_controller_spec.rb +10 -0
- data/spec/dummy/app/controllers/users_controller.rb +6 -0
- data/spec/dummy/config/routes.rb +1 -0
- data/spec/lib/apipie/extractor/recorder_spec.rb +43 -6
- data/spec/lib/apipie/generator/swagger/method_description/api_schema_service_spec.rb +13 -0
- data/spec/lib/apipie/generator/swagger/method_description/response_schema_service_spec.rb +2 -2
- data/spec/lib/apipie/generator/swagger/param_description/builder_spec.rb +14 -0
- data/spec/lib/apipie/swagger_generator_spec.rb +1 -1
- data/spec/lib/swagger/openapi_2_0_schema.json +8 -1
- data/spec/test_engine/memes_controller_spec.rb +1 -1
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ebba895c2d4385bd3ccc47fe9663ca6e5b06f213308e09c5899e9f8b7ee6b74c
|
4
|
+
data.tar.gz: 11f9e1572ae63af8b463b4c42a2d9c0b74f094f4ef523060f6948cc11172e089
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4fdb149329633f14091638be50d9b1f99c27bcdb4a5e279b042a835c16bc80b54fa750a7fe0fd69b3d0686badd82d93aef88b6b0c172a2ea9706509526f4dd0a
|
7
|
+
data.tar.gz: 98d1d2a93f9403b47dea88edec25761986b6bdc0fb0db9ed83737f72eb5ac3b3c3b4b1b1eddab54d6db48366ad0a3006c4e7bf58ce257586730ea9a3add04faf
|
data/.rubocop.yml
CHANGED
@@ -46,7 +46,7 @@ Metrics/ClassLength:
|
|
46
46
|
- spec/dummy/app/controllers/users_controller.rb
|
47
47
|
|
48
48
|
Metrics/BlockLength:
|
49
|
-
Max:
|
49
|
+
Max: 26 # default
|
50
50
|
Exclude:
|
51
51
|
- app/controllers/apipie/apipies_controller.rb
|
52
52
|
- lib/apipie/generator/swagger/param_description/composite.rb
|
data/.rubocop_todo.yml
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# This configuration was generated by
|
2
2
|
# `rubocop --auto-gen-config --exclude-limit 180`
|
3
|
-
# on 2023-06-
|
3
|
+
# on 2023-06-09 05:29:05 UTC using RuboCop version 1.52.0.
|
4
4
|
# The point is for the user to remove these configuration records
|
5
5
|
# one by one as the offenses are removed from the code base.
|
6
6
|
# Note that changes in the inspected code, or installation of new
|
@@ -118,7 +118,7 @@ Layout/ElseAlignment:
|
|
118
118
|
- 'lib/apipie/param_description.rb'
|
119
119
|
- 'lib/apipie/resource_description.rb'
|
120
120
|
|
121
|
-
# Offense count:
|
121
|
+
# Offense count: 58
|
122
122
|
# This cop supports safe autocorrection (--autocorrect).
|
123
123
|
Layout/EmptyLineAfterGuardClause:
|
124
124
|
Exclude:
|
@@ -783,6 +783,12 @@ Lint/Void:
|
|
783
783
|
Metrics/AbcSize:
|
784
784
|
Max: 96
|
785
785
|
|
786
|
+
# Offense count: 1
|
787
|
+
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns, inherit_mode.
|
788
|
+
# AllowedMethods: refine
|
789
|
+
Metrics/BlockLength:
|
790
|
+
Max: 26
|
791
|
+
|
786
792
|
# Offense count: 4
|
787
793
|
# Configuration parameters: CountBlocks.
|
788
794
|
Metrics/BlockNesting:
|
@@ -793,11 +799,16 @@ Metrics/BlockNesting:
|
|
793
799
|
Metrics/CyclomaticComplexity:
|
794
800
|
Max: 24
|
795
801
|
|
796
|
-
# Offense count:
|
802
|
+
# Offense count: 79
|
797
803
|
# Configuration parameters: CountComments, CountAsOne, AllowedMethods, AllowedPatterns.
|
798
804
|
Metrics/MethodLength:
|
799
805
|
Max: 58
|
800
806
|
|
807
|
+
# Offense count: 1
|
808
|
+
# Configuration parameters: CountComments, CountAsOne.
|
809
|
+
Metrics/ModuleLength:
|
810
|
+
Max: 101
|
811
|
+
|
801
812
|
# Offense count: 4
|
802
813
|
# Configuration parameters: CountKeywordArgs.
|
803
814
|
Metrics/ParameterLists:
|
@@ -1048,7 +1059,7 @@ RSpec/EmptyLineAfterHook:
|
|
1048
1059
|
RSpec/ExampleLength:
|
1049
1060
|
Max: 85
|
1050
1061
|
|
1051
|
-
# Offense count:
|
1062
|
+
# Offense count: 159
|
1052
1063
|
# This cop supports safe autocorrection (--autocorrect).
|
1053
1064
|
# Configuration parameters: CustomTransform, IgnoredWords, DisallowedExamples.
|
1054
1065
|
# DisallowedExamples: works
|
@@ -1137,7 +1148,7 @@ RSpec/MessageSpies:
|
|
1137
1148
|
RSpec/MultipleExpectations:
|
1138
1149
|
Max: 19
|
1139
1150
|
|
1140
|
-
# Offense count:
|
1151
|
+
# Offense count: 156
|
1141
1152
|
# Configuration parameters: AllowSubject.
|
1142
1153
|
RSpec/MultipleMemoizedHelpers:
|
1143
1154
|
Max: 15
|
@@ -1162,18 +1173,17 @@ RSpec/NamedSubject:
|
|
1162
1173
|
- 'spec/lib/swagger/rake_swagger_spec.rb'
|
1163
1174
|
- 'spec/lib/swagger/swagger_dsl_spec.rb'
|
1164
1175
|
|
1165
|
-
# Offense count:
|
1176
|
+
# Offense count: 94
|
1166
1177
|
# Configuration parameters: AllowedGroups.
|
1167
1178
|
RSpec/NestedGroups:
|
1168
1179
|
Max: 6
|
1169
1180
|
|
1170
|
-
# Offense count:
|
1181
|
+
# Offense count: 1
|
1171
1182
|
# Configuration parameters: AllowedPatterns.
|
1172
1183
|
# AllowedPatterns: ^expect_, ^assert_
|
1173
1184
|
RSpec/NoExpectationExample:
|
1174
1185
|
Exclude:
|
1175
1186
|
- 'spec/controllers/users_controller_spec.rb'
|
1176
|
-
- 'spec/test_engine/memes_controller_spec.rb'
|
1177
1187
|
|
1178
1188
|
# Offense count: 2
|
1179
1189
|
# This cop supports safe autocorrection (--autocorrect).
|
@@ -1232,6 +1242,7 @@ RSpec/VerifiedDoubles:
|
|
1232
1242
|
- 'spec/lib/apipie/apipies_controller_spec.rb'
|
1233
1243
|
- 'spec/lib/apipie/extractor/writer_spec.rb'
|
1234
1244
|
- 'spec/lib/validators/array_validator_spec.rb'
|
1245
|
+
- 'spec/lib/apipie/extractor/recorder_spec.rb'
|
1235
1246
|
|
1236
1247
|
# Offense count: 1
|
1237
1248
|
RSpec/VoidExpect:
|
@@ -1366,7 +1377,7 @@ Style/AndOr:
|
|
1366
1377
|
Exclude:
|
1367
1378
|
- 'lib/apipie/param_description.rb'
|
1368
1379
|
|
1369
|
-
# Offense count:
|
1380
|
+
# Offense count: 18
|
1370
1381
|
# This cop supports safe autocorrection (--autocorrect).
|
1371
1382
|
# Configuration parameters: EnforcedStyle, ProceduralMethods, FunctionalMethods, AllowedMethods, AllowedPatterns, AllowBracesOnProceduralOneLiners, BracesRequiredMethods.
|
1372
1383
|
# SupportedStyles: line_count_based, semantic, braces_for_chaining, always_braces
|
@@ -1522,7 +1533,7 @@ Style/EmptyElse:
|
|
1522
1533
|
- 'lib/apipie/extractor/recorder.rb'
|
1523
1534
|
- 'lib/apipie/extractor/writer.rb'
|
1524
1535
|
|
1525
|
-
# Offense count:
|
1536
|
+
# Offense count: 27
|
1526
1537
|
# This cop supports safe autocorrection (--autocorrect).
|
1527
1538
|
# Configuration parameters: EnforcedStyle.
|
1528
1539
|
# SupportedStyles: compact, expanded
|
@@ -1765,7 +1776,6 @@ Style/Proc:
|
|
1765
1776
|
Style/RaiseArgs:
|
1766
1777
|
Exclude:
|
1767
1778
|
- 'lib/apipie/application.rb'
|
1768
|
-
- 'lib/apipie/dsl_definition.rb'
|
1769
1779
|
- 'lib/apipie/extractor/writer.rb'
|
1770
1780
|
- 'lib/apipie/param_description.rb'
|
1771
1781
|
- 'lib/apipie/see_description.rb'
|
@@ -1917,7 +1927,7 @@ Style/StringConcatenation:
|
|
1917
1927
|
- 'lib/apipie/application.rb'
|
1918
1928
|
- 'lib/apipie/extractor/writer.rb'
|
1919
1929
|
|
1920
|
-
# Offense count:
|
1930
|
+
# Offense count: 1212
|
1921
1931
|
# This cop supports safe autocorrection (--autocorrect).
|
1922
1932
|
# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
|
1923
1933
|
# SupportedStyles: single_quotes, double_quotes
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,20 @@
|
|
1
1
|
Changelog
|
2
2
|
===========
|
3
3
|
|
4
|
+
## [v1.2.2](https://github.com/Apipie/apipie-rails/tree/v1.2.2) (2023-07-18)
|
5
|
+
[Full Changelog](https://github.com/Apipie/apipie-rails/compare/v1.2.1...v1.2.2)
|
6
|
+
* Fixed Swagger warnings for properties ([#892](https://github.com/Apipie/apipie-rails/pull/892)) (shev-vadim-net)
|
7
|
+
* Improved support for multipart/form-data example recording ([#891](https://github.com/Apipie/apipie-rails/pull/891)) (Butiri Cristian & hossenlopp)
|
8
|
+
* rubocop (1.54.2) fixes required with latest version ([#893](https://github.com/Apipie/apipie-rails/pull/893)) (Mathieu Jobin)
|
9
|
+
|
10
|
+
## [v1.2.1](https://github.com/Apipie/apipie-rails/tree/v1.2.1) (2023-06-09)
|
11
|
+
[Full Changelog](https://github.com/Apipie/apipie-rails/compare/v1.2.0...v1.2.1)
|
12
|
+
* rspec: Fixes deprecated matcher ([#882](https://github.com/Apipie/apipie-rails/pull/882)) (David Wessman)
|
13
|
+
* Fix streaming bug ([#677](https://github.com/Apipie/apipie-rails/pull/677)) (Hunter Braun)
|
14
|
+
* Update README URLs based on HTTP redirects ([#448](https://github.com/Apipie/apipie-rails/pull/448)) (ReadmeCritic)
|
15
|
+
* Swagger: Adds option to skip default tags ([#881](https://github.com/Apipie/apipie-rails/pull/881)) (David Wessman)
|
16
|
+
* Parameter validation: Raises error for all missing ([#886](https://github.com/Apipie/apipie-rails/pull/886)) (David Wessman)
|
17
|
+
|
4
18
|
## [v1.2.0](https://github.com/Apipie/apipie-rails/tree/v1.2.0) (2023-06-03)
|
5
19
|
[Full Changelog](https://github.com/Apipie/apipie-rails/compare/v1.1.0...v1.2.0)
|
6
20
|
* Allow resource_name to be inherited ([#872](https://github.com/Apipie/apipie-rails/pull/872)) (Eric Hankins)
|
data/README.rst
CHANGED
@@ -56,7 +56,7 @@ Run your application and see the result at
|
|
56
56
|
use ``http://localhost:3000/apipie.json``.
|
57
57
|
|
58
58
|
For a more comprehensive getting started guide, see
|
59
|
-
`this demo <https://github.com/
|
59
|
+
`this demo <https://github.com/Apipie/apipie-demo>`_, which includes
|
60
60
|
features such as generating documentation from tests, recording examples etc.
|
61
61
|
|
62
62
|
Screenshots
|
@@ -78,7 +78,7 @@ See `Contributors page <https://github.com/Apipie/apipie-rails/graphs/contribut
|
|
78
78
|
License
|
79
79
|
-------
|
80
80
|
|
81
|
-
Apipie-rails is released under the `MIT License <
|
81
|
+
Apipie-rails is released under the `MIT License <https://opensource.org/licenses/MIT>`_
|
82
82
|
|
83
83
|
===============
|
84
84
|
Documentation
|
@@ -1730,6 +1730,9 @@ There are several configuration parameters that determine the structure of the g
|
|
1730
1730
|
See [https://swagger.io/docs/specification/2-0/authentication/] for details of what values can be specified
|
1731
1731
|
By default, no security is defined.
|
1732
1732
|
|
1733
|
+
``config.generator.swagger.skip_default_tags``
|
1734
|
+
By setting ``false`` (default): The resource name for e.g. ``/pets/{petId}`` will automatically be added as a tag ``pets``.
|
1735
|
+
By setting ``true``: The tags needs to be explicitly added to the resource using the DSL.
|
1733
1736
|
|
1734
1737
|
Known limitations of the current implementation
|
1735
1738
|
-------------------------------------------------
|
@@ -1940,7 +1943,7 @@ Then, you can install dependencies and run the test suite:
|
|
1940
1943
|
Disqus Integration
|
1941
1944
|
====================
|
1942
1945
|
|
1943
|
-
You can setup `Disqus <
|
1946
|
+
You can setup `Disqus <https://disqus.com/>`_ discussion within
|
1944
1947
|
your documentation. Just set the credentials in the Apipie
|
1945
1948
|
configuration:
|
1946
1949
|
|
data/lib/apipie/application.rb
CHANGED
@@ -405,12 +405,10 @@ module Apipie
|
|
405
405
|
version_prefix = version_prefix(klass)
|
406
406
|
path = klass.controller_path
|
407
407
|
|
408
|
-
|
409
|
-
|
410
|
-
path
|
411
|
-
else
|
408
|
+
unless version_prefix == '/'
|
409
|
+
path =
|
412
410
|
path.gsub(version_prefix, '')
|
413
|
-
|
411
|
+
end
|
414
412
|
|
415
413
|
path.gsub('/', '-')
|
416
414
|
elsif klass.respond_to?(:controller_name)
|
@@ -241,9 +241,11 @@ module Apipie
|
|
241
241
|
method_params = self.class._apipie_get_method_params(action_name)
|
242
242
|
|
243
243
|
if Apipie.configuration.validate_presence?
|
244
|
-
|
245
|
-
|
246
|
-
|
244
|
+
Validator::BaseValidator.raise_if_missing_params do |missing|
|
245
|
+
method_params.each do |_, param|
|
246
|
+
# check if required parameters are present
|
247
|
+
missing << param if param.required && !params.key?(param.name)
|
248
|
+
end
|
247
249
|
end
|
248
250
|
end
|
249
251
|
|
@@ -285,7 +287,6 @@ module Apipie
|
|
285
287
|
old_method.bind(self).call(*args)
|
286
288
|
end
|
287
289
|
end
|
288
|
-
|
289
290
|
end
|
290
291
|
end
|
291
292
|
|
data/lib/apipie/errors.rb
CHANGED
@@ -24,6 +24,20 @@ module Apipie
|
|
24
24
|
end
|
25
25
|
end
|
26
26
|
|
27
|
+
class ParamMultipleMissing < ParamError
|
28
|
+
attr_accessor :params
|
29
|
+
|
30
|
+
def initialize(params)
|
31
|
+
@params = params
|
32
|
+
end
|
33
|
+
|
34
|
+
def to_s
|
35
|
+
params.map do |param|
|
36
|
+
ParamMissing.new(param).to_s
|
37
|
+
end.join("\n")
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
27
41
|
class ParamMissing < DefinedParamError
|
28
42
|
def to_s
|
29
43
|
unless @param.options[:missing_message].nil?
|
@@ -24,10 +24,10 @@ module Apipie
|
|
24
24
|
end
|
25
25
|
|
26
26
|
def handle_record(record)
|
27
|
-
add_to_records(record)
|
28
27
|
if ignore_call?(record)
|
29
28
|
Extractor.logger.info("REST_API: skipping #{record_to_s(record)}")
|
30
29
|
else
|
30
|
+
add_to_records(record)
|
31
31
|
refine_description(record)
|
32
32
|
end
|
33
33
|
end
|
@@ -114,4 +114,3 @@ module Apipie
|
|
114
114
|
end
|
115
115
|
end
|
116
116
|
end
|
117
|
-
|
@@ -44,7 +44,7 @@ module Apipie
|
|
44
44
|
@path = request.path
|
45
45
|
@params = request.request_parameters
|
46
46
|
if [:POST, :PUT, :PATCH, :DELETE].include?(@verb)
|
47
|
-
@request_data = @params
|
47
|
+
@request_data = request.content_type == "multipart/form-data" ? reformat_multipart_data(@params) : @params
|
48
48
|
else
|
49
49
|
@query = request.query_string
|
50
50
|
end
|
@@ -66,8 +66,14 @@ module Apipie
|
|
66
66
|
lines = ["Content-Type: multipart/form-data; boundary=#{MULTIPART_BOUNDARY}",'']
|
67
67
|
boundary = "--#{MULTIPART_BOUNDARY}"
|
68
68
|
form.each do |key, attrs|
|
69
|
-
if attrs.is_a?(String)
|
69
|
+
if attrs.is_a?(String) # rubocop:disable Style/CaseLikeIf
|
70
70
|
lines << boundary << content_disposition(key) << "Content-Length: #{attrs.size}" << '' << attrs
|
71
|
+
elsif attrs.is_a?(Rack::Test::UploadedFile) || attrs.is_a?(ActionDispatch::Http::UploadedFile)
|
72
|
+
reformat_uploaded_file(boundary, attrs, key, lines)
|
73
|
+
elsif attrs.is_a?(Array)
|
74
|
+
reformat_array(boundary, attrs, key, lines)
|
75
|
+
elsif attrs.is_a?(TrueClass) || attrs.is_a?(FalseClass)
|
76
|
+
reformat_boolean(boundary, attrs, key, lines)
|
71
77
|
else
|
72
78
|
reformat_hash(boundary, attrs, lines)
|
73
79
|
end
|
@@ -88,6 +94,24 @@ module Apipie
|
|
88
94
|
end
|
89
95
|
end
|
90
96
|
|
97
|
+
def reformat_boolean(boundary, attrs, key, lines)
|
98
|
+
lines << boundary << content_disposition(key)
|
99
|
+
lines << '' << attrs.to_s
|
100
|
+
end
|
101
|
+
|
102
|
+
def reformat_array(boundary, attrs, key, lines)
|
103
|
+
attrs.each do |item|
|
104
|
+
lines << boundary << content_disposition("#{key}[]")
|
105
|
+
lines << '' << item
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def reformat_uploaded_file(boundary, file, key, lines)
|
110
|
+
lines << boundary << %{#{content_disposition(key)}; filename="#{file.original_filename}"}
|
111
|
+
lines << "Content-Length: #{file.size}" << "Content-Type: #{file.content_type}" << "Content-Transfer-Encoding: binary"
|
112
|
+
lines << '' << %{... contents of "#{key}" ...}
|
113
|
+
end
|
114
|
+
|
91
115
|
def content_disposition(name)
|
92
116
|
%{Content-Disposition: form-data; name="#{name}"}
|
93
117
|
end
|
data/lib/apipie/extractor.rb
CHANGED
@@ -15,10 +15,13 @@ class Apipie::Railtie
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
end
|
18
|
-
app.middleware.use ::Apipie::Extractor::Recorder::Middleware
|
19
18
|
|
20
|
-
|
21
|
-
|
19
|
+
if Apipie.configuration.record
|
20
|
+
app.middleware.use ::Apipie::Extractor::Recorder::Middleware
|
21
|
+
|
22
|
+
ActionController::TestCase.send(:prepend, Apipie::Extractor::Recorder::FunctionalTestRecording)
|
23
|
+
ActionController::TestCase::Behavior.send(:prepend, Apipie::Extractor::Recorder::FunctionalTestRecording)
|
24
|
+
end
|
22
25
|
end
|
23
26
|
end
|
24
27
|
|
@@ -10,7 +10,7 @@ module Apipie
|
|
10
10
|
:json_input_uses_refs, :suppress_warnings, :api_host,
|
11
11
|
:generate_x_computed_id_field, :allow_additional_properties_in_response,
|
12
12
|
:responses_use_refs, :schemes, :security_definitions,
|
13
|
-
:global_security].freeze
|
13
|
+
:global_security, :skip_default_tags].freeze
|
14
14
|
|
15
15
|
attr_accessor(*CONFIG_ATTRIBUTES)
|
16
16
|
|
@@ -43,6 +43,7 @@ module Apipie
|
|
43
43
|
alias include_warning_tags? include_warning_tags
|
44
44
|
alias json_input_uses_refs? json_input_uses_refs
|
45
45
|
alias responses_use_refs? responses_use_refs
|
46
|
+
alias skip_default_tags? skip_default_tags
|
46
47
|
alias generate_x_computed_id_field? generate_x_computed_id_field
|
47
48
|
alias swagger_include_warning_tags? swagger_include_warning_tags
|
48
49
|
alias swagger_json_input_uses_refs? swagger_json_input_uses_refs
|
@@ -61,6 +62,7 @@ module Apipie
|
|
61
62
|
@schemes = [:https]
|
62
63
|
@security_definitions = {}
|
63
64
|
@global_security = []
|
65
|
+
@skip_default_tags = false
|
64
66
|
end
|
65
67
|
|
66
68
|
def self.deprecated_methods
|
@@ -47,9 +47,12 @@ class Apipie::Generator::Swagger::MethodDescription::ApiSchemaService
|
|
47
47
|
end
|
48
48
|
|
49
49
|
def tags
|
50
|
-
|
51
|
-
|
52
|
-
|
50
|
+
tags = if Apipie.configuration.generator.swagger.skip_default_tags?
|
51
|
+
[]
|
52
|
+
else
|
53
|
+
[@method_description.resource._id]
|
54
|
+
end
|
55
|
+
tags + warning_tags + @method_description.tag_list.tags
|
53
56
|
end
|
54
57
|
|
55
58
|
def warning_tags
|
@@ -11,7 +11,7 @@ module Apipie
|
|
11
11
|
# Replace all null bytes
|
12
12
|
path = ::Rack::Utils.unescape(path || '')
|
13
13
|
.encode(Encoding::UTF_8, invalid: :replace, replace: '')
|
14
|
-
.gsub(
|
14
|
+
.gsub("\x0", '')
|
15
15
|
|
16
16
|
full_path = path.empty? ? @root : File.join(@root, path)
|
17
17
|
paths = "#{full_path}#{ext}"
|
data/lib/apipie/validator.rb
CHANGED
@@ -38,6 +38,16 @@ module Apipie
|
|
38
38
|
return nil
|
39
39
|
end
|
40
40
|
|
41
|
+
def self.raise_if_missing_params
|
42
|
+
missing_params = []
|
43
|
+
yield missing_params
|
44
|
+
if missing_params.size > 1
|
45
|
+
raise ParamMultipleMissing.new(missing_params)
|
46
|
+
elsif missing_params.size == 1
|
47
|
+
raise ParamMissing.new(missing_params.first)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
41
51
|
# check if value is valid
|
42
52
|
def valid?(value)
|
43
53
|
if self.validate(value)
|
@@ -345,14 +355,18 @@ module Apipie
|
|
345
355
|
|
346
356
|
def validate(value)
|
347
357
|
return false if !value.is_a? Hash
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
|
358
|
+
|
359
|
+
BaseValidator.raise_if_missing_params do |missing|
|
360
|
+
@hash_params&.each do |k, p|
|
361
|
+
if Apipie.configuration.validate_presence?
|
362
|
+
missing << p if p.required && !value.key?(k)
|
363
|
+
end
|
364
|
+
if Apipie.configuration.validate_value?
|
365
|
+
p.validate(value[k]) if value.key?(k)
|
366
|
+
end
|
354
367
|
end
|
355
368
|
end
|
369
|
+
|
356
370
|
return true
|
357
371
|
end
|
358
372
|
|
data/lib/apipie/version.rb
CHANGED
@@ -37,6 +37,7 @@ describe UsersController do
|
|
37
37
|
expect(methods.keys).to include(:update)
|
38
38
|
expect(methods.keys).to include(:two_urls)
|
39
39
|
expect(methods.keys).to include(:action_with_headers)
|
40
|
+
expect(methods.keys).to include(:multiple_required_params)
|
40
41
|
end
|
41
42
|
|
42
43
|
it "should contain info about resource" do
|
@@ -101,6 +102,10 @@ describe UsersController do
|
|
101
102
|
expect { get :show, :params => { :id => 5 }}.to raise_error(Apipie::ParamMissing, /session_parameter_is_required/)
|
102
103
|
end
|
103
104
|
|
105
|
+
it "should fail if multiple required parameters are missing" do
|
106
|
+
expect { get :multiple_required_params }.to raise_error(Apipie::ParamMultipleMissing, /required_param1.*\n.*required_param2|required_param2.*\n.*required_parameter1/)
|
107
|
+
end
|
108
|
+
|
104
109
|
it "should pass if required parameter has wrong type" do
|
105
110
|
expect { get :show, :params => { :id => 5 , :session => "secret_hash" }}.not_to raise_error
|
106
111
|
expect { get :show, :params => { :id => "ten" , :session => "secret_hash" }}.not_to raise_error
|
@@ -246,6 +251,11 @@ describe UsersController do
|
|
246
251
|
post :create, :params => { :user => { :name => "root", :pass => "12345", :membership => "____" } }
|
247
252
|
}.to raise_error(Apipie::ParamInvalid, /membership/)
|
248
253
|
|
254
|
+
# Should include both pass and name
|
255
|
+
expect {
|
256
|
+
post :create, :params => { :user => { :membership => "standard" } }
|
257
|
+
}.to raise_error(Apipie::ParamMultipleMissing, /pass.*\n.*name|name.*\n.*pass/)
|
258
|
+
|
249
259
|
expect {
|
250
260
|
post :create, :params => { :user => { :name => "root" } }
|
251
261
|
}.to raise_error(Apipie::ParamMissing, /pass/)
|
@@ -301,4 +301,10 @@ class UsersController < ApplicationController
|
|
301
301
|
header :HeaderNameWithDefaultValue, 'Header with default value', required: true, default: 'default value'
|
302
302
|
def action_with_headers
|
303
303
|
end
|
304
|
+
|
305
|
+
api :GET, '/users/multiple_required_params'
|
306
|
+
param :required_param1, String, required: true
|
307
|
+
param :required_param2, String, required: true
|
308
|
+
def multiple_required_params
|
309
|
+
end
|
304
310
|
end
|
data/spec/dummy/config/routes.rb
CHANGED
@@ -4,6 +4,11 @@ require 'spec_helper'
|
|
4
4
|
|
5
5
|
describe 'Apipie::Extractor::Recorder' do
|
6
6
|
let(:recorder) { Apipie::Extractor::Recorder.new }
|
7
|
+
let(:controller) do
|
8
|
+
controller = ActionController::Metal.new
|
9
|
+
controller.set_request!(request)
|
10
|
+
controller
|
11
|
+
end
|
7
12
|
|
8
13
|
describe '#analyse_controller' do
|
9
14
|
subject do
|
@@ -19,12 +24,6 @@ describe 'Apipie::Extractor::Recorder' do
|
|
19
24
|
request
|
20
25
|
end
|
21
26
|
|
22
|
-
let(:controller) do
|
23
|
-
controller = ActionController::Metal.new
|
24
|
-
controller.set_request!(request)
|
25
|
-
controller
|
26
|
-
end
|
27
|
-
|
28
27
|
it { is_expected.to eq(action) }
|
29
28
|
|
30
29
|
context 'when a api_action_matcher is configured' do
|
@@ -37,4 +36,42 @@ describe 'Apipie::Extractor::Recorder' do
|
|
37
36
|
it { is_expected.to eq(matcher_action) }
|
38
37
|
end
|
39
38
|
end
|
39
|
+
|
40
|
+
describe '#analyse_functional_test' do
|
41
|
+
context 'with multipart-form data' do
|
42
|
+
subject do
|
43
|
+
recorder.analyse_controller(controller)
|
44
|
+
recorder.analyze_functional_test(test_context)
|
45
|
+
recorder.record[:request_data]
|
46
|
+
end
|
47
|
+
|
48
|
+
let(:test_context) do
|
49
|
+
double(controller: controller, request: request, response: ActionDispatch::Response.new(200))
|
50
|
+
end
|
51
|
+
|
52
|
+
let(:file) do
|
53
|
+
instance_double(
|
54
|
+
ActionDispatch::Http::UploadedFile,
|
55
|
+
original_filename: 'file.txt',
|
56
|
+
content_type: 'text/plain',
|
57
|
+
size: '1MB'
|
58
|
+
)
|
59
|
+
end
|
60
|
+
|
61
|
+
let(:request) do
|
62
|
+
request = ActionDispatch::Request.new({})
|
63
|
+
request.request_method = 'POST'
|
64
|
+
request.headers['Content-Type'] = 'multipart/form-data'
|
65
|
+
request.request_parameters = { file: file }
|
66
|
+
request
|
67
|
+
end
|
68
|
+
|
69
|
+
before do
|
70
|
+
allow(file).to receive(:is_a?).and_return(false)
|
71
|
+
allow(file).to receive(:is_a?).with(ActionDispatch::Http::UploadedFile).and_return(true)
|
72
|
+
end
|
73
|
+
|
74
|
+
it { is_expected.to include("filename=\"#{file.original_filename}\"") }
|
75
|
+
end
|
76
|
+
end
|
40
77
|
end
|
@@ -64,6 +64,19 @@ describe Apipie::Generator::Swagger::MethodDescription::ApiSchemaService do
|
|
64
64
|
it { is_expected.to include(*tags) }
|
65
65
|
end
|
66
66
|
|
67
|
+
context 'when Apipie.configuration.generator.swagger.skip_default_tags is enabled' do
|
68
|
+
before { Apipie.configuration.generator.swagger.skip_default_tags = true }
|
69
|
+
after { Apipie.configuration.generator.swagger.skip_default_tags = false }
|
70
|
+
|
71
|
+
it { is_expected.to be_empty }
|
72
|
+
|
73
|
+
context 'when tags are available' do
|
74
|
+
let(:tags) { ['Tag 1', 'Tag 2'] }
|
75
|
+
|
76
|
+
it { is_expected.to eq(tags) }
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
67
80
|
context 'when Apipie.configuration.generator.swagger.include_warning_tags is enabled' do
|
68
81
|
before { Apipie.configuration.generator.swagger.include_warning_tags = true }
|
69
82
|
|
@@ -56,7 +56,7 @@ describe Apipie::Generator::Swagger::MethodDescription::ResponseSchemaService do
|
|
56
56
|
expect(properties).to eq(
|
57
57
|
{
|
58
58
|
a_number: {
|
59
|
-
type: 'number'
|
59
|
+
type: 'number', required: true
|
60
60
|
},
|
61
61
|
an_optional_number: {
|
62
62
|
type: 'number'
|
@@ -72,7 +72,7 @@ describe Apipie::Generator::Swagger::MethodDescription::ResponseSchemaService do
|
|
72
72
|
expect(properties).to eq(
|
73
73
|
{
|
74
74
|
a_number: {
|
75
|
-
type: %w[number null]
|
75
|
+
type: %w[number null], required: true
|
76
76
|
},
|
77
77
|
an_optional_number: {
|
78
78
|
type: %w[number null]
|
@@ -78,6 +78,12 @@ describe Apipie::Generator::Swagger::ParamDescription::Builder do
|
|
78
78
|
|
79
79
|
it { is_expected.to be_blank }
|
80
80
|
|
81
|
+
context 'when is required' do
|
82
|
+
let(:base_param_description_options) { { required: true } }
|
83
|
+
|
84
|
+
it { is_expected.to eq(true) }
|
85
|
+
end
|
86
|
+
|
81
87
|
context 'when in_schema is false' do
|
82
88
|
let(:in_schema) { false }
|
83
89
|
|
@@ -107,6 +113,14 @@ describe Apipie::Generator::Swagger::ParamDescription::Builder do
|
|
107
113
|
end
|
108
114
|
end
|
109
115
|
end
|
116
|
+
|
117
|
+
context 'when is required' do
|
118
|
+
let(:base_param_description_options) { { required: true } }
|
119
|
+
|
120
|
+
it 'does not output an option without default warning' do
|
121
|
+
expect { subject }.not_to output(/is optional but default value is not specified/).to_stderr
|
122
|
+
end
|
123
|
+
end
|
110
124
|
end
|
111
125
|
|
112
126
|
describe '.with_type' do
|
@@ -996,7 +996,14 @@
|
|
996
996
|
"$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
|
997
997
|
},
|
998
998
|
"required": {
|
999
|
-
"
|
999
|
+
"anyOf": [
|
1000
|
+
{
|
1001
|
+
"$ref": "http://json-schema.org/draft-04/schema#/definitions/stringArray"
|
1002
|
+
},
|
1003
|
+
{
|
1004
|
+
"type": "boolean"
|
1005
|
+
}
|
1006
|
+
]
|
1000
1007
|
},
|
1001
1008
|
"enum": {
|
1002
1009
|
"$ref": "http://json-schema.org/draft-04/schema#/properties/enum"
|
@@ -4,7 +4,7 @@ describe TestEngine::MemesController do
|
|
4
4
|
|
5
5
|
describe "#index" do
|
6
6
|
it "should have the full mounted path of engine" do
|
7
|
-
Apipie.routes_for_action(TestEngine::MemesController, :index, {}).first[:path].
|
7
|
+
expect(Apipie.routes_for_action(TestEngine::MemesController, :index, {}).first[:path]).to eq("/test/memes")
|
8
8
|
end
|
9
9
|
end
|
10
10
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: apipie-rails
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Pavel Pokorny
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2023-
|
12
|
+
date: 2023-07-18 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionpack
|
@@ -472,7 +472,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
472
472
|
- !ruby/object:Gem::Version
|
473
473
|
version: '0'
|
474
474
|
requirements: []
|
475
|
-
rubygems_version: 3.4.
|
475
|
+
rubygems_version: 3.4.14
|
476
476
|
signing_key:
|
477
477
|
specification_version: 4
|
478
478
|
summary: Rails REST API documentation tool
|