apipie-rails 1.1.0 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/build.yml +12 -48
  3. data/.github/workflows/rubocop-challenger.yml +2 -2
  4. data/.github/workflows/rubocop.yml +2 -4
  5. data/.rubocop.yml +38 -37
  6. data/.rubocop_todo.yml +45 -64
  7. data/.vscode/settings.json +3 -0
  8. data/CHANGELOG.md +11 -2
  9. data/Gemfile +20 -0
  10. data/README.rst +6 -6
  11. data/app/controllers/apipie/apipies_controller.rb +3 -17
  12. data/gemfiles/Gemfile.tools +9 -0
  13. data/lib/apipie/application.rb +18 -7
  14. data/lib/apipie/dsl_definition.rb +1 -1
  15. data/lib/apipie/extractor/collector.rb +1 -1
  16. data/lib/apipie/extractor/recorder.rb +1 -1
  17. data/lib/apipie/generator/swagger/warning.rb +1 -1
  18. data/lib/apipie/resource_description.rb +28 -3
  19. data/lib/apipie/version.rb +1 -1
  20. data/spec/controllers/api/v2/architectures_controller_spec.rb +10 -3
  21. data/spec/controllers/api/v2/empty_middle_controller_spec.rb +23 -0
  22. data/spec/controllers/api/v2/nested/resources_controller_spec.rb +16 -0
  23. data/spec/controllers/api/v2/sub/footguns_controller_spec.rb +19 -0
  24. data/spec/dummy/app/controllers/api/v2/base_controller.rb +6 -0
  25. data/spec/dummy/app/controllers/api/v2/empty_middle_controller.rb +14 -0
  26. data/spec/dummy/app/controllers/api/v2/nested/resources_controller.rb +2 -2
  27. data/spec/dummy/app/controllers/api/v2/sub/footguns_controller.rb +30 -0
  28. data/spec/lib/apipie/apipies_controller_spec.rb +63 -19
  29. data/spec/lib/apipie/extractor/collector_spec.rb +57 -0
  30. metadata +11 -9
  31. data/gemfiles/Gemfile.rails50 +0 -10
  32. data/gemfiles/Gemfile.rails51 +0 -10
  33. data/gemfiles/Gemfile.rails52 +0 -10
  34. data/gemfiles/Gemfile.rails60 +0 -17
  35. data/gemfiles/Gemfile.rails61 +0 -17
  36. data/gemfiles/Gemfile.rails70 +0 -17
data/Gemfile ADDED
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ gemspec path: '.'
6
+
7
+ # use ENV vars, with default value as fallback for local setup
8
+ ruby(ENV['RUBY_VERSION'] || '3.2.2')
9
+ gem 'actionpack', "~> #{ENV['RAILS_VERSION'] || '7.0'}.0"
10
+ gem 'activesupport', "~> #{ENV['RAILS_VERSION'] || '7.0'}.0"
11
+
12
+ gem 'mime-types' # , '~> 3.0'
13
+ gem 'rails-controller-testing'
14
+ gem 'rspec-rails' # , '~> 5.0'
15
+
16
+ # net-smtp not included by default in Ruby 3.1
17
+ # Will be fixed by https://github.com/mikel/mail/pull/1439
18
+ gem 'net-smtp', require: false if Gem.ruby_version >= Gem::Version.new('3.1.0')
19
+
20
+ gem 'test_engine', path: './spec/dummy/components/test_engine', group: :test
data/README.rst CHANGED
@@ -108,6 +108,10 @@ resource_id
108
108
  name
109
109
  Human readable name of resource. By default ``class.name.humanize`` is used.
110
110
 
111
+ - Can be specified as a proc, which will receive the controller class as an argument.
112
+ - Can be a symbol, which will be sent to the controller class to get the name.
113
+ - Can be a string, which will be used as is.
114
+
111
115
  short (also short_description)
