params_wrapper_test.rb 12.4 KB
Newer Older
1
require "abstract_unit"
2 3 4

module Admin; class User; end; end

5 6
module ParamsWrapperTestHelp
  def with_default_wrapper_options(&block)
7
    @controller.class._set_wrapper_options(format: [:json])
8 9 10 11 12 13 14 15 16
    @controller.class.inherited(@controller.class)
    yield
  end

  def assert_parameters(expected)
    assert_equal expected, self.class.controller_class.last_parameters
  end
end

17
class ParamsWrapperTest < ActionController::TestCase
18 19
  include ParamsWrapperTestHelp

20
  class UsersController < ActionController::Base
21 22 23 24 25 26 27
    class << self
      attr_accessor :last_parameters
    end

    def parse
      self.class.last_parameters = request.params.except(:controller, :action)
      head :ok
28
    end
K
kennyj 已提交
29
  end
30

31 32 33 34 35
  class User
    def self.attribute_names
      []
    end

36
    def self.stored_attributes
S
Sid Ngeth 已提交
37 38
      { settings: [:color, :size] }
    end
39
  end
S
Sid Ngeth 已提交
40

41
  class Person
42 43 44 45
    def self.attribute_names
      []
    end
  end
46 47 48

  tests UsersController

49 50 51 52
  def teardown
    UsersController.last_parameters = nil
  end

53 54
  def test_filtered_parameters
    with_default_wrapper_options do
55 56
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu" }
57
      assert_equal({ "controller" => "params_wrapper_test/users", "action" => "parse", "username" => "sikachu", "user" => { "username" => "sikachu" } }, @request.filtered_parameters)
58 59 60
    end
  end

V
Vijay Dev 已提交
61
  def test_derived_name_from_controller
62
    with_default_wrapper_options do
63 64
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu" }
65
      assert_parameters("username" => "sikachu", "user" => { "username" => "sikachu" })
66 67 68
    end
  end

S
Sid Ngeth 已提交
69
  def test_store_accessors_wrapped
70 71 72 73 74 75 76
    assert_called(User, :attribute_names, times: 2, returns: ["username"]) do
      with_default_wrapper_options do
        @request.env["CONTENT_TYPE"] = "application/json"
        post :parse, params: { "username" => "sikachu", "color" => "blue", "size" => "large" }
        assert_parameters("username" => "sikachu", "color" => "blue", "size" => "large",
                           "user" => { "username" => "sikachu", "color" => "blue", "size" => "large" })
      end
S
Sid Ngeth 已提交
77 78 79
    end
  end

80 81 82 83
  def test_specify_wrapper_name
    with_default_wrapper_options do
      UsersController.wrap_parameters :person

84 85
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu" }
86
      assert_parameters("username" => "sikachu", "person" => { "username" => "sikachu" })
87 88 89 90 91 92 93
    end
  end

  def test_specify_wrapper_model
    with_default_wrapper_options do
      UsersController.wrap_parameters Person

94 95
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu" }
96
      assert_parameters("username" => "sikachu", "person" => { "username" => "sikachu" })
97 98 99
    end
  end

100
  def test_specify_include_option
101
    with_default_wrapper_options do
102
      UsersController.wrap_parameters include: :username
103

104 105
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu", "title" => "Developer" }
106
      assert_parameters("username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu" })
107 108 109
    end
  end

110
  def test_specify_exclude_option
111
    with_default_wrapper_options do
112
      UsersController.wrap_parameters exclude: :title
113

114 115
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu", "title" => "Developer" }
116
      assert_parameters("username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu" })
117 118 119
    end
  end

120
  def test_specify_both_wrapper_name_and_include_option
121
    with_default_wrapper_options do
122
      UsersController.wrap_parameters :person, include: :username
123

124 125
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu", "title" => "Developer" }
126
      assert_parameters("username" => "sikachu", "title" => "Developer", "person" => { "username" => "sikachu" })
127 128 129 130 131
    end
  end

  def test_not_enabled_format
    with_default_wrapper_options do
132 133
      @request.env["CONTENT_TYPE"] = "application/xml"
      post :parse, params: { "username" => "sikachu", "title" => "Developer" }
134
      assert_parameters("username" => "sikachu", "title" => "Developer")
135 136 137
    end
  end

138 139 140
  def test_wrap_parameters_false
    with_default_wrapper_options do
      UsersController.wrap_parameters false
