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.
Files changed (51) hide show
  1. data/.gitignore +1 -1
  2. data/.travis.yml +6 -0
  3. data/CHANGELOG.md +97 -0
  4. data/Gemfile +1 -1
  5. data/Gemfile.rails30 +5 -0
  6. data/Gemfile.rails32 +5 -0
  7. data/Gemfile.rails40 +5 -0
  8. data/Gemfile.rails41 +5 -0
  9. data/README.rst +126 -11
  10. data/apipie-rails.gemspec +1 -1
  11. data/app/controllers/apipie/apipies_controller.rb +3 -0
  12. data/app/helpers/apipie_helper.rb +9 -0
  13. data/app/views/apipie/apipies/_metadata.erb +1 -0
  14. data/app/views/apipie/apipies/_method_detail.erb +46 -0
  15. data/app/views/apipie/apipies/_params.html.erb +12 -0
  16. data/app/views/apipie/apipies/_params_plain.html.erb +4 -0
  17. data/app/views/apipie/apipies/apipie_checksum.json.erb +1 -0
  18. data/app/views/apipie/apipies/method.html.erb +1 -37
  19. data/app/views/apipie/apipies/plain.html.erb +1 -0
  20. data/app/views/apipie/apipies/resource.html.erb +6 -37
  21. data/app/views/apipie/apipies/static.html.erb +1 -0
  22. data/lib/apipie/application.rb +16 -2
  23. data/lib/apipie/configuration.rb +8 -2
  24. data/lib/apipie/dsl_definition.rb +25 -6
  25. data/lib/apipie/error_description.rb +22 -10
  26. data/lib/apipie/extractor.rb +2 -1
  27. data/lib/apipie/extractor/writer.rb +8 -6
  28. data/lib/apipie/method_description.rb +7 -4
  29. data/lib/apipie/middleware/checksum_in_headers.rb +35 -0
  30. data/lib/apipie/param_description.rb +25 -4
  31. data/lib/apipie/resource_description.rb +8 -4
  32. data/lib/apipie/routing.rb +1 -0
  33. data/lib/apipie/validator.rb +71 -3
  34. data/lib/apipie/version.rb +1 -1
  35. data/lib/tasks/apipie.rake +26 -5
  36. data/spec/controllers/apipies_controller_spec.rb +2 -0
  37. data/spec/controllers/concerns_controller_spec.rb +1 -1
  38. data/spec/controllers/users_controller_spec.rb +130 -19
  39. data/spec/dummy/app/controllers/api/v1/architectures_controller.rb +1 -0
  40. data/spec/dummy/app/controllers/api/v2/nested/architectures_controller.rb +22 -20
  41. data/spec/dummy/app/controllers/concerns/sample_controller.rb +32 -30
  42. data/spec/dummy/app/controllers/users_controller.rb +18 -5
  43. data/spec/lib/method_description_spec.rb +22 -0
  44. data/spec/lib/param_description_spec.rb +77 -0
  45. data/spec/lib/rake_spec.rb +68 -0
  46. data/spec/lib/resource_description_spec.rb +18 -0
  47. data/spec/lib/validator_spec.rb +9 -0
  48. data/spec/spec_helper.rb +2 -1
  49. data/spec/support/rake.rb +21 -0
  50. metadata +20 -7
  51. 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.new(args)
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.new(args)
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 = "#{Apipie.api_base_url(@resource._version)}#{api.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
- unless @validator.valid?(value)
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(&:name)
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
@@ -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
@@ -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 < Apipie::Validator::BaseValidator
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 < Apipie::Validator::BaseValidator
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 < Apipie::Validator::BaseValidator
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
 
@@ -1,3 +1,3 @@
1
1
  module Apipie
2
- VERSION = '0.0.24'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -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 File.directory?("#{Rails.root}/app/views/apipie/apipies")
64
- ActionView::Base.new("#{Rails.root}/app/views/apipie/apipies")
65
- else
66
- ActionView::Base.new(File.expand_path("../../../app/views/apipie/apipies", __FILE__))
67
- end
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 == 9
301
- a.instance_variable_get('@params_ordered').count.should == 7
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>Param description for all methods</p>\n",
411
+ :description=>"\n<p>Deprecated parameter not documented</p>\n",
337
412
  :expected_type=>"hash",
338
413
  :allow_nil=>false,
339
- :name=>"resource_param",
414
+ :name=>"legacy_param",
340
415
  :required=>false,
341
- :full_name=>"resource_param",
416
+ :full_name=>"legacy_param",
417
+ :show=>false,
342
418
  :params=>
343
- [{:required=>true,
344
- :allow_nil => false,
345
- :validator=>"Must be String",
346
- :description=>"\n<p>Username for login</p>\n",
347
- :name=>"ausername", :full_name=>"resource_param[ausername]",
348
- :expected_type=>"string"},
349
- {:required=>true,
350
- :allow_nil => false,
351
- :validator=>"Must be String",
352
- :description=>"\n<p>Password for login</p>\n",
353
- :name=>"apassword", :full_name=>"resource_param[apassword]",
354
- :expected_type=>"string"}
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