112
116
  Short description of the resource (it's shown on both the list of resources, and resource details)
113
117
 
@@ -1180,7 +1184,7 @@ Here is an example of how to rescue and process a +ParamMissing+ or
1180
1184
  +ParamInvalid+ error from within the ApplicationController.
1181
1185
 
1182
1186
  .. code:: ruby
1183
-
1187
+
1184
1188
  class ApplicationController < ActionController::Base
1185
1189
 
1186
1190
  # ParamError is superclass of ParamMissing, ParamInvalid
@@ -1925,14 +1929,10 @@ And if you write one on your own, don't hesitate to share it with us!
1925
1929
  Contributing
1926
1930
  ====================
1927
1931
 
1928
- Since this gem does not have a Gemfile, you need to specify it in your shell with:
1929
-
1930
- .. code:: shell
1931
- BUNDLE_GEMFILE='gemfiles/Gemfile.rails61'
1932
-
1933
1932
  Then, you can install dependencies and run the test suite:
1934
1933
 
1935
1934
  .. code:: shell
1935
+
1936
1936
  > bundle install
1937
1937
  > bundle exec rspec
1938
1938
 
@@ -154,26 +154,12 @@ module Apipie
154
154
 
155
155
  def render_from_cache
156
156
  path = Apipie.configuration.doc_base_url.dup
157
- # some params can contain dot, but only one in row
158
- if [:resource, :method, :format, :version].any? { |p| params[p].to_s.gsub(".", "") =~ /\W/ || params[p].to_s.include?('..') }
159
- head :bad_request and return
160
- end
161
-
162
157
  path << "/" << params[:version] if params[:version].present?
163
158
  path << "/" << params[:resource] if params[:resource].present?
164
159
  path << "/" << params[:method] if params[:method].present?
165
- if params[:format].present?
166
- path << ".#{params[:format]}"
167
- else
168
- path << ".html"
169
- end
170
-
171
- # we sanitize the params before so in ideal case, this condition
172
- # will be never satisfied. It's here for cases somebody adds new
173
- # param into the path later and forgets about sanitation.
174
- if path.include?('..')
175
- head :bad_request and return
176
- end
160
+ # Sanitize path against directory traversal attacks (e.g. ../../foo)
161
+ # by turning path into an absolute path before appending it to the cache dir
162
+ path = File.expand_path("#{path}.#{request.format.symbol}", '/')
177
163
 
178
164
  cache_file = File.join(Apipie.configuration.cache_dir, path)
179
165
  if File.exist?(cache_file)
@@ -0,0 +1,9 @@
1
+ # This Gemfile is used for IDEs like VS Code that need specific gems installed
2
+ # for their tools to work properly. It is not used for the application itself.
3
+
4
+ source 'https://rubygems.org'
5
+
6
+ gem 'rubocop-rails'
7
+ gem 'rubocop-rspec'
8
+ gem 'rubocop-performance'
9
+ gem 'ruby-lsp', '~> 0.5.1'
@@ -122,15 +122,26 @@ module Apipie
122
122
  # resource_description? It's used to derivate the default value of
123
123
  # versions for methods.
124
124
  def controller_versions(controller)
125
- ret = @controller_versions[controller.to_s]
126
- return ret unless ret.empty?
127
- if controller == ActionController::Base || controller.nil?
128
- return [Apipie.configuration.default_version]
129
- else
130
- return controller_versions(controller.to_s.constantize.superclass)
125
+ value_from_parents(controller, default: [Apipie.configuration.default_version]) do |c|
126
+ ret = @controller_versions[c.to_s]
127
+ ret unless ret.empty?
131
128
  end
132
129
  end
133
130
 
131
+ # Recursively walks up the controller hierarchy looking for a value
132
+ # from the block.
133
+ # Stops at ActionController::Base.
134
+ # @param [Class] controller controller to start from
135
+ # @param [Array] args arguments passed to the block
136
+ # @param [Object] default default value to return if no value is found
137
+ # @param [Proc] block block to call with controller and args
138
+ def value_from_parents(controller, *args, default: nil, &block)
139
+ return default if controller == ActionController::Base || controller == AbstractController::Base || controller.nil?
140
+
141
+ thing = yield(controller, *args)
142
+ thing || value_from_parents(controller.superclass, *args, default: default, &block)
143
+ end
144
+
134
145
  def set_controller_versions(controller, versions)
135
146
  @controller_versions[controller.to_s] = versions
136
147
  end
@@ -443,7 +454,7 @@ module Apipie
443
454
  end
444
455
 
445
456
  def version_prefix(klass)
446
- version = controller_versions(klass.to_s).first
457
+ version = controller_versions(klass).first
447
458
  base_url = get_base_url(version)
448
459
  return "/" if base_url.blank?
449
460
  base_url[1..-1] + "/"
@@ -259,7 +259,7 @@ module Apipie
259
259
  if Apipie.configuration.validate_key?
260
260
  params.reject{|k,_| %w[format controller action].include?(k.to_s) }.each_pair do |param, _|
261
261
  # params allowed
262
- if method_params.select {|_,p| p.name.to_s == param.to_s}.empty?
262
+ if method_params.none? {|_,p| p.name.to_s == param.to_s}
263
263
  self.class._apipie_handle_validate_key_error params, param
264
264
  end
265
265
  end
@@ -19,7 +19,7 @@ module Apipie
19
19
  def ignore_call?(record)
20
20
  return true unless record[:controller]
21
21
  return true if @ignored.include?(record[:controller].name)
22
- return true if @ignored.include?("#{Apipie.resource_id(record[:controller].name)}##{record[:action]}")
22
+ return true if @ignored.include?("#{Apipie.get_resource_id(record[:controller].name)}##{record[:action]}")
23
23
  return true unless @api_controllers_paths.include?(controller_full_path(record[:controller]))
24
24
  end
25
25
 
@@ -48,7 +48,7 @@ module Apipie
48
48
  else
49
49
  @query = request.query_string
50
50
  end
51
- if response.content_type != 'application/pdf'
51
+ if response.media_type != 'application/pdf'
52
52
  @response_data = parse_data(response.body)
53
53
  end
54
54
  @code = response.code
@@ -59,7 +59,7 @@ class Apipie::Generator::Swagger::Warning
59
59
  #
60
60
  # @return [Apipie::Generator::Swagger::Warning]
61
61
  def self.for_code(code, method_id, message_attributes = {})
62
- if !CODES.values.include?(code)
62
+ if !CODES.value?(code)
63
63
  raise ArgumentError, 'Unknown warning code'
64
64
  end
65
65
 
@@ -26,7 +26,9 @@ module Apipie
26
26
  @controller = controller
27
27
  @_id = id
28
28
  @_version = version || Apipie.configuration.default_version
29
- @_parent = Apipie.get_resource_description(controller.superclass, version)
29
+ @_parent = Apipie.value_from_parents(controller.superclass, version) do |parent, ver|
30
+ Apipie.get_resource_description(parent, ver)
31
+ end
30
32
 
31
33
  update_from_dsl_data(dsl_data) if dsl_data
32
34
  end
@@ -60,7 +62,16 @@ module Apipie
60
62
  end
61
63
 
62
64
  def name
63
- @name ||= @_resource_name.presence || @_id.split('-').map(&:capitalize).join('::')
65
+ @name ||= case resource_name
66
+ when Proc
67
+ resource_name.call(controller)
68
+ when Symbol
69
+ controller.public_send(resource_name)
70
+ when String
71
+ resource_name
72
+ else
73
+ default_name
74
+ end
64
75
  end
65
76
  alias _name name
66
77
 
@@ -90,7 +101,9 @@ module Apipie
90
101
  Apipie.full_url crumbs.join('/')
91
102
  end
92
103
 
93
- def api_url; "#{Apipie.api_base_url(_version)}#{@_path}"; end
104
+ def api_url
105
+ "#{Apipie.api_base_url(_version)}#{@_path}"
106
+ end
94
107
 
95
108
  def valid_method_name?(method_name)
96
109
  @_methods.keys.map(&:to_s).include?(method_name.to_s)
@@ -123,5 +136,17 @@ module Apipie
123
136
  }
