apipie-rails 0.5.19 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/build.yml +31 -0
- data/.github/workflows/rubocop-challenger.yml +28 -0
- data/.github/workflows/rubocop.yml +18 -0
- data/.gitignore +1 -0
- data/.rubocop.yml +128 -0
- data/.rubocop_todo.yml +2056 -0
- data/.vscode/settings.json +3 -0
- data/CHANGELOG.md +161 -0
- data/Gemfile +20 -0
- data/README.rst +117 -23
- data/Rakefile +0 -5
- data/apipie-rails.gemspec +18 -9
- data/app/controllers/apipie/apipies_controller.rb +14 -29
- data/app/helpers/apipie_helper.rb +1 -1
- data/app/public/apipie/javascripts/bundled/bootstrap-collapse.js +70 -41
- data/app/public/apipie/javascripts/bundled/bootstrap.js +1033 -479
- data/app/public/apipie/javascripts/bundled/jquery.js +5 -5
- data/app/public/apipie/stylesheets/bundled/bootstrap-responsive.min.css +9 -12
- data/app/public/apipie/stylesheets/bundled/bootstrap.min.css +9 -689
- data/app/views/apipie/apipies/_deprecation.html.erb +16 -0
- data/app/views/apipie/apipies/_params.html.erb +7 -1
- data/config/locales/en.yml +8 -0
- data/config/locales/ko.yml +31 -0
- data/gemfiles/Gemfile.tools +9 -0
- data/lib/apipie/apipie_module.rb +7 -7
- data/lib/apipie/application.rb +132 -97
- data/lib/apipie/configuration.rb +43 -33
- data/lib/apipie/dsl_definition.rb +44 -33
- data/lib/apipie/error_description.rb +3 -3
- data/lib/apipie/errors.rb +17 -17
- data/lib/apipie/extractor/collector.rb +5 -6
- data/lib/apipie/extractor/recorder.rb +35 -8
- data/lib/apipie/extractor/writer.rb +15 -15
- data/lib/apipie/extractor.rb +6 -9
- data/lib/apipie/generator/config.rb +12 -0
- data/lib/apipie/generator/generator.rb +2 -0
- data/lib/apipie/generator/swagger/computed_interface_id.rb +23 -0
- data/lib/apipie/generator/swagger/config.rb +80 -0
- data/lib/apipie/generator/swagger/context.rb +38 -0
- data/lib/apipie/generator/swagger/method_description/api_decorator.rb +20 -0
- data/lib/apipie/generator/swagger/method_description/api_schema_service.rb +89 -0
- data/lib/apipie/generator/swagger/method_description/decorator.rb +22 -0
- data/lib/apipie/generator/swagger/method_description/parameters_service.rb +139 -0
- data/lib/apipie/generator/swagger/method_description/response_schema_service.rb +46 -0
- data/lib/apipie/generator/swagger/method_description/response_service.rb +58 -0
- data/lib/apipie/generator/swagger/method_description.rb +2 -0
- data/lib/apipie/generator/swagger/operation_id.rb +51 -0
- data/lib/apipie/generator/swagger/param_description/builder.rb +114 -0
- data/lib/apipie/generator/swagger/param_description/composite.rb +119 -0
- data/lib/apipie/generator/swagger/param_description/description.rb +15 -0
- data/lib/apipie/generator/swagger/param_description/in.rb +37 -0
- data/lib/apipie/generator/swagger/param_description/name.rb +18 -0
- data/lib/apipie/generator/swagger/param_description/path_params_composite.rb +61 -0
- data/lib/apipie/generator/swagger/param_description/referenced_composite.rb +36 -0
- data/lib/apipie/generator/swagger/param_description/type.rb +128 -0
- data/lib/apipie/generator/swagger/param_description.rb +18 -0
- data/lib/apipie/generator/swagger/path_decorator.rb +36 -0
- data/lib/apipie/generator/swagger/referenced_definitions.rb +17 -0
- data/lib/apipie/generator/swagger/resource_description_collection.rb +30 -0
- data/lib/apipie/generator/swagger/resource_description_composite.rb +56 -0
- data/lib/apipie/generator/swagger/schema.rb +63 -0
- data/lib/apipie/generator/swagger/swagger.rb +2 -0
- data/lib/apipie/generator/swagger/type.rb +16 -0
- data/lib/apipie/generator/swagger/type_extractor.rb +51 -0
- data/lib/apipie/generator/swagger/warning.rb +74 -0
- data/lib/apipie/generator/swagger/warning_writer.rb +54 -0
- data/lib/apipie/helpers.rb +3 -3
- data/lib/apipie/markup.rb +9 -8
- data/lib/apipie/method_description/api.rb +12 -0
- data/lib/apipie/method_description/apis_service.rb +82 -0
- data/lib/apipie/method_description.rb +12 -56
- data/lib/apipie/param_description/deprecation.rb +24 -0
- data/lib/apipie/param_description.rb +57 -24
- data/lib/apipie/resource_description.rb +42 -14
- data/lib/apipie/response_description.rb +3 -3
- data/lib/apipie/response_description_adapter.rb +12 -10
- data/lib/apipie/routing.rb +1 -1
- data/lib/apipie/rspec/response_validation_helper.rb +3 -3
- data/lib/apipie/static_dispatcher.rb +10 -2
- data/lib/apipie/swagger_generator.rb +28 -691
- data/lib/apipie/validator.rb +41 -11
- data/lib/apipie/version.rb +1 -1
- data/lib/apipie-rails.rb +36 -5
- data/lib/generators/apipie/install/install_generator.rb +1 -1
- data/lib/generators/apipie/views_generator.rb +1 -1
- data/lib/tasks/apipie.rake +37 -32
- data/rel-eng/gem_release.ipynb +41 -9
- data/spec/controllers/api/v2/architectures_controller_spec.rb +10 -3
- data/spec/controllers/api/v2/empty_middle_controller_spec.rb +23 -0
- data/spec/controllers/api/v2/nested/resources_controller_spec.rb +18 -2
- data/spec/controllers/api/v2/sub/footguns_controller_spec.rb +19 -0
- data/spec/controllers/included_param_group_controller_spec.rb +13 -0
- data/spec/{lib/swagger/response_validation_spec.rb → controllers/pets_controller_spec.rb} +26 -32
- data/spec/controllers/users_controller_spec.rb +47 -6
- data/spec/dummy/Rakefile +1 -1
- data/spec/dummy/app/controllers/api/v2/architectures_controller.rb +2 -1
- data/spec/dummy/app/controllers/api/v2/base_controller.rb +6 -0
- data/spec/dummy/app/controllers/api/v2/empty_middle_controller.rb +14 -0
- data/spec/dummy/app/controllers/api/v2/nested/resources_controller.rb +2 -2
- data/spec/dummy/app/controllers/api/v2/sub/footguns_controller.rb +30 -0
- data/spec/dummy/app/controllers/concerns_controller.rb +1 -1
- data/spec/dummy/app/controllers/{concerns/extending_concern.rb → extending_concern.rb} +0 -2
- data/spec/dummy/app/controllers/included_param_group_controller.rb +19 -0
- data/spec/dummy/app/controllers/overridden_concerns_controller.rb +2 -2
- data/spec/dummy/app/controllers/pets_controller.rb +5 -5
- data/spec/dummy/app/controllers/pets_using_self_describing_classes_controller.rb +2 -2
- data/spec/dummy/app/controllers/{concerns/sample_controller.rb → sample_controller.rb} +0 -2
- data/spec/dummy/app/controllers/twitter_example_controller.rb +2 -2
- data/spec/dummy/app/controllers/users_controller.rb +17 -5
- data/spec/dummy/app/helpers/random_param_group.rb +8 -0
- data/spec/dummy/components/test_engine/test_engine.gemspec +1 -1
- data/spec/dummy/config/application.rb +2 -5
- data/spec/dummy/config/boot.rb +2 -2
- data/spec/dummy/config/environment.rb +1 -1
- data/spec/dummy/config/environments/development.rb +0 -3
- data/spec/dummy/config/environments/production.rb +0 -3
- data/spec/dummy/config/environments/test.rb +0 -5
- data/spec/dummy/config/initializers/apipie.rb +2 -2
- data/spec/dummy/config/routes.rb +8 -0
- data/spec/dummy/config.ru +1 -1
- data/spec/dummy/script/rails +2 -2
- data/spec/{controllers → lib/apipie}/apipies_controller_spec.rb +95 -23
- data/spec/lib/apipie/application_spec.rb +62 -0
- data/spec/lib/apipie/configuration_spec.rb +38 -0
- data/spec/lib/apipie/extractor/collector_spec.rb +57 -0
- data/spec/lib/apipie/extractor/recorder_spec.rb +77 -0
- data/spec/lib/{extractor → apipie/extractor}/writer_spec.rb +8 -6
- data/spec/lib/{extractor → apipie}/extractor_spec.rb +1 -1
- data/spec/lib/{file_handler_spec.rb → apipie/file_handler_spec.rb} +7 -0
- data/spec/lib/apipie/generator/swagger/config_spec.rb +19 -0
- data/spec/lib/apipie/generator/swagger/context_spec.rb +56 -0
- data/spec/lib/apipie/generator/swagger/method_description/api_schema_service_spec.rb +119 -0
- data/spec/lib/apipie/generator/swagger/method_description/response_schema_service_spec.rb +105 -0
- data/spec/lib/apipie/generator/swagger/operation_id_spec.rb +63 -0
- data/spec/lib/apipie/generator/swagger/param_description/builder_spec.rb +215 -0
- data/spec/lib/apipie/generator/swagger/param_description/composite_spec.rb +95 -0
- data/spec/lib/apipie/generator/swagger/param_description/description_spec.rb +79 -0
- data/spec/lib/apipie/generator/swagger/param_description/in_spec.rb +86 -0
- data/spec/lib/apipie/generator/swagger/param_description/name_spec.rb +81 -0
- data/spec/lib/apipie/generator/swagger/param_description/type_spec.rb +183 -0
- data/spec/lib/apipie/generator/swagger/param_description_spec.rb +28 -0
- data/spec/lib/apipie/generator/swagger/path_decorator_spec.rb +57 -0
- data/spec/lib/apipie/generator/swagger/referenced_definitions_spec.rb +35 -0
- data/spec/lib/apipie/generator/swagger/resource_description_composite_spec.rb +37 -0
- data/spec/lib/apipie/generator/swagger/resource_descriptions_collection_spec.rb +57 -0
- data/spec/lib/apipie/generator/swagger/schema_spec.rb +89 -0
- data/spec/lib/apipie/generator/swagger/type_extractor_spec.rb +38 -0
- data/spec/lib/apipie/generator/swagger/warning_spec.rb +51 -0
- data/spec/lib/apipie/generator/swagger/warning_writer_spec.rb +71 -0
- data/spec/lib/apipie/method_description/apis_service_spec.rb +60 -0
- data/spec/lib/apipie/method_description_spec.rb +133 -0
- data/spec/lib/apipie/no_documented_method_spec.rb +17 -0
- data/spec/lib/apipie/param_description/deprecation_spec.rb +31 -0
- data/spec/lib/{param_description_spec.rb → apipie/param_description_spec.rb} +332 -6
- data/spec/lib/{param_group_spec.rb → apipie/param_group_spec.rb} +6 -5
- data/spec/lib/apipie/resource_description_spec.rb +91 -0
- data/spec/lib/apipie/response_does_not_match_swagger_schema_spec.rb +35 -0
- data/spec/lib/apipie/swagger_generator_spec.rb +94 -0
- data/spec/lib/{validator_spec.rb → apipie/validator_spec.rb} +48 -12
- data/spec/lib/rake_spec.rb +3 -5
- data/spec/lib/swagger/openapi_2_0_schema.json +8 -1
- data/spec/lib/swagger/rake_swagger_spec.rb +30 -10
- data/spec/lib/swagger/swagger_dsl_spec.rb +18 -12
- data/spec/lib/validators/array_validator_spec.rb +1 -1
- data/spec/spec_helper.rb +10 -32
- data/spec/support/custom_bool_validator.rb +17 -0
- data/spec/{controllers → test_engine}/memes_controller_spec.rb +1 -1
- metadata +173 -125
- data/.travis.yml +0 -41
- data/Gemfile +0 -1
- data/Gemfile.rails41 +0 -7
- data/Gemfile.rails42 +0 -14
- data/Gemfile.rails50 +0 -9
- data/Gemfile.rails51 +0 -9
- data/Gemfile.rails60 +0 -10
- data/Gemfile.rails61 +0 -10
- data/spec/lib/application_spec.rb +0 -49
- data/spec/lib/method_description_spec.rb +0 -98
- data/spec/lib/resource_description_spec.rb +0 -48
- /data/spec/lib/{extractor → apipie/extractor/recorder}/middleware_spec.rb +0 -0
@@ -13,9 +13,6 @@ Dummy::Application.configure do
|
|
13
13
|
config.consider_all_requests_local = true
|
14
14
|
config.action_controller.perform_caching = false
|
15
15
|
|
16
|
-
# Don't care if the mailer can't send
|
17
|
-
config.action_mailer.raise_delivery_errors = false
|
18
|
-
|
19
16
|
# Print deprecation notices to the Rails logger
|
20
17
|
config.active_support.deprecation = :log
|
21
18
|
|
@@ -34,9 +34,6 @@ Dummy::Application.configure do
|
|
34
34
|
# Enable serving of images, stylesheets, and javascripts from an asset server
|
35
35
|
# config.action_controller.asset_host = "http://assets.example.com"
|
36
36
|
|
37
|
-
# Disable delivery errors, bad email addresses will be ignored
|
38
|
-
# config.action_mailer.raise_delivery_errors = false
|
39
|
-
|
40
37
|
# Enable threaded mode
|
41
38
|
# config.threadsafe!
|
42
39
|
|
@@ -20,11 +20,6 @@ Dummy::Application.configure do
|
|
20
20
|
# Disable request forgery protection in test environment
|
21
21
|
config.action_controller.allow_forgery_protection = false
|
22
22
|
|
23
|
-
# Tell Action Mailer not to deliver emails to the real world.
|
24
|
-
# The :test delivery method accumulates sent emails in the
|
25
|
-
# ActionMailer::Base.deliveries array.
|
26
|
-
config.action_mailer.delivery_method = :test
|
27
|
-
|
28
23
|
# Use SQL instead of Active Record's schema dumper when creating the test database.
|
29
24
|
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
30
25
|
# like if you have constraints or database-specific column types
|
@@ -23,7 +23,7 @@ Apipie.configure do |config|
|
|
23
23
|
# rake apipie:cache
|
24
24
|
#
|
25
25
|
config.use_cache = Rails.env.production?
|
26
|
-
|
26
|
+
config.cache_dir = File.join(Rails.root, "tmp", "apipie-cache") # optional
|
27
27
|
|
28
28
|
# set to enable/disable reloading controllers (and the documentation with it),
|
29
29
|
# by default enabled in development
|
@@ -89,7 +89,7 @@ class Apipie::Validator::IntegerValidator < Apipie::Validator::BaseValidator
|
|
89
89
|
end
|
90
90
|
|
91
91
|
def self.build(param_description, argument, options, block)
|
92
|
-
if argument == Integer
|
92
|
+
if argument == Integer
|
93
93
|
self.new(param_description, argument)
|
94
94
|
end
|
95
95
|
end
|
data/spec/dummy/config/routes.rb
CHANGED
@@ -8,9 +8,11 @@ Dummy::Application.routes.draw do
|
|
8
8
|
resources :users do
|
9
9
|
collection do
|
10
10
|
post :create_route
|
11
|
+
get :multiple_required_params
|
11
12
|
end
|
12
13
|
end
|
13
14
|
resources :concerns, :only => [:index, :show]
|
15
|
+
get '/:resource_id/:custom_subst' => 'concerns#custom'
|
14
16
|
namespace :files do
|
15
17
|
get '/*file_path', format: false, :action => 'download'
|
16
18
|
end
|
@@ -44,6 +46,12 @@ Dummy::Application.routes.draw do
|
|
44
46
|
get "/pets/returns_response_with_valid_array" => "pets#returns_response_with_valid_array"
|
45
47
|
get "/pets/returns_response_with_invalid_array" => "pets#returns_response_with_invalid_array"
|
46
48
|
get "/pets/undocumented_method" => "pets#undocumented_method"
|
49
|
+
|
50
|
+
# generate 1000 routes for testing performance of route matching used by api! method
|
51
|
+
# it's okay that these don't go anywhere real
|
52
|
+
1000.times do |i|
|
53
|
+
get "/api/v1/pets/#{i}" => "pets#{i}#show"
|
54
|
+
end
|
47
55
|
end
|
48
56
|
|
49
57
|
apipie
|
data/spec/dummy/config.ru
CHANGED
data/spec/dummy/script/rails
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
3
|
|
4
|
-
APP_PATH = File.expand_path('
|
5
|
-
require File.expand_path('
|
4
|
+
APP_PATH = File.expand_path('../config/application', __dir__)
|
5
|
+
require File.expand_path('../config/boot', __dir__)
|
6
6
|
require 'rails/commands'
|
@@ -2,7 +2,7 @@ require 'spec_helper'
|
|
2
2
|
require 'fileutils'
|
3
3
|
require "json-schema"
|
4
4
|
|
5
|
-
describe Apipie::ApipiesController do
|
5
|
+
describe Apipie::ApipiesController, type: :controller do
|
6
6
|
|
7
7
|
describe "GET index" do
|
8
8
|
|
@@ -47,6 +47,30 @@ describe Apipie::ApipiesController do
|
|
47
47
|
|
48
48
|
assert_response :not_found
|
49
49
|
end
|
50
|
+
|
51
|
+
it "succeeds on method details with a supported language" do
|
52
|
+
allow(Apipie.configuration).to receive(:languages).and_return(%w[en es])
|
53
|
+
|
54
|
+
get :index, :params => { :version => "2.0", :resource => "architectures", :method => "index.es" }
|
55
|
+
|
56
|
+
assert_response :success
|
57
|
+
end
|
58
|
+
|
59
|
+
it "succeeds on method details with the default language" do
|
60
|
+
allow(Apipie.configuration).to receive_messages(default_locale: "en", languages: [])
|
61
|
+
|
62
|
+
get :index, :params => { :version => "2.0", :resource => "architectures", :method => "index.en" }
|
63
|
+
|
64
|
+
assert_response :success
|
65
|
+
end
|
66
|
+
|
67
|
+
it "returns not_found on a method with an unsupported language" do
|
68
|
+
allow(Apipie.configuration).to receive(:languages).and_return(%w[en es])
|
69
|
+
|
70
|
+
get :index, :params => { :version => "2.0", :resource => "architectures", :method => "index.jp" }
|
71
|
+
|
72
|
+
assert_response :not_found
|
73
|
+
end
|
50
74
|
end
|
51
75
|
|
52
76
|
describe "reload_controllers" do
|
@@ -134,7 +158,7 @@ describe Apipie::ApipiesController do
|
|
134
158
|
describe "GET index as swagger" do
|
135
159
|
|
136
160
|
let(:swagger_schema) do
|
137
|
-
File.read(
|
161
|
+
File.read("#{Rails.root.parent}/lib/swagger/openapi_2_0_schema.json")
|
138
162
|
end
|
139
163
|
|
140
164
|
it "outputs swagger when format is json and type is swagger" do
|
@@ -184,6 +208,7 @@ describe Apipie::ApipiesController do
|
|
184
208
|
get :index
|
185
209
|
expect(test).to eq(true)
|
186
210
|
end
|
211
|
+
|
187
212
|
it "remove all resources" do
|
188
213
|
Apipie.configuration.authorize = Proc.new do |&args|
|
189
214
|
false
|
@@ -191,6 +216,7 @@ describe Apipie::ApipiesController do
|
|
191
216
|
get :index
|
192
217
|
expect(assigns(:doc)[:resources]).to eq({})
|
193
218
|
end
|
219
|
+
|
194
220
|
it "remove all methods" do
|
195
221
|
Apipie.configuration.authorize = Proc.new do |controller, method, doc|
|
196
222
|
!method
|
@@ -200,6 +226,7 @@ describe Apipie::ApipiesController do
|
|
200
226
|
expect(assigns(:doc)[:resources]["twitter_example"][:methods]).to eq([])
|
201
227
|
expect(assigns(:doc)[:resources]["users"][:methods]).to eq([])
|
202
228
|
end
|
229
|
+
|
203
230
|
it "remove specific method" do
|
204
231
|
Apipie.configuration.authorize = nil
|
205
232
|
get :index
|
@@ -216,6 +243,7 @@ describe Apipie::ApipiesController do
|
|
216
243
|
expect(assigns(:doc)[:resources]["users"][:methods].size).to eq(users_methods - 1)
|
217
244
|
expect(assigns(:doc)[:resources]["twitter_example"][:methods].size).to eq(twitter_example_methods)
|
218
245
|
end
|
246
|
+
|
219
247
|
it "does not allow access to swagger when authorization is set" do
|
220
248
|
get :index, :params => { :format => "json", :type => "swagger"}
|
221
249
|
|
@@ -228,13 +256,13 @@ describe Apipie::ApipiesController do
|
|
228
256
|
let(:cache_dir) { File.join(Rails.root, "tmp", "apipie-cache") }
|
229
257
|
|
230
258
|
before do
|
231
|
-
FileUtils.rm_r(cache_dir) if File.
|
232
|
-
FileUtils.mkdir_p(File.join(cache_dir, "apidoc", "v1", "resource"))
|
259
|
+
FileUtils.rm_r(cache_dir) if File.exist?(cache_dir)
|
260
|
+
FileUtils.mkdir_p(File.join(cache_dir, "apidoc", "v1", "resource-with-namespace"))
|
233
261
|
File.open(File.join(cache_dir, "apidoc", "v1.html"), "w") { |f| f << "apidoc.html cache v1" }
|
234
262
|
File.open(File.join(cache_dir, "apidoc", "v2.html"), "w") { |f| f << "apidoc.html cache v2" }
|
235
263
|
File.open(File.join(cache_dir, "apidoc", "v1.json"), "w") { |f| f << "apidoc.json cache" }
|
236
|
-
File.open(File.join(cache_dir, "apidoc", "v1", "resource.html"), "w") { |f| f << "resource.html cache" }
|
237
|
-
File.open(File.join(cache_dir, "apidoc", "v1", "resource", "method.html"), "w") { |f| f << "method.html cache" }
|
264
|
+
File.open(File.join(cache_dir, "apidoc", "v1", "resource-with-namespace.html"), "w") { |f| f << "resource-with-namespace.html cache" }
|
265
|
+
File.open(File.join(cache_dir, "apidoc", "v1", "resource-with-namespace", "method.html"), "w") { |f| f << "method.html cache" }
|
238
266
|
|
239
267
|
Apipie.configuration.use_cache = true
|
240
268
|
@orig_cache_dir = Apipie.configuration.cache_dir
|
@@ -247,27 +275,71 @@ describe Apipie::ApipiesController do
|
|
247
275
|
Apipie.configuration.use_cache = false
|
248
276
|
Apipie.configuration.default_version = @orig_version
|
249
277
|
Apipie.configuration.cache_dir = @orig_cache_dir
|
250
|
-
# FileUtils.rm_r(cache_dir) if File.
|
278
|
+
# FileUtils.rm_r(cache_dir) if File.exist?(cache_dir)
|
251
279
|
end
|
252
280
|
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
281
|
+
context 'when the file exists' do
|
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
|
+
|
286
|
+
get :index, :params => { :version => 'v1' }
|
287
|
+
expect(response.body).to eq("apidoc.html cache v1")
|
288
|
+
|
289
|
+
get :index, :params => { :version => 'v2' }
|
290
|
+
expect(response.body).to eq("apidoc.html cache v2")
|
291
|
+
|
292
|
+
get :index, :params => { :version => 'v1', :format => "html" }
|
293
|
+
expect(response.body).to eq("apidoc.html cache v1")
|
294
|
+
|
295
|
+
get :index, :params => { :version => 'v1', :format => "json" }
|
296
|
+
expect(response.body).to eq("apidoc.json cache")
|
297
|
+
|
298
|
+
get :index, :params => { :version => 'v1', :format => "html", :resource => "resource-with-namespace" }
|
299
|
+
expect(response.body).to eq("resource-with-namespace.html cache")
|
300
|
+
|
301
|
+
get :index, :params => { :version => 'v1', :format => "html", :resource => "resource-with-namespace", :method => "method" }
|
302
|
+
expect(response.body).to eq("method.html cache")
|
303
|
+
end
|
268
304
|
end
|
269
305
|
|
270
|
-
|
306
|
+
context 'when the file does not exist' do
|
307
|
+
it 'returns a not found' do
|
308
|
+
get :index, :params => { :version => 'v3-does-not-exist' }
|
309
|
+
expect(response).to have_http_status(:not_found)
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
context 'preventing path traversal' do
|
314
|
+
context 'when resource contains ..' do
|
315
|
+
it "returns a not found" do
|
316
|
+
get :index, :params => { :version => 'v1', :format => "html", :resource => "../resource-with-namespace", :method => "method" }
|
317
|
+
expect(response).to have_http_status(:not_found)
|
318
|
+
end
|
319
|
+
end
|
271
320
|
|
321
|
+
context 'when method contains ..' do
|
322
|
+
it "returns a not found" do
|
323
|
+
get :index, :params => { :version => 'v1', :format => "html", :resource => "resource-with-namespace", :method => "../method" }
|
324
|
+
expect(response).to have_http_status(:not_found)
|
325
|
+
end
|
326
|
+
end
|
327
|
+
|
328
|
+
context 'when version contains ..' do
|
329
|
+
it "returns a not found" do
|
330
|
+
get :index, :params => { :version => '../v1', :format => "html", :resource => "resource-with-namespace", :method => "method" }
|
331
|
+
expect(response).to have_http_status(:not_found)
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
context 'when format contains ..' do
|
336
|
+
it "returns a not found" do
|
337
|
+
get :index, :params => { :version => 'v1', :format => "../html", :resource => "resource-with-namespace", :method => "method" }
|
338
|
+
expect(response).to have_http_status(:not_found)
|
339
|
+
end
|
340
|
+
end
|
341
|
+
end
|
342
|
+
|
343
|
+
end
|
272
344
|
|
273
345
|
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Apipie::Application do
|
4
|
+
|
5
|
+
describe "api_controllers_paths" do
|
6
|
+
before do
|
7
|
+
Apipie.configuration.api_controllers_matcher = [File.join(Rails.root, "app", "controllers", "**","*.rb"),
|
8
|
+
File.join(Rails.root, "lib", "**","*.rb")]
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should support receiving array as parameter" do
|
12
|
+
expect { Apipie.api_controllers_paths}.
|
13
|
+
not_to raise_error
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
shared_examples 'resource id' do
|
20
|
+
let(:resource_class) { Api::V2::Nested::ArchitecturesController }
|
21
|
+
let(:base_url) { '/some-api' }
|
22
|
+
|
23
|
+
before { allow(described_class).to receive(:get_base_url).and_return(base_url) }
|
24
|
+
|
25
|
+
context "with namespaced_resources enabled" do
|
26
|
+
before { Apipie.configuration.namespaced_resources = true }
|
27
|
+
after { Apipie.configuration.namespaced_resources = false }
|
28
|
+
|
29
|
+
it "returns the namespaces" do
|
30
|
+
is_expected.to eq('api-v2-nested-architectures')
|
31
|
+
end
|
32
|
+
|
33
|
+
context "with an undefined base url" do
|
34
|
+
let(:base_url) { nil }
|
35
|
+
|
36
|
+
it "should not raise an error" do
|
37
|
+
expect { method_call }.not_to raise_error
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with namespaced_resources disabled" do
|
43
|
+
before { Apipie.configuration.namespaced_resources = false }
|
44
|
+
|
45
|
+
it "returns the controller name" do
|
46
|
+
is_expected.to eq('architectures')
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe '.get_resource_id' do
|
52
|
+
subject(:method_call) { Apipie.get_resource_id(resource_class) }
|
53
|
+
|
54
|
+
it_behaves_like 'resource id'
|
55
|
+
end
|
56
|
+
|
57
|
+
describe '.get_resource_name' do
|
58
|
+
subject(:method_call) { Apipie.get_resource_name(resource_class) }
|
59
|
+
|
60
|
+
it_behaves_like 'resource id'
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'Apipie::Configuration' do
|
6
|
+
let(:configuration) { Apipie::Configuration.new }
|
7
|
+
|
8
|
+
describe '#api_action_matcher=' do
|
9
|
+
subject(:setter) { configuration.api_action_matcher = matcher }
|
10
|
+
|
11
|
+
let(:matcher) { proc { |_| :some_action } }
|
12
|
+
|
13
|
+
it { is_expected.to eq(matcher) }
|
14
|
+
|
15
|
+
context 'when matcher does not implement .call method' do
|
16
|
+
let(:matcher) { 'I do not implement .call' }
|
17
|
+
|
18
|
+
it 'raises and exception' do
|
19
|
+
expect { setter }.to raise_error('Must implement .call method')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe 'generator configuration' do
|
25
|
+
let(:generator_config) { configuration.generator }
|
26
|
+
|
27
|
+
describe '#swagger' do
|
28
|
+
subject(:setter) { generator_config.swagger.include_warning_tags = true }
|
29
|
+
|
30
|
+
it 'assigns the correct value' do
|
31
|
+
expect { setter }
|
32
|
+
.to change(configuration.generator.swagger, :include_warning_tags?)
|
33
|
+
.from(false)
|
34
|
+
.to(true)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
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
|
@@ -0,0 +1,77 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'spec_helper'
|
4
|
+
|
5
|
+
describe 'Apipie::Extractor::Recorder' do
|
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
|
12
|
+
|
13
|
+
describe '#analyse_controller' do
|
14
|
+
subject do
|
15
|
+
recorder.analyse_controller(controller)
|
16
|
+
recorder.record[:action]
|
17
|
+
end
|
18
|
+
|
19
|
+
let(:action) { :show }
|
20
|
+
|
21
|
+
let(:request) do
|
22
|
+
request = ActionDispatch::Request.new({})
|
23
|
+
request.request_parameters = { action: action }
|
24
|
+
request
|
25
|
+
end
|
26
|
+
|
27
|
+
it { is_expected.to eq(action) }
|
28
|
+
|
29
|
+
context 'when a api_action_matcher is configured' do
|
30
|
+
let(:matcher_action) { "#{action}_from_new_matcher" }
|
31
|
+
|
32
|
+
before do
|
33
|
+
Apipie.configuration.api_action_matcher = proc { |_| matcher_action }
|
34
|
+
end
|
35
|
+
|
36
|
+
it { is_expected.to eq(matcher_action) }
|
37
|
+
end
|
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
|
77
|
+
end
|
@@ -6,7 +6,8 @@ describe Apipie::Extractor::Writer do
|
|
6
6
|
let(:writer_class) { Apipie::Extractor::Writer }
|
7
7
|
let(:writer) { writer_class.new(collector) }
|
8
8
|
let(:test_examples_file) { File.join(Rails.root, "doc", "apipie_examples_test.json") }
|
9
|
-
let(:records) {
|
9
|
+
let(:records) {
|
10
|
+
{
|
10
11
|
"concern_resources#show" =>
|
11
12
|
[{
|
12
13
|
:controller=>ConcernsController,
|
@@ -31,7 +32,8 @@ describe Apipie::Extractor::Writer do
|
|
31
32
|
}]
|
32
33
|
}
|
33
34
|
}
|
34
|
-
let(:loaded_records) {
|
35
|
+
let(:loaded_records) {
|
36
|
+
{
|
35
37
|
"concern_resources#show" =>
|
36
38
|
[{
|
37
39
|
"verb"=>:GET,
|
@@ -57,16 +59,16 @@ describe Apipie::Extractor::Writer do
|
|
57
59
|
}
|
58
60
|
}
|
59
61
|
|
60
|
-
context 'with doc_path
|
62
|
+
context 'with doc_path overridden in configuration' do
|
61
63
|
around(:each) do |example|
|
62
64
|
standard_path = Apipie.configuration.doc_path
|
63
|
-
Apipie.configuration.doc_path = 'user_specified_doc_path'
|
65
|
+
Apipie.configuration.doc_path = 'tmp/user_specified_doc_path'
|
64
66
|
example.run
|
65
67
|
Apipie.configuration.doc_path = standard_path
|
66
68
|
end
|
67
69
|
|
68
70
|
it 'should use the doc_path specified in configuration' do
|
69
|
-
expect(writer_class.examples_file).to eql(File.join(Rails.root, 'user_specified_doc_path', 'apipie_examples.json'))
|
71
|
+
expect(writer_class.examples_file).to eql(File.join(Rails.root, 'tmp', 'user_specified_doc_path', 'apipie_examples.json'))
|
70
72
|
end
|
71
73
|
end
|
72
74
|
|
@@ -104,7 +106,7 @@ describe Apipie::Extractor::Writer do
|
|
104
106
|
end
|
105
107
|
|
106
108
|
after do
|
107
|
-
File.unlink(test_examples_file) if File.
|
109
|
+
File.unlink(test_examples_file) if File.exist?(test_examples_file)
|
108
110
|
end
|
109
111
|
end
|
110
112
|
end
|
@@ -2,7 +2,7 @@ require "spec_helper"
|
|
2
2
|
|
3
3
|
describe Apipie::Extractor do
|
4
4
|
it 'handles routes without (.:format)' do
|
5
|
-
Apipie::Extractor.apis_from_routes.
|
5
|
+
Apipie::Extractor.apis_from_routes.each_value do |apis|
|
6
6
|
apis.each { |api| expect(api[:path]).not_to be_nil }
|
7
7
|
end
|
8
8
|
end
|
@@ -14,5 +14,12 @@ describe Apipie::FileHandler do
|
|
14
14
|
it { expect(file_handler.match? path).to be_falsy }
|
15
15
|
it { expect { file_handler.match? path }.to_not raise_error }
|
16
16
|
end
|
17
|
+
|
18
|
+
context 'when the path contans an invalid byte sequence in UTF-8' do
|
19
|
+
let(:path) { "%B6" }
|
20
|
+
|
21
|
+
it { expect(file_handler.match? path).to be_falsy }
|
22
|
+
it { expect { file_handler.match? path }.to_not raise_error }
|
23
|
+
end
|
17
24
|
end
|
18
25
|
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Apipie::Generator::Swagger::Config do
|
4
|
+
let(:config) { described_class.clone.instance }
|
5
|
+
|
6
|
+
before { Singleton.__init__(described_class) }
|
7
|
+
|
8
|
+
describe 'deprecation warnings' do
|
9
|
+
context 'when a deprecated method is call' do
|
10
|
+
subject(:deprecated_method_call) { config.swagger_include_warning_tags? }
|
11
|
+
|
12
|
+
it 'returns a deprecations warning' do
|
13
|
+
expect { deprecated_method_call }
|
14
|
+
.to output(/DEPRECATION WARNING: config.swagger_include_warning_tags is deprecated/)
|
15
|
+
.to_stderr
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Apipie::Generator::Swagger::Context do
|
4
|
+
let(:allow_null) { true }
|
5
|
+
let(:in_schema) { true }
|
6
|
+
let(:http_method) { 'get' }
|
7
|
+
let(:prefix) { nil }
|
8
|
+
|
9
|
+
let(:context_instance) do
|
10
|
+
described_class.new(
|
11
|
+
allow_null: allow_null,
|
12
|
+
http_method: http_method,
|
13
|
+
in_schema: in_schema,
|
14
|
+
controller_method: 'show',
|
15
|
+
prefix: prefix
|
16
|
+
)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#in_schema?' do
|
20
|
+
subject { context_instance }
|
21
|
+
|
22
|
+
it { is_expected.to be_in_schema }
|
23
|
+
|
24
|
+
context 'when in_schema is false' do
|
25
|
+
let(:in_schema) { false }
|
26
|
+
|
27
|
+
it { is_expected.not_to be_in_schema }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#allow_null?' do
|
32
|
+
subject { context_instance }
|
33
|
+
|
34
|
+
it { is_expected.to be_allow_null }
|
35
|
+
|
36
|
+
context 'when allow_null is false' do
|
37
|
+
let(:allow_null) { false }
|
38
|
+
|
39
|
+
it { is_expected.not_to be_allow_null }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
describe '#add_to_prefix!' do
|
44
|
+
before { context_instance.add_to_prefix!('some-prefix') }
|
45
|
+
|
46
|
+
subject { context_instance.prefix }
|
47
|
+
|
48
|
+
it { is_expected.to eq('some-prefix') }
|
49
|
+
|
50
|
+
context 'when context has already a prefix' do
|
51
|
+
let(:prefix) { 'existing-prefix' }
|
52
|
+
|
53
|
+
it { is_expected.to eq('existing-prefix[some-prefix]') }
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|