apipie-rails 1.2.1 → 1.2.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 555b019a70732e777c4f42b25dd62362be62674c55f31dba9106434969ff7f9f
4
- data.tar.gz: e63cd96de5768bc21b4a86b755b883440a36ca8c8914ec5af4c89dfe525d94ab
3
+ metadata.gz: 589dc3b1a0a39f1b2fae7fa811e27969b3f8de5c6eb2e187ca1c61e3d77edd5a
4
+ data.tar.gz: b99b476c03dadcce53f6fe2c4e712a9e6a30960762de9fead0b755ef3d6ebee2
5
5
  SHA512:
6
- metadata.gz: 0d6aca2dea2281738587924ee7e3388b1b36beb25d9bac7e46f05044080535f52fb77a3523d9262344410f3d76683c0d33a7d0188d99a51d957a9f9392ba7a3e
7
- data.tar.gz: 7f74cc96e3694406b579649cbd44b8a9ab7d7c273b57d93a7530e1b67a2e32dca27efa408b27a10d87f342abc5badde819e7f02e363ff3d924d3988db33501f2
6
+ metadata.gz: 765673e5c7ca984ad30d1d1f815f583f92d3f9dfdd595228c74e73b9fac3fd0e60260f65e6f9e8eb6b19f24de1f8b814cb917f38bf312ec8a30c52b8e1eea901
7
+ data.tar.gz: 3afe26c57541633e04017eb022f4f526ed08c22b4d1a2ad7ca44364a49ce88f5e868e1651a468e5d0707325bf4abdc2fc15c1bbc8bebae0bc288b795ac6f0848
data/.rubocop_todo.yml CHANGED
@@ -1242,6 +1242,7 @@ RSpec/VerifiedDoubles:
1242
1242
  - 'spec/lib/apipie/apipies_controller_spec.rb'
1243
1243
  - 'spec/lib/apipie/extractor/writer_spec.rb'
1244
1244
  - 'spec/lib/validators/array_validator_spec.rb'
1245
+ - 'spec/lib/apipie/extractor/recorder_spec.rb'
1245
1246
 
1246
1247
  # Offense count: 1
1247
1248
  RSpec/VoidExpect:
data/CHANGELOG.md CHANGED
@@ -1,6 +1,16 @@
1
1
  Changelog
2
2
  ===========
3
3
 
