apipie-rails 1.1.0 → 1.2.0

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.
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