124
137
  end
125
138
 
139
+ protected
140
+
141
+ def resource_name
142
+ @_resource_name.presence || @_parent&.resource_name
143
+ end
144
+
145
+ private
146
+
147
+ def default_name
148
+ @_id.split('-').map(&:capitalize).join('::')
149
+ end
150
+
126
151
  end
127
152
  end
@@ -1,3 +1,3 @@
1
1
  module Apipie
2
- VERSION = "1.1.0"
2
+ VERSION = "1.2.0"
3
3
  end
@@ -1,12 +1,19 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Api::V2::ArchitecturesController do
4
+ let(:resource_description) { Apipie.get_resource_description(described_class, "2.0") }
5
+
4
6
  describe "resource description" do
5
- subject { Apipie.get_resource_description(Api::V2::ArchitecturesController, "2.0") }
7
+ describe 'version' do
8
+ subject { resource_description._version }
6
9
 
7
- it "should be version 2.0" do
8
- expect(subject._version).to eq('2.0')
10
+ it { is_expected.to eq('2.0') }
9
11
  end
10
12
 
13
+ describe 'name' do
14
+ subject { resource_description.name }
15
+
16
+ it { is_expected.to eq('Architectures') }
17
+ end
11
18
  end
12
19
  end
@@ -0,0 +1,23 @@
1
+ require 'spec_helper'
2
+
3
+ describe Api::V2::EmptyMiddleController do
4
+ let(:resource_description) { Apipie.get_resource_description(described_class, '2.0') }
5
+
6
+ describe 'resource description' do
7
+ subject { resource_description }
8
+
9
+ context 'when namespaced resources are enabled' do
10
+ before { Apipie.configuration.namespaced_resources = true }
11
+ after { Apipie.configuration.namespaced_resources = false }
12
+
13
+ # we don't actually expect the resource description to be nil, but resource IDs
14
+ # are computed at file load time, and altering the value of namespaced_resources
15
+ # after the fact doesn't change the resource ID, so it can't be found
16
+ it { is_expected.to be_nil }
17
+ end
18
+
19
+ context 'when namespaced resources are disabled' do
20
+ it { is_expected.to be_nil }
21
+ end
22
+ end
23
+ end
@@ -1,6 +1,22 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe Api::V2::Nested::ResourcesController do
4
+ let(:resource_description) { Apipie.get_resource_description(described_class, "2.0") }
5
+
6
+ describe "resource description" do
7
+ describe 'version' do
8
+ subject { resource_description._version }
9
+
10
+ it { is_expected.to eq('2.0') }
11
+ end
12
+
13
+ describe 'name' do
14
+ subject { resource_description.name }
15
+
16
+ it { is_expected.to eq('Rsrcs') }
17
+ end
18
+ end
19
+
4
20
  describe '.get_resource_id' do
