Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Signed cookies not available in controller tests #27145

Closed
sgrif opened this issue Nov 22, 2016 · 17 comments
Closed

Signed cookies not available in controller tests #27145

sgrif opened this issue Nov 22, 2016 · 17 comments

Comments

@sgrif
Copy link
Contributor

sgrif commented Nov 22, 2016

This issue has been ported from the report at rspec/rspec-rails#1658, as it can be replicated purely with Rails using public API. This test passes using Rails 4.2

Steps to reproduce

Reproduction Script
begin
  require "bundler/inline"
rescue LoadError => e
  $stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
  raise e
end

gemfile(true) do
  source "https://rubygems.org"
  gem "rails", github: "rails/rails"
end

require "action_controller/railtie"

class TestApp < Rails::Application
  config.root = File.dirname(__FILE__)
  secrets.secret_token    = "secret_token"
  secrets.secret_key_base = "secret_key_base"

  config.logger = Logger.new($stdout)
  Rails.logger  = config.logger

  routes.draw do
    get "/" => "test#index"
  end
end

class TestController < ActionController::Base
  include Rails.application.routes.url_helpers

  def index
    render plain: "Home"
  end

  def foo_cookie
    cookies.encrypted["foo"]
  end
end

require "rails/test_help"
require "minitest/autorun"

class TestControllerTest < ActionController::TestCase
  setup do
    cookies.encrypted["foo"] = "bar"
  end

  test "accessing cookies directly" do
    get :index
    assert_equal "bar", cookies.encrypted["foo"]
  end

  test "accessing helper method" do
    get :index
    assert_equal "bar", @controller.foo_cookie
  end
end

Expected behavior

Changes to cookies.encrypted in the test setup should appear in the controller's cookies

Actual behavior

Changes to cookies.encrypted in the test setup do not affect the controller's cookies

System configuration

Rails version: 5.0.0, 5.0.0.1, master

Ruby version: 2.3.3

@maclover7
Copy link
Contributor

maclover7 commented Nov 22, 2016

Looks like this was introduced via ae29142, cc @eileencodes @tenderlove

Relevant commits:

@maclover7
Copy link
Contributor

I think I have a fix for this, just adding a regression test to the test suite.

@maclover7
Copy link
Contributor

Opened #27146 with a possible solution to this ticket.

@maclover7 maclover7 self-assigned this Nov 22, 2016
@maclover7
Copy link
Contributor

Closing since #27146 was merged.

@devohh
Copy link

devohh commented Feb 28, 2017

@maclover7 @sgrif I think the problem is still alive. I left a comment on that page. Am I missing something ?

@rafaelfranca rafaelfranca reopened this Feb 28, 2017
@rafaelfranca
Copy link
Member

@devohh this is still an issue that needs to be fixed.

@eileencodes
Copy link
Member

eileencodes commented Feb 28, 2017

Hrm, the original issue was about controller tests, and @devohh said the problem is with integration tests? Can you send a test script demonstrating the problem?

@eileencodes
Copy link
Member

Oh sorry @rafaelfranca I didn't see you reverted the original fix. Nevermind :)

@devohh
Copy link

devohh commented Mar 5, 2017

@eileencodes @rafaelfranca The same issue occurs during integration test AND also during controller test.

@alexcameron89
Copy link
Member

This issue has been fixed in Rails 5.1 & master by 78c6c4b from @maclover7.

To double check, I also verified it with the original reproduction app in the RSpec issue, and it passed with an upgrade to 5.1.0. 👍

@eileencodes
Copy link
Member

That commit from Jon was merged but there was a second that was related and reverted, but never fixed. See #27586

@eileencodes eileencodes reopened this May 8, 2017
@alexcameron89
Copy link
Member

Sorry about that, I did not run the script from #27586. Thanks @eileencodes.

Here's the second script mentioned for reference on this issue.

begin
  require "bundler/inline"
rescue LoadError => e
  $stderr.puts "Bundler version 1.10 or later is required. Please update your Bundler"
  raise e
end

gemfile(true) do
  source "https://rubygems.org"
  gem "rails", github: "rails/rails", branch: "5-0-stable"
  gem "pry-byebug"
end

require "action_controller/railtie"

class TestApp < Rails::Application
  config.root = File.dirname(__FILE__)
  config.session_store :cookie_store, key: "cookie_store_key"
  secrets.secret_token    = "secret_token"
  secrets.secret_key_base = "secret_key_base"

  config.logger = Logger.new($stdout)
  Rails.logger  = config.logger

  routes.draw do
    resources :users, only: [:index]
  end
end

class UsersController < ActionController::Base
  def index
    unless cookies[:name].present?
      cookies[:name] = "Alice"
    end
    render plain: "Home"
  end
end

require "minitest/autorun"
require "rack/test"

class UsersControllerTest < ActionController::TestCase
  setup do
    @controller = UsersController.new
    @routes = Rails.application.routes
  end

  test '#index sets a cookie if it is not already present' do
    get :index
    assert_response :ok
    assert_equal "Alice", cookies[:name]

    cookies[:name] = "Bob"

    get :index
    assert_response :ok
    assert_equal "Bob", cookies[:name]
  end
end

@schneems
Copy link
Member

schneems commented Aug 2, 2018

This issue is still valid?

@denisw
Copy link

denisw commented Aug 5, 2018

On a fresh Rails 5.2 install, I still can't use cookies.encrypted in an integration test:

require 'test_helper'

class MyControllerTest < ActionDispatch::IntegrationTest
  test "displays current user's first name" do
    user = users(:alice)
    cookies.encrypted[:current_user] = user.id
    get '/'
    assert_select "p", user.first_name
  end
end

Results in:

Error:
MyControllerTest#test_displays_current_user's_first_name:
NoMethodError: undefined method `encrypted' for #<Rack::Test::CookieJar:0x00007fea2f04ad00>
    test/controllers/my_controller_test.rb:6:in `block in <class:DashboardControllerTest>'

@shicholas
Copy link

Can confirm too, I guess an alt is to log in or fetch a token for an API first instead of trying to stub the cookie before the test.

@rafaelfranca
Copy link
Member

This issue is fixed for ActionController::TestCase based tests. ActionDispatch::IntegrationTest doesn't support access to encrypted cookies by design because they are integration tests and don't allow access to anything that a browser would not.

@oreoshake
Copy link
Contributor

I thought ActionController::TestCase is (was?) deprecated?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

10 participants