mirror of
https://github.com/heartcombo/devise.git
synced 2022-11-09 12:18:31 -05:00
No need to append ?unauthenticated=true in URLs anymore since Flash was moved to a middleware in Rails 3.
This commit is contained in:
parent
0f7b311171
commit
23e608e27b
17 changed files with 112 additions and 115 deletions
|
@ -15,9 +15,8 @@
|
|||
* Compatibility with Datamapper and Mongoid.
|
||||
* Make config.devise available on config/application.rb.
|
||||
* TokenAuthenticatable now works with HTTP Basic Auth.
|
||||
* Allow :unlock_strategy to be :none and add :lock_strategy which can be :failed_attempts or
|
||||
none. Setting those values to :none means that you want to handle lock and unlocking by
|
||||
yourself.
|
||||
* Allow :unlock_strategy to be :none and add :lock_strategy which can be :failed_attempts or none. Setting those values to :none means that you want to handle lock and unlocking by yourself.
|
||||
* No need to append ?unauthenticated=true in URLs anymore since Flash was moved to a middleware in Rails 3.
|
||||
|
||||
* bug fix
|
||||
* Do not allow unlockable strategies based on time to access a controller.
|
||||
|
|
|
@ -4,9 +4,6 @@ class Devise::SessionsController < ApplicationController
|
|||
|
||||
# GET /resource/sign_in
|
||||
def new
|
||||
Devise::FLASH_MESSAGES.each do |message|
|
||||
set_now_flash_message :alert, message if params[message] == "true"
|
||||
end unless flash[:notice]
|
||||
clean_up_passwords(build_resource)
|
||||
render_with_scope :new
|
||||
end
|
||||
|
|
|
@ -67,7 +67,7 @@ module Devise
|
|||
#
|
||||
def stored_location_for(resource_or_scope)
|
||||
scope = Devise::Mapping.find_scope!(resource_or_scope)
|
||||
session.delete(:"#{scope}.return_to")
|
||||
session.delete(:"#{scope}_return_to")
|
||||
end
|
||||
|
||||
# The default url to be used after signing in. This is used by all Devise
|
||||
|
|
|
@ -90,15 +90,9 @@ module Devise
|
|||
#
|
||||
# Please refer to README or en.yml locale file to check what messages are
|
||||
# available.
|
||||
def set_flash_message(key, kind, now=false)
|
||||
flash_hash = now ? flash.now : flash
|
||||
flash_hash[key] = I18n.t(:"#{resource_name}.#{kind}", :resource_name => resource_name,
|
||||
:scope => [:devise, controller_name.to_sym], :default => kind)
|
||||
end
|
||||
|
||||
# Shortcut to set flash.now message. Same rules applied from set_flash_message
|
||||
def set_now_flash_message(key, kind)
|
||||
set_flash_message(key, kind, true)
|
||||
def set_flash_message(key, kind)
|
||||
flash[key] = I18n.t(:"#{resource_name}.#{kind}", :resource_name => resource_name,
|
||||
:scope => [:devise, controller_name.to_sym], :default => kind)
|
||||
end
|
||||
|
||||
def clean_up_passwords(object)
|
||||
|
|
|
@ -10,6 +10,8 @@ module Devise
|
|||
include ActionController::UrlFor
|
||||
include ActionController::Redirecting
|
||||
|
||||
delegate :flash, :to => :request
|
||||
|
||||
def self.call(env)
|
||||
action(:respond).call(env)
|
||||
end
|
||||
|
@ -20,31 +22,44 @@ module Devise
|
|||
|
||||
def respond
|
||||
if http_auth?
|
||||
self.status = 401
|
||||
self.headers["WWW-Authenticate"] = %(Basic realm=#{Devise.http_authentication_realm.inspect})
|
||||
self.content_type = request.format.to_s
|
||||
self.response_body = http_auth_body
|
||||
elsif action = warden_options[:recall]
|
||||
default_message :invalid
|
||||
env["PATH_INFO"] = attempted_path
|
||||
params.merge!(query_string_params)
|
||||
self.response = recall_controller.action(action).call(env)
|
||||
http_auth
|
||||
elsif warden_options[:recall]
|
||||
recall
|
||||
else
|
||||
scope = warden_options[:scope]
|
||||
store_location!(scope)
|
||||
redirect_to send(:"new_#{scope}_session_path", query_string_params)
|
||||
redirect
|
||||
end
|
||||
end
|
||||
|
||||
def http_auth
|
||||
self.status = 401
|
||||
self.headers["WWW-Authenticate"] = %(Basic realm=#{Devise.http_authentication_realm.inspect})
|
||||
self.content_type = request.format.to_s
|
||||
self.response_body = http_auth_body
|
||||
end
|
||||
|
||||
def recall
|
||||
env["PATH_INFO"] = attempted_path
|
||||
flash.now[:alert] = i18n_message(:invalid)
|
||||
self.response = recall_controller.action(warden_options[:recall]).call(env)
|
||||
end
|
||||
|
||||
def redirect
|
||||
store_location!
|
||||
flash[:alert] = i18n_message unless flash[:notice]
|
||||
redirect_to send(:"new_#{scope}_session_path")
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def message
|
||||
@message ||= warden.message || warden_options[:message] || default_message
|
||||
end
|
||||
def i18n_message(default = nil)
|
||||
message = warden.message || warden_options[:message] || default || :unauthenticated
|
||||
|
||||
def default_message(message=nil)
|
||||
@default_message = message if message
|
||||
@default_message ||= :unauthenticated
|
||||
if message.is_a?(Symbol)
|
||||
I18n.t(:"#{scope}.#{message}", :resource_name => scope,
|
||||
:scope => [:devise, :sessions], :default => [message, message.to_s])
|
||||
else
|
||||
message.to_s
|
||||
end
|
||||
end
|
||||
|
||||
def http_auth?
|
||||
|
@ -52,26 +67,8 @@ module Devise
|
|||
end
|
||||
|
||||
def http_auth_body
|
||||
body = if message.is_a?(Symbol)
|
||||
I18n.t "devise.sessions.#{message}", :default => message.to_s
|
||||
else
|
||||
message.to_s
|
||||
end
|
||||
|
||||
method = :"to_#{request.format.to_sym}"
|
||||
{}.respond_to?(method) ? { :error => body }.send(method) : body
|
||||
end
|
||||
|
||||
# Build the proper query string based on the given message.
|
||||
def query_string_params
|
||||
case message
|
||||
when Symbol
|
||||
{ message => "true" }
|
||||
when String
|
||||
{ :message => message }
|
||||
else
|
||||
{}
|
||||
end
|
||||
{}.respond_to?(method) ? { :error => i18n_message }.send(method) : i18n_message
|
||||
end
|
||||
|
||||
def recall_controller
|
||||
|
@ -86,6 +83,10 @@ module Devise
|
|||
env['warden.options']
|
||||
end
|
||||
|
||||
def scope
|
||||
@scope ||= warden_options[:scope]
|
||||
end
|
||||
|
||||
def attempted_path
|
||||
warden_options[:attempted_path]
|
||||
end
|
||||
|
@ -94,8 +95,8 @@ module Devise
|
|||
# scoped session provided by warden here, since the user is not authenticated
|
||||
# yet, but we still need to store the uri based on scope, so different scopes
|
||||
# would never use the same uri to redirect.
|
||||
def store_location!(scope)
|
||||
session[:"#{scope}.return_to"] = attempted_path if request && request.get?
|
||||
def store_location!
|
||||
session[:"#{scope}_return_to"] = attempted_path if request && request.get?
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -121,20 +121,20 @@ class ControllerAuthenticableTest < ActionController::TestCase
|
|||
|
||||
test 'stored location for returns the location for a given scope' do
|
||||
assert_nil @controller.stored_location_for(:user)
|
||||
@controller.session[:"user.return_to"] = "/foo.bar"
|
||||
@controller.session[:"user_return_to"] = "/foo.bar"
|
||||
assert_equal "/foo.bar", @controller.stored_location_for(:user)
|
||||
end
|
||||
|
||||
test 'stored location for accepts a resource as argument' do
|
||||
assert_nil @controller.stored_location_for(:user)
|
||||
@controller.session[:"user.return_to"] = "/foo.bar"
|
||||
@controller.session[:"user_return_to"] = "/foo.bar"
|
||||
assert_equal "/foo.bar", @controller.stored_location_for(User.new)
|
||||
end
|
||||
|
||||
test 'stored location cleans information after reading' do
|
||||
@controller.session[:"user.return_to"] = "/foo.bar"
|
||||
@controller.session[:"user_return_to"] = "/foo.bar"
|
||||
assert_equal "/foo.bar", @controller.stored_location_for(:user)
|
||||
assert_nil @controller.session[:"user.return_to"]
|
||||
assert_nil @controller.session[:"user_return_to"]
|
||||
end
|
||||
|
||||
test 'after sign in path defaults to root path if none by was specified for the given scope' do
|
||||
|
@ -152,7 +152,7 @@ class ControllerAuthenticableTest < ActionController::TestCase
|
|||
|
||||
test 'sign in and redirect uses the stored location' do
|
||||
user = User.new
|
||||
@controller.session[:"user.return_to"] = "/foo.bar"
|
||||
@controller.session[:"user_return_to"] = "/foo.bar"
|
||||
@mock_warden.expects(:user).with(:user).returns(nil)
|
||||
@mock_warden.expects(:set_user).with(user, :scope => :user).returns(true)
|
||||
@controller.expects(:redirect_to).with("/foo.bar")
|
||||
|
|
|
@ -16,7 +16,9 @@ class FailureTest < ActiveSupport::TestCase
|
|||
'rack.input' => "",
|
||||
'warden' => OpenStruct.new(:message => nil)
|
||||
}.merge!(env_params)
|
||||
Devise::FailureApp.call(env).to_a
|
||||
|
||||
@response = Devise::FailureApp.call(env).to_a
|
||||
@request = ActionDispatch::Request.new(env)
|
||||
end
|
||||
|
||||
def call_failure_with_http(env_params={})
|
||||
|
@ -26,49 +28,55 @@ class FailureTest < ActiveSupport::TestCase
|
|||
|
||||
context 'When redirecting' do
|
||||
test 'return 302 status' do
|
||||
assert_equal 302, call_failure.first
|
||||
call_failure
|
||||
assert_equal 302, @response.first
|
||||
end
|
||||
|
||||
test 'return to the default redirect location' do
|
||||
assert_equal 'http://test.host/users/sign_in?unauthenticated=true', call_failure.second['Location']
|
||||
call_failure
|
||||
assert_equal 'You need to sign in or sign up before continuing.', @request.flash[:alert]
|
||||
assert_equal 'http://test.host/users/sign_in', @response.second['Location']
|
||||
end
|
||||
|
||||
test 'uses the proxy failure message as symbol' do
|
||||
warden = OpenStruct.new(:message => :test)
|
||||
location = call_failure('warden' => warden).second['Location']
|
||||
assert_equal 'http://test.host/users/sign_in?test=true', location
|
||||
call_failure('warden' => OpenStruct.new(:message => :test))
|
||||
assert_equal 'test', @request.flash[:alert]
|
||||
assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
|
||||
end
|
||||
|
||||
test 'uses the proxy failure message as string' do
|
||||
warden = OpenStruct.new(:message => 'Hello world')
|
||||
location = call_failure('warden' => warden).second['Location']
|
||||
assert_equal 'http://test.host/users/sign_in?message=Hello+world', location
|
||||
call_failure('warden' => OpenStruct.new(:message => 'Hello world'))
|
||||
assert_equal 'Hello world', @request.flash[:alert]
|
||||
assert_equal 'http://test.host/users/sign_in', @response.second["Location"]
|
||||
end
|
||||
|
||||
test 'set content type to default text/html' do
|
||||
assert_equal 'text/html; charset=utf-8', call_failure.second['Content-Type']
|
||||
call_failure
|
||||
assert_equal 'text/html; charset=utf-8', @response.second['Content-Type']
|
||||
end
|
||||
|
||||
test 'setup a default message' do
|
||||
assert_match /You are being/, call_failure.last.body
|
||||
assert_match /redirected/, call_failure.last.body
|
||||
assert_match /\?unauthenticated=true/, call_failure.last.body
|
||||
call_failure
|
||||
assert_match /You are being/, @response.last.body
|
||||
assert_match /redirected/, @response.last.body
|
||||
assert_match /users\/sign_in/, @response.last.body
|
||||
end
|
||||
end
|
||||
|
||||
context 'For HTTP request' do
|
||||
test 'return 401 status' do
|
||||
assert_equal 401, call_failure_with_http.first
|
||||
call_failure_with_http
|
||||
assert_equal 401, @response.first
|
||||
end
|
||||
|
||||
test 'return WWW-authenticate headers' do
|
||||
assert_equal 'Basic realm="Application"', call_failure_with_http.second["WWW-Authenticate"]
|
||||
call_failure_with_http
|
||||
assert_equal 'Basic realm="Application"', @response.second["WWW-Authenticate"]
|
||||
end
|
||||
|
||||
test 'uses the proxy failure message as response body' do
|
||||
warden = OpenStruct.new(:message => :invalid)
|
||||
response = call_failure_with_http('warden' => warden).third
|
||||
assert_equal 'Invalid email or password.', response.body
|
||||
call_failure_with_http('warden' => OpenStruct.new(:message => :invalid))
|
||||
assert_equal 'Invalid email or password.', @response.third.body
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -79,9 +87,9 @@ class FailureTest < ActiveSupport::TestCase
|
|||
"warden.options" => { :recall => "new", :attempted_path => "/users/sign_in" },
|
||||
"warden" => stub_everything
|
||||
}
|
||||
response = call_failure(env).third
|
||||
assert response.body.include?('<h2>Sign in</h2>')
|
||||
assert response.body.include?('Invalid email or password.')
|
||||
call_failure(env)
|
||||
assert @response.third.body.include?('<h2>Sign in</h2>')
|
||||
assert @response.third.body.include?('Invalid email or password.')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -88,9 +88,9 @@ class ConfirmationTest < ActionController::IntegrationTest
|
|||
|
||||
test 'error message is configurable by resource name' do
|
||||
store_translations :en, :devise => {
|
||||
:sessions => { :admin => { :unconfirmed => "Not confirmed user" } }
|
||||
:sessions => { :user => { :unconfirmed => "Not confirmed user" } }
|
||||
} do
|
||||
get new_admin_session_path(:unconfirmed => true)
|
||||
sign_in_as_user(:confirm => false)
|
||||
assert_contain 'Not confirmed user'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -50,7 +50,7 @@ class DatabaseAuthenticationSanityTest < ActionController::IntegrationTest
|
|||
test 'not signed in as admin should not be able to access admins actions' do
|
||||
get admins_path
|
||||
|
||||
assert_redirected_to new_admin_session_path(:unauthenticated => true)
|
||||
assert_redirected_to new_admin_session_path
|
||||
assert_not warden.authenticated?(:admin)
|
||||
end
|
||||
|
||||
|
@ -60,7 +60,7 @@ class DatabaseAuthenticationSanityTest < ActionController::IntegrationTest
|
|||
assert_not warden.authenticated?(:admin)
|
||||
|
||||
get admins_path
|
||||
assert_redirected_to new_admin_session_path(:unauthenticated => true)
|
||||
assert_redirected_to new_admin_session_path
|
||||
end
|
||||
|
||||
test 'signed in as admin should be able to access admin actions' do
|
||||
|
@ -146,7 +146,7 @@ class AuthenticationTest < ActionController::IntegrationTest
|
|||
test 'redirect from warden shows sign in or sign up message' do
|
||||
get admins_path
|
||||
|
||||
warden_path = new_admin_session_path(:unauthenticated => true)
|
||||
warden_path = new_admin_session_path
|
||||
assert_redirected_to warden_path
|
||||
|
||||
get warden_path
|
||||
|
@ -157,35 +157,35 @@ class AuthenticationTest < ActionController::IntegrationTest
|
|||
sign_in_as_user
|
||||
|
||||
assert_template 'home/index'
|
||||
assert_nil session[:"user.return_to"]
|
||||
assert_nil session[:"user_return_to"]
|
||||
end
|
||||
|
||||
test 'redirect to requested url after sign in' do
|
||||
get users_path
|
||||
assert_redirected_to new_user_session_path(:unauthenticated => true)
|
||||
assert_equal users_path, session[:"user.return_to"]
|
||||
assert_redirected_to new_user_session_path
|
||||
assert_equal users_path, session[:"user_return_to"]
|
||||
|
||||
follow_redirect!
|
||||
sign_in_as_user :visit => false
|
||||
|
||||
assert_template 'users/index'
|
||||
assert_nil session[:"user.return_to"]
|
||||
assert_nil session[:"user_return_to"]
|
||||
end
|
||||
|
||||
test 'redirect to last requested url overwriting the stored return_to option' do
|
||||
get expire_user_path(create_user)
|
||||
assert_redirected_to new_user_session_path(:unauthenticated => true)
|
||||
assert_equal expire_user_path(create_user), session[:"user.return_to"]
|
||||
assert_redirected_to new_user_session_path
|
||||
assert_equal expire_user_path(create_user), session[:"user_return_to"]
|
||||
|
||||
get users_path
|
||||
assert_redirected_to new_user_session_path(:unauthenticated => true)
|
||||
assert_equal users_path, session[:"user.return_to"]
|
||||
assert_redirected_to new_user_session_path
|
||||
assert_equal users_path, session[:"user_return_to"]
|
||||
|
||||
follow_redirect!
|
||||
sign_in_as_user :visit => false
|
||||
|
||||
assert_template 'users/index'
|
||||
assert_nil session[:"user.return_to"]
|
||||
assert_nil session[:"user_return_to"]
|
||||
end
|
||||
|
||||
test 'redirect to configured home path for a given scope after sign in' do
|
||||
|
@ -199,7 +199,7 @@ class AuthenticationTest < ActionController::IntegrationTest
|
|||
|
||||
User.destroy_all
|
||||
get '/users'
|
||||
assert_redirected_to '/users/sign_in?unauthenticated=true'
|
||||
assert_redirected_to new_user_session_path
|
||||
end
|
||||
|
||||
test 'allows session to be set by a given scope' do
|
||||
|
|
|
@ -93,9 +93,9 @@ class LockTest < ActionController::IntegrationTest
|
|||
|
||||
test 'error message is configurable by resource name' do
|
||||
store_translations :en, :devise => {
|
||||
:sessions => { :admin => { :locked => "You are locked!" } }
|
||||
:sessions => { :user => { :locked => "You are locked!" } }
|
||||
} do
|
||||
get new_admin_session_path(:locked => true)
|
||||
user = sign_in_as_user(:locked => true)
|
||||
assert_contain 'You are locked!'
|
||||
end
|
||||
end
|
||||
|
|
|
@ -134,7 +134,7 @@ class PasswordTest < ActionController::IntegrationTest
|
|||
request_forgot_password
|
||||
reset_password :reset_password_token => user.reload.reset_password_token
|
||||
|
||||
assert_current_path new_user_session_path(:unconfirmed => true)
|
||||
assert_equal new_user_session_path, @request.path
|
||||
assert !warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
|
|
|
@ -28,9 +28,9 @@ class RegistrationTest < ActionController::IntegrationTest
|
|||
fill_in 'password confirmation', :with => 'new_user123'
|
||||
click_button 'Sign up'
|
||||
|
||||
assert_contain 'You have signed up successfully.'
|
||||
assert_contain 'You have signed up successfully'
|
||||
assert_contain 'Sign in'
|
||||
assert_not_contain 'Confirm your account'
|
||||
assert_not_contain 'You have to confirm your account before continuing'
|
||||
|
||||
assert_not warden.authenticated?(:user)
|
||||
|
||||
|
@ -73,7 +73,9 @@ class RegistrationTest < ActionController::IntegrationTest
|
|||
|
||||
test 'a guest should not be able to change account' do
|
||||
get edit_user_registration_path
|
||||
assert_redirected_to new_user_session_path(:unauthenticated => true)
|
||||
assert_redirected_to new_user_session_path
|
||||
follow_redirect!
|
||||
assert_contain 'You need to sign in or sign up before continuing.'
|
||||
end
|
||||
|
||||
test 'a signed in user should not be able to access sign up' do
|
||||
|
|
|
@ -47,7 +47,7 @@ class RememberMeTest < ActionController::IntegrationTest
|
|||
user = create_user_and_remember('add')
|
||||
get users_path
|
||||
assert_not warden.authenticated?(:user)
|
||||
assert_redirected_to new_user_session_path(:unauthenticated => true)
|
||||
assert_redirected_to new_user_session_path
|
||||
end
|
||||
|
||||
test 'do not remember with token expired' do
|
||||
|
@ -55,7 +55,7 @@ class RememberMeTest < ActionController::IntegrationTest
|
|||
swap Devise, :remember_for => 0 do
|
||||
get users_path
|
||||
assert_not warden.authenticated?(:user)
|
||||
assert_redirected_to new_user_session_path(:unauthenticated => true)
|
||||
assert_redirected_to new_user_session_path
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ class SessionTimeoutTest < ActionController::IntegrationTest
|
|||
assert_not_nil last_request_at
|
||||
|
||||
get users_path
|
||||
assert_redirected_to new_user_session_path(:timeout => true)
|
||||
assert_redirected_to new_user_session_path
|
||||
assert_not warden.authenticated?(:user)
|
||||
end
|
||||
|
||||
|
@ -47,7 +47,7 @@ class SessionTimeoutTest < ActionController::IntegrationTest
|
|||
|
||||
get expire_user_path(user)
|
||||
get users_path
|
||||
assert_redirected_to new_user_session_path(:timeout => true)
|
||||
assert_redirected_to new_user_session_path
|
||||
assert_not warden.authenticated?(:user)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -47,7 +47,7 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
|
|||
test 'does not authenticate with improper authentication token key' do
|
||||
swap Devise, :token_authentication_key => :donald_duck_token do
|
||||
sign_in_as_new_user_with_token(:auth_token_key => :secret_token)
|
||||
assert_current_path new_user_session_path(:unauthenticated => true)
|
||||
assert_equal new_user_session_path, @request.path
|
||||
|
||||
assert_contain 'You need to sign in or sign up before continuing'
|
||||
assert_contain 'Sign in'
|
||||
|
@ -58,7 +58,7 @@ class TokenAuthenticationTest < ActionController::IntegrationTest
|
|||
test 'does not authenticate with improper authentication token value' do
|
||||
store_translations :en, :devise => {:sessions => {:invalid_token => 'LOL, that was not a single character correct.'}} do
|
||||
sign_in_as_new_user_with_token(:auth_token => '*** INVALID TOKEN ***')
|
||||
assert_current_path new_user_session_path(:invalid_token => true)
|
||||
assert_equal new_user_session_path, @request.path
|
||||
|
||||
assert_contain 'LOL, that was not a single character correct.'
|
||||
assert_contain 'Sign in'
|
||||
|
|
|
@ -50,10 +50,6 @@ class ActionDispatch::IntegrationTest
|
|||
admin
|
||||
end
|
||||
|
||||
def assert_current_path(path)
|
||||
assert_equal(prepend_host(path), prepend_host(current_url))
|
||||
end
|
||||
|
||||
# Fix assert_redirect_to in integration sessions because they don't take into
|
||||
# account Middleware redirects.
|
||||
#
|
||||
|
|
|
@ -6,14 +6,14 @@ class TestHelpersTest < ActionController::TestCase
|
|||
|
||||
test "redirects if attempting to access a page unauthenticated" do
|
||||
get :index
|
||||
assert_redirected_to "/users/sign_in?unauthenticated=true"
|
||||
assert_redirected_to new_user_session_path
|
||||
end
|
||||
|
||||
test "redirects if attempting to access a page with a unconfirmed account" do
|
||||
swap Devise, :confirm_within => 0 do
|
||||
sign_in create_user
|
||||
get :index
|
||||
assert_redirected_to "/users/sign_in?unconfirmed=true"
|
||||
assert_redirected_to new_user_session_path
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -35,7 +35,7 @@ class TestHelpersTest < ActionController::TestCase
|
|||
|
||||
sign_out user
|
||||
get :index
|
||||
assert_redirected_to "/users/sign_in?unauthenticated=true"
|
||||
assert_redirected_to new_user_session_path
|
||||
end
|
||||
|
||||
test "allows to sign in with different users" do
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue