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.
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