nested_parameters_test.rb 6.1 KB
Newer Older
1
require 'abstract_unit'
2 3 4
require 'action_controller/metal/strong_parameters'

class NestedParametersTest < ActiveSupport::TestCase
5 6 7 8
  def assert_filtered_out(params, key)
    assert !params.has_key?(key), "key #{key.inspect} has not been filtered out"
  end

9 10 11 12 13 14 15 16 17
  test "permitted nested parameters" do
    params = ActionController::Parameters.new({
      book: {
        title: "Romeo and Juliet",
        authors: [{
          name: "William Shakespeare",
          born: "1564-04-26"
        }, {
          name: "Christopher Marlowe"
18
        }, {
19
          name: %w(malicious injected names)
20 21 22 23
        }],
        details: {
          pages: 200,
          genre: "Tragedy"
24 25 26
        },
        id: {
          isbn: 'x'
27 28 29 30 31
        }
      },
      magazine: "Mjallo!"
    })

32
    permitted = params.permit book: [ :title, { authors: [ :name ] }, { details: :pages }, :id ]
33 34 35 36 37 38

    assert permitted.permitted?
    assert_equal "Romeo and Juliet", permitted[:book][:title]
    assert_equal "William Shakespeare", permitted[:book][:authors][0][:name]
    assert_equal "Christopher Marlowe", permitted[:book][:authors][1][:name]
    assert_equal 200, permitted[:book][:details][:pages]
39 40 41 42 43 44

    assert_filtered_out permitted, :magazine
    assert_filtered_out permitted[:book], :id
    assert_filtered_out permitted[:book][:details], :genre
    assert_filtered_out permitted[:book][:authors][0], :born
    assert_filtered_out permitted[:book][:authors][2], :name
45 46
  end

47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
  test "permitted nested parameters with a string or a symbol as a key" do
    params = ActionController::Parameters.new({
      book: {
        'authors' => [
          { name: 'William Shakespeare', born: '1564-04-26' },
          { name: 'Christopher Marlowe' }
        ]
      }
    })

    permitted = params.permit book: [ { 'authors' => [ :name ] } ]

    assert_equal 'William Shakespeare', permitted[:book]['authors'][0][:name]
    assert_equal 'William Shakespeare', permitted[:book][:authors][0][:name]
    assert_equal 'Christopher Marlowe', permitted[:book]['authors'][1][:name]
    assert_equal 'Christopher Marlowe', permitted[:book][:authors][1][:name]

    permitted = params.permit book: [ { authors: [ :name ] } ]

    assert_equal 'William Shakespeare', permitted[:book]['authors'][0][:name]
    assert_equal 'William Shakespeare', permitted[:book][:authors][0][:name]
    assert_equal 'Christopher Marlowe', permitted[:book]['authors'][1][:name]
    assert_equal 'Christopher Marlowe', permitted[:book][:authors][1][:name]
  end

72 73
  test "nested arrays with strings" do
    params = ActionController::Parameters.new({
74 75
      book: {
        genres: ["Tragedy"]
76 77 78
      }
    })

79
    permitted = params.permit book: {genres: []}
80 81 82 83 84
    assert_equal ["Tragedy"], permitted[:book][:genres]
  end

  test "permit may specify symbols or strings" do
    params = ActionController::Parameters.new({
85 86 87
      book: {
        title: "Romeo and Juliet",
        author: "William Shakespeare"
88
      },
89
      magazine: "Shakespeare Today"
90 91
    })

92
    permitted = params.permit({book: ["title", :author]}, "magazine")
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131
    assert_equal "Romeo and Juliet", permitted[:book][:title]
    assert_equal "William Shakespeare", permitted[:book][:author]
    assert_equal "Shakespeare Today", permitted[:magazine]
  end

  test "nested array with strings that should be hashes" do
    params = ActionController::Parameters.new({
      book: {
        genres: ["Tragedy"]
      }
    })

    permitted = params.permit book: { genres: :type }
    assert_empty permitted[:book][:genres]
  end

  test "nested array with strings that should be hashes and additional values" do
    params = ActionController::Parameters.new({
      book: {
        title: "Romeo and Juliet",
        genres: ["Tragedy"]
      }
    })

    permitted = params.permit book: [ :title, { genres: :type } ]
    assert_equal "Romeo and Juliet", permitted[:book][:title]
    assert_empty permitted[:book][:genres]
  end

  test "nested string that should be a hash" do
    params = ActionController::Parameters.new({
      book: {
        genre: "Tragedy"
      }
    })

    permitted = params.permit book: { genre: :type }
    assert_nil permitted[:book][:genre]
  end
132 133 134

  test "fields_for-style nested params" do
    params = ActionController::Parameters.new({
135 136 137 138 139
      book: {
        authors_attributes: {
          :'0' => { name: 'William Shakespeare', age_of_death: '52' },
          :'1' => { name: 'Unattributed Assistant' },
          :'2' => { name: %w(injected names)}
140 141 142
        }
      }
    })
143
    permitted = params.permit book: { authors_attributes: [ :name ] }
144 145

    assert_not_nil permitted[:book][:authors_attributes]['0']
146 147
    assert_not_nil permitted[:book][:authors_attributes]['1']
    assert_empty permitted[:book][:authors_attributes]['2']
148
    assert_equal 'William Shakespeare', permitted[:book][:authors_attributes]['0'][:name]
149 150 151 152 153 154 155
    assert_equal 'Unattributed Assistant', permitted[:book][:authors_attributes]['1'][:name]

    assert_filtered_out permitted[:book][:authors_attributes]['0'], :age_of_death
  end

  test "fields_for-style nested params with negative numbers" do
    params = ActionController::Parameters.new({
156 157 158 159
      book: {
        authors_attributes: {
          :'-1' => { name: 'William Shakespeare', age_of_death: '52' },
          :'-2' => { name: 'Unattributed Assistant' }
160 161 162
        }
      }
    })
163
    permitted = params.permit book: { authors_attributes: [:name] }
164 165 166 167 168 169 170

    assert_not_nil permitted[:book][:authors_attributes]['-1']
    assert_not_nil permitted[:book][:authors_attributes]['-2']
    assert_equal 'William Shakespeare', permitted[:book][:authors_attributes]['-1'][:name]
    assert_equal 'Unattributed Assistant', permitted[:book][:authors_attributes]['-2'][:name]

    assert_filtered_out permitted[:book][:authors_attributes]['-1'], :age_of_death
171
  end
172 173 174 175 176 177 178 179 180 181 182 183 184 185 186

  test "nested number as key" do
    params = ActionController::Parameters.new({
      product: {
        properties: {
          '0' => "prop0",
          '1' => "prop1"
        }
      }
    })
    params = params.require(:product).permit(:properties => ["0"])
    assert_not_nil        params[:properties]["0"]
    assert_nil            params[:properties]["1"]
    assert_equal "prop0", params[:properties]["0"]
  end
187
end