5
21
  subject { Apipie.get_resource_id(Api::V2::Nested::ResourcesController) }
6
22
 
@@ -0,0 +1,19 @@
1
+ require 'spec_helper'
2
+
3
+ describe Api::V2::Sub::FootgunsController do
4
+ let(:resource_description) { Apipie.get_resource_description(described_class, '2.0') }
5
+
6
+ describe 'resource description' do
7
+ describe 'version' do
8
+ subject { resource_description._version }
9
+
10
+ it { is_expected.to eq('2.0') }
11
+ end
12
+
13
+ describe 'name' do
14
+ subject { resource_description.name }
15
+
16
+ it { is_expected.to eq('snugtooF') }
17
+ end
18
+ end
19
+ end
@@ -5,6 +5,12 @@ module Api
5
5
  api_version '2.0'
6
6
  app_info 'Version 2.0 description'
7
7
  api_base_url '/api/v2'
8
+
9
+ name :reversed_name
10
+ end
11
+
12
+ def self.reversed_name
13
+ controller_name.capitalize.reverse
8
14
  end
9
15
  end
10
16
  end
@@ -0,0 +1,14 @@
1
+ module Api
2
+ module V2
3
+ class EmptyMiddleController < V2::BaseController
4
+ # This is an empty controller, used to test cases where controllers
5
+ # may inherit from a middle controler that does not define a resource_description,
6
+ # but the middle controller's parent does.
7
+
8
+ def inconsequential_method
9
+ # This method is here to ensure that the controller is not empty.
10
+ # It triggers method_added, which is used to add the resource description.
11
+ end
12
+ end
13
+ end
14
+ end
@@ -1,8 +1,8 @@
1
1
  module Api
2
2
  module V2
3
3
  class Nested::ResourcesController < V2::BaseController
4
- resource_description do
5
- name 'Resources'
4
+ resource_description do
5
+ name ->(controller) { controller.controller_name.delete('aeiou').capitalize }
6
6
  resource_id "resource"
