1 # frozen_string_literal: true
5 RSpec
.describe Auth
::SessionsController, type
: :controller do
10 request
.env['devise.mapping'] = Devise
.mappings
[:user]
13 it
'returns http success' do
15 expect(response
).to
have_http_status(:success)
19 describe
'DELETE #destroy' do
20 let(:user) { Fabricate(:user) }
23 request
.env['devise.mapping'] = Devise
.mappings
[:user]
26 context
'with a regular user' do
27 it
'redirects to home after sign out' do
28 sign_in(user
, scope
: :user)
31 expect(response
).to
redirect_to(new_user_session_path
)
35 context
'with a suspended user' do
36 it
'redirects to home after sign out' do
37 Fabricate(:account, user
: user
, suspended
: true)
38 sign_in(user
, scope
: :user)
41 expect(response
).to
redirect_to(new_user_session_path
)
46 describe
'POST #create' do
48 request
.env['devise.mapping'] = Devise
.mappings
[:user]
51 context
'using PAM authentication' do
52 context
'using a valid password' do
54 post
:create, params
: { user
: { email
: "pam_user1", password
: '123456' } }
57 it
'redirects to home' do
58 expect(response
).to
redirect_to(root_path
)
61 it
'logs the user in' do
62 expect(controller
.current_user
).to
be_instance_of(User
)
66 context
'using an invalid password' do
68 post
:create, params
: { user
: { email
: "pam_user1", password
: 'WRONGPW' } }
71 it
'shows a login error' do
72 expect(flash
[:alert]).to match I18n
.t('devise.failure.invalid', authentication_keys
: 'Email')
75 it
"doesn't log the user in" do
76 expect(controller
.current_user
).to be_nil
80 context
'using a valid email and existing user' do
82 account
= Fabricate
.build(:account, username
: 'pam_user1')
83 account
.save!
(validate
: false)
84 user
= Fabricate(:user, email
: 'pam@example.com', password
: nil, account
: account
)
89 post
:create, params
: { user
: { email
: user
.email
, password
: '123456' } }
92 it
'redirects to home' do
93 expect(response
).to
redirect_to(root_path
)
96 it
'logs the user in' do
97 expect(controller
.current_user
).to eq user
102 context
'using password authentication' do
103 let(:user) { Fabricate(:user, email
: 'foo@bar.com', password
: 'abcdefgh') }
105 context
'using a valid password' do
107 post
:create, params
: { user
: { email
: user
.email
, password
: user
.password
} }
110 it
'redirects to home' do
111 expect(response
).to
redirect_to(root_path
)
114 it
'logs the user in' do
115 expect(controller
.current_user
).to eq user
119 context
'using email with uppercase letters' do
121 post
:create, params
: { user
: { email
: user
.email
.upcase
, password
: user
.password
} }
124 it
'redirects to home' do
125 expect(response
).to
redirect_to(root_path
)
128 it
'logs the user in' do
129 expect(controller
.current_user
).to eq user
133 context
'using an invalid password' do
135 post
:create, params
: { user
: { email
: user
.email
, password
: 'wrongpw' } }
138 it
'shows a login error' do
139 expect(flash
[:alert]).to match I18n
.t('devise.failure.invalid', authentication_keys
: 'Email')
142 it
"doesn't log the user in" do
143 expect(controller
.current_user
).to be_nil
147 context
'using an unconfirmed password' do
149 request
.headers
['Accept-Language'] = accept_language
150 post
:create, params
: { user
: { email
: unconfirmed_user
.email
, password
: unconfirmed_user
.password
} }
153 let(:unconfirmed_user) { user
.tap
{ |u
| u
.update!
(confirmed_at
: nil) } }
154 let(:accept_language) { 'fr' }
156 it
'shows a translated login error' do
157 expect(flash
[:alert]).to
eq(I18n
.t('devise.failure.unconfirmed', locale
: accept_language
))
161 context
"logging in from the user's page" do
163 allow(controller
).to
receive(:single_user_mode?).and_return(single_user_mode
)
164 allow(controller
).to
receive(:stored_location_for).with(:user).and_return("/@#{user.account.username}")
165 post
:create, params
: { user
: { email
: user
.email
, password
: user
.password
} }
168 context
"in single user mode" do
169 let(:single_user_mode) { true }
171 it
'redirects to home' do
172 expect(response
).to
redirect_to(root_path
)
176 context
"in non-single user mode" do
177 let(:single_user_mode) { false }
179 it
"redirects back to the user's page" do
180 expect(response
).to
redirect_to(short_account_path(username
: user
.account
))
186 context
'using two-factor authentication' do
188 Fabricate(:user, email
: 'x@y.com', password
: 'abcdefgh',
189 otp_required_for_login
: true, otp_secret
: User
.generate_otp_secret(32))
191 let(:recovery_codes) do
192 codes
= user
.generate_otp_backup_codes!
197 context
'using email and password' do
199 post
:create, params
: { user
: { email
: user
.email
, password
: user
.password
} }
202 it
'renders two factor authentication page' do
203 expect(controller
).to
render_template("two_factor")
207 context
'using upcase email and password' do
209 post
:create, params
: { user
: { email
: user
.email
.upcase
, password
: user
.password
} }
212 it
'renders two factor authentication page' do
213 expect(controller
).to
render_template("two_factor")
217 context
'using a valid OTP' do
219 post
:create, params
: { user
: { otp_attempt
: user
.current_otp
} }, session
: { otp_user_id
: user
.id
}
222 it
'redirects to home' do
223 expect(response
).to
redirect_to(root_path
)
226 it
'logs the user in' do
227 expect(controller
.current_user
).to eq user
231 context
'when the server has an decryption error' do
233 allow_any_instance_of(User
).to
receive(:validate_and_consume_otp!
).and_raise(OpenSSL
::Cipher::CipherError)
234 post
:create, params
: { user
: { otp_attempt
: user
.current_otp
} }, session
: { otp_user_id
: user
.id
}
237 it
'shows a login error' do
238 expect(flash
[:alert]).to match I18n
.t('users.invalid_otp_token')
241 it
"doesn't log the user in" do
242 expect(controller
.current_user
).to be_nil
246 context
'using a valid recovery code' do
248 post
:create, params
: { user
: { otp_attempt
: recovery_codes
.first
} }, session
: { otp_user_id
: user
.id
}
251 it
'redirects to home' do
252 expect(response
).to
redirect_to(root_path
)
255 it
'logs the user in' do
256 expect(controller
.current_user
).to eq user
260 context
'using an invalid OTP' do
262 post
:create, params
: { user
: { otp_attempt
: 'wrongotp' } }, session
: { otp_user_id
: user
.id
}
265 it
'shows a login error' do
266 expect(flash
[:alert]).to match I18n
.t('users.invalid_otp_token')
269 it
"doesn't log the user in" do
270 expect(controller
.current_user
).to be_nil