4
+ ## [v1.2.3](https://github.com/Apipie/apipie-rails/tree/v1.2.3) (2023-10-11)
5
+ [Full Changelog](https://github.com/Apipie/apipie-rails/compare/v1.2.2...v1.2.3)
6
+ * Fix param: Consider default_value: nil as valid config ([#894](https://github.com/Apipie/apipie-rails/pull/894)) (davidwessman)
7
+
8
+ ## [v1.2.2](https://github.com/Apipie/apipie-rails/tree/v1.2.2) (2023-07-18)
9
+ [Full Changelog](https://github.com/Apipie/apipie-rails/compare/v1.2.1...v1.2.2)
10
+ * Fixed Swagger warnings for properties ([#892](https://github.com/Apipie/apipie-rails/pull/892)) (shev-vadim-net)
11
+ * Improved support for multipart/form-data example recording ([#891](https://github.com/Apipie/apipie-rails/pull/891)) (Butiri Cristian & hossenlopp)
12
+ * rubocop (1.54.2) fixes required with latest version ([#893](https://github.com/Apipie/apipie-rails/pull/893)) (Mathieu Jobin)
13
+
4
14
  ## [v1.2.1](https://github.com/Apipie/apipie-rails/tree/v1.2.1) (2023-06-09)
5
15
  [Full Changelog](https://github.com/Apipie/apipie-rails/compare/v1.2.0...v1.2.1)
6
16
  * rspec: Fixes deprecated matcher ([#882](https://github.com/Apipie/apipie-rails/pull/882)) (David Wessman)
@@ -405,12 +405,10 @@ module Apipie
405
405
  version_prefix = version_prefix(klass)
406
406
  path = klass.controller_path
407
407
 
408
- path =
409
- if version_prefix == '/'
410
- path
411
- else
408
+ unless version_prefix == '/'
409
+ path =
412
410
  path.gsub(version_prefix, '')
413
- end
411
+ end
414
412
 
415
413
  path.gsub('/', '-')
416
414
  elsif klass.respond_to?(:controller_name)
@@ -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
@@ -71,7 +71,7 @@ class Apipie::Generator::Swagger::ParamDescription::Builder
71
71
  end
72
72
 
73
73
  def for_default
74
- return {} if @param_description.options[:default_value].blank?
74
+ return {} unless @param_description.options.key?(:default_value)
75
75
 
76
76
  {
77
77
  default: @param_description.options[:default_value],
@@ -79,7 +79,7 @@ class Apipie::Generator::Swagger::ParamDescription::Builder
79
79
  end
80
80
 
81
81
  def required?
82
- required_from_path? || (!@in_schema && @param_description.required)
82
+ required_from_path? || @param_description.required
83
83
  end
84
84
 
85
85
  def required_from_path?
@@ -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(/\x0/, '')
14
+ .gsub("\x0", '')
15
15
 
16
16
  full_path = path.empty? ? @root : File.join(@root, path)
17
17
  paths = "#{full_path}#{ext}"
@@ -1,3 +1,3 @@
1
1
  module Apipie
2
- VERSION = "1.2.1"
2
+ VERSION = "1.2.3"
3
3
  end
@@ -57,8 +57,7 @@ describe Apipie::ApipiesController, type: :controller do
57
57
  end
58
58
 
59
59
  it "succeeds on method details with the default language" do
60
- allow(Apipie.configuration).to receive(:default_locale).and_return("en")
61
- allow(Apipie.configuration).to receive(:languages).and_return([])
60
+ allow(Apipie.configuration).to receive_messages(default_locale: "en", languages: [])
62
61
 
63
62
  get :index, :params => { :version => "2.0", :resource => "architectures", :method => "index.en" }
64
63
 
@@ -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
@@ -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
 
@@ -96,14 +102,48 @@ describe Apipie::Generator::Swagger::ParamDescription::Builder do
96
102
 
97
103
  subject { generated_block }
98
104
 
99
- context 'when is not required' do
100
- let(:base_param_description_options) { { required: false } }
105
+ context 'when required is true' do
106
+ let(:base_param_description_options) { { required: true } }
107
+
108
+ it 'does not output an option without default warning' do
109
+ expect { subject }.not_to output(
110
+ /is optional but default value is not specified/
111
+ ).to_stderr
112
+ end
113
+ end
114
+
115
+ context 'when required is false' do
116
+ context 'when default_value is nil' do
117
+ let(:base_param_description_options) do
118
+ { required: false, default_value: nil }
119
+ end
120
+
121
+ it 'will not warn' do
122
+ expect { subject }.not_to output(
123
+ /is optional but default value is not specified/
124
+ ).to_stderr
125
+ end
126
+ end
127
+
128
+ context 'when default_value is 123' do
129
+ let(:base_param_description_options) do
130
+ { required: false, default_value: 123 }
131
+ end
132
+
133
+ it 'will not warn' do
134
+ expect { subject }.not_to output(
135
+ /is optional but default value is not specified/
136
+ ).to_stderr
137
+ end
138
+ end
101
139
 
102
- context 'and no default is given' do
103
- before { param_description_options.delete(:default) }
140
+ context 'default_value not given' do
141
+ let(:base_param_description_options) { { required: false } }
104
142
 
105
- it 'outputs an option without default warning' do
106
- expect { subject }.to output(/is optional but default value is not specified/).to_stderr
143
+ it 'warns' do
144
+ expect { subject }.to output(
145
+ /is optional but default value is not specified/
146
+ ).to_stderr
107
147
  end
108
148
  end
109
149
  end
@@ -61,7 +61,7 @@ describe Apipie::SwaggerGenerator do
61
61
  expect(properties).to eq(
62
62
  {
63
63
  a_number: {
64
- type: 'number'
64
+ type: 'number', required: true
65
65
  },
66
66
  an_optional_number: {
67
67
  type: 'number'
@@ -996,7 +996,14 @@
996
996
  "$ref": "http://json-schema.org/draft-04/schema#/definitions/positiveIntegerDefault0"
997
997
  },
998
998
  "required": {
999
- "$ref": "http://json-schema.org/draft-04/schema#/definitions/stringArray"
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"
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.1
4
+ version: 1.2.3
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-06-09 00:00:00.000000000 Z
12
+ date: 2023-10-11 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.11
475
+ rubygems_version: 3.4.18
476
476
  signing_key:
477
477
  specification_version: 4
478
478
  summary: Rails REST API documentation tool