141 142
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu", "title" => "Developer" }
143
      assert_parameters("username" => "sikachu", "title" => "Developer")
144 145 146
    end
  end

147 148
  def test_specify_format
    with_default_wrapper_options do
149
      UsersController.wrap_parameters format: :xml
150

151 152
      @request.env["CONTENT_TYPE"] = "application/xml"
      post :parse, params: { "username" => "sikachu", "title" => "Developer" }
153
      assert_parameters("username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu", "title" => "Developer" })
154 155 156 157 158
    end
  end

  def test_not_wrap_reserved_parameters
    with_default_wrapper_options do
159 160
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "authenticity_token" => "pwned", "_method" => "put", "utf8" => "&#9731;", "username" => "sikachu" }
161
      assert_parameters("authenticity_token" => "pwned", "_method" => "put", "utf8" => "&#9731;", "username" => "sikachu", "user" => { "username" => "sikachu" })
162 163 164 165 166
    end
  end

  def test_no_double_wrap_if_key_exists
    with_default_wrapper_options do
167
      @request.env["CONTENT_TYPE"] = "application/json"
168
      post :parse, params: { "user" => { "username" => "sikachu" } }
169
      assert_parameters("user" => { "username" => "sikachu" })
170 171 172
    end
  end

173 174 175 176 177 178 179 180
  def test_no_double_wrap_if_key_exists_and_value_is_nil
    with_default_wrapper_options do
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "user" => nil }
      assert_parameters("user" => nil)
    end
  end

181 182
  def test_nested_params
    with_default_wrapper_options do
183
      @request.env["CONTENT_TYPE"] = "application/json"
184 185
      post :parse, params: { "person" => { "username" => "sikachu" } }
      assert_parameters("person" => { "username" => "sikachu" }, "user" => { "person" => { "username" => "sikachu" } })
186 187 188 189
    end
  end

  def test_derived_wrapped_keys_from_matching_model
190 191
    assert_called(User, :attribute_names, times: 2, returns: ["username"]) do
      with_default_wrapper_options do
192 193
        @request.env["CONTENT_TYPE"] = "application/json"
        post :parse, params: { "username" => "sikachu", "title" => "Developer" }
194
        assert_parameters("username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu" })
195
      end
196 197 198 199 200
    end
  end

  def test_derived_wrapped_keys_from_specified_model
    with_default_wrapper_options do
201 202
      assert_called(Person, :attribute_names, times: 2, returns: ["username"]) do
        UsersController.wrap_parameters Person
203

204 205
        @request.env["CONTENT_TYPE"] = "application/json"
        post :parse, params: { "username" => "sikachu", "title" => "Developer" }
206
        assert_parameters("username" => "sikachu", "title" => "Developer", "person" => { "username" => "sikachu" })
207
      end
208 209 210
    end
  end

211 212
  def test_not_wrapping_abstract_model
    with_default_wrapper_options do
213 214
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu", "title" => "Developer" }
215
      assert_parameters("username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu", "title" => "Developer" })
216 217
    end
  end
218 219 220

  def test_preserves_query_string_params
    with_default_wrapper_options do
221 222
      @request.env["CONTENT_TYPE"] = "application/json"
      get :parse, params: { "user" => { "username" => "nixon" } }
223
      assert_parameters(
224
        "user" => { "username" => "nixon" }
225 226 227 228 229 230
      )
    end
  end

  def test_empty_parameter_set
    with_default_wrapper_options do
231
      @request.env["CONTENT_TYPE"] = "application/json"
232
      post :parse, params: {}
233
      assert_parameters(
234
        "user" => {}
235 236 237
      )
    end
  end
J
Jon Moss 已提交
238 239 240

  def test_handles_empty_content_type
    with_default_wrapper_options do
241
      @request.env["CONTENT_TYPE"] = nil
J
Jon Moss 已提交
242 243 244
      _controller_class.dispatch(:parse, @request, @response)

      assert_equal 200, @response.status
245
      assert_equal "", @response.body
J
Jon Moss 已提交
246 247
    end
  end
248 249 250
end

class NamespacedParamsWrapperTest < ActionController::TestCase
251 252
  include ParamsWrapperTestHelp

253
  module Admin
254 255 256 257 258 259 260 261 262 263
    module Users
      class UsersController < ActionController::Base;
        class << self
          attr_accessor :last_parameters
        end

        def parse
          self.class.last_parameters = request.params.except(:controller, :action)
          head :ok
        end
264 265
      end
    end
