apipie-rails 0.9.3 → 0.9.4
Sign up to get free protection for your applications and to get access to all the features.
- 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
|