apipie-rails 0.0.24 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -1
- data/.travis.yml +6 -0
- data/CHANGELOG.md +97 -0
- data/Gemfile +1 -1
- data/Gemfile.rails30 +5 -0
- data/Gemfile.rails32 +5 -0
- data/Gemfile.rails40 +5 -0
- data/Gemfile.rails41 +5 -0
- data/README.rst +126 -11
- data/apipie-rails.gemspec +1 -1
- data/app/controllers/apipie/apipies_controller.rb +3 -0
- data/app/helpers/apipie_helper.rb +9 -0
- data/app/views/apipie/apipies/_metadata.erb +1 -0
- data/app/views/apipie/apipies/_method_detail.erb +46 -0
- data/app/views/apipie/apipies/_params.html.erb +12 -0
- data/app/views/apipie/apipies/_params_plain.html.erb +4 -0
- data/app/views/apipie/apipies/apipie_checksum.json.erb +1 -0
- data/app/views/apipie/apipies/method.html.erb +1 -37
- data/app/views/apipie/apipies/plain.html.erb +1 -0
- data/app/views/apipie/apipies/resource.html.erb +6 -37
- data/app/views/apipie/apipies/static.html.erb +1 -0
- data/lib/apipie/application.rb +16 -2
- data/lib/apipie/configuration.rb +8 -2
- data/lib/apipie/dsl_definition.rb +25 -6
- data/lib/apipie/error_description.rb +22 -10
- data/lib/apipie/extractor.rb +2 -1
- data/lib/apipie/extractor/writer.rb +8 -6
- data/lib/apipie/method_description.rb +7 -4
- data/lib/apipie/middleware/checksum_in_headers.rb +35 -0
- data/lib/apipie/param_description.rb +25 -4
- data/lib/apipie/resource_description.rb +8 -4
- data/lib/apipie/routing.rb +1 -0
- data/lib/apipie/validator.rb +71 -3
- data/lib/apipie/version.rb +1 -1
- data/lib/tasks/apipie.rake +26 -5
- data/spec/controllers/apipies_controller_spec.rb +2 -0
- data/spec/controllers/concerns_controller_spec.rb +1 -1
- data/spec/controllers/users_controller_spec.rb +130 -19
- data/spec/dummy/app/controllers/api/v1/architectures_controller.rb +1 -0
- data/spec/dummy/app/controllers/api/v2/nested/architectures_controller.rb +22 -20
- data/spec/dummy/app/controllers/concerns/sample_controller.rb +32 -30
- data/spec/dummy/app/controllers/users_controller.rb +18 -5
- data/spec/lib/method_description_spec.rb +22 -0
- data/spec/lib/param_description_spec.rb +77 -0
- data/spec/lib/rake_spec.rb +68 -0
- data/spec/lib/resource_description_spec.rb +18 -0
- data/spec/lib/validator_spec.rb +9 -0
- data/spec/spec_helper.rb +2 -1
- data/spec/support/rake.rb +21 -0
- metadata +20 -7
- data/CHANGELOG +0 -72
@@ -15,7 +15,7 @@ module Apipie
|
|
15
15
|
|
16
16
|
end
|
17
17
|
|
18
|
-
attr_reader :full_description, :method, :resource, :apis, :examples, :see, :formats
|
18
|
+
attr_reader :full_description, :method, :resource, :apis, :examples, :see, :formats, :metadata
|
19
19
|
|
20
20
|
def initialize(method, resource, dsl_data)
|
21
21
|
@method = method.to_s
|
@@ -30,7 +30,7 @@ module Apipie
|
|
30
30
|
@full_description = Apipie.markup_to_html(desc)
|
31
31
|
|
32
32
|
@errors = dsl_data[:errors].map do |args|
|
33
|
-
Apipie::ErrorDescription.
|
33
|
+
Apipie::ErrorDescription.from_dsl_data(args)
|
34
34
|
end
|
35
35
|
|
36
36
|
@see = dsl_data[:see].map do |args|
|
@@ -41,6 +41,8 @@ module Apipie
|
|
41
41
|
@examples = dsl_data[:examples]
|
42
42
|
@examples += load_recorded_examples
|
43
43
|
|
44
|
+
@metadata = dsl_data[:meta]
|
45
|
+
|
44
46
|
@params_ordered = dsl_data[:params].map do |args|
|
45
47
|
Apipie::ParamDescription.from_dsl_data(self, args)
|
46
48
|
end
|
@@ -76,7 +78,7 @@ module Apipie
|
|
76
78
|
@merged_errors = []
|
77
79
|
if @resource
|
78
80
|
resource_errors = @resource._errors_args.map do |args|
|
79
|
-
Apipie::ErrorDescription.
|
81
|
+
Apipie::ErrorDescription.from_dsl_data(args)
|
80
82
|
end
|
81
83
|
|
82
84
|
# exclude overwritten parent errors
|
@@ -101,7 +103,7 @@ module Apipie
|
|
101
103
|
end
|
102
104
|
|
103
105
|
def create_api_url(api)
|
104
|
-
path = "#{
|
106
|
+
path = "#{@resource._api_base_url}#{api.path}"
|
105
107
|
path = path[0..-2] if path[-1..-1] == '/'
|
106
108
|
return path
|
107
109
|
end
|
@@ -134,6 +136,7 @@ module Apipie
|
|
134
136
|
:errors => errors.map(&:to_json),
|
135
137
|
:params => params_ordered.map(&:to_json).flatten,
|
136
138
|
:examples => @examples,
|
139
|
+
:metadata => @metadata,
|
137
140
|
:see => see.map(&:to_json)
|
138
141
|
}
|
139
142
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# Middleware for rails app that adds checksum of JSON in the response headers
|
2
|
+
# which can help client to realize when JSON has changed
|
3
|
+
#
|
4
|
+
# Add the following to your application.rb
|
5
|
+
# require 'apipie/middleware/checksum_in_headers'
|
6
|
+
# # Add JSON checksum in headers for smarter caching
|
7
|
+
# config.middleware.use "Apipie::Middleware::ChecksumInHeaders"
|
8
|
+
#
|
9
|
+
# And in your apipie initializer allow checksum calculation
|
10
|
+
# Apipie.configuration.update_checksum = true
|
11
|
+
# and reload documentation
|
12
|
+
# Apipie.reload_documentation
|
13
|
+
#
|
14
|
+
# By default the header is added to requests on /api and /apipie only
|
15
|
+
# It can be changed with
|
16
|
+
# Apipie.configuration.checksum_path = ['/prefix/api']
|
17
|
+
# If set to nil the header is added always
|
18
|
+
|
19
|
+
module Apipie
|
20
|
+
module Middleware
|
21
|
+
class ChecksumInHeaders
|
22
|
+
def initialize(app)
|
23
|
+
@app = app
|
24
|
+
end
|
25
|
+
|
26
|
+
def call(env)
|
27
|
+
status, headers, body = @app.call(env)
|
28
|
+
if !Apipie.configuration.checksum_path || env['PATH_INFO'].start_with?(*Apipie.configuration.checksum_path)
|
29
|
+
headers.merge!( 'Apipie-Checksum' => Apipie.checksum )
|
30
|
+
end
|
31
|
+
return [status, headers, body]
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -8,8 +8,7 @@ module Apipie
|
|
8
8
|
# validator - Validator::BaseValidator subclass
|
9
9
|
class ParamDescription
|
10
10
|
|
11
|
-
attr_reader :method_description, :name, :desc, :allow_nil, :validator, :options
|
12
|
-
|
11
|
+
attr_reader :method_description, :name, :desc, :allow_nil, :validator, :options, :metadata, :show, :as
|
13
12
|
attr_accessor :parent, :required
|
14
13
|
|
15
14
|
def self.from_dsl_data(method_description, args)
|
@@ -39,14 +38,23 @@ module Apipie
|
|
39
38
|
|
40
39
|
@method_description = method_description
|
41
40
|
@name = concern_subst(name)
|
41
|
+
@as = options[:as] || @name
|
42
42
|
@desc = concern_subst(Apipie.markup_to_html(@options[:desc] || ''))
|
43
43
|
@parent = @options[:parent]
|
44
|
+
@metadata = @options[:meta]
|
45
|
+
|
44
46
|
@required = if @options.has_key? :required
|
45
47
|
@options[:required]
|
46
48
|
else
|
47
49
|
Apipie.configuration.required_by_default?
|
48
50
|
end
|
49
51
|
|
52
|
+
@show = if @options.has_key? :show
|
53
|
+
@options[:show]
|
54
|
+
else
|
55
|
+
true
|
56
|
+
end
|
57
|
+
|
50
58
|
@allow_nil = @options[:allow_nil] || false
|
51
59
|
|
52
60
|
action_awareness
|
@@ -59,15 +67,24 @@ module Apipie
|
|
59
67
|
|
60
68
|
def validate(value)
|
61
69
|
return true if @allow_nil && value.nil?
|
62
|
-
|
70
|
+
if (!@allow_nil && value.nil?) || !@validator.valid?(value)
|
63
71
|
error = @validator.error
|
64
72
|
error = ParamError.new(error) unless error.is_a? StandardError
|
65
73
|
raise error
|
66
74
|
end
|
67
75
|
end
|
68
76
|
|
77
|
+
def process_value(value)
|
78
|
+
if @validator.respond_to?(:process_value)
|
79
|
+
@validator.process_value(value)
|
80
|
+
else
|
81
|
+
value
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
69
85
|
def full_name
|
70
|
-
name_parts = parents_and_self.map
|
86
|
+
name_parts = parents_and_self.map{|p| p.name if p.show}.compact
|
87
|
+
return name.to_s if name_parts.blank?
|
71
88
|
return ([name_parts.first] + name_parts[1..-1].map { |n| "[#{n}]" }).join("")
|
72
89
|
end
|
73
90
|
|
@@ -92,6 +109,8 @@ module Apipie
|
|
92
109
|
:allow_nil => allow_nil,
|
93
110
|
:validator => validator.to_s,
|
94
111
|
:expected_type => validator.expected_type,
|
112
|
+
:metadata => metadata,
|
113
|
+
:show => show,
|
95
114
|
:params => validator.hash_params_ordered.map(&:to_json)
|
96
115
|
}
|
97
116
|
else
|
@@ -102,6 +121,8 @@ module Apipie
|
|
102
121
|
:required => required,
|
103
122
|
:allow_nil => allow_nil,
|
104
123
|
:validator => validator.to_s,
|
124
|
+
:metadata => metadata,
|
125
|
+
:show => show,
|
105
126
|
:expected_type => validator.expected_type
|
106
127
|
}
|
107
128
|
end
|
@@ -12,7 +12,7 @@ module Apipie
|
|
12
12
|
class ResourceDescription
|
13
13
|
|
14
14
|
attr_reader :controller, :_short_description, :_full_description, :_methods, :_id,
|
15
|
-
:_path, :_name, :_params_args, :_errors_args, :_formats, :_parent
|
15
|
+
:_path, :_name, :_params_args, :_errors_args, :_formats, :_parent, :_metadata
|
16
16
|
|
17
17
|
def initialize(controller, resource_name, dsl_data = nil, version = nil, &block)
|
18
18
|
|
@@ -37,19 +37,22 @@ module Apipie
|
|
37
37
|
@_formats = dsl_data[:formats]
|
38
38
|
@_errors_args = dsl_data[:errors]
|
39
39
|
@_params_args = dsl_data[:params]
|
40
|
+
@_metadata = dsl_data[:meta]
|
41
|
+
@_api_base_url = dsl_data[:api_base_url]
|
40
42
|
|
41
43
|
if dsl_data[:app_info]
|
42
44
|
Apipie.configuration.app_info[_version] = dsl_data[:app_info]
|
43
45
|
end
|
44
|
-
if dsl_data[:api_base_url]
|
45
|
-
Apipie.configuration.api_base_url[_version] = dsl_data[:api_base_url]
|
46
|
-
end
|
47
46
|
end
|
48
47
|
|
49
48
|
def _version
|
50
49
|
@_version || @_parent.try(:_version) || Apipie.configuration.default_version
|
51
50
|
end
|
52
51
|
|
52
|
+
def _api_base_url
|
53
|
+
@_api_base_url || @_parent.try(:_api_base_url) || Apipie.api_base_url(_version)
|
54
|
+
end
|
55
|
+
|
53
56
|
def add_method_description(method_description)
|
54
57
|
Apipie.debug "@resource_descriptions[#{self._version}][#{self._name}]._methods[#{method_description.method}] = #{method_description}"
|
55
58
|
@_methods[method_description.method.to_sym] = method_description
|
@@ -94,6 +97,7 @@ module Apipie
|
|
94
97
|
:full_description => @_full_description,
|
95
98
|
:version => _version,
|
96
99
|
:formats => @_formats,
|
100
|
+
:metadata => @_metadata,
|
97
101
|
:methods => methods
|
98
102
|
}
|
99
103
|
end
|
data/lib/apipie/routing.rb
CHANGED
@@ -3,6 +3,7 @@ module Apipie
|
|
3
3
|
module MapperExtensions
|
4
4
|
def apipie
|
5
5
|
namespace "apipie", :path => Apipie.configuration.doc_base_url do
|
6
|
+
get 'apipie_checksum', to: "apipies#apipie_checksum", :format => "json"
|
6
7
|
constraints(:version => /[^\/]+/) do
|
7
8
|
get("(:version)/(:resource)/(:method)" => "apipies#index", :as => :apipie)
|
8
9
|
end
|
data/lib/apipie/validator.rb
CHANGED
@@ -150,6 +150,28 @@ module Apipie
|
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
153
|
+
class ArrayClassValidator < BaseValidator
|
154
|
+
|
155
|
+
def initialize(param_description, argument)
|
156
|
+
super(param_description)
|
157
|
+
@array = argument
|
158
|
+
end
|
159
|
+
|
160
|
+
def validate(value)
|
161
|
+
@array.include?(value.class)
|
162
|
+
end
|
163
|
+
|
164
|
+
def self.build(param_description, argument, options, block)
|
165
|
+
if argument.is_a?(Array) && argument.first.class == Class && !block.is_a?(Proc)
|
166
|
+
self.new(param_description, argument)
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def description
|
171
|
+
"Must be one of: #{@array.join(', ')}."
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
153
175
|
class ProcValidator < BaseValidator
|
154
176
|
|
155
177
|
def initialize(param_description, argument)
|
@@ -205,6 +227,7 @@ module Apipie
|
|
205
227
|
end
|
206
228
|
|
207
229
|
def validate(value)
|
230
|
+
return false if !value.is_a? Hash
|
208
231
|
if @hash_params
|
209
232
|
@hash_params.each do |k, p|
|
210
233
|
if Apipie.configuration.validate_presence?
|
@@ -218,6 +241,16 @@ module Apipie
|
|
218
241
|
return true
|
219
242
|
end
|
220
243
|
|
244
|
+
def process_value(value)
|
245
|
+
if @hash_params && value
|
246
|
+
return @hash_params.each_with_object({}) do |(key, param), api_params|
|
247
|
+
if value.has_key?(key)
|
248
|
+
api_params[param.as] = param.process_value(value[key])
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
253
|
+
|
221
254
|
def description
|
222
255
|
"Must be a Hash"
|
223
256
|
end
|
@@ -250,7 +283,7 @@ module Apipie
|
|
250
283
|
|
251
284
|
|
252
285
|
# special type of validator: we say that it's not specified
|
253
|
-
class UndefValidator <
|
286
|
+
class UndefValidator < BaseValidator
|
254
287
|
|
255
288
|
def validate(value)
|
256
289
|
true
|
@@ -267,7 +300,7 @@ module Apipie
|
|
267
300
|
end
|
268
301
|
end
|
269
302
|
|
270
|
-
class NumberValidator <
|
303
|
+
class NumberValidator < BaseValidator
|
271
304
|
|
272
305
|
def validate(value)
|
273
306
|
self.class.validate(value)
|
@@ -288,7 +321,7 @@ module Apipie
|
|
288
321
|
end
|
289
322
|
end
|
290
323
|
|
291
|
-
class BooleanValidator <
|
324
|
+
class BooleanValidator < BaseValidator
|
292
325
|
|
293
326
|
def validate(value)
|
294
327
|
%w[true false].include?(value.to_s)
|
@@ -305,6 +338,41 @@ module Apipie
|
|
305
338
|
end
|
306
339
|
end
|
307
340
|
|
341
|
+
class NestedValidator < BaseValidator
|
342
|
+
|
343
|
+
def initialize(param_description, argument, param_group)
|
344
|
+
super(param_description)
|
345
|
+
@validator = Apipie::Validator:: HashValidator.new(param_description, argument, param_group)
|
346
|
+
@type = argument
|
347
|
+
end
|
348
|
+
|
349
|
+
def validate(value)
|
350
|
+
value ||= [] # Rails convert empty array to nil
|
351
|
+
return false if value.class != Array
|
352
|
+
value.each do |child|
|
353
|
+
return false unless @validator.validate(child)
|
354
|
+
end
|
355
|
+
true
|
356
|
+
end
|
357
|
+
|
358
|
+
def process_value(value)
|
359
|
+
value ||= [] # Rails convert empty array to nil
|
360
|
+
@values = []
|
361
|
+
value.each do |child|
|
362
|
+
@values << @validator.process_value(child)
|
363
|
+
end
|
364
|
+
@values
|
365
|
+
end
|
366
|
+
|
367
|
+
def self.build(param_description, argument, options, block)
|
368
|
+
self.new(param_description, block, options[:param_group]) if block.is_a?(Proc) && block.arity == 0 && argument == Array
|
369
|
+
end
|
370
|
+
|
371
|
+
def description
|
372
|
+
"Must be an Array of nested elements"
|
373
|
+
end
|
374
|
+
end
|
375
|
+
|
308
376
|
end
|
309
377
|
end
|
310
378
|
|
data/lib/apipie/version.rb
CHANGED
data/lib/tasks/apipie.rake
CHANGED
@@ -35,6 +35,16 @@ namespace :apipie do
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
+
desc "Generate static documentation json"
|
39
|
+
task :static_json, [:version] => :environment do |t, args|
|
40
|
+
with_loaded_documentation do
|
41
|
+
args.with_defaults(:version => Apipie.configuration.default_version)
|
42
|
+
out = ENV["OUT"] || File.join(::Rails.root, 'doc', 'apidoc')
|
43
|
+
doc = Apipie.to_json(args[:version])
|
44
|
+
generate_json_page(out, doc)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
38
48
|
desc "Generate cache to avoid production dependencies on markup languages"
|
39
49
|
task :cache => :environment do
|
40
50
|
with_loaded_documentation do
|
@@ -60,11 +70,15 @@ namespace :apipie do
|
|
60
70
|
|
61
71
|
# Attempt to use the Rails application views, otherwise default to built in views
|
62
72
|
def renderer
|
63
|
-
if
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
73
|
+
return @apipie_renderer if @apipie_renderer
|
74
|
+
base_path = if File.directory?("#{Rails.root}/app/views/apipie/apipies")
|
75
|
+
"#{Rails.root}/app/views/apipie/apipies"
|
76
|
+
else
|
77
|
+
File.expand_path("../../../app/views/apipie/apipies", __FILE__)
|
78
|
+
end
|
79
|
+
@apipie_renderer = ActionView::Base.new(base_path)
|
80
|
+
@apipie_renderer.singleton_class.send(:include, ApipieHelper)
|
81
|
+
return @apipie_renderer
|
68
82
|
end
|
69
83
|
|
70
84
|
def render_page(file_name, template, variables, layout = 'apipie')
|
@@ -79,6 +93,13 @@ namespace :apipie do
|
|
79
93
|
end
|
80
94
|
end
|
81
95
|
|
96
|
+
def generate_json_page(file_base, doc)
|
97
|
+
FileUtils.mkdir_p(file_base) unless File.exists?(file_base)
|
98
|
+
|
99
|
+
filename = 'schema_apipie.json'
|
100
|
+
File.open("#{file_base}/#{filename}", 'w') { |file| file.write(JSON.pretty_generate(doc)) }
|
101
|
+
end
|
102
|
+
|
82
103
|
def generate_one_page(file_base, doc)
|
83
104
|
FileUtils.mkdir_p(File.dirname(file_base)) unless File.exists?(File.dirname(file_base))
|
84
105
|
|
@@ -120,6 +120,7 @@ describe Apipie::ApipiesController do
|
|
120
120
|
File.open(File.join(cache_dir, "apidoc", "v1", "resource", "method.html"), "w") { |f| f << "method.html cache" }
|
121
121
|
|
122
122
|
Apipie.configuration.use_cache = true
|
123
|
+
@orig_cache_dir = Apipie.configuration.cache_dir
|
123
124
|
Apipie.configuration.cache_dir = cache_dir
|
124
125
|
@orig_version = Apipie.configuration.default_version
|
125
126
|
Apipie.configuration.default_version = 'v1'
|
@@ -128,6 +129,7 @@ describe Apipie::ApipiesController do
|
|
128
129
|
after do
|
129
130
|
Apipie.configuration.use_cache = false
|
130
131
|
Apipie.configuration.default_version = @orig_version
|
132
|
+
Apipie.configuration.cache_dir = @orig_cache_dir
|
131
133
|
# FileUtils.rm_r(cache_dir) if File.exists?(cache_dir)
|
132
134
|
end
|
133
135
|
|
@@ -13,7 +13,7 @@ describe ConcernsController do
|
|
13
13
|
end
|
14
14
|
|
15
15
|
it "should pass if required parameter is missing" do
|
16
|
-
lambda { get :show, :id => 5 }.should_not raise_error
|
16
|
+
lambda { get :show, :id => '5' }.should_not raise_error
|
17
17
|
end
|
18
18
|
|
19
19
|
it "peserved the order of methods being defined in file" do
|
@@ -110,6 +110,13 @@ describe UsersController do
|
|
110
110
|
assert_response :success
|
111
111
|
end
|
112
112
|
|
113
|
+
it "should work with nil value for a required hash param" do
|
114
|
+
expect {
|
115
|
+
get :show, :id => '5', :session => "secret_hash", :hash_param => {:dummy_hash => nil}
|
116
|
+
}.to raise_error(Apipie::ParamInvalid, /dummy_hash/)
|
117
|
+
assert_response :success
|
118
|
+
end
|
119
|
+
|
113
120
|
it "should fail if required parameter is missing" do
|
114
121
|
lambda { get :show, :id => 5 }.should raise_error(Apipie::ParamMissing, /\bsession\b/)
|
115
122
|
end
|
@@ -142,7 +149,7 @@ describe UsersController do
|
|
142
149
|
assert_response :success
|
143
150
|
get :show, :id => 5, :session => "secret_hash", :array_param => "two"
|
144
151
|
assert_response :success
|
145
|
-
get :show, :id => 5, :session => "secret_hash", :array_param => 1
|
152
|
+
get :show, :id => 5, :session => "secret_hash", :array_param => '1'
|
146
153
|
assert_response :success
|
147
154
|
get :show, :id => 5, :session => "secret_hash", :boolean_param => false
|
148
155
|
assert_response :success
|
@@ -199,6 +206,10 @@ describe UsersController do
|
|
199
206
|
post :create, :user => { :name => "root" }
|
200
207
|
}.should raise_error(Apipie::ParamMissing, /pass/)
|
201
208
|
|
209
|
+
lambda {
|
210
|
+
post :create, :user => "a string is not a hash"
|
211
|
+
}.should raise_error(Apipie::ParamInvalid, /user/)
|
212
|
+
|
202
213
|
post :create, :user => { :name => "root", :pass => "pwd" }
|
203
214
|
assert_response :success
|
204
215
|
end
|
@@ -211,6 +222,8 @@ describe UsersController do
|
|
211
222
|
:description => "\n<p>Additional optional facts about the user</p>\n",
|
212
223
|
:required => false,
|
213
224
|
:allow_nil => true,
|
225
|
+
:metadata => nil,
|
226
|
+
:show => true,
|
214
227
|
:expected_type => "hash")
|
215
228
|
end
|
216
229
|
|
@@ -225,6 +238,67 @@ describe UsersController do
|
|
225
238
|
assert_response :success
|
226
239
|
end
|
227
240
|
|
241
|
+
describe "nested elements" do
|
242
|
+
|
243
|
+
context "with valid input" do
|
244
|
+
it "should succeed" do
|
245
|
+
put :update,
|
246
|
+
{
|
247
|
+
:id => 5,
|
248
|
+
:user => {
|
249
|
+
:name => "root",
|
250
|
+
:pass => "12345"
|
251
|
+
},
|
252
|
+
:comments => [
|
253
|
+
{
|
254
|
+
:comment => 'comment1'
|
255
|
+
},
|
256
|
+
{
|
257
|
+
:comment => 'comment2'
|
258
|
+
}
|
259
|
+
]
|
260
|
+
}
|
261
|
+
|
262
|
+
assert_response :success
|
263
|
+
end
|
264
|
+
end
|
265
|
+
context "with bad input" do
|
266
|
+
it "should raise an error" do
|
267
|
+
expect{ put :update,
|
268
|
+
{
|
269
|
+
:id => 5,
|
270
|
+
:user => {
|
271
|
+
:name => "root",
|
272
|
+
:pass => "12345"
|
273
|
+
},
|
274
|
+
:comments => [
|
275
|
+
{
|
276
|
+
:comment => 'comment1'
|
277
|
+
},
|
278
|
+
{
|
279
|
+
:comment => {bad_input: 5}
|
280
|
+
}
|
281
|
+
]
|
282
|
+
}
|
283
|
+
}.to raise_error(Apipie::ParamInvalid)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
it "should work with empty array" do
|
287
|
+
put :update,
|
288
|
+
{
|
289
|
+
:id => 5,
|
290
|
+
:user => {
|
291
|
+
:name => "root",
|
292
|
+
:pass => "12345"
|
293
|
+
},
|
294
|
+
:comments => [
|
295
|
+
]
|
296
|
+
}
|
297
|
+
|
298
|
+
assert_response :success
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
228
302
|
end
|
229
303
|
end
|
230
304
|
|
@@ -297,8 +371,8 @@ describe UsersController do
|
|
297
371
|
|
298
372
|
it "should contain all params description" do
|
299
373
|
a = Apipie.get_method_description(UsersController, :show)
|
300
|
-
a.params.count.should ==
|
301
|
-
a.instance_variable_get('@params_ordered').count.should ==
|
374
|
+
a.params.count.should == 11
|
375
|
+
a.instance_variable_get('@params_ordered').count.should == 9
|
302
376
|
end
|
303
377
|
|
304
378
|
it "should contain all api method description" do
|
@@ -319,7 +393,7 @@ describe UsersController do
|
|
319
393
|
it "should be described by valid json" do
|
320
394
|
json = Apipie[UsersController, :two_urls].to_json
|
321
395
|
expected_hash = {
|
322
|
-
:errors => [{:code=>404, :description=>"Missing"},
|
396
|
+
:errors => [{:code=>404, :description=>"Missing", :metadata => {:some => "metadata"}},
|
323
397
|
{:code=>500, :description=>"Server crashed for some <%= reason %>"}],
|
324
398
|
:examples => [],
|
325
399
|
:doc_url => "#{Apipie.configuration.doc_base_url}/development/users/two_urls",
|
@@ -331,33 +405,48 @@ describe UsersController do
|
|
331
405
|
:validator=>"Must be String",
|
332
406
|
:description=>"\n<p>Authorization</p>\n",
|
333
407
|
:name=>"oauth",
|
408
|
+
:show=>true,
|
334
409
|
:expected_type=>"string"},
|
335
410
|
{:validator=>"Must be a Hash",
|
336
|
-
:description=>"\n<p>
|
411
|
+
:description=>"\n<p>Deprecated parameter not documented</p>\n",
|
337
412
|
:expected_type=>"hash",
|
338
413
|
:allow_nil=>false,
|
339
|
-
:name=>"
|
414
|
+
:name=>"legacy_param",
|
340
415
|
:required=>false,
|
341
|
-
:full_name=>"
|
416
|
+
:full_name=>"legacy_param",
|
417
|
+
:show=>false,
|
342
418
|
:params=>
|
343
|
-
[{:
|
344
|
-
:
|
345
|
-
:
|
346
|
-
:
|
347
|
-
:name=>"
|
348
|
-
:
|
349
|
-
|
350
|
-
:
|
351
|
-
:
|
352
|
-
:
|
353
|
-
|
354
|
-
|
419
|
+
[{:validator=>"Must be a Hash",
|
420
|
+
:description=>"\n<p>Param description for all methods</p>\n",
|
421
|
+
:expected_type=>"hash",
|
422
|
+
:allow_nil=>false,
|
423
|
+
:name=>"resource_param",
|
424
|
+
:required=>false,
|
425
|
+
:full_name=>"resource_param",
|
426
|
+
:show=>true,
|
427
|
+
:params=>
|
428
|
+
[{:required=>true,
|
429
|
+
:allow_nil => false,
|
430
|
+
:validator=>"Must be String",
|
431
|
+
:description=>"\n<p>Username for login</p>\n",
|
432
|
+
:name=>"ausername", :full_name=>"resource_param[ausername]",
|
433
|
+
:show=>true,
|
434
|
+
:expected_type=>"string"},
|
435
|
+
{:required=>true,
|
436
|
+
:allow_nil => false,
|
437
|
+
:validator=>"Must be String",
|
438
|
+
:description=>"\n<p>Password for login</p>\n",
|
439
|
+
:name=>"apassword", :full_name=>"resource_param[apassword]",
|
440
|
+
:show=>true,
|
441
|
+
:expected_type=>"string"}
|
442
|
+
]}
|
355
443
|
]
|
356
444
|
},
|
357
445
|
{:required=>false, :validator=>"Parameter has to be Integer.",
|
358
446
|
:allow_nil => false,
|
359
447
|
:description=>"\n<p>Company ID</p>\n",
|
360
448
|
:name=>"id", :full_name=>"id",
|
449
|
+
:show=>true,
|
361
450
|
:expected_type=>"numeric"},
|
362
451
|
],
|
363
452
|
:name => 'two_urls',
|
@@ -476,4 +565,26 @@ EOS2
|
|
476
565
|
end
|
477
566
|
end
|
478
567
|
end
|
568
|
+
|
569
|
+
describe "Parameter processing / extraction" do
|
570
|
+
before do
|
571
|
+
Apipie.configuration.process_params = true
|
572
|
+
end
|
573
|
+
|
574
|
+
it "process correctly the parameters" do
|
575
|
+
post :create, {:user => {:name => 'dummy', :pass => 'dummy', :membership => 'standard'}, :facts => nil}
|
576
|
+
|
577
|
+
expect(assigns(:api_params).with_indifferent_access).to eq({:user => {:name=>"dummy", :pass=>"dummy", :membership=>"standard"}, :facts => nil}.with_indifferent_access)
|
578
|
+
end
|
579
|
+
|
580
|
+
it "ignore not described parameters" do
|
581
|
+
post :create, {:user => {:name => 'dummy', :pass => 'dummy', :membership => 'standard', :id => 0}}
|
582
|
+
|
583
|
+
expect(assigns(:api_params).with_indifferent_access).to eq({:user => {:name=>"dummy", :pass=>"dummy", :membership=>"standard"}}.with_indifferent_access)
|
584
|
+
end
|
585
|
+
|
586
|
+
after do
|
587
|
+
Apipie.configuration.process_params = false
|
588
|
+
end
|
589
|
+
end
|
479
590
|
end
|