7
7
  end
8
8
  api :GET, "/nested/resources/", "List all nested resources."
@@ -0,0 +1,30 @@
1
+ module Api
2
+ module V2
3
+ module Sub
4
+ class FootgunsController < V2::EmptyMiddleController
5
+ resource_description do
6
+ short 'Footguns are bad'
7
+ end
8
+
9
+ api :GET, '/footguns/', 'List all footguns.'
10
+ def index; end
11
+
12
+ api :GET, '/footguns/:id/', 'Show a footgun.'
13
+ def show; end
14
+
15
+ api :POST, '/footguns/', 'Create a footgun.'
16
+ def create; end
17
+
18
+ api :PUT, '/footguns/:id/', 'Update a footgun.'
19
+ param :footgun, Hash, :required => true do
20
+ param :name, String
21
+ end
22
+ def update; end
23
+
24
+ api! 'Delete a footgun.'
25
+ api_version '2.0' # forces removal of the method description
26
+ def destroy; end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -258,12 +258,12 @@ describe Apipie::ApipiesController, type: :controller do
258
258
 
259
259
  before do
260
260
  FileUtils.rm_r(cache_dir) if File.exist?(cache_dir)
261
- FileUtils.mkdir_p(File.join(cache_dir, "apidoc", "v1", "resource"))
261
+ FileUtils.mkdir_p(File.join(cache_dir, "apidoc", "v1", "resource-with-namespace"))
262
262
  File.open(File.join(cache_dir, "apidoc", "v1.html"), "w") { |f| f << "apidoc.html cache v1" }
263
263
  File.open(File.join(cache_dir, "apidoc", "v2.html"), "w") { |f| f << "apidoc.html cache v2" }
264
264
  File.open(File.join(cache_dir, "apidoc", "v1.json"), "w") { |f| f << "apidoc.json cache" }
265
- File.open(File.join(cache_dir, "apidoc", "v1", "resource.html"), "w") { |f| f << "resource.html cache" }
266
- File.open(File.join(cache_dir, "apidoc", "v1", "resource", "method.html"), "w") { |f| f << "method.html cache" }
265
+ File.open(File.join(cache_dir, "apidoc", "v1", "resource-with-namespace.html"), "w") { |f| f << "resource-with-namespace.html cache" }
266
+ File.open(File.join(cache_dir, "apidoc", "v1", "resource-with-namespace", "method.html"), "w") { |f| f << "method.html cache" }
267
267
 
268
268
  Apipie.configuration.use_cache = true
269
269
  @orig_cache_dir = Apipie.configuration.cache_dir
@@ -279,24 +279,68 @@ describe Apipie::ApipiesController, type: :controller do
279
279
  # FileUtils.rm_r(cache_dir) if File.exist?(cache_dir)
280
280
  end
281
281
 
282
- it "uses the file in cache dir instead of generating the content on runtime" do
283
- get :index
284
- expect(response.body).to eq("apidoc.html cache v1")
285
- get :index, :params => { :version => 'v1' }
286
- expect(response.body).to eq("apidoc.html cache v1")
287
- get :index, :params => { :version => 'v2' }
288
- expect(response.body).to eq("apidoc.html cache v2")
289
- get :index, :params => { :version => 'v1', :format => "html" }
290
- expect(response.body).to eq("apidoc.html cache v1")
291
- get :index, :params => { :version => 'v1', :format => "json" }
292
- expect(response.body).to eq("apidoc.json cache")
293
- get :index, :params => { :version => 'v1', :format => "html", :resource => "resource" }
294
- expect(response.body).to eq("resource.html cache")
295
- get :index, :params => { :version => 'v1', :format => "html", :resource => "resource", :method => "method" }
296
- expect(response.body).to eq("method.html cache")
282
+ context 'when the file exists' do
283
+ it "uses the file in cache dir instead of generating the content on runtime" do
284
+ get :index
285
+ expect(response.body).to eq("apidoc.html cache v1")
286
+
287
+ get :index, :params => { :version => 'v1' }
288
+ expect(response.body).to eq("apidoc.html cache v1")
289
+
290
+ get :index, :params => { :version => 'v2' }
291
+ expect(response.body).to eq("apidoc.html cache v2")
292
+
293
+ get :index, :params => { :version => 'v1', :format => "html" }
294
+ expect(response.body).to eq("apidoc.html cache v1")
295
+
296
+ get :index, :params => { :version => 'v1', :format => "json" }
297
+ expect(response.body).to eq("apidoc.json cache")
298
+
299
+ get :index, :params => { :version => 'v1', :format => "html", :resource => "resource-with-namespace" }
300
+ expect(response.body).to eq("resource-with-namespace.html cache")
301
+
302
+ get :index, :params => { :version => 'v1', :format => "html", :resource => "resource-with-namespace", :method => "method" }
303
+ expect(response.body).to eq("method.html cache")
304
+ end
297
305
  end
