beseku
beseku

Reputation: 915

Signed cookies and Test:unit don't mix: "NoMethodError"

I am using signed cookies to maintain my user across pages, pretty much implemented as here.

I use two methods, sign_in(account) and sign_out to manipulate my cookies, creating or destroying them as you would expect ...

module SessionsHelper
  def sign_in account
    cookies.signed[:auth_account] = {
      :expires => 1.week.from_now,
      :value => [account.id, account.hash]
    }
  end

  def sign_out
    cookies.delete(:auth_account)
  end
end

However, when trying to use this method, or the authenticate method that matches it in the ApplicationController from the functional tests, I get a NoMethodError:

NoMethodError: undefined method `signed' for {}:ActiveSupport::HashWithIndifferentAccess

I realise from this and this that this is an issue with the way cookies are defined differently in the test case, but I can't get any of these solutions to work. For completeness, an example test that fails with the above error:

require 'test_helper'

class AccountsControllerTest < ActionController::TestCase
  include SessionsHelper

  setup do
    # We need to fake authentication by manually
    # assigning an account to the sign_in process
    sign_in accounts(:ia)

    @account = accounts(:ia)
  end

  test "should 403 on index if unauthenticated" do
    sign_out

    get :index
    assert_response :forbidden
  end

  test "should 200 on index if authenticated" do
    get :index
    assert_response :success
  end
end

Upvotes: 4

Views: 291

Answers (1)

gilsilas
gilsilas

Reputation: 1461

You can't set cookies in your test with the cookies variable like you do in your controller. The cookies variable in your tests is use for read cookies after doing requests call (get/post...) and not for writing

In order to spoof login within your tests you should set cookies via @request.cookies[:auth]

you can put the following method in your test_helper and use it in all your tests

def signin user
  @request.cookies[:auth] = user.auth
end

and in your tests

test "get dashboard if logged in" do
  signin @user
  get :index
end

Upvotes: 1

Related Questions