Is there a way to check if the rails set a persistent cookie?

I am using TestUnit and I want to test the "remember me" function (when a user logs in).

the cookie variable (as well as require / response.cookies) contains only the cookie value without time expiration.

Rails somehow tells the web browser when the cookie expires, so I guess there should be a way to check the cookie expiration time.

EDIT

test "set permanent cookie" do post :create, email: 'email', password: 'password', remember_me: true # cookies[:auth_token] = random_string # @request.cookies[:auth_token] = also_random_string # @response.cookies[:auth_token] = also_random_string end 

the problem is that I can only get cookie values ​​and not a hash that contain expiration time.

+7
source share
2 answers

As you have noticed, the Hash cookies contains values, not the expiration time, when you check it after the post call (this was the behavior, at least since Rails 2.3).

You have two options:

You can check the response.headers["Set-Cookie"] element first. It will include the expiration time. However, the Set-Cookie value is just one line that you will need to parse. For example, cookies["foo"] = {:value => "bar", :expires => Time.now + 10.years } will provide you with:

 response.headers["Set-Cookie"] # => "foo=bar; path=/; expires=Mon, 16-Aug-2021 21:54:30 GMT" 

Another option (taken from this question / answer ) was to drown out the cookie doll and make sure it was sent expires :

 stub_cookie_jar = HashWithIndifferentAccess.new controller.stub(:cookies) { stub_cookie_jar } post :create, email: 'email', password: 'password', remember_me: true expiring_cookie = stub_cookie_jar['expiring_cookie'] expiring_cookie[:expires].to_i.should be_within(1).of(1.hour.from_now.to_i) 
+4
source

Unfortunately, I could not get the solutions presented or related to @DylanMarkow's answer, so here's how I tested that the “persistent” cookie was set when the “Remember me” checkbox was checked (tests are affected / openly copied from Test: : Unit of tests that DHH did in the commit added by cookies.permanent in Rails ).

Tests use RSpec and FactoryGirl .

<strong> specifications / requests / authentication_requests_spec.rb

 require 'spec_helper' describe "Authentication Requests" do # ... describe "authorization" do # ... describe "cookies" do let(:user) { FactoryGirl.create(:user) } subject { response.headers["Set-Cookie"] } context "when remember me is set" do before { sign_in_request(user) } it { should =~ %r(.+expires.+#{20.years.from_now.year}) } end context "when remember me is not set" do before { sign_in_request(user, remember_me: false) } it { should_not =~ %r(expires) } end end end end 

specifications /utilities.rb

 def sign_in_request(user, remember_me: "true") post session_path( session: { email: user.email, password: user.password, remember_me: remember_me } ) end 

The following are snippets of i18n , Haml , Bootstrap, and Simple form application code

app / views / sessions / new.html.haml

 = simple_form_for :session, url: session_path, html: {class: 'form-vertical' } do |f| = f.input :email = f.input :password .checkbox = f.input :remember_me, as: :boolean, label: false do = check_box_tag :remember_me, 1, true = label_tag :remember_me = f.submit t('.signin'), class: "btn btn-large btn-primary" 

application / controllers / sessions_controller.rb

 class SessionsController < ApplicationController # ... def create if user = User.authenticate(params[:session][:email], params[:session][:password]) sign_in user flash[:success] = t('flash.successful_signin') redirect_to root_url else flash.now[:error] = t('flash.invalid_credentials') render 'new' end end # ... end 

application / models / user.rb

 class User < ActiveRecord::Base has_secure_password # ... before_create :generate_authentication_token def self.authenticate(email, password) find_by_email(email).try(:authenticate, password) end private def generate_authentication_token begin self.authentication_token = SecureRandom.urlsafe_base64 end while User.exists?(authentication_token: self.authentication_token) end end 

application / controllers / application_controller.rb

 class ApplicationController < ActionController::Base # ... private # A cookie that does not have an expiry will automatically be expired by # the browser when browser session is finished. # cookies.permanent sets the expiry to 20 years # Booleans seem to get passed from forms as strings def sign_in(user) if remember_me cookies.permanent[:authentication_token] = user.authentication_token else cookies[:authentication_token] = user.authentication_token end self.current_user = user end helper_method :sign_in def remember_me params[:session].try(:[], :remember_me) == "true" || params[:remember_me] == "true" end # ... end 
+1
source

All Articles