298
306
 
299
- end
307
+ context 'when the file does not exist' do
308
+ it 'returns a not found' do
309
+ get :index, :params => { :version => 'v3-does-not-exist' }
310
+ expect(response).to have_http_status(:not_found)
311
+ end
312
+ end
313
+
314
+ context 'preventing path traversal' do
315
+ context 'when resource contains ..' do
316
+ it "returns a not found" do
317
+ get :index, :params => { :version => 'v1', :format => "html", :resource => "../resource-with-namespace", :method => "method" }
318
+ expect(response).to have_http_status(:not_found)
319
+ end
320
+ end
300
321
 
322
+ context 'when method contains ..' do
323
+ it "returns a not found" do
324
+ get :index, :params => { :version => 'v1', :format => "html", :resource => "resource-with-namespace", :method => "../method" }
325
+ expect(response).to have_http_status(:not_found)
326
+ end
327
+ end
328
+
329
+ context 'when version contains ..' do
330
+ it "returns a not found" do
331
+ get :index, :params => { :version => '../v1', :format => "html", :resource => "resource-with-namespace", :method => "method" }
332
+ expect(response).to have_http_status(:not_found)
333
+ end
334
+ end
335
+
336
+ context 'when format contains ..' do
337
+ it "returns a not found" do
338
+ get :index, :params => { :version => 'v1', :format => "../html", :resource => "resource-with-namespace", :method => "method" }
339
+ expect(response).to have_http_status(:not_found)
340
+ end
341
+ end
342
+ end
343
+
344
+ end
301
345
 
302
346
  end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+
5
+ describe Apipie::Extractor::Collector do
6
+ let(:recorder) { described_class.new }
7
+
8
+ describe '#ignore_call?' do
9
+ subject { recorder.ignore_call?(record) }
10
+
11
+ let(:record) { { controller: controller, action: action } }
12
+ let(:controller) { ActionController::Base }
13
+ let(:action) { nil }
14
+
15
+ context 'when controller is nil' do
16
+ let(:controller) { nil }
17
+
18
+ it { is_expected.to be true }
19
+ end
20
+
21
+ context 'when controller is ignored' do
22
+ before do
23
+ allow(Apipie.configuration).to receive(:ignored_by_recorder).and_return(['ActionController::Bas'])
24
+ end
25
+
26
+ it { is_expected.to be true }
27
+ end
28
+
29
+ context 'when resource#method is ignored' do
30
+ let(:action) { 'ignored_action' }
31
+
32
+ before do
33
+ allow(Apipie.configuration).to receive(:ignored_by_recorder).and_return(['ActionController::Bas#ignored_action'])
34
+ end
35
+
36
+ it { is_expected.to be true }
37
+ end
38
+
39
+ context 'when controller is not an API controller' do
40
+ before do
41
+ allow(Apipie::Extractor).to receive(:controller_path).with('action_controller/base').and_return('foo')
42
+ allow(Apipie).to receive(:api_controllers_paths).and_return([])
43
+ end
44
+
45
+ it { is_expected.to be true }
46
+ end
47
+
48
+ context 'when controller is an API controller' do
49
+ before do
50
+ allow(Apipie::Extractor).to receive(:controller_path).with('action_controller/base').and_return('foo')
51
+ allow(Apipie).to receive(:api_controllers_paths).and_return(['foo'])
52
+ end
53
+
54
+ it { is_expected.to be_falsey }
55
+ end
56
+ end
57
+ 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.1.0
4
+ version: 1.2.0
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-05-16 00:00:00.000000000 Z
12
+ date: 2023-06-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: actionpack
@@ -208,8 +208,10 @@ files:
208
208
  - ".rspec"
