apipie-rails 0.0.24 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|