Question

Given a functional test such as:

def test_exciting_rails_upgrades
    login(m=users(:manager))

    post :import_users_map_fields, :csv_file => fixture_file_upload('/users.csv', 'text/csv')
    assert flash.empty?
    flash.discard
    # other goodies omitted

end

In Rails 2.3.2 there are no errors, however in 2.3.15 the error is:

    NoMethodError: undefined method `discard' for {}:Hash
    /test/functional/broken_upgrades.rb:119:in `test_exciting_rails_upgrades'

Why is flash a Hash class instead of a FlashHash?

From the source it looks like both 2.3.2 and 2.3.15 ActionPack files lib/action_controller/flash.rb create the FlashHash class and inherit from Hash. However what is shown in this functional test in both 2.3.2 and 2.3.15 is a Hash class, not a HashFlash, so one cannot call discard on it.

Can anyone else reproduce this error with 2.3.15 and flash.discard?

Was it helpful?

Solution

Here are two test cases you can use to prove ActionController changes the type of 'flash' depending on whether or not it is already set.

In my app, you cannot see :index unless you're logged in, so in test_flash_is_now_a_flashhash you see that flash was set by the backend properly, while in test_flash_is_a_plain_hash it was not.

def test_flash_is_a_plain_hash
  login(users(:permitted_user))
  get :index
  assert flash.instance_of?(Hash)
end

def test_flash_is_now_a_flashhash
  get :index
  assert_redirected_to :controller => "login"
  assert flash.instance_of?(ActionController::Flash::FlashHash)
end

You can see this for yourself in the ActionController::TestRequest code:

def flash
    session['flash'] || {}
end

Update: This has been fixed in Rails branch 2-3-stable.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top