apipie-rails 0.9.3 → 0.9.4
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 +4 -4
- data/.github/workflows/rubocop.yml +2 -2
- data/.rubocop.yml +15 -0
- data/.rubocop_todo.yml +3 -276
- data/CHANGELOG.md +6 -0
- data/app/controllers/apipie/apipies_controller.rb +2 -2
- data/app/helpers/apipie_helper.rb +1 -1
- data/lib/apipie/apipie_module.rb +2 -2
- data/lib/apipie/application.rb +12 -2
- data/lib/apipie/dsl_definition.rb +4 -4
- data/lib/apipie/error_description.rb +1 -1
- data/lib/apipie/errors.rb +2 -16
- data/lib/apipie/extractor/collector.rb +1 -1
- data/lib/apipie/extractor/recorder.rb +1 -1
- data/lib/apipie/extractor.rb +1 -1
- data/lib/apipie/generator/swagger/operation_id.rb +1 -1
- data/lib/apipie/helpers.rb +3 -3
- data/lib/apipie/method_description.rb +1 -1
- data/lib/apipie/resource_description.rb +10 -7
- data/lib/apipie/response_description.rb +1 -1
- data/lib/apipie/response_description_adapter.rb +3 -3
- data/lib/apipie/routing.rb +1 -1
- data/lib/apipie/rspec/response_validation_helper.rb +1 -1
- data/lib/apipie/swagger_generator.rb +6 -6
- data/lib/apipie/validator.rb +2 -2
- data/lib/apipie/version.rb +1 -1
- data/lib/tasks/apipie.rake +10 -10
- data/spec/dummy/config.ru +1 -1
- data/spec/lib/apipie/apipies_controller_spec.rb +4 -0
- data/spec/lib/apipie/application_spec.rb +16 -15
- data/spec/lib/apipie/generator/swagger/context_spec.rb +1 -0
- data/spec/lib/apipie/no_documented_method_spec.rb +17 -0
- data/spec/lib/apipie/resource_description_spec.rb +71 -28
- data/spec/lib/apipie/response_does_not_match_swagger_schema_spec.rb +35 -0
- data/spec/lib/rake_spec.rb +1 -1
- data/spec/lib/swagger/rake_swagger_spec.rb +2 -2
- data/spec/lib/swagger/swagger_dsl_spec.rb +10 -4
- data/spec/spec_helper.rb +2 -2
- metadata +5 -3
@@ -14,27 +14,25 @@ module Apipie
|
|
14
14
|
class ResourceDescription
|
15
15
|
|
16
16
|
attr_reader :controller, :_short_description, :_full_description, :_methods, :_id,
|
17
|
-
:_path, :
|
17
|
+
:_path, :_params_args, :_returns_args, :_tag_list_arg, :_errors_args,
|
18
18
|
:_formats, :_parent, :_metadata, :_headers, :_deprecated
|
19
19
|
|
20
|
-
def initialize(controller,
|
21
|
-
|
20
|
+
def initialize(controller, id, dsl_data = nil, version = nil)
|
22
21
|
@_methods = ActiveSupport::OrderedHash.new
|
23
22
|
@_params_args = []
|
24
23
|
@_errors_args = []
|
25
24
|
@_returns_args = []
|
26
25
|
|
27
26
|
@controller = controller
|
28
|
-
@_id =
|
27
|
+
@_id = id
|
29
28
|
@_version = version || Apipie.configuration.default_version
|
30
|
-
@_name = @_id.humanize
|
31
29
|
@_parent = Apipie.get_resource_description(controller.superclass, version)
|
32
30
|
|
33
31
|
update_from_dsl_data(dsl_data) if dsl_data
|
34
32
|
end
|
35
33
|
|
36
34
|
def update_from_dsl_data(dsl_data)
|
37
|
-
@
|
35
|
+
@_resource_name = dsl_data[:resource_name] if dsl_data[:resource_name]
|
38
36
|
@_full_description = dsl_data[:description]
|
39
37
|
@_short_description = dsl_data[:short_description]
|
40
38
|
@_path = dsl_data[:path] || ""
|
@@ -61,6 +59,11 @@ module Apipie
|
|
61
59
|
@_api_base_url || @_parent.try(:_api_base_url) || Apipie.api_base_url(_version)
|
62
60
|
end
|
63
61
|
|
62
|
+
def name
|
63
|
+
@name ||= @_resource_name.presence || @_id.split('-').map(&:capitalize).join('::')
|
64
|
+
end
|
65
|
+
alias _name name
|
66
|
+
|
64
67
|
def add_method_description(method_description)
|
65
68
|
Apipie.debug "@resource_descriptions[#{self._version}][#{self._name}]._methods[#{method_description.method}] = #{method_description}"
|
66
69
|
@_methods[method_description.method.to_sym] = method_description
|
@@ -108,7 +111,7 @@ module Apipie
|
|
108
111
|
:doc_url => doc_url,
|
109
112
|
:id => _id,
|
110
113
|
:api_url => api_url,
|
111
|
-
:name =>
|
114
|
+
:name => name,
|
112
115
|
:short_description => Apipie.app.translate(@_short_description, lang),
|
113
116
|
:full_description => Apipie.markup_to_html(Apipie.app.translate(@_full_description, lang)),
|
114
117
|
:version => _version,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Apipie
|
2
2
|
|
3
|
-
def self.prop(name, expected_type, options={}, sub_properties=[])
|
3
|
+
def self.prop(name, expected_type, options = {}, sub_properties = [])
|
4
4
|
Apipie::ResponseDescriptionAdapter::PropDesc.new(name, expected_type, options, sub_properties)
|
5
5
|
end
|
6
6
|
|
@@ -60,7 +60,7 @@ module Apipie
|
|
60
60
|
return self.send(key) if self.respond_to?(key.to_s)
|
61
61
|
end
|
62
62
|
|
63
|
-
def initialize(expected_type, enum_values=nil, sub_properties=nil)
|
63
|
+
def initialize(expected_type, enum_values = nil, sub_properties = nil)
|
64
64
|
@expected_type = expected_type
|
65
65
|
@enum_values = enum_values
|
66
66
|
@is_enum = !!enum_values
|
@@ -84,7 +84,7 @@ module Apipie
|
|
84
84
|
#======================================================================
|
85
85
|
|
86
86
|
|
87
|
-
def initialize(name, expected_type, options={}, sub_properties=[])
|
87
|
+
def initialize(name, expected_type, options = {}, sub_properties = [])
|
88
88
|
@name = name
|
89
89
|
@required = true
|
90
90
|
@required = false if options[:required] == false
|
data/lib/apipie/routing.rb
CHANGED
@@ -4,7 +4,7 @@ module Apipie
|
|
4
4
|
def apipie(options = {})
|
5
5
|
namespace "apipie", :path => Apipie.configuration.doc_base_url do
|
6
6
|
get 'apipie_checksum', :to => "apipies#apipie_checksum", :format => "json"
|
7
|
-
constraints(:version =>
|
7
|
+
constraints(:version => %r{[^/]+}, :resource => %r{[^/]+}, :method => %r{[^/]+}) do
|
8
8
|
get(options.reverse_merge("(:version)/(:resource)/(:method)" => "apipies#index", :as => :apipie))
|
9
9
|
end
|
10
10
|
end
|
@@ -112,7 +112,7 @@ class ActionController::Base
|
|
112
112
|
end
|
113
113
|
|
114
114
|
module Apipie
|
115
|
-
def self.print_validation_errors(validation_errors, schema, response, error_object=nil)
|
115
|
+
def self.print_validation_errors(validation_errors, schema, response, error_object = nil)
|
116
116
|
Rails.logger.warn(validation_errors.to_s)
|
117
117
|
if Rails.env.test?
|
118
118
|
puts "schema validation errors:"
|
@@ -33,7 +33,7 @@ module Apipie
|
|
33
33
|
end
|
34
34
|
|
35
35
|
|
36
|
-
def generate_from_resources(version, resources, method_name, lang, clear_warnings=false)
|
36
|
+
def generate_from_resources(version, resources, method_name, lang, clear_warnings = false)
|
37
37
|
init_swagger_vars(version, lang, clear_warnings)
|
38
38
|
|
39
39
|
@only_method = method_name
|
@@ -48,7 +48,7 @@ module Apipie
|
|
48
48
|
# Initialization
|
49
49
|
#--------------------------------------------------------------------------
|
50
50
|
|
51
|
-
def init_swagger_vars(version, lang, clear_warnings=false)
|
51
|
+
def init_swagger_vars(version, lang, clear_warnings = false)
|
52
52
|
|
53
53
|
# docs = {
|
54
54
|
# :name => Apipie.configuration.app_name,
|
@@ -284,7 +284,7 @@ module Apipie
|
|
284
284
|
|
285
285
|
def swagger_path(str)
|
286
286
|
str = str.gsub(/:(\w+)/, '{\1}')
|
287
|
-
str = str.gsub(
|
287
|
+
str = str.gsub(%r{/$}, '')
|
288
288
|
|
289
289
|
if str[0] != '/'
|
290
290
|
warn_added_missing_slash(str)
|
@@ -339,7 +339,7 @@ module Apipie
|
|
339
339
|
response_schema(adapter, allow_nulls)
|
340
340
|
end
|
341
341
|
|
342
|
-
def response_schema(response, allow_nulls=false)
|
342
|
+
def response_schema(response, allow_nulls = false)
|
343
343
|
begin
|
344
344
|
# no need to warn about "missing default value for optional param" when processing response definitions
|
345
345
|
prev_value = @disable_default_value_warning
|
@@ -445,7 +445,7 @@ module Apipie
|
|
445
445
|
"#/definitions/#{name}"
|
446
446
|
end
|
447
447
|
|
448
|
-
def gen_referenced_block_from_params_array(name, params_array, allow_nulls=false)
|
448
|
+
def gen_referenced_block_from_params_array(name, params_array, allow_nulls = false)
|
449
449
|
return ref_to(:name) if @definitions.key(:name)
|
450
450
|
|
451
451
|
schema_obj = Apipie::Generator::Swagger::ParamDescription::Composite.new(
|
@@ -531,7 +531,7 @@ module Apipie
|
|
531
531
|
end
|
532
532
|
|
533
533
|
|
534
|
-
def add_params_from_hash(swagger_params_array, param_defs, prefix=nil, default_value_for_in=nil)
|
534
|
+
def add_params_from_hash(swagger_params_array, param_defs, prefix = nil, default_value_for_in = nil)
|
535
535
|
param_defs.each do |name, desc|
|
536
536
|
if !prefix.nil?
|
537
537
|
name = "#{prefix}[#{name}]"
|
data/lib/apipie/validator.rb
CHANGED
@@ -190,7 +190,7 @@ module Apipie
|
|
190
190
|
|
191
191
|
# arguments value must be an array
|
192
192
|
class ArrayValidator < Apipie::Validator::BaseValidator
|
193
|
-
def initialize(param_description, argument, options={})
|
193
|
+
def initialize(param_description, argument, options = {})
|
194
194
|
super(param_description)
|
195
195
|
@type = argument
|
196
196
|
@items_type = options[:of]
|
@@ -495,7 +495,7 @@ module Apipie
|
|
495
495
|
|
496
496
|
def initialize(param_description, argument, param_group)
|
497
497
|
super(param_description)
|
498
|
-
@validator = Apipie::Validator::
|
498
|
+
@validator = Apipie::Validator::HashValidator.new(param_description, argument, param_group)
|
499
499
|
@type = argument
|
500
500
|
end
|
501
501
|
|
data/lib/apipie/version.rb
CHANGED
data/lib/tasks/apipie.rake
CHANGED
@@ -20,7 +20,7 @@ namespace :apipie do
|
|
20
20
|
task :static, [:version] => :environment do |t, args|
|
21
21
|
with_loaded_documentation do
|
22
22
|
args.with_defaults(:version => Apipie.configuration.default_version)
|
23
|
-
out = ENV["OUT"] || File.join(
|
23
|
+
out = ENV["OUT"] || File.join(Rails.root, Apipie.configuration.doc_path, 'apidoc')
|
24
24
|
subdir = File.basename(out)
|
25
25
|
copy_jscss(out)
|
26
26
|
Apipie.configuration.version_in_url = false
|
@@ -44,7 +44,7 @@ namespace :apipie do
|
|
44
44
|
task :static_json, [:version] => :environment do |t, args|
|
45
45
|
with_loaded_documentation do
|
46
46
|
args.with_defaults(:version => Apipie.configuration.default_version)
|
47
|
-
out = ENV["OUT"] || File.join(
|
47
|
+
out = ENV["OUT"] || File.join(Rails.root, Apipie.configuration.doc_path, 'apidoc')
|
48
48
|
([nil] + Apipie.configuration.languages).each do |lang|
|
49
49
|
doc = Apipie.to_json(args[:version], nil, nil, lang)
|
50
50
|
generate_json_page(out, doc, lang)
|
@@ -55,7 +55,7 @@ namespace :apipie do
|
|
55
55
|
desc "Generate static swagger json"
|
56
56
|
task :static_swagger_json, [:version, :swagger_content_type_input, :filename_suffix] => :environment do |t, args|
|
57
57
|
with_loaded_documentation do
|
58
|
-
out = ENV["OUT"] || File.join(
|
58
|
+
out = ENV["OUT"] || File.join(Rails.root, Apipie.configuration.doc_path, 'apidoc')
|
59
59
|
generate_swagger_using_args(args, out)
|
60
60
|
end
|
61
61
|
end
|
@@ -68,7 +68,7 @@ namespace :apipie do
|
|
68
68
|
desc "Did swagger output change since the last execution of this task?"
|
69
69
|
task :did_swagger_change, [:version, :swagger_content_type_input, :filename_suffix] => :environment do |t, args|
|
70
70
|
with_loaded_documentation do
|
71
|
-
out = ENV["OUT_REF"] || File.join(
|
71
|
+
out = ENV["OUT_REF"] || File.join(Rails.root, Apipie.configuration.doc_path, 'apidoc_ref')
|
72
72
|
paths = generate_swagger_using_args(args, out)
|
73
73
|
paths.each {|path|
|
74
74
|
existing_files_in_dir = Pathname(out).children(true)
|
@@ -123,17 +123,17 @@ namespace :apipie do
|
|
123
123
|
# Default output dir ('public/apipie_cache') can be changed with OUT=/some/dir
|
124
124
|
desc "Generate cache to avoid production dependencies on markup languages"
|
125
125
|
task :cache => :environment do
|
126
|
-
puts "#{Time.now} | Started"
|
126
|
+
puts "#{Time.zone.now} | Started"
|
127
127
|
cache_part = ENV['cache_part']
|
128
128
|
generate_index = (cache_part == 'resources' ? false : true)
|
129
129
|
generate_resources = (cache_part == 'index' ? false : true)
|
130
130
|
with_loaded_documentation do
|
131
|
-
puts "#{Time.now} | Documents loaded..."
|
131
|
+
puts "#{Time.zone.now} | Documents loaded..."
|
132
132
|
([nil] + Apipie.configuration.languages).each do |lang|
|
133
133
|
I18n.locale = lang || Apipie.configuration.default_locale
|
134
|
-
puts "#{Time.now} | Processing docs for #{lang}"
|
134
|
+
puts "#{Time.zone.now} | Processing docs for #{lang}"
|
135
135
|
cache_dir = ENV["OUT"] || Apipie.configuration.cache_dir
|
136
|
-
subdir = Apipie.configuration.doc_base_url.sub(
|
136
|
+
subdir = Apipie.configuration.doc_base_url.sub(%r{\A/},"")
|
137
137
|
subdir_levels = subdir.split('/').length
|
138
138
|
subdir_traversal_prefix = '../' * subdir_levels
|
139
139
|
file_base = File.join(cache_dir, Apipie.configuration.doc_base_url)
|
@@ -159,7 +159,7 @@ namespace :apipie do
|
|
159
159
|
end
|
160
160
|
end
|
161
161
|
end
|
162
|
-
puts "#{Time.now} | Finished"
|
162
|
+
puts "#{Time.zone.now} | Finished"
|
163
163
|
end
|
164
164
|
|
165
165
|
# Attempt to use the Rails application views, otherwise default to built in views
|
@@ -221,7 +221,7 @@ namespace :apipie do
|
|
221
221
|
File.open("#{file_base}/#{filename}", 'w') { |file| file.write(JSON.pretty_generate(doc)) }
|
222
222
|
end
|
223
223
|
|
224
|
-
def generate_swagger_json_page(file_base, doc, sfx="", lang = nil)
|
224
|
+
def generate_swagger_json_page(file_base, doc, sfx = "", lang = nil)
|
225
225
|
FileUtils.mkdir_p(file_base) unless File.exist?(file_base)
|
226
226
|
|
227
227
|
path = Pathname.new("#{file_base}/schema_swagger#{sfx}#{lang_ext(lang)}.json")
|
data/spec/dummy/config.ru
CHANGED
@@ -209,6 +209,7 @@ describe Apipie::ApipiesController, type: :controller do
|
|
209
209
|
get :index
|
210
210
|
expect(test).to eq(true)
|
211
211
|
end
|
212
|
+
|
212
213
|
it "remove all resources" do
|
213
214
|
Apipie.configuration.authorize = Proc.new do |&args|
|
214
215
|
false
|
@@ -216,6 +217,7 @@ describe Apipie::ApipiesController, type: :controller do
|
|
216
217
|
get :index
|
217
218
|
expect(assigns(:doc)[:resources]).to eq({})
|
218
219
|
end
|
220
|
+
|
219
221
|
it "remove all methods" do
|
220
222
|
Apipie.configuration.authorize = Proc.new do |controller, method, doc|
|
221
223
|
!method
|
@@ -225,6 +227,7 @@ describe Apipie::ApipiesController, type: :controller do
|
|
225
227
|
expect(assigns(:doc)[:resources]["twitter_example"][:methods]).to eq([])
|
226
228
|
expect(assigns(:doc)[:resources]["users"][:methods]).to eq([])
|
227
229
|
end
|
230
|
+
|
228
231
|
it "remove specific method" do
|
229
232
|
Apipie.configuration.authorize = nil
|
230
233
|
get :index
|
@@ -241,6 +244,7 @@ describe Apipie::ApipiesController, type: :controller do
|
|
241
244
|
expect(assigns(:doc)[:resources]["users"][:methods].size).to eq(users_methods - 1)
|
242
245
|
expect(assigns(:doc)[:resources]["twitter_example"][:methods].size).to eq(twitter_example_methods)
|
243
246
|
end
|
247
|
+
|
244
248
|
it "does not allow access to swagger when authorization is set" do
|
245
249
|
get :index, :params => { :format => "json", :type => "swagger"}
|
246
250
|
|
@@ -16,36 +16,37 @@ describe Apipie::Application do
|
|
16
16
|
|
17
17
|
end
|
18
18
|
|
19
|
-
describe
|
20
|
-
subject
|
19
|
+
describe '.get_resource_name' do
|
20
|
+
subject(:get_resource_name) do
|
21
|
+
Apipie.get_resource_name(Api::V2::Nested::ArchitecturesController)
|
22
|
+
end
|
23
|
+
|
24
|
+
let(:base_url) { '/some-api' }
|
25
|
+
|
26
|
+
before { allow(Apipie.app).to receive(:get_base_url).and_return(base_url) }
|
21
27
|
|
22
28
|
context "with namespaced_resources enabled" do
|
23
29
|
before { Apipie.configuration.namespaced_resources = true }
|
24
|
-
|
25
|
-
|
26
|
-
it "should not overwrite the parent resource" do
|
27
|
-
is_expected.not_to eq(Apipie.get_resource_name(Api::V2::ArchitecturesController))
|
28
|
-
end
|
30
|
+
after { Apipie.configuration.namespaced_resources = false }
|
29
31
|
|
32
|
+
it "returns the namespaces" do
|
33
|
+
is_expected.to eq('api-v2-nested-architectures')
|
30
34
|
end
|
31
35
|
|
32
36
|
context "with an undefined base url" do
|
33
|
-
|
37
|
+
let(:base_url) { nil }
|
34
38
|
|
35
39
|
it "should not raise an error" do
|
36
|
-
expect {
|
37
|
-
not_to raise_error
|
40
|
+
expect { get_resource_name }.not_to raise_error
|
38
41
|
end
|
39
42
|
end
|
40
|
-
|
41
|
-
after { Apipie.configuration.namespaced_resources = false }
|
42
43
|
end
|
43
44
|
|
44
|
-
context "with namespaced_resources
|
45
|
+
context "with namespaced_resources disabled" do
|
45
46
|
before { Apipie.configuration.namespaced_resources = false }
|
46
47
|
|
47
|
-
it "
|
48
|
-
is_expected.to eq(
|
48
|
+
it "returns the controller name" do
|
49
|
+
is_expected.to eq('architectures')
|
49
50
|
end
|
50
51
|
end
|
51
52
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Apipie::NoDocumentedMethod do
|
4
|
+
let(:error) { described_class.new(controller_name, method_name) }
|
5
|
+
let(:controller_name) { 'UserController' }
|
6
|
+
let(:method_name) { 'index' }
|
7
|
+
|
8
|
+
describe '#to_s' do
|
9
|
+
subject { error.to_s }
|
10
|
+
|
11
|
+
let(:error_message) do
|
12
|
+
"There is no documented method #{controller_name}##{method_name}"
|
13
|
+
end
|
14
|
+
|
15
|
+
it { is_expected.to eq(error_message) }
|
16
|
+
end
|
17
|
+
end
|
@@ -1,48 +1,91 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe Apipie::ResourceDescription do
|
4
|
+
let(:resource_description) do
|
5
|
+
Apipie::ResourceDescription.new(controller, id, dsl_data)
|
6
|
+
end
|
4
7
|
|
8
|
+
let(:controller) { ApplicationController }
|
9
|
+
let(:id) { 'dummy' }
|
5
10
|
let(:dsl_data) { ActionController::Base.send(:_apipie_dsl_data_init) }
|
6
11
|
|
7
|
-
describe
|
12
|
+
describe '#_methods' do
|
13
|
+
subject(:methods) { resource_description._methods }
|
8
14
|
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
15
|
+
context 'when has method descriptions' do
|
16
|
+
before do
|
17
|
+
resource_description.add_method_description(
|
18
|
+
Apipie::MethodDescription.new(:a, resource_description, dsl_data)
|
19
|
+
)
|
20
|
+
resource_description.add_method_description(
|
21
|
+
Apipie::MethodDescription.new(:b, resource_description, dsl_data)
|
22
|
+
)
|
23
|
+
resource_description.add_method_description(
|
24
|
+
Apipie::MethodDescription.new(:c, resource_description, dsl_data)
|
25
|
+
)
|
26
|
+
end
|
13
27
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
:weight => '830g'
|
18
|
-
}
|
19
|
-
resource = Apipie::ResourceDescription.new(ApplicationController, "dummy", dsl_data.update(:meta => meta))
|
20
|
-
expect(resource.to_json[:metadata]).to eq(meta)
|
28
|
+
it 'should be ordered' do
|
29
|
+
expect(methods.keys).to eq([:a, :b, :c])
|
30
|
+
end
|
21
31
|
end
|
22
|
-
|
23
32
|
end
|
24
33
|
|
25
|
-
describe
|
34
|
+
describe '#to_json' do
|
35
|
+
let(:json_data) { resource_description.to_json }
|
36
|
+
|
37
|
+
describe 'metadata' do
|
38
|
+
subject { json_data[:metadata] }
|
26
39
|
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
40
|
+
it { is_expected.to be_nil }
|
41
|
+
|
42
|
+
context 'when meta data are provided' do
|
43
|
+
let(:meta) { { length: 32, weight: '830g' } }
|
44
|
+
let(:dsl_data) { super().update({ meta: meta }) }
|
45
|
+
|
46
|
+
it { is_expected.to eq(meta) }
|
47
|
+
end
|
35
48
|
end
|
36
49
|
|
37
|
-
|
38
|
-
|
39
|
-
|
50
|
+
describe 'methods' do
|
51
|
+
subject(:methods_as_json) { json_data[:methods] }
|
52
|
+
|
53
|
+
context 'when has method descriptions' do
|
54
|
+
before do
|
55
|
+
resource_description.add_method_description(
|
56
|
+
Apipie::MethodDescription.new(:a, resource_description, dsl_data)
|
57
|
+
)
|
58
|
+
resource_description.add_method_description(
|
59
|
+
Apipie::MethodDescription.new(:b, resource_description, dsl_data)
|
60
|
+
)
|
61
|
+
resource_description.add_method_description(
|
62
|
+
Apipie::MethodDescription.new(:c, resource_description, dsl_data)
|
63
|
+
)
|
64
|
+
end
|
65
|
+
|
66
|
+
it 'should be ordered' do
|
67
|
+
expect(methods_as_json.map { |h| h[:name] }).to eq(['a', 'b', 'c'])
|
68
|
+
end
|
69
|
+
end
|
40
70
|
end
|
71
|
+
end
|
72
|
+
|
73
|
+
describe 'name' do
|
74
|
+
subject { resource_description.name }
|
75
|
+
|
76
|
+
it { is_expected.to eq('Dummy') }
|
41
77
|
|
42
|
-
|
43
|
-
|
44
|
-
|
78
|
+
context 'when given id contains dashes' do
|
79
|
+
let(:id) { 'some-nested-resource' }
|
80
|
+
|
81
|
+
it { is_expected.to eq('Some::Nested::Resource') }
|
45
82
|
end
|
46
83
|
|
84
|
+
context 'when resource_name is given' do
|
85
|
+
let(:resource_name) { 'Some-Resource' }
|
86
|
+
let(:dsl_data) { super().merge!(resource_name: 'Some-Resource') }
|
87
|
+
|
88
|
+
it { is_expected.to eq(resource_name) }
|
89
|
+
end
|
47
90
|
end
|
48
91
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Apipie::ResponseDoesNotMatchSwaggerSchema do
|
4
|
+
let(:error) do
|
5
|
+
described_class.new(
|
6
|
+
controller_name,
|
7
|
+
method_name,
|
8
|
+
response_code,
|
9
|
+
error_messages,
|
10
|
+
schema,
|
11
|
+
returned_object
|
12
|
+
)
|
13
|
+
end
|
14
|
+
|
15
|
+
let(:controller_name) { 'UserController' }
|
16
|
+
let(:method_name) { 'index' }
|
17
|
+
let(:response_code) { 200 }
|
18
|
+
let(:error_messages) { [] }
|
19
|
+
let(:schema) { {} }
|
20
|
+
let(:returned_object) { {} }
|
21
|
+
|
22
|
+
describe '#to_s' do
|
23
|
+
subject { error.to_s }
|
24
|
+
|
25
|
+
let(:error_message) do
|
26
|
+
<<~HEREDOC.chomp
|
27
|
+
Response does not match swagger schema (#{controller_name}##{method_name} #{response_code}): #{error_messages}
|
28
|
+
Schema: #{JSON(schema)}
|
29
|
+
Returned object: #{returned_object}
|
30
|
+
HEREDOC
|
31
|
+
end
|
32
|
+
|
33
|
+
it { is_expected.to eq(error_message) }
|
34
|
+
end
|
35
|
+
end
|
data/spec/lib/rake_spec.rb
CHANGED
@@ -37,11 +37,11 @@ describe 'rake tasks' do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
let(:doc_output) do
|
40
|
-
File.join(
|
40
|
+
File.join(Rails.root, doc_path, 'apidoc')
|
41
41
|
end
|
42
42
|
|
43
43
|
let(:ref_output) do
|
44
|
-
File.join(
|
44
|
+
File.join(Rails.root, doc_path, 'apidoc_ref')
|
45
45
|
end
|
46
46
|
|
47
47
|
|
@@ -24,17 +24,17 @@ describe "Swagger Responses" do
|
|
24
24
|
schema
|
25
25
|
end
|
26
26
|
|
27
|
-
def swagger_response_for(path, code=200, method='get')
|
27
|
+
def swagger_response_for(path, code = 200, method = 'get')
|
28
28
|
response = swagger[:paths][path][method][:responses][code]
|
29
29
|
response[:schema] = resolve_refs(response[:schema])
|
30
30
|
response
|
31
31
|
end
|
32
32
|
|
33
|
-
def swagger_params_for(path, method='get')
|
33
|
+
def swagger_params_for(path, method = 'get')
|
34
34
|
swagger[:paths][path][method][:parameters]
|
35
35
|
end
|
36
36
|
|
37
|
-
def swagger_param_by_name(param_name, path, method='get')
|
37
|
+
def swagger_param_by_name(param_name, path, method = 'get')
|
38
38
|
params = swagger_params_for(path, method)
|
39
39
|
matching = params.select{|p| p[:name] == param_name }
|
40
40
|
raise "multiple params named [#{param_name}] in swagger definition for [#{method} #{path}]" if matching.length > 1
|
@@ -72,7 +72,7 @@ describe "Swagger Responses" do
|
|
72
72
|
deep_match?(actual, expected)
|
73
73
|
end
|
74
74
|
|
75
|
-
def deep_match?(actual, expected, breadcrumb=[])
|
75
|
+
def deep_match?(actual, expected, breadcrumb = [])
|
76
76
|
pending_params = actual.params_ordered.dup
|
77
77
|
expected.each do |expected_param|
|
78
78
|
expected_param_name = expected_param.is_a?(Hash) ? expected_param.keys.first : expected_param
|
@@ -338,6 +338,7 @@ describe "Swagger Responses" do
|
|
338
338
|
|
339
339
|
expect(returns_obj).to match_field_structure([:pet_name, :animal_type])
|
340
340
|
end
|
341
|
+
|
341
342
|
it 'should have the 201 response described in the swagger' do
|
342
343
|
response = swagger_response_for('/pets/{id}/extra_info', 201)
|
343
344
|
expect(response[:description]).to eq("Found a pet")
|
@@ -359,6 +360,7 @@ describe "Swagger Responses" do
|
|
359
360
|
{:pet_measurements => [:weight, :height, :num_legs]}
|
360
361
|
])
|
361
362
|
end
|
363
|
+
|
362
364
|
it 'should have the 202 response described in the swagger' do
|
363
365
|
response = swagger_response_for('/pets/{id}/extra_info', 202)
|
364
366
|
expect(response[:description]).to eq('Accepted')
|
@@ -388,6 +390,7 @@ describe "Swagger Responses" do
|
|
388
390
|
{:additional_histories => [:did_visit_vet, :avg_meals_per_day]}
|
389
391
|
])
|
390
392
|
end
|
393
|
+
|
391
394
|
it 'should have the 203 response described in the swagger' do
|
392
395
|
response = swagger_response_for('/pets/{id}/extra_info', 203)
|
393
396
|
expect(response[:description]).to eq('Non-Authoritative Information')
|
@@ -424,6 +427,7 @@ describe "Swagger Responses" do
|
|
424
427
|
|
425
428
|
expect(returns_obj).to match_field_structure([:int_array, :enum_array])
|
426
429
|
end
|
430
|
+
|
427
431
|
it 'should have the 204 response described in the swagger' do
|
428
432
|
response = swagger_response_for('/pets/{id}/extra_info', 204)
|
429
433
|
|
@@ -444,6 +448,7 @@ describe "Swagger Responses" do
|
|
444
448
|
:num_fleas
|
445
449
|
])
|
446
450
|
end
|
451
|
+
|
447
452
|
it 'should have the 422 response described in the swagger' do
|
448
453
|
response = swagger_response_for('/pets/{id}/extra_info', 422)
|
449
454
|
expect(response[:description]).to eq('Fleas were discovered on the pet')
|
@@ -568,6 +573,7 @@ describe "Swagger Responses" do
|
|
568
573
|
{:pet_measurements => [:weight, :height, :num_legs]}
|
569
574
|
])
|
570
575
|
end
|
576
|
+
|
571
577
|
it 'should have the 200 response described in the swagger' do
|
572
578
|
response = swagger_response_for('/pets_with_measurements_described_as_class/{id}', 200)
|
573
579
|
expect(response[:description]).to eq('measurements of the pet')
|
data/spec/spec_helper.rb
CHANGED
@@ -24,7 +24,7 @@ require 'test_engine'
|
|
24
24
|
#
|
25
25
|
# will verify that the selected response schema includes a required string field called 'pet_name'
|
26
26
|
#
|
27
|
-
RSpec::Matchers.define :have_field do |name, type, opts={}|
|
27
|
+
RSpec::Matchers.define :have_field do |name, type, opts = {}|
|
28
28
|
def fail(msg)
|
29
29
|
@fail_message = msg
|
30
30
|
false
|
@@ -62,7 +62,7 @@ RSpec.configure do |config|
|
|
62
62
|
config.mock_with :rspec
|
63
63
|
|
64
64
|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
|
65
|
-
config.fixture_path = "#{
|
65
|
+
config.fixture_path = "#{Rails.root}/spec/fixtures"
|
66
66
|
|
67
67
|
# If you're not using ActiveRecord, or you'd prefer not to run each of your
|
68
68
|
# examples within a transaction, remove the following line or assign false
|