266
  end
267

268
  class SampleOne
269
    def self.attribute_names
270 271
      ["username"]
    end
272 273
  end

274
  class SampleTwo
275
    def self.attribute_names
276 277 278 279 280
      ["title"]
    end
  end

  tests Admin::Users::UsersController
281

282
  def teardown
283
    Admin::Users::UsersController.last_parameters = nil
284 285
  end

V
Vijay Dev 已提交
286
  def test_derived_name_from_controller
287
    with_default_wrapper_options do
288 289
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu" }
290
      assert_parameters("username" => "sikachu", "user" => { "username" => "sikachu" })
291 292 293
    end
  end

294
  def test_namespace_lookup_from_model
295
    Admin.const_set(:User, Class.new(SampleOne))
296 297
    begin
      with_default_wrapper_options do
298 299
        @request.env["CONTENT_TYPE"] = "application/json"
        post :parse, params: { "username" => "sikachu", "title" => "Developer" }
300
        assert_parameters("username" => "sikachu", "title" => "Developer", "user" => { "username" => "sikachu" })
301 302 303
      end
    ensure
      Admin.send :remove_const, :User
304 305 306
    end
  end

V
Vijay Dev 已提交
307
  def test_hierarchy_namespace_lookup_from_model
308
    Object.const_set(:User, Class.new(SampleTwo))
309 310
    begin
      with_default_wrapper_options do
311 312
        @request.env["CONTENT_TYPE"] = "application/json"
        post :parse, params: { "username" => "sikachu", "title" => "Developer" }
313
        assert_parameters("username" => "sikachu", "title" => "Developer", "user" => { "title" => "Developer" })
314 315 316 317 318
      end
    ensure
      Object.send :remove_const, :User
    end
  end
319 320 321 322 323 324 325 326
end

class AnonymousControllerParamsWrapperTest < ActionController::TestCase
  include ParamsWrapperTestHelp

  tests(Class.new(ActionController::Base) do
    class << self
      attr_accessor :last_parameters
327
    end
328

329 330 331
    def parse
      self.class.last_parameters = request.params.except(:controller, :action)
      head :ok
332
    end
333 334 335 336
  end)

  def test_does_not_implicitly_wrap_params
    with_default_wrapper_options do
337 338
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu" }
339
      assert_parameters("username" => "sikachu")
340 341 342 343 344
    end
  end

  def test_does_wrap_params_if_name_provided
    with_default_wrapper_options do
345
      @controller.class.wrap_parameters(name: "guest")
346 347
      @request.env["CONTENT_TYPE"] = "application/json"
      post :parse, params: { "username" => "sikachu" }
348
      assert_parameters("username" => "sikachu", "guest" => { "username" => "sikachu" })
349 350
    end
  end
351
end
352 353 354 355 356 357

class IrregularInflectionParamsWrapperTest < ActionController::TestCase
  include ParamsWrapperTestHelp

  class ParamswrappernewsItem
    def self.attribute_names
358
      ["test_attr"]
359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375
    end
  end

  class ParamswrappernewsController < ActionController::Base
    class << self
      attr_accessor :last_parameters
    end

    def parse
      self.class.last_parameters = request.params.except(:controller, :action)
      head :ok
    end
  end

  tests ParamswrappernewsController

  def test_uses_model_attribute_names_with_irregular_inflection
Z
Zuhao Wan 已提交
376 377
    with_dup do
      ActiveSupport::Inflector.inflections do |inflect|
378
        inflect.irregular "paramswrappernews_item", "paramswrappernews"
Z
Zuhao Wan 已提交
379
      end
380

Z
Zuhao Wan 已提交
381
      with_default_wrapper_options do
382 383
        @request.env["CONTENT_TYPE"] = "application/json"
        post :parse, params: { "username" => "sikachu", "test_attr" => "test_value" }
384
        assert_parameters("username" => "sikachu", "test_attr" => "test_value", "paramswrappernews_item" => { "test_attr" => "test_value" })
Z
Zuhao Wan 已提交
385
      end
386 387
    end
  end
Z
Zuhao Wan 已提交
388 389 390

  private

391 392 393 394 395 396 397
    def with_dup
      original = ActiveSupport::Inflector::Inflections.instance_variable_get(:@__instance__)[:en]
      ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, en: original.dup)
      yield
    ensure
      ActiveSupport::Inflector::Inflections.instance_variable_set(:@__instance__, en: original)
    end
398
end