209
209
  - ".rubocop.yml"
210
210
  - ".rubocop_todo.yml"
211
+ - ".vscode/settings.json"
211
212
  - APACHE-LICENSE-2.0
212
213
  - CHANGELOG.md
214
+ - Gemfile
213
215
  - MIT-LICENSE
214
216
  - NOTICE
215
217
  - PROPOSAL_FOR_RESPONSE_DESCRIPTIONS.md
@@ -258,12 +260,7 @@ files:
258
260
  - config/locales/tr.yml
259
261
  - config/locales/zh-CN.yml
260
262
  - config/locales/zh-TW.yml
261
- - gemfiles/Gemfile.rails50
262
- - gemfiles/Gemfile.rails51
263
- - gemfiles/Gemfile.rails52
264
- - gemfiles/Gemfile.rails60
265
- - gemfiles/Gemfile.rails61
266
- - gemfiles/Gemfile.rails70
263
+ - gemfiles/Gemfile.tools
267
264
  - images/screenshot-1.png
268
265
  - images/screenshot-2.png
269
266
  - lib/apipie-rails.rb
@@ -342,7 +339,9 @@ files:
342
339
  - rel-eng/tito.props
343
340
  - spec/controllers/api/v1/architectures_controller_spec.rb
344
341
  - spec/controllers/api/v2/architectures_controller_spec.rb
342
+ - spec/controllers/api/v2/empty_middle_controller_spec.rb
345
343
  - spec/controllers/api/v2/nested/resources_controller_spec.rb
344
+ - spec/controllers/api/v2/sub/footguns_controller_spec.rb
346
345
  - spec/controllers/concerns_controller_spec.rb
347
346
  - spec/controllers/extended_controller_spec.rb
348
347
  - spec/controllers/included_param_group_controller_spec.rb
@@ -354,8 +353,10 @@ files:
354
353
  - spec/dummy/app/controllers/api/v1/base_controller.rb
355
354
  - spec/dummy/app/controllers/api/v2/architectures_controller.rb
356
355
  - spec/dummy/app/controllers/api/v2/base_controller.rb
356
+ - spec/dummy/app/controllers/api/v2/empty_middle_controller.rb
357
357
  - spec/dummy/app/controllers/api/v2/nested/architectures_controller.rb
358
358
  - spec/dummy/app/controllers/api/v2/nested/resources_controller.rb
359
+ - spec/dummy/app/controllers/api/v2/sub/footguns_controller.rb
359
360
  - spec/dummy/app/controllers/application_controller.rb
360
361
  - spec/dummy/app/controllers/concerns_controller.rb
361
362
  - spec/dummy/app/controllers/extended_controller.rb
@@ -408,6 +409,7 @@ files:
408
409
  - spec/lib/apipie/apipies_controller_spec.rb
409
410
  - spec/lib/apipie/application_spec.rb
410
411
  - spec/lib/apipie/configuration_spec.rb
412
+ - spec/lib/apipie/extractor/collector_spec.rb
411
413
  - spec/lib/apipie/extractor/recorder/middleware_spec.rb
412
414
  - spec/lib/apipie/extractor/recorder_spec.rb
413
415
  - spec/lib/apipie/extractor/writer_spec.rb
@@ -470,7 +472,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
470
472
  - !ruby/object:Gem::Version
471
473
  version: '0'
472
474
  requirements: []
473
- rubygems_version: 3.1.6
475
+ rubygems_version: 3.4.11
474
476
  signing_key:
475
477
  specification_version: 4
476
478
  summary: Rails REST API documentation tool
@@ -1,10 +0,0 @@
1
- source "https://rubygems.org"
2
-
3
- gemspec path: '..'
4
-
5
- gem 'actionpack', '~> 5.0.0'
6
- gem 'activesupport', '~> 5.0.0'
7
- gem 'mime-types', '~> 2.99.3'
8
- gem 'rails-controller-testing'
9
-
10
- gem 'test_engine', path: '../spec/dummy/components/test_engine', group: :test