2019-04-29 20:27:42 -04:00
# frozen_string_literal: true
2019-12-16 19:33:51 -05:00
require " rotp "
2016-12-16 11:21:28 -05:00
2022-07-27 22:27:38 -04:00
RSpec . describe UsersController do
2021-12-22 12:09:43 -05:00
fab! ( :user ) { Fabricate ( :user ) }
2021-12-07 13:45:58 -05:00
fab! ( :user1 ) { Fabricate ( :user ) }
2021-12-16 14:36:49 -05:00
fab! ( :another_user ) { Fabricate ( :user ) }
fab! ( :invitee ) { Fabricate ( :user ) }
fab! ( :inviter ) { Fabricate ( :user ) }
2021-12-07 13:45:58 -05:00
fab! ( :admin ) { Fabricate ( :admin ) }
2021-12-16 14:36:49 -05:00
fab! ( :moderator ) { Fabricate ( :moderator ) }
fab! ( :inactive_user ) { Fabricate ( :inactive_user ) }
2021-12-07 13:45:58 -05:00
2022-09-25 23:58:40 -04:00
before { Group . refresh_automatic_groups! }
2021-12-16 14:36:49 -05:00
# Unfortunately, there are tests that depend on the user being created too
# late for fab! to work.
let ( :user_deferred ) { Fabricate ( :user ) }
2016-12-16 11:21:28 -05:00
2019-10-16 01:53:31 -04:00
describe " # full account registration flow " do
it " will correctly handle honeypot and challenge " do
2020-10-01 19:01:40 -04:00
get " /session/hp.json "
2019-10-16 01:53:31 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2019-10-16 01:53:31 -04:00
params = {
email : " jane@jane.com " ,
name : " jane " ,
username : " jane " ,
password_confirmation : json [ " value " ] ,
challenge : json [ " challenge " ] . reverse ,
password : SecureRandom . hex ,
}
secure_session = SecureSession . new ( session [ " secure_session_id " ] )
expect ( secure_session [ UsersController :: HONEYPOT_KEY ] ) . to eq ( json [ " value " ] )
expect ( secure_session [ UsersController :: CHALLENGE_KEY ] ) . to eq ( json [ " challenge " ] )
post " /u.json " , params : params
expect ( response . status ) . to eq ( 200 )
jane = User . find_by ( username : " jane " )
expect ( jane . email ) . to eq ( " jane@jane.com " )
expect ( secure_session [ UsersController :: HONEYPOT_KEY ] ) . to eq ( nil )
expect ( secure_session [ UsersController :: CHALLENGE_KEY ] ) . to eq ( nil )
end
end
2018-05-27 23:20:47 -04:00
describe " # perform_account_activation " do
2021-12-16 14:36:49 -05:00
let ( :email_token ) { Fabricate ( :email_token , user : user_deferred ) }
2018-05-27 23:20:47 -04:00
2018-05-24 22:04:25 -04:00
before { UsersController . any_instance . stubs ( :honeypot_or_challenge_fails? ) . returns ( false ) }
2022-07-27 12:14:14 -04:00
context " with invalid token " do
2018-05-24 22:04:25 -04:00
it " return success " do
2018-05-27 23:20:47 -04:00
put " /u/activate-account/invalid-tooken "
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( flash [ :error ] ) . to be_present
end
end
2022-07-27 12:14:14 -04:00
context " with valid token " do
context " with welcome message " do
2018-05-24 22:04:25 -04:00
it " enqueues a welcome message if the user object indicates so " do
2021-06-01 08:38:55 -04:00
SiteSetting . send_welcome_message = true
2021-12-16 14:36:49 -05:00
user_deferred . update ( active : false )
2021-11-25 02:34:39 -05:00
put " /u/activate-account/ #{ email_token . token } "
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
expect ( Jobs :: SendSystemMessage . jobs . size ) . to eq ( 1 )
expect ( Jobs :: SendSystemMessage . jobs . first [ " args " ] . first [ " message_type " ] ) . to eq (
" welcome_user " ,
)
2018-05-24 22:04:25 -04:00
end
it " doesn't enqueue the welcome message if the object returns false " do
2021-12-16 14:36:49 -05:00
user_deferred . update ( active : true )
2021-11-25 02:34:39 -05:00
put " /u/activate-account/ #{ email_token . token } "
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
expect ( Jobs :: SendSystemMessage . jobs . size ) . to eq ( 0 )
2018-05-24 22:04:25 -04:00
end
end
2022-07-27 12:14:14 -04:00
context " with honeypot " do
2018-05-24 22:04:25 -04:00
it " raises an error if the honeypot is invalid " do
UsersController . any_instance . stubs ( :honeypot_or_challenge_fails? ) . returns ( true )
2021-11-25 02:34:39 -05:00
put " /u/activate-account/ #{ email_token . token } "
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 403 )
2018-05-24 22:04:25 -04:00
end
end
2022-07-27 12:14:14 -04:00
context " with response " do
2018-05-24 22:04:25 -04:00
it " correctly logs on user " do
2021-11-25 02:34:39 -05:00
email_token
events = DiscourseEvent . track_events { put " /u/activate-account/ #{ email_token . token } " }
2018-05-24 22:04:25 -04:00
2018-05-27 23:20:47 -04:00
expect ( events . map { | event | event [ :event_name ] } ) . to contain_exactly (
2021-11-25 02:34:39 -05:00
:user_confirmed_email ,
:user_first_logged_in ,
:user_logged_in ,
2018-05-24 22:04:25 -04:00
)
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( flash [ :error ] ) . to be_blank
expect ( session [ :current_user_id ] ) . to be_present
expect ( CGI . unescapeHTML ( response . body ) ) . to_not include (
I18n . t ( " activation.approval_required " ) ,
)
end
end
2022-07-27 12:14:14 -04:00
context " when user is not approved " do
2018-05-24 22:04:25 -04:00
before { SiteSetting . must_approve_users = true }
it " should return the right response " do
2021-11-25 02:34:39 -05:00
put " /u/activate-account/ #{ email_token . token } "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( CGI . unescapeHTML ( response . body ) ) . to include ( I18n . t ( " activation.approval_required " ) )
expect ( response . body ) . to_not have_tag ( :script , with : { src : " /assets/application.js " } )
expect ( flash [ :error ] ) . to be_blank
expect ( session [ :current_user_id ] ) . to be_blank
end
end
end
2018-05-27 23:20:47 -04:00
context " when cookies contains a destination URL " do
2018-05-24 22:04:25 -04:00
it " should redirect to the URL " do
destination_url = " http://thisisasite.com/somepath "
cookies [ :destination_url ] = destination_url
2021-11-25 02:34:39 -05:00
put " /u/activate-account/ #{ email_token . token } "
2018-05-24 22:04:25 -04:00
expect ( response ) . to redirect_to ( destination_url )
end
end
2022-04-05 07:57:00 -04:00
context " when cookies does not contain a destination URL but users was invited to topic " do
let ( :invite ) { Fabricate ( :invite ) }
let ( :topic ) { Fabricate ( :topic ) }
before do
TopicInvite . create! ( topic : topic , invite : invite )
Fabricate ( :invited_user , invite : invite , user : email_token . user )
invite . reload
end
it " should redirect to the topic " do
put " /u/activate-account/ #{ email_token . token } "
expect ( response ) . to redirect_to ( topic . relative_url )
end
end
2018-05-24 22:04:25 -04:00
end
describe " # password_reset " do
let ( :token ) { SecureRandom . hex }
2022-07-27 12:14:14 -04:00
context " when login is required " do
2018-05-24 22:04:25 -04:00
it " returns success " do
SiteSetting . login_required = true
get " /u/password-reset/ #{ token } "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2022-10-28 17:41:26 -04:00
expect ( CGI . unescapeHTML ( response . body ) ) . to include (
I18n . t ( " password_reset.no_token " , base_url : Discourse . base_url ) ,
)
2018-05-24 22:04:25 -04:00
end
end
2022-07-27 12:14:14 -04:00
context " with missing token " do
2018-11-21 00:17:37 -05:00
it " disallows login " do
2018-05-24 22:04:25 -04:00
get " /u/password-reset/ #{ token } "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( CGI . unescapeHTML ( response . body ) ) . to include (
2022-10-28 17:41:26 -04:00
I18n . t ( " password_reset.no_token " , base_url : Discourse . base_url ) ,
)
2018-05-24 22:04:25 -04:00
expect ( response . body ) . to_not have_tag ( :script , with : { src : " /assets/application.js " } )
expect ( session [ :current_user_id ] ) . to be_blank
end
2018-11-21 00:17:37 -05:00
it " responds with proper error message " do
get " /u/password-reset/ #{ token } .json "
expect ( response . status ) . to eq ( 200 )
2022-10-28 17:41:26 -04:00
expect ( response . parsed_body [ " message " ] ) . to eq (
I18n . t ( " password_reset.no_token " , base_url : Discourse . base_url ) ,
)
2018-11-21 00:17:37 -05:00
expect ( session [ :current_user_id ] ) . to be_blank
end
2018-05-24 22:04:25 -04:00
end
2022-07-27 12:14:14 -04:00
context " with invalid token " do
2018-05-24 22:04:25 -04:00
it " disallows login " do
get " /u/password-reset/ev!l_trout@! "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( CGI . unescapeHTML ( response . body ) ) . to include (
2022-10-28 17:41:26 -04:00
I18n . t ( " password_reset.no_token " , base_url : Discourse . base_url ) ,
)
2018-05-24 22:04:25 -04:00
expect ( response . body ) . to_not have_tag ( :script , with : { src : " /assets/application.js " } )
expect ( session [ :current_user_id ] ) . to be_blank
end
it " responds with proper error message " do
put " /u/password-reset/evil_trout!.json " , params : { password : " awesomeSecretPassword " }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2022-10-28 17:41:26 -04:00
expect ( response . parsed_body [ " message " ] ) . to eq (
I18n . t ( " password_reset.no_token " , base_url : Discourse . base_url ) ,
)
2018-05-24 22:04:25 -04:00
expect ( session [ :current_user_id ] ) . to be_blank
end
end
2022-07-27 12:14:14 -04:00
context " with valid token " do
2021-12-16 14:36:49 -05:00
let! ( :user_auth_token ) { UserAuthToken . generate! ( user_id : user1 . id ) }
let! ( :email_token ) do
Fabricate ( :email_token , user : user1 , scope : EmailToken . scopes [ :password_reset ] )
2023-01-09 06:18:21 -05:00
end
2021-11-25 02:34:39 -05:00
2018-05-24 22:04:25 -04:00
context " when rendered " do
it " renders referrer never on get requests " do
2021-11-25 02:34:39 -05:00
get " /u/password-reset/ #{ email_token . token } "
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( response . body ) . to include ( '<meta name="referrer" content="never">' )
end
end
it " returns success " do
events =
DiscourseEvent . track_events do
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } " , params : { password : " hg9ow8yhg98o " }
2018-05-24 22:04:25 -04:00
end
2018-05-27 23:20:47 -04:00
expect ( events . map { | event | event [ :event_name ] } ) . to contain_exactly (
2021-04-11 22:48:42 -04:00
:user_logged_in ,
:user_first_logged_in ,
:user_confirmed_email ,
2018-05-24 22:04:25 -04:00
)
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-09-28 05:28:33 -04:00
expect ( response . body ) . to have_tag ( " div # data-preloaded " ) do | element |
2018-09-17 04:31:46 -04:00
json = JSON . parse ( element . current_scope . attribute ( " data-preloaded " ) . value )
2020-01-15 05:27:12 -05:00
expect ( json [ " password_reset " ] ) . to include (
'{"is_developer":false,"admin":false,"second_factor_required":false,"security_key_required":false,"backup_enabled":false,"multiple_second_factor_methods":false}' ,
)
2018-09-17 04:31:46 -04:00
end
2018-05-24 22:04:25 -04:00
2021-11-25 02:34:39 -05:00
expect ( session [ " password- #{ email_token . token } " ] ) . to be_blank
2018-05-24 22:04:25 -04:00
expect ( UserAuthToken . where ( id : user_auth_token . id ) . count ) . to eq ( 0 )
end
it " disallows double password reset " do
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } " , params : { password : " hg9ow8yHG32O " }
put " /u/password-reset/ #{ email_token . token } " , params : { password : " test123987AsdfXYZ " }
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . confirm_password? ( " hg9ow8yHG32O " ) ) . to eq ( true )
expect ( user1 . user_auth_tokens . count ) . to eq ( 1 )
2018-05-24 22:04:25 -04:00
end
it " doesn't redirect to wizard on get " do
2021-12-16 14:36:49 -05:00
user1 . update! ( admin : true )
2018-05-24 22:04:25 -04:00
2021-11-25 02:34:39 -05:00
get " /u/password-reset/ #{ email_token . token } .json "
2018-05-24 22:04:25 -04:00
expect ( response ) . not_to redirect_to ( wizard_path )
end
it " redirects to the wizard if you're the first admin " do
2021-12-16 14:36:49 -05:00
user1 . update! ( admin : true )
2018-05-24 22:04:25 -04:00
2021-11-25 02:34:39 -05:00
get " /u/password-reset/ #{ email_token . token } "
put " /u/password-reset/ #{ email_token . token } " ,
params : {
password : " hg9ow8yhg98oadminlonger " ,
}
2018-05-24 22:04:25 -04:00
expect ( response ) . to redirect_to ( wizard_path )
end
2020-04-17 14:39:04 -04:00
it " sets the users timezone if the param is present " do
2021-11-25 02:34:39 -05:00
get " /u/password-reset/ #{ email_token . token } "
2021-12-16 14:36:49 -05:00
expect ( user1 . user_option . timezone ) . to eq ( nil )
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } " ,
params : {
password : " hg9ow8yhg98oadminlonger " ,
timezone : " America/Chicago " ,
}
2021-12-16 14:36:49 -05:00
expect ( user1 . user_option . reload . timezone ) . to eq ( " America/Chicago " )
2020-04-17 14:39:04 -04:00
end
2018-11-13 19:32:42 -05:00
it " logs the password change " do
2021-11-25 02:34:39 -05:00
get " /u/password-reset/ #{ email_token . token } "
2018-11-13 19:32:42 -05:00
expect do
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } " ,
params : {
password : " hg9ow8yhg98oadminlonger " ,
}
2018-11-13 19:32:42 -05:00
end . to change { UserHistory . count } . by ( 1 )
2021-11-25 02:34:39 -05:00
user_history = UserHistory . last
2021-12-16 14:36:49 -05:00
expect ( user_history . target_user_id ) . to eq ( user1 . id )
2021-11-25 02:34:39 -05:00
expect ( user_history . action ) . to eq ( UserHistory . actions [ :change_password ] )
2018-11-13 19:32:42 -05:00
end
2018-05-24 22:04:25 -04:00
it " doesn't invalidate the token when loading the page " do
get " /u/password-reset/ #{ email_token . token } .json "
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2021-11-25 02:34:39 -05:00
expect ( email_token . reload . confirmed ) . to eq ( false )
expect ( UserAuthToken . where ( id : user_auth_token . id ) . count ) . to eq ( 1 )
2018-05-24 22:04:25 -04:00
end
2022-07-27 12:14:14 -04:00
context " with rate limiting " do
2018-10-22 13:00:30 -04:00
before do
RateLimiter . clear_all!
RateLimiter . enable
2023-01-09 06:18:21 -05:00
end
2018-10-22 13:00:30 -04:00
it " rate limits reset passwords " do
freeze_time
2021-02-03 18:03:30 -05:00
6 . times do
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } " ,
params : {
2018-10-22 13:00:30 -04:00
second_factor_token : 123_456 ,
second_factor_method : 1 ,
}
expect ( response . status ) . to eq ( 200 )
end
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } " ,
params : {
2018-10-22 13:00:30 -04:00
second_factor_token : 123_456 ,
second_factor_method : 1 ,
}
expect ( response . status ) . to eq ( 429 )
end
2021-02-03 18:03:30 -05:00
it " rate limits reset passwords by username " do
freeze_time
6 . times do | x |
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } " ,
params : {
2021-02-03 18:03:30 -05:00
second_factor_token : 123_456 ,
second_factor_method : 1 ,
} ,
env : {
REMOTE_ADDR : " 1.2.3. #{ x } " ,
}
expect ( response . status ) . to eq ( 200 )
end
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } " ,
params : {
2021-02-03 18:03:30 -05:00
second_factor_token : 123_456 ,
second_factor_method : 1 ,
} ,
env : {
REMOTE_ADDR : " 1.2.3.4 " ,
}
expect ( response . status ) . to eq ( 429 )
end
2018-10-22 13:00:30 -04:00
end
2022-07-27 12:14:14 -04:00
context " when 2 factor authentication is required " do
2021-12-16 14:36:49 -05:00
fab! ( :second_factor ) { Fabricate ( :user_second_factor_totp , user : user1 ) }
2018-05-24 22:04:25 -04:00
it " does not change with an invalid token " do
2021-12-16 14:36:49 -05:00
user1 . user_auth_tokens . destroy_all
2018-05-24 22:04:25 -04:00
2021-11-25 02:34:39 -05:00
get " /u/password-reset/ #{ email_token . token } "
2018-05-24 22:04:25 -04:00
2018-09-28 05:28:33 -04:00
expect ( response . body ) . to have_tag ( " div # data-preloaded " ) do | element |
2018-09-17 04:31:46 -04:00
json = JSON . parse ( element . current_scope . attribute ( " data-preloaded " ) . value )
2020-01-15 05:27:12 -05:00
expect ( json [ " password_reset " ] ) . to include (
'{"is_developer":false,"admin":false,"second_factor_required":true,"security_key_required":false,"backup_enabled":false,"multiple_second_factor_methods":false}' ,
)
2018-09-17 04:31:46 -04:00
end
2018-05-24 22:04:25 -04:00
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } " ,
params : {
2018-06-28 04:12:32 -04:00
password : " hg9ow8yHG32O " ,
second_factor_token : " 000000 " ,
second_factor_method : UserSecondFactor . methods [ :totp ] ,
}
2018-05-24 22:04:25 -04:00
expect ( response . body ) . to include ( I18n . t ( " login.invalid_second_factor_code " ) )
2021-12-16 14:36:49 -05:00
user1 . reload
expect ( user1 . confirm_password? ( " hg9ow8yHG32O " ) ) . not_to eq ( true )
expect ( user1 . user_auth_tokens . count ) . not_to eq ( 1 )
2018-05-24 22:04:25 -04:00
end
it " changes password with valid 2-factor tokens " do
2021-11-25 02:34:39 -05:00
get " /u/password-reset/ #{ email_token . token } "
2018-05-24 22:04:25 -04:00
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } " ,
params : {
2018-05-24 22:04:25 -04:00
password : " hg9ow8yHG32O " ,
2018-06-28 04:12:32 -04:00
second_factor_token : ROTP :: TOTP . new ( second_factor . data ) . now ,
second_factor_method : UserSecondFactor . methods [ :totp ] ,
2018-05-24 22:04:25 -04:00
}
2021-12-16 14:36:49 -05:00
user1 . reload
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . confirm_password? ( " hg9ow8yHG32O " ) ) . to eq ( true )
expect ( user1 . user_auth_tokens . count ) . to eq ( 1 )
2018-05-24 22:04:25 -04:00
end
end
2019-10-01 22:08:41 -04:00
2022-07-27 12:14:14 -04:00
context " when security key authentication is required " do
2020-01-09 19:45:56 -05:00
let! ( :user_security_key ) do
Fabricate (
:user_security_key ,
2021-12-16 14:36:49 -05:00
user : user1 ,
2020-01-09 19:45:56 -05:00
credential_id : valid_security_key_data [ :credential_id ] ,
public_key : valid_security_key_data [ :public_key ] ,
)
end
2019-10-01 22:08:41 -04:00
2020-01-09 19:45:56 -05:00
before do
simulate_localhost_webauthn_challenge
2019-10-01 22:08:41 -04:00
2020-01-09 19:45:56 -05:00
# store challenge in secure session by visiting the email login page
2021-11-25 02:34:39 -05:00
get " /u/password-reset/ #{ email_token . token } "
2020-01-09 19:45:56 -05:00
end
2019-10-01 22:08:41 -04:00
2020-01-09 19:45:56 -05:00
it " preloads with a security key challenge and allowed credential ids " do
2019-10-01 22:08:41 -04:00
expect ( response . body ) . to have_tag ( " div # data-preloaded " ) do | element |
json = JSON . parse ( element . current_scope . attribute ( " data-preloaded " ) . value )
password_reset = JSON . parse ( json [ " password_reset " ] )
expect ( password_reset [ " challenge " ] ) . not_to eq ( nil )
2020-01-09 19:45:56 -05:00
expect ( password_reset [ " allowed_credential_ids " ] ) . to eq (
[ user_security_key . credential_id ] ,
)
2019-10-01 22:08:41 -04:00
expect ( password_reset [ " security_key_required " ] ) . to eq ( true )
end
end
it " stages a webauthn challenge and rp-id for the user " do
secure_session = SecureSession . new ( session [ " secure_session_id " ] )
2021-12-16 14:36:49 -05:00
expect ( Webauthn . challenge ( user1 , secure_session ) ) . not_to eq ( nil )
expect ( Webauthn . rp_id ( user1 , secure_session ) ) . to eq ( Discourse . current_hostname )
2019-10-01 22:08:41 -04:00
end
it " changes password with valid security key challenge and authentication " do
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } .json " ,
params : {
2019-10-01 22:08:41 -04:00
password : " hg9ow8yHG32O " ,
2020-01-15 05:27:12 -05:00
second_factor_token : valid_security_key_auth_post_data ,
2019-10-01 22:08:41 -04:00
second_factor_method : UserSecondFactor . methods [ :security_key ] ,
}
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
user1 . reload
expect ( user1 . confirm_password? ( " hg9ow8yHG32O " ) ) . to eq ( true )
expect ( user1 . user_auth_tokens . count ) . to eq ( 1 )
2019-10-01 22:08:41 -04:00
end
2020-01-09 19:45:56 -05:00
2020-01-15 05:27:12 -05:00
it " does not change a password if a fake TOTP token is provided " do
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } .json " ,
params : {
2020-01-15 05:27:12 -05:00
password : " hg9ow8yHG32O " ,
second_factor_token : " blah " ,
second_factor_method : UserSecondFactor . methods [ :security_key ] ,
}
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . confirm_password? ( " hg9ow8yHG32O " ) ) . to eq ( false )
2020-01-15 05:27:12 -05:00
end
2020-01-09 19:45:56 -05:00
context " when security key authentication fails " do
it " shows an error message and does not change password " do
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } " ,
params : {
2020-01-09 19:45:56 -05:00
password : " hg9ow8yHG32O " ,
2020-01-15 05:27:12 -05:00
second_factor_token : {
2020-01-09 19:45:56 -05:00
signature : " bad " ,
clientData : " bad " ,
authenticatorData : " bad " ,
credentialId : " bad " ,
} ,
second_factor_method : UserSecondFactor . methods [ :security_key ] ,
}
expect ( response . status ) . to eq ( 200 )
2020-01-15 05:27:12 -05:00
expect ( response . body ) . to include ( I18n . t ( " webauthn.validation.not_found_error " ) )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . confirm_password? ( " hg9ow8yHG32O " ) ) . to eq ( false )
2020-01-09 19:45:56 -05:00
end
end
2019-10-01 22:08:41 -04:00
end
2018-05-24 22:04:25 -04:00
end
2022-07-27 12:14:14 -04:00
context " with submit change " do
2021-12-16 14:36:49 -05:00
let ( :email_token ) do
Fabricate ( :email_token , user : user1 , scope : EmailToken . scopes [ :password_reset ] )
2023-01-09 06:18:21 -05:00
end
2018-05-24 22:04:25 -04:00
it " fails when the password is blank " do
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } .json " , params : { password : " " }
2018-05-24 22:04:25 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " errors " ] ) . to be_present
2018-05-24 22:04:25 -04:00
expect ( session [ :current_user_id ] ) . to be_blank
end
it " fails when the password is too long " do
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } .json " ,
params : {
password : ( " x " * ( User . max_password_length + 1 ) ) ,
}
2018-05-24 22:04:25 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " errors " ] ) . to be_present
2018-05-24 22:04:25 -04:00
expect ( session [ :current_user_id ] ) . to be_blank
end
it " logs in the user " do
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } .json " , params : { password : " ksjafh928r " }
2018-05-24 22:04:25 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " errors " ] ) . to be_blank
2018-05-24 22:04:25 -04:00
expect ( session [ :current_user_id ] ) . to be_present
end
it " doesn't log in the user when not approved " do
SiteSetting . must_approve_users = true
2021-12-16 14:36:49 -05:00
user1 . update! ( approved : false )
2018-05-24 22:04:25 -04:00
2021-11-25 02:34:39 -05:00
put " /u/password-reset/ #{ email_token . token } .json " , params : { password : " ksjafh928r " }
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " errors " ] ) . to be_blank
2018-05-24 22:04:25 -04:00
expect ( session [ :current_user_id ] ) . to be_blank
end
end
end
describe " # confirm_email_token " do
2021-12-16 14:36:49 -05:00
let! ( :email_token ) { Fabricate ( :email_token , user : user1 ) }
2018-05-24 22:04:25 -04:00
it " token doesn't match any records " do
get " /u/confirm-email-token/ #{ SecureRandom . hex } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( email_token . reload . confirmed ) . to eq ( false )
end
it " token matches " do
get " /u/confirm-email-token/ #{ email_token . token } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( email_token . reload . confirmed ) . to eq ( true )
end
end
describe " # admin_login " do
2022-07-27 12:14:14 -04:00
it " enqueues mail with admin email and sso enabled " do
put " /u/admin-login " , params : { email : admin . email }
expect ( response . status ) . to eq ( 200 )
expect ( Jobs :: CriticalUserEmail . jobs . size ) . to eq ( 1 )
args = Jobs :: CriticalUserEmail . jobs . first [ " args " ] . first
expect ( args [ " user_id " ] ) . to eq ( admin . id )
2018-05-24 22:04:25 -04:00
end
2022-08-15 10:30:07 -04:00
it " passes through safe mode " do
put " /u/admin-login " , params : { email : admin . email , use_safe_mode : true }
expect ( response . status ) . to eq ( 200 )
expect ( Jobs :: CriticalUserEmail . jobs . size ) . to eq ( 1 )
args = Jobs :: CriticalUserEmail . jobs . first [ " args " ] . first
expect ( args [ " email_token " ] ) . to end_with ( " ?safe_mode=no_plugins,no_themes " )
end
2018-05-24 22:04:25 -04:00
context " when email is incorrect " do
it " should return the right response " do
put " /u/admin-login " , params : { email : " random " }
expect ( response . status ) . to eq ( 200 )
response_body = response . body
expect ( response_body ) . to match ( I18n . t ( " admin_login.errors.unknown_email_address " ) )
expect ( response_body ) . to_not match ( I18n . t ( " login.second_factor_description " ) )
end
end
end
describe " # toggle_anon " do
it " allows you to toggle anon if enabled " do
SiteSetting . allow_anonymous_posting = true
user = sign_in ( Fabricate ( :user ) )
user . trust_level = 1
user . save!
post " /u/toggle-anon.json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( session [ :current_user_id ] ) . to eq ( AnonymousShadowCreator . get ( user ) . id )
post " /u/toggle-anon.json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( session [ :current_user_id ] ) . to eq ( user . id )
end
end
describe " # create " do
def honeypot_magic ( params )
2020-10-01 19:01:40 -04:00
get " /session/hp.json "
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-24 22:04:25 -04:00
params [ :password_confirmation ] = json [ " value " ]
params [ :challenge ] = json [ " challenge " ] . reverse
params
end
before do
UsersController . any_instance . stubs ( :honeypot_value ) . returns ( nil )
UsersController . any_instance . stubs ( :challenge_value ) . returns ( nil )
SiteSetting . allow_new_registrations = true
2020-03-31 14:29:15 -04:00
@user = Fabricate . build ( :user , email : " foobar@example.com " , password : " strongpassword " )
2018-05-24 22:04:25 -04:00
end
let ( :post_user_params ) do
{ name : @user . name , username : @user . username , password : " strongpassword " , email : @user . email }
end
2020-03-15 06:17:28 -04:00
def post_user ( extra_params = { } )
post " /u.json " , params : post_user_params . merge ( extra_params )
2018-05-24 22:04:25 -04:00
end
context " when email params is missing " do
it " should raise the right error " do
post " /u.json " ,
params : {
name : @user . name ,
username : @user . username ,
2021-05-20 21:43:47 -04:00
password : " testing12352343 " ,
2018-05-24 22:04:25 -04:00
}
expect ( response . status ) . to eq ( 400 )
end
end
context " when creating a user " do
it " sets the user locale to I18n.locale " do
SiteSetting . default_locale = " en "
I18n . stubs ( :locale ) . returns ( :fr )
post_user
expect ( User . find_by ( username : @user . username ) . locale ) . to eq ( " fr " )
end
2019-11-24 19:49:27 -05:00
2020-03-15 06:17:28 -04:00
it " requires invite code when specified " do
expect ( SiteSetting . require_invite_code ) . to eq ( false )
2020-03-25 22:44:02 -04:00
SiteSetting . invite_code = " abc def "
2020-03-15 06:17:28 -04:00
expect ( SiteSetting . require_invite_code ) . to eq ( true )
post_user ( invite_code : " abcd " )
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2020-03-15 06:17:28 -04:00
expect ( json [ " success " ] ) . to eq ( false )
2020-03-25 22:44:02 -04:00
# case insensitive and stripped of leading/ending spaces
post_user ( invite_code : " AbC deF " )
2020-03-15 06:17:28 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2020-03-15 06:17:28 -04:00
expect ( json [ " success " ] ) . to eq ( true )
end
2019-11-24 19:49:27 -05:00
context " when timezone is provided as a guess on signup " do
it " sets the timezone " do
2020-03-15 06:17:28 -04:00
post_user ( timezone : " Australia/Brisbane " )
2019-11-24 19:49:27 -05:00
expect ( response . status ) . to eq ( 200 )
expect ( User . find_by ( username : @user . username ) . user_option . timezone ) . to eq (
" Australia/Brisbane " ,
)
end
end
2020-04-29 21:39:24 -04:00
context " with local logins disabled " do
before do
SiteSetting . enable_local_logins = false
SiteSetting . enable_google_oauth2_logins = true
end
it " blocks registration without authenticator information " do
post_user
expect ( response . status ) . to eq ( 403 )
end
it " blocks with a regular api key " do
2021-12-16 14:36:49 -05:00
api_key = Fabricate ( :api_key , user : user1 )
2020-04-29 21:39:24 -04:00
post " /u.json " , params : post_user_params , headers : { HTTP_API_KEY : api_key . key }
expect ( response . status ) . to eq ( 403 )
end
it " works with an admin api key " do
2021-12-07 13:45:58 -05:00
api_key = Fabricate ( :api_key , user : admin )
2020-04-29 21:39:24 -04:00
post " /u.json " , params : post_user_params , headers : { HTTP_API_KEY : api_key . key }
expect ( response . status ) . to eq ( 200 )
end
end
2022-03-03 11:17:02 -05:00
context " with external_ids " do
fab! ( :api_key , refind : false ) { Fabricate ( :api_key , user : admin ) }
let ( :plugin_auth_provider ) do
authenticator_class =
Class . new ( Auth :: ManagedAuthenticator ) do
def name
" pluginauth "
end
def enabled?
true
2023-01-09 06:18:21 -05:00
end
2022-03-03 11:17:02 -05:00
end
provider = Auth :: AuthProvider . new
provider . authenticator = authenticator_class . new
provider
end
before { DiscoursePluginRegistry . register_auth_provider ( plugin_auth_provider ) }
after { DiscoursePluginRegistry . reset! }
it " creates User record " do
params = {
username : " foobar " ,
email : " test@example.com " ,
external_ids : {
" pluginauth " = > " pluginauth_uid " ,
} ,
}
expect {
post " /u.json " , params : params , headers : { HTTP_API_KEY : api_key . key }
} . to change { UserAssociatedAccount . count } . by ( 1 ) . and change { User . count } . by ( 1 )
expect ( response . status ) . to eq ( 200 )
user = User . last
user_associated_account = UserAssociatedAccount . last
expect ( user . username ) . to eq ( " foobar " )
expect ( user . email ) . to eq ( " test@example.com " )
expect ( user . user_associated_account_ids ) . to contain_exactly ( user_associated_account . id )
expect ( user_associated_account . provider_name ) . to eq ( " pluginauth " )
expect ( user_associated_account . provider_uid ) . to eq ( " pluginauth_uid " )
expect ( user_associated_account . user_id ) . to eq ( user . id )
end
it " returns error if external ID provider does not exist " do
params = {
username : " foobar " ,
email : " test@example.com " ,
external_ids : {
" pluginauth2 " = > " pluginauth_uid " ,
} ,
}
post " /u.json " , params : params , headers : { HTTP_API_KEY : api_key . key }
expect ( response . status ) . to eq ( 400 )
end
end
2018-05-24 22:04:25 -04:00
end
context " when creating a non active user (unconfirmed email) " do
2018-05-27 23:20:47 -04:00
it " returns 403 forbidden when local logins are disabled " do
2018-05-24 22:04:25 -04:00
SiteSetting . enable_local_logins = false
post_user
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 403 )
2018-05-24 22:04:25 -04:00
end
it " returns an error when new registrations are disabled " do
SiteSetting . allow_new_registrations = false
2018-05-27 23:20:47 -04:00
2018-05-24 22:04:25 -04:00
post_user
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-24 22:04:25 -04:00
expect ( json [ " success " ] ) . to eq ( false )
expect ( json [ " message " ] ) . to be_present
end
it " creates a user correctly " do
post_user
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " active " ] ) . to be_falsey
2018-05-24 22:04:25 -04:00
# should save user_created_message in session
expect ( session [ " user_created_message " ] ) . to be_present
expect ( session [ SessionController :: ACTIVATE_USER_KEY ] ) . to be_present
2018-05-27 23:20:47 -04:00
expect ( Jobs :: SendSystemMessage . jobs . size ) . to eq ( 0 )
expect ( Jobs :: CriticalUserEmail . jobs . size ) . to eq ( 1 )
args = Jobs :: CriticalUserEmail . jobs . first [ " args " ] . first
expect ( args [ " type " ] ) . to eq ( " signup " )
2018-05-24 22:04:25 -04:00
end
2022-07-27 12:14:14 -04:00
context " when `must approve users` site setting is enabled " do
2018-05-24 22:04:25 -04:00
before { SiteSetting . must_approve_users = true }
it " creates a user correctly " do
post_user
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " active " ] ) . to be_falsey
2018-05-24 22:04:25 -04:00
# should save user_created_message in session
expect ( session [ " user_created_message " ] ) . to be_present
expect ( session [ SessionController :: ACTIVATE_USER_KEY ] ) . to be_present
2018-05-27 23:20:47 -04:00
expect ( Jobs :: SendSystemMessage . jobs . size ) . to eq ( 0 )
expect ( Jobs :: CriticalUserEmail . jobs . size ) . to eq ( 1 )
args = Jobs :: CriticalUserEmail . jobs . first [ " args " ] . first
expect ( args [ " type " ] ) . to eq ( " signup " )
2018-05-24 22:04:25 -04:00
end
end
2022-07-27 12:14:14 -04:00
context " when users already exists with given email " do
2018-05-24 22:04:25 -04:00
let! ( :existing ) { Fabricate ( :user , email : post_user_params [ :email ] ) }
it " returns an error if hide_email_address_taken is disabled " do
SiteSetting . hide_email_address_taken = false
2018-05-27 23:20:47 -04:00
2018-05-24 22:04:25 -04:00
post_user
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-24 22:04:25 -04:00
expect ( json [ " success " ] ) . to eq ( false )
expect ( json [ " message " ] ) . to be_present
end
it " returns success if hide_email_address_taken is enabled " do
SiteSetting . hide_email_address_taken = true
expect { post_user } . to_not change { User . count }
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
expect ( session [ " user_created_message " ] ) . to be_present
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-24 22:04:25 -04:00
expect ( json [ " active " ] ) . to be_falsey
2018-05-27 23:20:47 -04:00
expect ( json [ " message " ] ) . to eq (
I18n . t ( " login.activate_email " , email : post_user_params [ :email ] ) ,
)
2020-12-07 16:25:35 -05:00
expect ( json [ " user_id " ] ) . not_to be_present
existing . destroy!
expect { post_user } . to change { User . count }
expect ( response . status ) . to eq ( 200 )
json = response . parsed_body
expect ( json [ " active " ] ) . to be_falsey
expect ( json [ " message " ] ) . to eq (
I18n . t ( " login.activate_email " , email : post_user_params [ :email ] ) ,
)
expect ( json [ " user_id " ] ) . not_to be_present
2018-05-24 22:04:25 -04:00
end
end
end
2022-07-27 12:14:14 -04:00
context " when creating as active " do
2018-05-24 22:04:25 -04:00
it " won't create the user as active " do
post " /u.json " , params : post_user_params . merge ( active : true )
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " active " ] ) . to be_falsey
2018-05-24 22:04:25 -04:00
end
context " with a regular api key " do
2021-12-16 14:36:49 -05:00
fab! ( :api_key , refind : false ) { Fabricate ( :api_key , user : user1 ) }
2018-05-24 22:04:25 -04:00
it " won't create the user as active with a regular key " do
post " /u.json " ,
2020-04-06 18:55:44 -04:00
params : post_user_params . merge ( active : true ) ,
headers : {
HTTP_API_KEY : api_key . key ,
}
2018-05-24 22:04:25 -04:00
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " active " ] ) . to be_falsey
2018-05-24 22:04:25 -04:00
end
end
context " with an admin api key " do
2019-12-12 06:45:00 -05:00
fab! ( :api_key , refind : false ) { Fabricate ( :api_key , user : admin ) }
2018-05-24 22:04:25 -04:00
2019-04-12 15:25:02 -04:00
it " creates the user as active with a an admin key " do
2018-05-24 22:04:25 -04:00
SiteSetting . send_welcome_message = true
SiteSetting . must_approve_users = true
2018-05-27 23:20:47 -04:00
#Sidekiq::Client.expects(:enqueue).never
2020-04-06 18:55:44 -04:00
post " /u.json " ,
params : post_user_params . merge ( approved : true , active : true ) ,
headers : {
HTTP_API_KEY : api_key . key ,
}
2018-05-24 22:04:25 -04:00
2018-05-27 23:20:47 -04:00
expect ( Jobs :: CriticalUserEmail . jobs . size ) . to eq ( 0 )
expect ( Jobs :: SendSystemMessage . jobs . size ) . to eq ( 0 )
expect ( response . status ) . to eq ( 200 )
2021-11-25 02:34:39 -05:00
expect ( response . parsed_body [ " active " ] ) . to be_truthy
new_user = User . find ( response . parsed_body [ " user_id " ] )
2018-05-24 22:04:25 -04:00
expect ( new_user . active ) . to eq ( true )
expect ( new_user . approved ) . to eq ( true )
expect ( new_user . approved_by_id ) . to eq ( admin . id )
expect ( new_user . approved_at ) . to_not eq ( nil )
2021-11-25 02:34:39 -05:00
expect ( new_user . email_tokens . where ( confirmed : true , email : new_user . email ) ) . to exist
2018-05-24 22:04:25 -04:00
end
2019-04-12 15:25:02 -04:00
it " will create a reviewable when a user is created as active but not approved " do
Jobs . run_immediately!
SiteSetting . must_approve_users = true
2020-04-06 18:55:44 -04:00
post " /u.json " ,
params : post_user_params . merge ( active : true ) ,
headers : {
HTTP_API_KEY : api_key . key ,
}
2019-04-12 15:25:02 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2019-04-12 15:25:02 -04:00
new_user = User . find ( json [ " user_id " ] )
expect ( json [ " active " ] ) . to be_truthy
expect ( new_user . approved ) . to eq ( false )
expect ( ReviewableUser . pending . find_by ( target : new_user ) ) . to be_present
end
it " won't create a reviewable when a user is not active " do
Jobs . run_immediately!
SiteSetting . must_approve_users = true
2020-04-06 18:55:44 -04:00
post " /u.json " , params : post_user_params , headers : { HTTP_API_KEY : api_key . key }
2019-04-12 15:25:02 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2019-04-12 15:25:02 -04:00
new_user = User . find ( json [ " user_id " ] )
expect ( json [ " active " ] ) . to eq ( false )
expect ( new_user . approved ) . to eq ( false )
expect ( ReviewableUser . pending . find_by ( target : new_user ) ) . to be_blank
end
2018-05-24 22:04:25 -04:00
it " won't create the developer as active " do
UsernameCheckerService . expects ( :is_developer? ) . returns ( true )
2020-04-06 18:55:44 -04:00
post " /u.json " ,
params : post_user_params . merge ( active : true ) ,
headers : {
HTTP_API_KEY : api_key . key ,
}
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " active " ] ) . to be_falsy
2018-05-24 22:04:25 -04:00
end
2019-06-07 11:51:58 -04:00
it " won't set the new user's locale to the admin's locale " do
SiteSetting . allow_user_locale = true
admin . update! ( locale : :fr )
2020-04-06 18:55:44 -04:00
post " /u.json " ,
params : post_user_params . merge ( active : true ) ,
headers : {
HTTP_API_KEY : api_key . key ,
}
2019-06-07 11:51:58 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2019-06-07 11:51:58 -04:00
new_user = User . find ( json [ " user_id " ] )
expect ( new_user . locale ) . not_to eq ( " fr " )
end
2020-03-31 14:29:15 -04:00
it " will auto approve user if the user email domain matches auto_approve_email_domains setting " do
Jobs . run_immediately!
SiteSetting . must_approve_users = true
SiteSetting . auto_approve_email_domains = " example.com "
2020-04-06 18:55:44 -04:00
post " /u.json " ,
params : post_user_params . merge ( active : true ) ,
headers : {
HTTP_API_KEY : api_key . key ,
}
2020-03-31 14:29:15 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2020-03-31 14:29:15 -04:00
new_user = User . find ( json [ " user_id " ] )
expect ( json [ " active " ] ) . to be_truthy
expect ( new_user . approved ) . to be_truthy
expect ( ReviewableUser . pending . find_by ( target : new_user ) ) . to be_blank
end
2018-05-24 22:04:25 -04:00
end
end
2022-07-27 12:14:14 -04:00
context " when creating as staged " do
2018-05-24 22:04:25 -04:00
it " won't create the user as staged " do
post " /u.json " , params : post_user_params . merge ( staged : true )
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
new_user = User . where ( username : post_user_params [ :username ] ) . first
expect ( new_user . staged? ) . to eq ( false )
end
context " with a regular api key " do
2021-12-16 14:36:49 -05:00
fab! ( :api_key , refind : false ) { Fabricate ( :api_key , user : user1 ) }
2018-05-24 22:04:25 -04:00
it " won't create the user as staged with a regular key " do
2020-04-06 18:55:44 -04:00
post " /u.json " ,
params : post_user_params . merge ( staged : true ) ,
headers : {
HTTP_API_KEY : api_key . key ,
}
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
new_user = User . where ( username : post_user_params [ :username ] ) . first
expect ( new_user . staged? ) . to eq ( false )
end
end
context " with an admin api key " do
2021-12-07 13:45:58 -05:00
fab! ( :user ) { admin }
2019-12-12 06:45:00 -05:00
fab! ( :api_key , refind : false ) { Fabricate ( :api_key , user : user ) }
2018-05-24 22:04:25 -04:00
it " creates the user as staged with a regular key " do
2020-04-06 18:55:44 -04:00
post " /u.json " ,
params : post_user_params . merge ( staged : true ) ,
headers : {
HTTP_API_KEY : api_key . key ,
}
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
new_user = User . where ( username : post_user_params [ :username ] ) . first
expect ( new_user . staged? ) . to eq ( true )
end
it " won't create the developer as staged " do
UsernameCheckerService . expects ( :is_developer? ) . returns ( true )
2020-04-06 18:55:44 -04:00
post " /u.json " ,
params : post_user_params . merge ( staged : true ) ,
headers : {
HTTP_API_KEY : api_key . key ,
}
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
new_user = User . where ( username : post_user_params [ :username ] ) . first
expect ( new_user . staged? ) . to eq ( false )
end
end
end
context " when creating an active user (confirmed email) " do
before { User . any_instance . stubs ( :active? ) . returns ( true ) }
it " enqueues a welcome email " do
User . any_instance . expects ( :enqueue_welcome_message ) . with ( " welcome_user " )
2018-05-27 23:20:47 -04:00
2018-05-24 22:04:25 -04:00
post_user
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
# should save user_created_message in session
expect ( session [ " user_created_message " ] ) . to be_present
expect ( session [ SessionController :: ACTIVATE_USER_KEY ] ) . to be_present
end
it " shows the 'active' message " do
User . any_instance . expects ( :enqueue_welcome_message )
post_user
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " message " ] ) . to eq ( I18n . t " login.active " )
2018-05-24 22:04:25 -04:00
end
it " should be logged in " do
User . any_instance . expects ( :enqueue_welcome_message )
post_user
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( session [ :current_user_id ] ) . to be_present
end
it " indicates the user is active in the response " do
User . any_instance . expects ( :enqueue_welcome_message )
post_user
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " active " ] ) . to be_truthy
2018-05-24 22:04:25 -04:00
end
2018-05-27 23:20:47 -04:00
it 'doesn\'t succeed when new registrations are disabled' do
2018-05-24 22:04:25 -04:00
SiteSetting . allow_new_registrations = false
post_user
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-24 22:04:25 -04:00
expect ( json [ " success " ] ) . to eq ( false )
expect ( json [ " message " ] ) . to be_present
end
2022-07-27 12:14:14 -04:00
context " with authentication records for " do
2018-05-24 22:04:25 -04:00
before do
2018-05-28 03:12:54 -04:00
OmniAuth . config . test_mode = true
2018-05-24 22:04:25 -04:00
OmniAuth . config . mock_auth [ :twitter ] = OmniAuth :: AuthHash . new (
provider : " twitter " ,
uid : " 123545 " ,
info :
OmniAuth :: AuthHash :: InfoHash . new (
email : " osama@mail.com " ,
2020-06-18 06:01:02 -04:00
nickname : " testosama " ,
name : " Osama Test " ,
2018-05-24 22:04:25 -04:00
) ,
)
Rails . application . env_config [ " omniauth.auth " ] = OmniAuth . config . mock_auth [ :twitter ]
SiteSetting . enable_twitter_logins = true
get " /auth/twitter/callback.json "
end
2018-05-28 03:12:54 -04:00
after do
Rails . application . env_config [ " omniauth.auth " ] = OmniAuth . config . mock_auth [ :twitter ] = nil
OmniAuth . config . test_mode = false
end
2018-05-24 22:04:25 -04:00
it " should create twitter user info if required " do
post " /u.json " ,
params : {
name : " Test Osama " ,
username : " testosama " ,
password : " strongpassword " ,
email : " osama@mail.com " ,
}
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2018-12-07 10:39:06 -05:00
expect ( UserAssociatedAccount . where ( provider_name : " twitter " ) . count ) . to eq ( 1 )
2018-05-24 22:04:25 -04:00
end
it " returns an error when email has been changed from the validated email address " do
post " /u.json " ,
params : {
name : " Test Osama " ,
username : " testosama " ,
password : " strongpassword " ,
email : " unvalidatedemail@mail.com " ,
}
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-24 22:04:25 -04:00
expect ( json [ " success " ] ) . to eq ( false )
expect ( json [ " message " ] ) . to be_present
end
it " will create the user successfully if email validation is required " do
post " /u.json " ,
params : {
name : " Test Osama " ,
username : " testosama " ,
password : " strongpassword " ,
email : " osama@mail.com " ,
}
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-24 22:04:25 -04:00
expect ( json [ " success " ] ) . to eq ( true )
end
2020-06-18 06:01:02 -04:00
it " doesn't use provided username/name if sso_overrides is enabled " do
2021-02-08 05:04:33 -05:00
SiteSetting . auth_overrides_username = true
SiteSetting . auth_overrides_name = true
2020-06-18 06:01:02 -04:00
post " /u.json " ,
params : {
username : " attemptednewname " ,
name : " Attempt At New Name " ,
password : " strongpassword " ,
email : " osama@mail.com " ,
}
expect ( response . status ) . to eq ( 200 )
json = response . parsed_body
expect ( json [ " success " ] ) . to eq ( true )
2021-07-28 02:07:18 -04:00
user = User . last
expect ( user . username ) . to eq ( " testosama " )
expect ( user . name ) . to eq ( " Osama Test " )
2020-06-18 06:01:02 -04:00
end
2018-05-24 22:04:25 -04:00
end
2020-07-10 12:56:33 -04:00
context " with no email in the auth payload " do
before do
OmniAuth . config . test_mode = true
OmniAuth . config . mock_auth [ :twitter ] = OmniAuth :: AuthHash . new (
provider : " twitter " ,
uid : " 123545 " ,
info : OmniAuth :: AuthHash :: InfoHash . new ( nickname : " testosama " , name : " Osama Test " ) ,
)
Rails . application . env_config [ " omniauth.auth " ] = OmniAuth . config . mock_auth [ :twitter ]
SiteSetting . enable_twitter_logins = true
get " /auth/twitter/callback.json "
end
after do
Rails . application . env_config [ " omniauth.auth " ] = OmniAuth . config . mock_auth [ :twitter ] = nil
OmniAuth . config . test_mode = false
end
it " will create the user successfully " do
Rails . application . env_config [ " omniauth.auth " ] . info . email = nil
post " /u.json " ,
params : {
name : " Test Osama " ,
username : " testosama " ,
password : " strongpassword " ,
email : " osama@mail.com " ,
}
expect ( response . status ) . to eq ( 200 )
json = response . parsed_body
expect ( json [ " success " ] ) . to eq ( true )
end
end
2018-05-24 22:04:25 -04:00
end
2018-05-27 23:20:47 -04:00
it " creates user successfully but doesn't activate the account " do
post_user
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-27 23:20:47 -04:00
expect ( json [ " success " ] ) . to eq ( true )
expect ( User . find_by ( username : @user . username ) . active ) . to eq ( false )
2018-05-24 22:04:25 -04:00
end
shared_examples " honeypot fails " do
it " should not create a new user " do
2019-10-16 01:53:31 -04:00
User . any_instance . expects ( :enqueue_welcome_message ) . never
2018-05-24 22:04:25 -04:00
expect { post " /u.json " , params : create_params } . to_not change { User . count }
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-24 22:04:25 -04:00
expect ( json [ " success " ] ) . to eq ( true )
# should not change the session
expect ( session [ " user_created_message " ] ) . to be_blank
expect ( session [ SessionController :: ACTIVATE_USER_KEY ] ) . to be_blank
end
end
context " when honeypot value is wrong " do
before { UsersController . any_instance . stubs ( :honeypot_value ) . returns ( " abc " ) }
2019-05-03 12:17:06 -04:00
let ( :create_params ) do
2023-01-09 06:18:21 -05:00
{
2019-05-03 12:17:06 -04:00
name : @user . name ,
2018-05-24 22:04:25 -04:00
username : @user . username ,
password : " strongpassword " ,
2019-05-03 12:17:06 -04:00
email : @user . email ,
2018-05-24 22:04:25 -04:00
password_confirmation : " wrong " ,
2023-01-09 06:18:21 -05:00
}
2018-05-24 22:04:25 -04:00
end
include_examples " honeypot fails "
end
context " when challenge answer is wrong " do
before { UsersController . any_instance . stubs ( :challenge_value ) . returns ( " abc " ) }
let ( :create_params ) do
2023-01-09 06:18:21 -05:00
{
2018-05-24 22:04:25 -04:00
name : @user . name ,
username : @user . username ,
password : " strongpassword " ,
2019-05-03 12:17:06 -04:00
email : @user . email ,
2018-05-24 22:04:25 -04:00
challenge : " abc " ,
2023-01-09 06:18:21 -05:00
}
2018-05-24 22:04:25 -04:00
end
include_examples " honeypot fails "
end
context " when 'invite only' setting is enabled " do
before { SiteSetting . invite_only = true }
let ( :create_params ) do
{
name : @user . name ,
username : @user . username ,
password : " strongpassword " ,
email : @user . email ,
}
2023-01-09 06:18:21 -05:00
end
2018-05-24 22:04:25 -04:00
include_examples " honeypot fails "
end
shared_examples " failed signup " do
it " should not create a new User " do
expect { post " /u.json " , params : create_params } . to_not change { User . count }
2019-05-03 12:17:06 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
end
it " should report failed " do
post " /u.json " , params : create_params
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-24 22:04:25 -04:00
expect ( json [ " success " ] ) . not_to eq ( true )
# should not change the session
expect ( session [ " user_created_message " ] ) . to be_blank
expect ( session [ SessionController :: ACTIVATE_USER_KEY ] ) . to be_blank
end
end
context " when password is blank " do
let ( :create_params ) do
{ name : @user . name , username : @user . username , password : " " , email : @user . email }
2023-01-09 06:18:21 -05:00
end
2018-05-24 22:04:25 -04:00
include_examples " failed signup "
end
context " when password is too long " do
let ( :create_params ) do
{
name : @user . name ,
username : @user . username ,
password : " x " * ( User . max_password_length + 1 ) ,
email : @user . email ,
}
2023-01-09 06:18:21 -05:00
end
2018-05-24 22:04:25 -04:00
include_examples " failed signup "
end
context " when password param is missing " do
let ( :create_params ) { { name : @user . name , username : @user . username , email : @user . email } }
include_examples " failed signup "
end
context " with a reserved username " do
2019-09-13 14:11:27 -04:00
let ( :create_params ) do
{ name : @user . name , username : " Reserved " , email : @user . email , password : " strongpassword " }
2023-01-09 06:18:21 -05:00
end
2018-05-24 22:04:25 -04:00
before { SiteSetting . reserved_usernames = " a|reserved|b " }
include_examples " failed signup "
end
2019-09-13 14:11:27 -04:00
context " with a username that matches a user route " do
let ( :create_params ) do
{
name : @user . name ,
username : " account-created " ,
email : @user . email ,
password : " strongpassword " ,
}
2023-01-09 06:18:21 -05:00
end
2019-09-13 14:11:27 -04:00
include_examples " failed signup "
end
2019-05-03 12:17:06 -04:00
context " with a missing username " do
let ( :create_params ) { { name : @user . name , email : @user . email , password : " x " * 20 } }
it " should not create a new User " do
expect { post " /u.json " , params : create_params } . to_not change { User . count }
expect ( response . status ) . to eq ( 400 )
end
end
2018-05-24 22:04:25 -04:00
context " when an Exception is raised " do
before { User . any_instance . stubs ( :save ) . raises ( ActiveRecord :: StatementInvalid . new ( " Oh no " ) ) }
let ( :create_params ) do
{
name : @user . name ,
username : @user . username ,
password : " strongpassword " ,
email : @user . email ,
}
2023-01-09 06:18:21 -05:00
end
2018-05-24 22:04:25 -04:00
include_examples " failed signup "
end
context " with custom fields " do
2021-12-16 14:36:49 -05:00
fab! ( :user_field ) { Fabricate ( :user_field ) }
fab! ( :another_field ) { Fabricate ( :user_field ) }
fab! ( :optional_field ) { Fabricate ( :user_field , required : false ) }
2018-05-24 22:04:25 -04:00
context " without a value for the fields " do
let ( :create_params ) do
{ name : @user . name , password : " watwatwat " , username : @user . username , email : @user . email }
2023-01-09 06:18:21 -05:00
end
2018-05-24 22:04:25 -04:00
include_examples " failed signup "
end
context " with values for the fields " do
2021-12-16 14:36:49 -05:00
let ( :update_user_url ) { " /u/ #{ user1 . username } .json " }
2021-07-30 13:50:47 -04:00
let ( :field_id ) { user_field . id . to_s }
2021-12-16 14:36:49 -05:00
before { sign_in ( user1 ) }
2021-07-30 13:50:47 -04:00
context " with multple select fields " do
let ( :valid_options ) { %w[ Axe Sword ] }
fab! ( :user_field ) do
Fabricate ( :user_field , field_type : " multiselect " ) do
user_field_options do
[
Fabricate ( :user_field_option , value : " Axe " ) ,
Fabricate ( :user_field_option , value : " Sword " ) ,
]
end
end
end
2021-09-03 09:26:57 -04:00
it " should allow single values and not just arrays " do
expect do
put update_user_url , params : { user_fields : { field_id = > " Axe " } }
2021-12-16 14:36:49 -05:00
end . to change { user1 . reload . user_fields [ field_id ] } . from ( nil ) . to ( " Axe " )
2021-09-03 09:26:57 -04:00
expect do
put update_user_url , params : { user_fields : { field_id = > %w[ Axe Juice Sword ] } }
2021-12-16 14:36:49 -05:00
end . to change { user1 . reload . user_fields [ field_id ] } . from ( " Axe " ) . to ( %w[ Axe Sword ] )
2021-09-03 09:26:57 -04:00
end
2021-07-30 13:50:47 -04:00
it " shouldn't allow unregistered field values " do
expect do
put update_user_url , params : { user_fields : { field_id = > %w[ Juice ] } }
2021-12-16 14:36:49 -05:00
end . not_to change { user1 . reload . user_fields [ field_id ] }
2021-07-30 13:50:47 -04:00
end
it " should filter valid values " do
expect do
put update_user_url , params : { user_fields : { field_id = > %w[ Axe Juice Sword ] } }
2021-12-16 14:36:49 -05:00
end . to change { user1 . reload . user_fields [ field_id ] } . from ( nil ) . to ( valid_options )
2021-07-30 13:50:47 -04:00
end
it " allows registered field values " do
expect do
put update_user_url , params : { user_fields : { field_id = > valid_options } }
2021-12-16 14:36:49 -05:00
end . to change { user1 . reload . user_fields [ field_id ] } . from ( nil ) . to ( valid_options )
2021-07-30 13:50:47 -04:00
end
it " value can't be nil or empty if the field is required " do
put update_user_url , params : { user_fields : { field_id = > valid_options } }
user_field . update! ( required : true )
expect do
put update_user_url , params : { user_fields : { field_id = > nil } }
2021-12-16 14:36:49 -05:00
end . not_to change { user1 . reload . user_fields [ field_id ] }
2021-07-30 13:50:47 -04:00
expect do
put update_user_url , params : { user_fields : { field_id = > " " } }
2021-12-16 14:36:49 -05:00
end . not_to change { user1 . reload . user_fields [ field_id ] }
2021-07-30 13:50:47 -04:00
end
it " value can nil or empty if the field is not required " do
put update_user_url , params : { user_fields : { field_id = > valid_options } }
user_field . update! ( required : false )
expect do
put update_user_url , params : { user_fields : { field_id = > nil } }
2021-12-16 14:36:49 -05:00
end . to change { user1 . reload . user_fields [ field_id ] } . from ( valid_options ) . to ( nil )
2021-07-30 13:50:47 -04:00
expect do
put update_user_url , params : { user_fields : { field_id = > " " } }
2021-12-16 14:36:49 -05:00
end . to change { user1 . reload . user_fields [ field_id ] } . from ( nil ) . to ( " " )
2021-07-30 13:50:47 -04:00
end
end
context " with dropdown fields " do
let ( :valid_options ) { [ " Black Mesa " , " Fox Hound " ] }
fab! ( :user_field ) do
Fabricate ( :user_field , field_type : " dropdown " ) do
user_field_options do
[
Fabricate ( :user_field_option , value : " Black Mesa " ) ,
Fabricate ( :user_field_option , value : " Fox Hound " ) ,
]
end
end
end
it " shouldn't allow unregistered field values " do
expect do
put update_user_url , params : { user_fields : { field_id = > " Umbrella Corporation " } }
2021-12-16 14:36:49 -05:00
end . not_to change { user1 . reload . user_fields [ field_id ] }
2021-07-30 13:50:47 -04:00
end
it " allows registered field values " do
expect do
put update_user_url , params : { user_fields : { field_id = > valid_options . first } }
2021-12-16 14:36:49 -05:00
end . to change { user1 . reload . user_fields [ field_id ] } . from ( nil ) . to ( valid_options . first )
2021-07-30 13:50:47 -04:00
end
it " value can't be nil if the field is required " do
put update_user_url , params : { user_fields : { field_id = > valid_options . first } }
user_field . update! ( required : true )
expect do
put update_user_url , params : { user_fields : { field_id = > nil } }
2021-12-16 14:36:49 -05:00
end . not_to change { user1 . reload . user_fields [ field_id ] }
2021-07-30 13:50:47 -04:00
end
it " value can be set to nil if the field is not required " do
put update_user_url , params : { user_fields : { field_id = > valid_options . last } }
user_field . update! ( required : false )
expect do
put update_user_url , params : { user_fields : { field_id = > nil } }
2021-12-16 14:36:49 -05:00
end . to change { user1 . reload . user_fields [ field_id ] } . from ( valid_options . last ) . to ( nil )
2021-07-30 13:50:47 -04:00
end
end
2018-05-24 22:04:25 -04:00
let ( :create_params ) do
{
name : @user . name ,
password : " suChS3cuRi7y " ,
username : @user . username ,
email : @user . email ,
user_fields : {
user_field . id . to_s = > " value1 " ,
another_field . id . to_s = > " value2 " ,
2023-01-09 06:18:21 -05:00
} ,
2018-05-24 22:04:25 -04:00
}
2023-01-09 06:18:21 -05:00
end
2018-05-24 22:04:25 -04:00
it " should succeed without the optional field " do
post " /u.json " , params : create_params
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
inserted = User . find_by_email ( @user . email )
expect ( inserted ) . to be_present
expect ( inserted . custom_fields ) . to be_present
expect ( inserted . custom_fields [ " user_field_ #{ user_field . id } " ] ) . to eq ( " value1 " )
expect ( inserted . custom_fields [ " user_field_ #{ another_field . id } " ] ) . to eq ( " value2 " )
expect ( inserted . custom_fields [ " user_field_ #{ optional_field . id } " ] ) . to be_blank
end
it " should succeed with the optional field " do
create_params [ :user_fields ] [ optional_field . id . to_s ] = " value3 "
post " /u.json " , params : create_params . merge ( create_params )
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
inserted = User . find_by_email ( @user . email )
expect ( inserted ) . to be_present
expect ( inserted . custom_fields ) . to be_present
expect ( inserted . custom_fields [ " user_field_ #{ user_field . id } " ] ) . to eq ( " value1 " )
expect ( inserted . custom_fields [ " user_field_ #{ another_field . id } " ] ) . to eq ( " value2 " )
expect ( inserted . custom_fields [ " user_field_ #{ optional_field . id } " ] ) . to eq ( " value3 " )
end
it " trims excessively long fields " do
create_params [ :user_fields ] [ optional_field . id . to_s ] = ( " x " * 3000 )
post " /u.json " , params : create_params . merge ( create_params )
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
inserted = User . find_by_email ( @user . email )
val = inserted . custom_fields [ " user_field_ #{ optional_field . id } " ]
expect ( val . length ) . to eq ( UserField . max_length )
end
end
end
context " with only optional custom fields " do
2021-12-16 14:36:49 -05:00
fab! ( :user_field ) { Fabricate ( :user_field , required : false ) }
2018-05-24 22:04:25 -04:00
context " without values for the fields " do
let ( :create_params ) do
{
name : @user . name ,
password : " suChS3cuRi7y " ,
username : @user . username ,
email : @user . email ,
}
2023-01-09 06:18:21 -05:00
end
2018-05-24 22:04:25 -04:00
it " should succeed " do
post " /u.json " , params : create_params
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
inserted = User . find_by_email ( @user . email )
expect ( inserted ) . to be_present
expect ( inserted . custom_fields ) . not_to be_present
expect ( inserted . custom_fields [ " user_field_ #{ user_field . id } " ] ) . to be_blank
end
end
end
context " when taking over a staged account " do
before do
UsersController . any_instance . stubs ( :honeypot_value ) . returns ( " abc " )
UsersController . any_instance . stubs ( :challenge_value ) . returns ( " efg " )
2020-10-01 19:01:40 -04:00
SessionController . any_instance . stubs ( :honeypot_value ) . returns ( " abc " )
SessionController . any_instance . stubs ( :challenge_value ) . returns ( " efg " )
2018-05-24 22:04:25 -04:00
end
2021-12-16 14:36:49 -05:00
fab! ( :staged ) { Fabricate ( :staged , email : " staged@account.com " , active : true ) }
2018-05-24 22:04:25 -04:00
it " succeeds " do
post " /u.json " ,
params :
honeypot_magic ( email : staged . email , username : " zogstrip " , password : " P4ssw0rd$$ " )
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
result = response . parsed_body
2018-05-24 22:04:25 -04:00
expect ( result [ " success " ] ) . to eq ( true )
created_user = User . find_by_email ( staged . email )
expect ( created_user . staged ) . to eq ( false )
expect ( created_user . active ) . to eq ( false )
expect ( created_user . registration_ip_address ) . to be_present
expect ( ! ! created_user . custom_fields [ " from_staged " ] ) . to eq ( true )
# do not allow emails changes please
put " /u/update-activation-email.json " , params : { email : " bob@bob.com " }
created_user . reload
expect ( created_user . email ) . to eq ( " staged@account.com " )
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 403 )
2018-05-24 22:04:25 -04:00
end
end
end
describe " # username " do
it " raises an error when not logged in " do
put " /u/somename/preferences/username.json "
expect ( response . status ) . to eq ( 403 )
end
context " while logged in " do
2021-05-20 21:43:47 -04:00
let ( :old_username ) { " OrigUsername " }
2018-05-24 22:04:25 -04:00
let ( :new_username ) { " #{ old_username } 1234 " }
2021-12-16 14:36:49 -05:00
fab! ( :user ) { Fabricate ( :user , username : " OrigUsername " ) }
2018-05-24 22:04:25 -04:00
before do
user . username = old_username
sign_in ( user )
end
it " raises an error without a new_username param " do
put " /u/ #{ user . username } /preferences/username.json " , params : { username : user . username }
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 400 )
2018-05-24 22:04:25 -04:00
expect ( user . reload . username ) . to eq ( old_username )
end
it 'raises an error when you don\'t have permission to change the username' do
Guardian . any_instance . expects ( :can_edit_username? ) . with ( user ) . returns ( false )
put " /u/ #{ user . username } /preferences/username.json " , params : { new_username : new_username }
expect ( response ) . to be_forbidden
expect ( user . reload . username ) . to eq ( old_username )
end
it " raises an error when change_username fails " do
put " /u/ #{ user . username } /preferences/username.json " , params : { new_username : " @ " }
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 422 )
2018-05-24 22:04:25 -04:00
2020-05-07 11:04:12 -04:00
body = response . parsed_body
2018-05-24 22:04:25 -04:00
expect ( body [ " errors " ] . first ) . to include (
I18n . t ( " user.username.short " , min : User . username_length . begin ) ,
)
expect ( user . reload . username ) . to eq ( old_username )
end
it " should succeed in normal circumstances " do
put " /u/ #{ user . username } /preferences/username.json " , params : { new_username : new_username }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( user . reload . username ) . to eq ( new_username )
end
2019-09-13 14:11:27 -04:00
it " raises an error when the username clashes with an existing user route " do
put " /u/ #{ user . username } /preferences/username.json " ,
params : {
new_username : " account-created " ,
}
2020-05-07 11:04:12 -04:00
body = response . parsed_body
2019-09-13 14:11:27 -04:00
expect ( body [ " errors " ] . first ) . to include ( I18n . t ( " login.reserved_username " ) )
end
it " raises an error when the username is in the reserved list " do
SiteSetting . reserved_usernames = " reserved "
put " /u/ #{ user . username } /preferences/username.json " , params : { new_username : " reserved " }
2020-05-07 11:04:12 -04:00
body = response . parsed_body
2019-09-13 14:11:27 -04:00
expect ( body [ " errors " ] . first ) . to include ( I18n . t ( " login.reserved_username " ) )
end
2018-05-24 22:04:25 -04:00
it " should fail if the user is old " do
# Older than the change period and >1 post
user . created_at = Time . now - ( SiteSetting . username_change_period + 1 ) . days
PostCreator . new (
user ,
title : " This is a test topic " ,
raw : " This is a test this is a test " ,
) . create
put " /u/ #{ user . username } /preferences/username.json " , params : { new_username : new_username }
expect ( response ) . to be_forbidden
expect ( user . reload . username ) . to eq ( old_username )
end
it " should create a staff action log when a staff member changes the username " do
2021-12-07 13:45:58 -05:00
acting_user = admin
2018-05-24 22:04:25 -04:00
sign_in ( acting_user )
put " /u/ #{ user . username } /preferences/username.json " , params : { new_username : new_username }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect (
UserHistory . where (
action : UserHistory . actions [ :change_username ] ,
target_user_id : user . id ,
acting_user_id : acting_user . id ,
2023-01-09 06:18:21 -05:00
) ,
2018-05-24 22:04:25 -04:00
) . to be_present
expect ( user . reload . username ) . to eq ( new_username )
end
it " should return a JSON response with the updated username " do
put " /u/ #{ user . username } /preferences/username.json " , params : { new_username : new_username }
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " username " ] ) . to eq ( new_username )
2018-05-24 22:04:25 -04:00
end
2019-08-01 00:49:53 -04:00
2021-02-08 05:04:33 -05:00
it " should respond with proper error message if auth_overrides_username is enabled " do
SiteSetting . discourse_connect_url = " http://someurl.com "
SiteSetting . enable_discourse_connect = true
SiteSetting . auth_overrides_username = true
2021-12-07 13:45:58 -05:00
acting_user = admin
2019-08-01 00:49:53 -04:00
sign_in ( acting_user )
put " /u/ #{ user . username } /preferences/username.json " , params : { new_username : new_username }
expect ( response . status ) . to eq ( 422 )
2021-02-08 05:04:33 -05:00
expect ( response . parsed_body [ " errors " ] . first ) . to include (
I18n . t ( " errors.messages.auth_overrides_username " ) ,
)
2019-08-01 03:23:50 -04:00
end
2018-05-24 22:04:25 -04:00
end
end
describe " # check_username " do
it " raises an error without any parameters " do
get " /u/check_username.json "
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 400 )
2018-05-24 22:04:25 -04:00
end
shared_examples " when username is unavailable " do
2018-05-27 23:20:47 -04:00
it " should return available as false in the JSON and return a suggested username " do
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " available " ] ) . to eq ( false )
expect ( response . parsed_body [ " suggestion " ] ) . to be_present
2018-05-24 22:04:25 -04:00
end
end
shared_examples " when username is available " do
it " should return available in the JSON " do
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " available " ] ) . to eq ( true )
2018-05-24 22:04:25 -04:00
end
end
it " returns nothing when given an email param but no username " do
get " /u/check_username.json " , params : { email : " dood@example.com " }
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
end
2022-07-27 12:14:14 -04:00
context " when username is available " do
2018-05-24 22:04:25 -04:00
before { get " /u/check_username.json " , params : { username : " BruceWayne " } }
include_examples " when username is available "
end
2022-07-27 12:14:14 -04:00
context " when username is unavailable " do
2021-12-16 14:36:49 -05:00
before { get " /u/check_username.json " , params : { username : user1 . username } }
2018-05-24 22:04:25 -04:00
include_examples " when username is unavailable "
end
shared_examples " checking an invalid username " do
2018-05-27 23:20:47 -04:00
it " should not return an available key but should return an error message " do
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " available " ] ) . to eq ( nil )
expect ( response . parsed_body [ " errors " ] ) . to be_present
2018-05-24 22:04:25 -04:00
end
end
2022-07-27 12:14:14 -04:00
context " when has invalid characters " do
2018-05-24 22:04:25 -04:00
before { get " /u/check_username.json " , params : { username : " bad username " } }
include_examples " checking an invalid username "
it " should return the invalid characters message " do
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " errors " ] ) . to include ( I18n . t ( :" user.username.characters " ) )
2018-05-24 22:04:25 -04:00
end
end
2022-07-27 12:14:14 -04:00
context " when is too long " do
2018-05-24 22:04:25 -04:00
before do
2022-01-08 17:39:46 -05:00
get " /u/check_username.json " ,
params : {
username : SecureRandom . alphanumeric ( SiteSetting . max_username_length . to_i + 1 ) ,
}
2018-05-24 22:04:25 -04:00
end
include_examples " checking an invalid username "
it 'should return the "too long" message' do
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2022-01-08 17:39:46 -05:00
expect ( response . parsed_body [ " errors " ] ) . to include (
I18n . t ( :" user.username.long " , max : SiteSetting . max_username_length ) ,
)
2018-05-24 22:04:25 -04:00
end
end
describe " different case of existing username " do
2022-07-27 12:14:14 -04:00
context " when it's my username " do
2021-12-07 13:45:58 -05:00
fab! ( :user ) { Fabricate ( :user , username : " hansolo " ) }
2018-05-24 22:04:25 -04:00
before do
sign_in ( user )
get " /u/check_username.json " , params : { username : " HanSolo " }
end
include_examples " when username is available "
end
2022-07-27 12:14:14 -04:00
context " when it's someone else's username " do
2021-12-07 13:45:58 -05:00
fab! ( :user ) { Fabricate ( :user , username : " hansolo " ) }
2021-12-16 14:36:49 -05:00
fab! ( :someone_else ) { Fabricate ( :user ) }
2018-05-24 22:04:25 -04:00
before do
2021-12-16 14:36:49 -05:00
sign_in ( someone_else )
2018-05-24 22:04:25 -04:00
get " /u/check_username.json " , params : { username : " HanSolo " }
end
include_examples " when username is unavailable "
end
2022-07-27 12:14:14 -04:00
context " when an admin changing it for someone else " do
2021-12-07 13:45:58 -05:00
fab! ( :user ) { Fabricate ( :user , username : " hansolo " ) }
2018-05-24 22:04:25 -04:00
before do
2021-12-07 13:45:58 -05:00
sign_in ( admin )
2018-05-24 22:04:25 -04:00
get " /u/check_username.json " , params : { username : " HanSolo " , for_user_id : user . id }
end
include_examples " when username is available "
end
end
end
2021-03-22 11:46:03 -04:00
describe " # check_email " do
it " returns success if hide_email_address_taken is true " do
SiteSetting . hide_email_address_taken = true
2021-12-16 14:36:49 -05:00
get " /u/check_email.json " , params : { email : user1 . email }
2021-03-22 11:46:03 -04:00
expect ( response . parsed_body [ " success " ] ) . to be_present
end
2021-03-23 17:44:51 -04:00
it " returns success if email is empty " do
get " /u/check_email.json "
expect ( response . parsed_body [ " success " ] ) . to be_present
end
2021-03-22 11:46:03 -04:00
it " returns failure if email is not valid " do
get " /u/check_email.json " , params : { email : " invalid " }
expect ( response . parsed_body [ " failed " ] ) . to be_present
end
it " returns failure if email exists " do
2021-12-16 14:36:49 -05:00
get " /u/check_email.json " , params : { email : user1 . email }
2021-03-22 11:46:03 -04:00
expect ( response . parsed_body [ " failed " ] ) . to be_present
2021-03-23 17:44:51 -04:00
2021-12-16 14:36:49 -05:00
get " /u/check_email.json " , params : { email : user1 . email . upcase }
2021-03-23 17:44:51 -04:00
expect ( response . parsed_body [ " failed " ] ) . to be_present
2021-03-22 11:46:03 -04:00
end
it " returns success if email does not exists " do
get " /u/check_email.json " , params : { email : " available@example.com " }
expect ( response . parsed_body [ " success " ] ) . to be_present
end
2021-03-23 17:44:51 -04:00
it " return success if user email is taken by staged user " do
get " /u/check_email.json " , params : { email : Fabricate ( :staged ) . email }
expect ( response . parsed_body [ " success " ] ) . to be_present
end
2021-03-22 11:46:03 -04:00
end
2018-05-24 22:04:25 -04:00
describe " # invited " do
2020-03-04 11:10:23 -05:00
it " fails for anonymous users " do
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } /invited.json " , params : { username : user1 . username }
2018-05-24 22:04:25 -04:00
2020-03-04 11:10:23 -05:00
expect ( response . status ) . to eq ( 403 )
end
it " returns success " do
user = Fabricate ( :user , trust_level : 2 )
2021-03-03 04:45:29 -05:00
Fabricate ( :invite , invited_by : user )
2020-03-04 11:10:23 -05:00
sign_in ( user )
get " /u/ #{ user . username } /invited.json " , params : { username : user . username }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2021-03-03 04:45:29 -05:00
expect ( response . parsed_body [ " counts " ] [ " pending " ] ) . to eq ( 1 )
expect ( response . parsed_body [ " counts " ] [ " total " ] ) . to eq ( 1 )
2018-05-24 22:04:25 -04:00
end
2020-03-04 11:47:09 -05:00
it " filters by all if viewing self " do
2020-03-04 11:10:23 -05:00
inviter = Fabricate ( :user , trust_level : 2 )
sign_in ( inviter )
2020-06-09 11:19:32 -04:00
Fabricate ( :invite , email : " billybob@example.com " , invited_by : inviter )
redeemed_invite = Fabricate ( :invite , email : " jimtom@example.com " , invited_by : inviter )
Fabricate ( :invited_user , invite : redeemed_invite , user : invitee )
2018-05-24 22:04:25 -04:00
2020-06-09 11:19:32 -04:00
get " /u/ #{ inviter . username } /invited.json " , params : { filter : " pending " , search : " billybob " }
2020-03-04 11:10:23 -05:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
2020-05-07 11:04:12 -04:00
invites = response . parsed_body [ " invites " ]
2018-05-24 22:04:25 -04:00
expect ( invites . size ) . to eq ( 1 )
expect ( invites . first ) . to include ( " email " = > " billybob@example.com " )
2020-03-04 11:47:09 -05:00
2020-06-09 11:19:32 -04:00
get " /u/ #{ inviter . username } /invited.json " ,
params : {
filter : " redeemed " ,
search : invitee . username ,
}
2020-03-04 11:47:09 -05:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
invites = response . parsed_body [ " invites " ]
2020-06-09 11:19:32 -04:00
expect ( invites . size ) . to eq ( 1 )
expect ( invites [ 0 ] [ " user " ] ) . to be_present
2018-05-24 22:04:25 -04:00
end
2020-03-04 11:47:09 -05:00
it " doesn't filter by email if another regular user " do
2020-03-04 11:10:23 -05:00
inviter = Fabricate ( :user , trust_level : 2 )
2020-03-04 11:47:09 -05:00
sign_in ( Fabricate ( :user , trust_level : 2 ) )
2020-03-04 11:10:23 -05:00
2020-06-09 11:19:32 -04:00
Fabricate ( :invite , email : " billybob@example.com " , invited_by : inviter )
redeemed_invite = Fabricate ( :invite , email : " jimtom@example.com " , invited_by : inviter )
Fabricate ( :invited_user , invite : redeemed_invite , user : invitee )
2020-03-04 11:47:09 -05:00
2020-06-09 11:19:32 -04:00
get " /u/ #{ inviter . username } /invited.json " , params : { filter : " pending " , search : " billybob " }
2020-03-04 11:47:09 -05:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
invites = response . parsed_body [ " invites " ]
2020-03-04 11:47:09 -05:00
expect ( invites . size ) . to eq ( 0 )
2020-06-09 11:19:32 -04:00
get " /u/ #{ inviter . username } /invited.json " ,
params : {
filter : " redeemed " ,
search : invitee . username ,
}
2020-03-04 11:47:09 -05:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
invites = response . parsed_body [ " invites " ]
2020-06-09 11:19:32 -04:00
expect ( invites . size ) . to eq ( 1 )
expect ( invites [ 0 ] [ " user " ] ) . to be_present
2020-03-04 11:47:09 -05:00
end
it " filters by email if staff " do
inviter = Fabricate ( :user , trust_level : 2 )
2021-12-16 14:36:49 -05:00
sign_in ( moderator )
2020-03-04 11:47:09 -05:00
2020-06-09 11:19:32 -04:00
invite_1 = Fabricate ( :invite , email : " billybob@example.com " , invited_by : inviter )
invitee_1 = Fabricate ( :user )
Fabricate ( :invited_user , invite : invite_1 , user : invitee_1 )
invite_2 = Fabricate ( :invite , email : " jimtom@example.com " , invited_by : inviter )
invitee_2 = Fabricate ( :user )
Fabricate ( :invited_user , invite : invite_2 , user : invitee_2 )
2018-05-24 22:04:25 -04:00
get " /u/ #{ inviter . username } /invited.json " , params : { search : " billybob " }
2020-03-04 11:10:23 -05:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
2020-05-07 11:04:12 -04:00
invites = response . parsed_body [ " invites " ]
2018-05-24 22:04:25 -04:00
expect ( invites . size ) . to eq ( 1 )
2020-06-09 11:19:32 -04:00
expect ( invites [ 0 ] [ " user " ] ) . to include ( " id " = > invitee_1 . id )
2018-05-24 22:04:25 -04:00
end
context " with guest " do
context " with pending invites " do
it " does not return invites " do
Fabricate ( :invite , invited_by : inviter )
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } /invited/pending.json "
2020-03-04 11:10:23 -05:00
expect ( response . status ) . to eq ( 403 )
2018-05-24 22:04:25 -04:00
end
end
context " with redeemed invites " do
2020-06-09 11:19:32 -04:00
it " returns invited_users " do
2020-03-04 11:10:23 -05:00
inviter = Fabricate ( :user , trust_level : 2 )
sign_in ( inviter )
2020-06-09 11:19:32 -04:00
invite = Fabricate ( :invite , invited_by : inviter )
2022-03-03 00:57:52 -05:00
_invited_user = Fabricate ( :invited_user , invite : invite , user : invitee )
2018-05-24 22:04:25 -04:00
get " /u/ #{ inviter . username } /invited.json "
2020-03-04 11:10:23 -05:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
2020-05-07 11:04:12 -04:00
invites = response . parsed_body [ " invites " ]
2018-05-24 22:04:25 -04:00
expect ( invites . size ) . to eq ( 1 )
2020-06-09 11:19:32 -04:00
expect ( invites [ 0 ] ) . to include ( " id " = > invite . id )
2018-05-24 22:04:25 -04:00
end
end
end
context " with authenticated user " do
context " with pending invites " do
context " with permission to see pending invites " do
it " returns invites " do
2020-03-04 11:10:23 -05:00
inviter = Fabricate ( :user , trust_level : 2 )
2018-05-24 22:04:25 -04:00
invite = Fabricate ( :invite , invited_by : inviter )
sign_in ( inviter )
get " /u/ #{ inviter . username } /invited/pending.json "
2020-03-04 11:10:23 -05:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
2020-05-07 11:04:12 -04:00
invites = response . parsed_body [ " invites " ]
2018-05-24 22:04:25 -04:00
expect ( invites . size ) . to eq ( 1 )
expect ( invites . first ) . to include ( " email " = > invite . email )
2021-10-14 10:57:01 -04:00
expect ( response . parsed_body [ " can_see_invite_details " ] ) . to eq ( true )
2018-05-24 22:04:25 -04:00
end
end
context " without permission to see pending invites " do
it " does not return invites " do
user = sign_in ( Fabricate ( :user ) )
Fabricate ( :invite , invited_by : inviter )
stub_guardian ( user ) do | guardian |
guardian . stubs ( :can_see_invite_details? ) . with ( inviter ) . returns ( false )
end
get " /u/ #{ inviter . username } /invited/pending.json "
2020-10-03 03:35:26 -04:00
expect ( response . status ) . to eq ( 422 )
2018-05-24 22:04:25 -04:00
end
end
2020-06-09 11:19:32 -04:00
context " with permission to see invite links " do
2021-10-14 10:57:01 -04:00
it " returns own invites " do
inviter = sign_in ( Fabricate ( :user , trust_level : 2 ) )
invite =
Fabricate (
:invite ,
invited_by : inviter ,
email : nil ,
max_redemptions_allowed : 5 ,
expires_at : 1 . month . from_now ,
emailed_status : Invite . emailed_status_types [ :not_required ] ,
)
get " /u/ #{ inviter . username } /invited/pending.json "
expect ( response . status ) . to eq ( 200 )
invites = response . parsed_body [ " invites " ]
expect ( invites . size ) . to eq ( 1 )
expect ( invites . first ) . to include ( " id " = > invite . id )
expect ( response . parsed_body [ " can_see_invite_details " ] ) . to eq ( true )
end
it " allows admin to see invites " do
inviter = Fabricate ( :user , trust_level : 2 )
2022-03-03 00:57:52 -05:00
_admin = sign_in ( Fabricate ( :admin ) )
2020-06-09 11:19:32 -04:00
invite =
Fabricate (
:invite ,
invited_by : inviter ,
email : nil ,
max_redemptions_allowed : 5 ,
expires_at : 1 . month . from_now ,
emailed_status : Invite . emailed_status_types [ :not_required ] ,
)
2021-03-03 04:45:29 -05:00
get " /u/ #{ inviter . username } /invited/pending.json "
2020-06-09 11:19:32 -04:00
expect ( response . status ) . to eq ( 200 )
invites = response . parsed_body [ " invites " ]
expect ( invites . size ) . to eq ( 1 )
expect ( invites . first ) . to include ( " id " = > invite . id )
2021-10-14 10:57:01 -04:00
expect ( response . parsed_body [ " can_see_invite_details " ] ) . to eq ( true )
2020-06-09 11:19:32 -04:00
end
end
context " without permission to see invite links " do
it " does not return invites " do
2022-03-03 00:57:52 -05:00
_user = Fabricate ( :user , trust_level : 2 )
2021-12-16 14:36:49 -05:00
inviter = admin
2020-06-09 11:19:32 -04:00
Fabricate (
:invite ,
invited_by : inviter ,
email : nil ,
max_redemptions_allowed : 5 ,
expires_at : 1 . month . from_now ,
emailed_status : Invite . emailed_status_types [ :not_required ] ,
)
2021-03-03 04:45:29 -05:00
get " /u/ #{ inviter . username } /invited/pending.json "
2020-06-09 11:19:32 -04:00
expect ( response . status ) . to eq ( 403 )
end
2018-05-24 22:04:25 -04:00
end
2021-03-02 02:13:04 -05:00
end
2020-10-03 03:35:26 -04:00
2021-03-03 04:45:29 -05:00
context " with redeemed invites " do
it " returns invites " do
2021-12-16 14:36:49 -05:00
sign_in ( moderator )
2021-03-03 04:45:29 -05:00
invite = Fabricate ( :invite , invited_by : inviter )
Fabricate ( :invited_user , invite : invite , user : invitee )
get " /u/ #{ inviter . username } /invited.json "
expect ( response . status ) . to eq ( 200 )
invites = response . parsed_body [ " invites " ]
expect ( invites . size ) . to eq ( 1 )
expect ( invites [ 0 ] ) . to include ( " id " = > invite . id )
end
end
2018-05-24 22:04:25 -04:00
end
end
describe " # update " do
context " with guest " do
it " raises an error " do
put " /u/guest.json "
expect ( response . status ) . to eq ( 403 )
end
end
2021-07-28 02:07:18 -04:00
it " does not allow name to be updated if auth auth_overrides_name is enabled " do
SiteSetting . auth_overrides_name = true
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2021-07-28 02:07:18 -04:00
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } " , params : { name : " test.test " }
2021-07-28 02:07:18 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . name ) . to_not eq ( " test.test " )
2021-07-28 02:07:18 -04:00
end
2018-05-24 22:04:25 -04:00
context " when username contains a period " do
before { sign_in ( user ) }
2019-04-28 23:58:52 -04:00
2019-05-06 23:12:20 -04:00
fab! ( :user ) { Fabricate ( :user , username : " test.test " , name : " Test User " ) }
2018-05-24 22:04:25 -04:00
it " should be able to update a user " do
2018-11-23 12:41:41 -05:00
put " /u/ #{ user . username } " , params : { name : " test.test " }
2018-05-24 22:04:25 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( user . reload . name ) . to eq ( " test.test " )
end
end
context " as a staff user " do
2022-07-27 12:14:14 -04:00
context " with uneditable field " do
2021-12-16 14:36:49 -05:00
fab! ( :user_field ) { Fabricate ( :user_field , editable : false ) }
2018-05-24 22:04:25 -04:00
it " allows staff to edit the field " do
2021-12-16 14:36:49 -05:00
sign_in ( admin )
2018-05-24 22:04:25 -04:00
put " /u/ #{ user . username } .json " ,
params : {
name : " Jim Tom " ,
title : " foobar " ,
user_fields : {
user_field . id . to_s = > " happy " ,
} ,
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
user . reload
expect ( user . user_fields [ user_field . id . to_s ] ) . to eq ( " happy " )
expect ( user . title ) . to eq ( " foobar " )
end
end
end
context " with authenticated user " do
context " with permission to update " do
2021-12-16 14:36:49 -05:00
fab! ( :upload ) { Fabricate ( :upload ) }
fab! ( :user ) { Fabricate ( :user ) }
before { sign_in ( user ) }
2018-05-24 22:04:25 -04:00
it " allows the update " do
2019-12-04 13:33:51 -05:00
SiteSetting . tagging_enabled = true
2018-05-24 22:04:25 -04:00
user2 = Fabricate ( :user )
user3 = Fabricate ( :user )
tags = [ Fabricate ( :tag ) , Fabricate ( :tag ) ]
2019-12-04 13:33:51 -05:00
tag_synonym = Fabricate ( :tag , target_tag : tags [ 1 ] )
2018-05-24 22:04:25 -04:00
put " /u/ #{ user . username } .json " ,
params : {
name : " Jim Tom " ,
muted_usernames : " #{ user2 . username } , #{ user3 . username } " ,
2019-12-04 13:33:51 -05:00
watched_tags : " #{ tags [ 0 ] . name } , #{ tag_synonym . name } " ,
2019-04-28 23:58:52 -04:00
card_background_upload_url : upload . url ,
profile_background_upload_url : upload . url ,
2018-05-24 22:04:25 -04:00
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2022-01-18 17:02:29 -05:00
expect ( response . parsed_body [ " user " ] [ " watched_tags " ] . count ) . to eq ( 2 )
2018-05-24 22:04:25 -04:00
user . reload
expect ( user . name ) . to eq " Jim Tom "
expect ( user . muted_users . pluck ( :username ) . sort ) . to eq [ user2 . username , user3 . username ] . sort
2019-04-28 23:58:52 -04:00
2018-05-24 22:04:25 -04:00
expect (
TagUser . where (
user : user ,
notification_level : TagUser . notification_levels [ :watching ] ,
) . pluck ( :tag_id ) ,
) . to contain_exactly ( tags [ 0 ] . id , tags [ 1 ] . id )
2018-08-08 00:46:34 -04:00
theme = Fabricate ( :theme , user_selectable : true )
2018-05-24 22:04:25 -04:00
put " /u/ #{ user . username } .json " ,
params : {
muted_usernames : " " ,
2018-07-12 00:18:21 -04:00
theme_ids : [ theme . id ] ,
2019-03-15 10:55:11 -04:00
email_level : UserOption . email_level_types [ :always ] ,
2018-05-24 22:04:25 -04:00
}
user . reload
expect ( user . muted_users . pluck ( :username ) . sort ) . to be_empty
2018-07-12 00:18:21 -04:00
expect ( user . user_option . theme_ids ) . to eq ( [ theme . id ] )
2019-03-15 10:55:11 -04:00
expect ( user . user_option . email_level ) . to eq ( UserOption . email_level_types [ :always ] )
2019-04-28 23:58:52 -04:00
expect ( user . profile_background_upload ) . to eq ( upload )
expect ( user . card_background_upload ) . to eq ( upload )
2018-05-24 22:04:25 -04:00
end
2022-01-18 17:02:29 -05:00
it " updates watched tags in everyone tag group " do
SiteSetting . tagging_enabled = true
tags = [ Fabricate ( :tag ) , Fabricate ( :tag ) ]
group =
Fabricate ( :group , name : " group " , mentionable_level : Group :: ALIAS_LEVELS [ :everyone ] )
tag_group = Fabricate ( :tag_group , tags : tags )
Fabricate ( :tag_group_permission , tag_group : tag_group , group : group )
tag_synonym = Fabricate ( :tag , target_tag : tags [ 1 ] )
put " /u/ #{ user . username } .json " ,
params : {
watched_tags : " #{ tags [ 0 ] . name } , #{ tag_synonym . name } " ,
}
expect ( response . status ) . to eq ( 200 )
expect ( response . parsed_body [ " user " ] [ " watched_tags " ] . count ) . to eq ( 2 )
end
2022-07-27 12:14:14 -04:00
context " when a locale is chosen that differs from I18n.locale " do
2020-01-08 12:01:46 -05:00
before { SiteSetting . allow_user_locale = true }
2018-05-24 22:04:25 -04:00
it " updates the user's locale " do
2020-01-08 12:01:46 -05:00
I18n . locale = :fr
2018-05-24 22:04:25 -04:00
put " /u/ #{ user . username } .json " , params : { locale : :fa_IR }
2020-01-08 12:01:46 -05:00
expect ( user . reload . locale ) . to eq ( " fa_IR " )
end
it " updates the title " do
2020-05-18 05:22:39 -04:00
BadgeGranter . enable_queue
2020-01-08 12:01:46 -05:00
user . update! ( locale : :fr )
user . change_trust_level! ( TrustLevel [ 4 ] )
BadgeGranter . process_queue!
leader_title = I18n . t ( " badges.leader.name " , locale : :fr )
put " /u/ #{ user . username } .json " , params : { title : leader_title }
expect ( user . reload . title ) . to eq ( leader_title )
2020-05-18 05:22:39 -04:00
ensure
BadgeGranter . disable_queue
BadgeGranter . clear_queue!
2018-05-24 22:04:25 -04:00
end
end
context " with user fields " do
2022-07-27 12:14:14 -04:00
context " with an editable field " do
2021-12-16 14:36:49 -05:00
fab! ( :user_field ) { Fabricate ( :user_field ) }
fab! ( :optional_field ) { Fabricate ( :user_field , required : false ) }
2018-05-24 22:04:25 -04:00
it " should update the user field " do
put " /u/ #{ user . username } .json " ,
params : {
name : " Jim Tom " ,
user_fields : {
user_field . id . to_s = > " happy " ,
} ,
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( user . user_fields [ user_field . id . to_s ] ) . to eq " happy "
end
it " cannot be updated to blank " do
put " /u/ #{ user . username } .json " ,
params : {
name : " Jim Tom " ,
user_fields : {
user_field . id . to_s = > " " ,
} ,
}
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 422 )
2018-05-24 22:04:25 -04:00
expect ( user . user_fields [ user_field . id . to_s ] ) . not_to eq ( " happy " )
end
it " trims excessively large fields " do
put " /u/ #{ user . username } .json " ,
params : {
name : " Jim Tom " ,
user_fields : {
user_field . id . to_s = > ( " x " * 3000 ) ,
} ,
}
expect ( user . user_fields [ user_field . id . to_s ] . size ) . to eq ( UserField . max_length )
end
it " should retain existing user fields " do
put " /u/ #{ user . username } .json " ,
params : {
name : " Jim Tom " ,
user_fields : {
user_field . id . to_s = > " happy " ,
optional_field . id . to_s = > " feet " ,
} ,
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( user . user_fields [ user_field . id . to_s ] ) . to eq ( " happy " )
expect ( user . user_fields [ optional_field . id . to_s ] ) . to eq ( " feet " )
put " /u/ #{ user . username } .json " ,
params : {
name : " Jim Tom " ,
user_fields : {
user_field . id . to_s = > " sad " ,
} ,
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
user . reload
expect ( user . user_fields [ user_field . id . to_s ] ) . to eq ( " sad " )
expect ( user . user_fields [ optional_field . id . to_s ] ) . to eq ( " feet " )
end
end
2021-01-20 11:31:52 -05:00
context " with user_notification_schedule attributes " do
it " updates the user's notification schedule " do
params = {
user_notification_schedule : {
enabled : true ,
day_0_start_time : 30 ,
day_0_end_time : 60 ,
day_1_start_time : 30 ,
day_1_end_time : 60 ,
day_2_start_time : 30 ,
day_2_end_time : 60 ,
day_3_start_time : 30 ,
day_3_end_time : 60 ,
day_4_start_time : 30 ,
day_4_end_time : 60 ,
day_5_start_time : 30 ,
day_5_end_time : 60 ,
day_6_start_time : 30 ,
day_6_end_time : 60 ,
} ,
}
put " /u/ #{ user . username } .json " , params : params
user . reload
expect ( user . user_notification_schedule . enabled ) . to eq ( true )
expect ( user . user_notification_schedule . day_0_start_time ) . to eq ( 30 )
expect ( user . user_notification_schedule . day_0_end_time ) . to eq ( 60 )
expect ( user . user_notification_schedule . day_6_start_time ) . to eq ( 30 )
expect ( user . user_notification_schedule . day_6_end_time ) . to eq ( 60 )
end
end
2022-07-27 12:14:14 -04:00
context " with uneditable field " do
2021-12-16 14:36:49 -05:00
fab! ( :user_field ) { Fabricate ( :user_field , editable : false ) }
2018-05-24 22:04:25 -04:00
it " does not update the user field " do
put " /u/ #{ user . username } .json " ,
params : {
name : " Jim Tom " ,
user_fields : {
user_field . id . to_s = > " happy " ,
} ,
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( user . user_fields [ user_field . id . to_s ] ) . to be_blank
end
end
2018-08-30 07:59:36 -04:00
2022-07-27 12:14:14 -04:00
context " with custom_field " do
2018-09-04 06:45:36 -04:00
before do
plugin = Plugin :: Instance . new
plugin . register_editable_user_custom_field :test2
2019-10-11 04:57:55 -04:00
plugin . register_editable_user_custom_field :test3 , staff_only : true
2018-09-04 06:45:36 -04:00
end
2020-05-15 09:04:38 -04:00
after { DiscoursePluginRegistry . reset! }
2018-09-04 06:45:36 -04:00
it " only updates allowed user fields " do
2019-10-11 04:57:55 -04:00
put " /u/ #{ user . username } .json " ,
params : {
custom_fields : {
test1 : :hello1 ,
test2 : :hello2 ,
test3 : :hello3 ,
} ,
}
2018-09-04 06:45:36 -04:00
expect ( response . status ) . to eq ( 200 )
expect ( user . custom_fields [ " test1 " ] ) . to be_blank
expect ( user . custom_fields [ " test2 " ] ) . to eq ( " hello2 " )
2019-10-11 04:57:55 -04:00
expect ( user . custom_fields [ " test3 " ] ) . to be_blank
2018-09-04 06:45:36 -04:00
end
2018-08-30 07:59:36 -04:00
2018-09-04 06:45:36 -04:00
it " works alongside a user field " do
user_field = Fabricate ( :user_field , editable : true )
2019-10-11 04:57:55 -04:00
put " /u/ #{ user . username } .json " ,
params : {
custom_fields : {
test1 : :hello1 ,
test2 : :hello2 ,
test3 : :hello3 ,
} ,
user_fields : {
user_field . id . to_s = > " happy " ,
} ,
}
2018-08-30 07:59:36 -04:00
expect ( response . status ) . to eq ( 200 )
2018-09-04 06:45:36 -04:00
expect ( user . custom_fields [ " test1 " ] ) . to be_blank
expect ( user . custom_fields [ " test2 " ] ) . to eq ( " hello2 " )
2019-10-11 04:57:55 -04:00
expect ( user . custom_fields [ " test3 " ] ) . to eq ( nil )
2018-09-04 06:45:36 -04:00
expect ( user . user_fields [ user_field . id . to_s ] ) . to eq ( " happy " )
2018-08-30 07:59:36 -04:00
end
2018-09-04 06:45:36 -04:00
2019-10-17 10:46:12 -04:00
it " works alongside a user field during creation " do
2021-12-16 14:36:49 -05:00
api_key = Fabricate ( :api_key , user : admin )
2019-10-17 10:46:12 -04:00
user_field = Fabricate ( :user_field , editable : true )
post " /u.json " ,
params : {
name : " Test User " ,
username : " testuser " ,
email : " user@mail.com " ,
password : " supersecure " ,
active : true ,
custom_fields : {
test2 : " custom field value " ,
} ,
user_fields : {
user_field . id . to_s = > " user field value " ,
2020-04-06 18:55:44 -04:00
} ,
2023-01-09 06:18:21 -05:00
} ,
2020-04-06 18:55:44 -04:00
headers : {
HTTP_API_KEY : api_key . key ,
2019-10-17 10:46:12 -04:00
}
expect ( response . status ) . to eq ( 200 )
u = User . find_by_email ( " user@mail.com " )
val = u . custom_fields [ " user_field_ #{ user_field . id } " ]
expect ( val ) . to eq ( " user field value " )
val = u . custom_fields [ " test2 " ]
expect ( val ) . to eq ( " custom field value " )
end
2018-09-04 06:45:36 -04:00
it " is secure when there are no registered editable fields " do
2020-05-15 09:04:38 -04:00
DiscoursePluginRegistry . reset!
2019-10-11 04:57:55 -04:00
put " /u/ #{ user . username } .json " ,
params : {
custom_fields : {
test1 : :hello1 ,
test2 : :hello2 ,
test3 : :hello3 ,
} ,
}
2018-09-04 06:45:36 -04:00
expect ( response . status ) . to eq ( 200 )
expect ( user . custom_fields [ " test1 " ] ) . to be_blank
expect ( user . custom_fields [ " test2 " ] ) . to be_blank
2019-10-11 04:57:55 -04:00
expect ( user . custom_fields [ " test3 " ] ) . to be_blank
2018-09-04 06:45:36 -04:00
put " /u/ #{ user . username } .json " , params : { custom_fields : %w[ arrayitem1 arrayitem2 ] }
expect ( response . status ) . to eq ( 200 )
end
2019-10-11 04:57:55 -04:00
it " allows staff to edit staff-editable fields " do
2021-12-16 14:36:49 -05:00
sign_in ( admin )
2019-10-11 04:57:55 -04:00
put " /u/ #{ user . username } .json " ,
params : {
custom_fields : {
test1 : :hello1 ,
test2 : :hello2 ,
test3 : :hello3 ,
} ,
}
expect ( response . status ) . to eq ( 200 )
expect ( user . custom_fields [ " test1 " ] ) . to be_blank
expect ( user . custom_fields [ " test2 " ] ) . to eq ( " hello2 " )
expect ( user . custom_fields [ " test3 " ] ) . to eq ( " hello3 " )
end
2018-08-30 07:59:36 -04:00
end
2018-05-24 22:04:25 -04:00
end
it " returns user JSON " do
put " /u/ #{ user . username } .json "
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-24 22:04:25 -04:00
expect ( json [ " user " ] [ " id " ] ) . to eq user . id
end
2022-06-30 02:54:20 -04:00
2022-12-07 20:44:29 -05:00
context " with sidebar " do
before { SiteSetting . navigation_menu = " sidebar " }
2022-06-30 02:54:20 -04:00
it " does not remove category or tag sidebar section links when params are not present " do
Fabricate ( :category_sidebar_section_link , user : user )
Fabricate ( :tag_sidebar_section_link , user : user )
expect do
put " /u/ #{ user . username } .json "
expect ( response . status ) . to eq ( 200 )
end . to_not change { user . sidebar_section_links . count }
end
it " should allow user to remove all category sidebar section links " do
Fabricate ( :category_sidebar_section_link , user : user )
expect do
put " /u/ #{ user . username } .json " , params : { sidebar_category_ids : nil }
expect ( response . status ) . to eq ( 200 )
end . to change { user . sidebar_section_links . count } . from ( 1 ) . to ( 0 )
end
it " should allow user to modify category sidebar section links " do
category = Fabricate ( :category )
restricted_category = Fabricate ( :category , read_restricted : true )
2022-07-13 20:56:25 -04:00
category_sidebar_section_link = Fabricate ( :category_sidebar_section_link , user : user )
2022-06-30 02:54:20 -04:00
put " /u/ #{ user . username } .json " ,
params : {
sidebar_category_ids : [ category . id , restricted_category . id ] ,
}
expect ( response . status ) . to eq ( 200 )
expect ( user . sidebar_section_links . count ) . to eq ( 1 )
2022-07-13 20:56:25 -04:00
expect ( SidebarSectionLink . exists? ( id : category_sidebar_section_link . id ) ) . to eq ( false )
2022-06-30 02:54:20 -04:00
sidebar_section_link = user . sidebar_section_links . first
expect ( sidebar_section_link . linkable ) . to eq ( category )
end
it " should allow user to remove all tag sidebar section links " do
SiteSetting . tagging_enabled = true
Fabricate ( :tag_sidebar_section_link , user : user )
expect do
put " /u/ #{ user . username } .json " , params : { sidebar_tag_names : nil }
expect ( response . status ) . to eq ( 200 )
end . to change { user . sidebar_section_links . count } . from ( 1 ) . to ( 0 )
end
it " should not allow user to add tag sidebar section links when tagging is disabled " do
SiteSetting . tagging_enabled = false
tag = Fabricate ( :tag )
put " /u/ #{ user . username } .json " , params : { sidebar_tag_names : [ tag . name ] }
expect ( response . status ) . to eq ( 200 )
expect ( user . reload . sidebar_section_links . count ) . to eq ( 0 )
end
it " should allow user to add tag sidebar section links " do
SiteSetting . tagging_enabled = true
tag = Fabricate ( :tag )
tag_sidebar_section_link = Fabricate ( :tag_sidebar_section_link , user : user )
put " /u/ #{ user . username } .json " ,
params : {
sidebar_tag_names : [ tag . name , " somerandomtag " ] ,
}
expect ( response . status ) . to eq ( 200 )
expect ( user . sidebar_section_links . count ) . to eq ( 1 )
expect ( SidebarSectionLink . exists? ( id : tag_sidebar_section_link . id ) ) . to eq ( false )
sidebar_section_link = user . sidebar_section_links . first
expect ( sidebar_section_link . linkable ) . to eq ( tag )
end
end
2018-05-24 22:04:25 -04:00
end
context " without permission to update " do
it " does not allow the update " do
user = Fabricate ( :user , name : " Billy Bob " )
sign_in ( Fabricate ( :user ) )
put " /u/ #{ user . username } .json " , params : { name : " Jim Tom " }
expect ( response ) . to be_forbidden
expect ( user . reload . name ) . not_to eq " Jim Tom "
end
end
end
2022-03-03 11:17:02 -05:00
context " with external_ids " do
fab! ( :api_key , refind : false ) { Fabricate ( :api_key , user : admin ) }
let ( :plugin_auth_provider ) do
authenticator_class =
Class . new ( Auth :: ManagedAuthenticator ) do
def name
" pluginauth "
end
def enabled?
true
2023-01-09 06:18:21 -05:00
end
2022-03-03 11:17:02 -05:00
end
provider = Auth :: AuthProvider . new
provider . authenticator = authenticator_class . new
provider
end
before do
DiscoursePluginRegistry . register_auth_provider ( plugin_auth_provider )
2022-11-18 09:37:21 -05:00
SiteSetting . discourse_connect_url = " http://localhost "
SiteSetting . enable_discourse_connect = true
2022-03-03 11:17:02 -05:00
end
after { DiscoursePluginRegistry . reset! }
it " can create UserAssociatedAccount records " do
params = { external_ids : { " pluginauth " = > " pluginauth_uid " } }
expect {
put " /u/ #{ user . username } .json " , params : params , headers : { HTTP_API_KEY : api_key . key }
} . to change { UserAssociatedAccount . count } . by ( 1 )
expect ( response . status ) . to eq ( 200 )
user_associated_account = UserAssociatedAccount . last
expect ( user . reload . user_associated_account_ids ) . to contain_exactly (
user_associated_account . id ,
)
expect ( user_associated_account . provider_name ) . to eq ( " pluginauth " )
expect ( user_associated_account . provider_uid ) . to eq ( " pluginauth_uid " )
expect ( user_associated_account . user_id ) . to eq ( user . id )
end
it " can destroy UserAssociatedAccount records " do
user . user_associated_accounts . create! (
provider_name : " pluginauth " ,
provider_uid : " pluginauth_uid " ,
)
params = { external_ids : { " pluginauth " = > nil } }
expect {
put " /u/ #{ user . username } .json " , params : params , headers : { HTTP_API_KEY : api_key . key }
} . to change { UserAssociatedAccount . count } . by ( - 1 )
expect ( response . status ) . to eq ( 200 )
expect ( user . reload . user_associated_account_ids ) . to be_blank
end
2022-11-18 09:37:21 -05:00
it " can create SingleSignOnRecord records " do
params = { external_ids : { discourse_connect : " discourse_connect_uid " } }
expect {
put " /u/ #{ user . username } .json " , params : params , headers : { HTTP_API_KEY : api_key . key }
} . to change { SingleSignOnRecord . count } . by ( 1 )
expect ( response . status ) . to eq ( 200 )
single_sign_on_record = SingleSignOnRecord . last
expect ( user . reload . single_sign_on_record ) . to eq ( single_sign_on_record )
expect ( single_sign_on_record . external_id ) . to eq ( " discourse_connect_uid " )
end
it " can update SingleSignOnRecord records " do
user = Fabricate ( :user )
SingleSignOnRecord . create! (
user_id : user . id ,
external_id : " discourse_connect_uid " ,
last_payload : " discourse_connect_uid " ,
)
params = { external_ids : { discourse_connect : " discourse_connect_uid_2 " } }
expect {
put " /u/ #{ user . username } .json " , params : params , headers : { HTTP_API_KEY : api_key . key }
} . not_to change { SingleSignOnRecord . count }
expect ( response . status ) . to eq ( 200 )
expect ( user . reload . single_sign_on_record . external_id ) . to eq ( " discourse_connect_uid_2 " )
end
it " can delete SingleSignOnRecord records " do
user = Fabricate ( :user )
SingleSignOnRecord . create! (
user_id : user . id ,
external_id : " discourse_connect_uid " ,
last_payload : " discourse_connect_uid " ,
)
params = { external_ids : { discourse_connect : nil } }
expect {
put " /u/ #{ user . username } .json " , params : params , headers : { HTTP_API_KEY : api_key . key }
} . to change { SingleSignOnRecord . count } . by ( - 1 )
expect ( response . status ) . to eq ( 200 )
expect ( user . reload . single_sign_on_record ) . to be_blank
end
it " can update SingleSignOnRecord and UserAssociatedAccount records in a single call " do
user = Fabricate ( :user )
user . user_associated_accounts . create! (
provider_name : " pluginauth " ,
provider_uid : " pluginauth_uid " ,
)
SingleSignOnRecord . create! (
user_id : user . id ,
external_id : " discourse_connect_uid " ,
last_payload : " discourse_connect_uid " ,
)
params = {
external_ids : {
discourse_connect : " discourse_connect_uid_2 " ,
pluginauth : " pluginauth_uid_2 " ,
} ,
}
expect {
put " /u/ #{ user . username } .json " , params : params , headers : { HTTP_API_KEY : api_key . key }
} . to change { SingleSignOnRecord . count + UserAssociatedAccount . count } . by ( 0 )
expect ( response . status ) . to eq ( 200 )
expect ( user . reload . single_sign_on_record . external_id ) . to eq ( " discourse_connect_uid_2 " )
user_associated_account = UserAssociatedAccount . last
expect ( user . reload . user_associated_account_ids ) . to contain_exactly (
user_associated_account . id ,
)
expect ( user_associated_account . provider_name ) . to eq ( " pluginauth " )
expect ( user_associated_account . provider_uid ) . to eq ( " pluginauth_uid_2 " )
expect ( user_associated_account . user_id ) . to eq ( user . id )
end
2022-03-03 11:17:02 -05:00
it " returns error if external ID provider does not exist " do
params = { external_ids : { " pluginauth2 " = > " pluginauth_uid " } }
put " /u/ #{ user . username } .json " , params : params , headers : { HTTP_API_KEY : api_key . key }
expect ( response . status ) . to eq ( 400 )
end
end
2022-10-12 15:35:25 -04:00
context " with user status " do
context " as a regular user " do
before do
SiteSetting . enable_user_status = true
sign_in ( user )
end
it " sets user status " do
status = { emoji : " tooth " , description : " off to dentist " }
put " /u/ #{ user . username } .json " , params : { status : status }
expect ( response . status ) . to eq ( 200 )
user . reload
expect ( user . user_status ) . not_to be_nil
expect ( user . user_status . emoji ) . to eq ( status [ :emoji ] )
expect ( user . user_status . description ) . to eq ( status [ :description ] )
end
it " updates user status " do
user . set_status! ( " off to dentist " , " tooth " )
user . reload
new_status = { emoji : " surfing_man " , description : " surfing " }
put " /u/ #{ user . username } .json " , params : { status : new_status }
expect ( response . status ) . to eq ( 200 )
user . reload
expect ( user . user_status ) . not_to be_nil
expect ( user . user_status . emoji ) . to eq ( new_status [ :emoji ] )
expect ( user . user_status . description ) . to eq ( new_status [ :description ] )
end
it " clears user status " do
user . set_status! ( " off to dentist " , " tooth " )
user . reload
put " /u/ #{ user . username } .json " , params : { status : nil }
expect ( response . status ) . to eq ( 200 )
user . reload
expect ( user . user_status ) . to be_nil
end
it " can't set status of another user " do
put " /u/ #{ user1 . username } .json " ,
params : {
status : {
emoji : " tooth " ,
description : " off to dentist " ,
} ,
}
expect ( response . status ) . to eq ( 403 )
user1 . reload
expect ( user1 . user_status ) . to be_nil
end
it " can't update status of another user " do
old_status = { emoji : " tooth " , description : " off to dentist " }
user1 . set_status! ( old_status [ :description ] , old_status [ :emoji ] )
user1 . reload
new_status = { emoji : " surfing_man " , description : " surfing " }
put " /u/ #{ user1 . username } .json " , params : { status : new_status }
expect ( response . status ) . to eq ( 403 )
user1 . reload
expect ( user1 . user_status ) . not_to be_nil
expect ( user1 . user_status . emoji ) . to eq ( old_status [ :emoji ] )
expect ( user1 . user_status . description ) . to eq ( old_status [ :description ] )
end
it " can't clear status of another user " do
user1 . set_status! ( " off to dentist " , " tooth " )
user1 . reload
put " /u/ #{ user1 . username } .json " , params : { status : nil }
expect ( response . status ) . to eq ( 403 )
user1 . reload
expect ( user1 . user_status ) . not_to be_nil
end
2022-11-16 12:42:56 -05:00
it " doesn't clear user status if it wasn't sent in the payload " do
2023-01-30 03:49:08 -05:00
new_status = { emoji : " tooth " , description : " off to dentist " }
2022-11-16 12:42:56 -05:00
user . set_status! ( new_status [ :description ] , new_status [ :emoji ] )
user . reload
put " /u/ #{ user . username } .json " , params : { bio_raw : " new bio " }
expect ( response . status ) . to eq ( 200 )
user . reload
expect ( user . user_status ) . not_to be_nil
expect ( user . user_status . emoji ) . to eq ( new_status [ :emoji ] )
expect ( user . user_status . description ) . to eq ( new_status [ :description ] )
end
2022-10-12 15:35:25 -04:00
context " when user status is disabled " do
before { SiteSetting . enable_user_status = false }
it " doesn't set user status " do
put " /u/ #{ user . username } .json " ,
params : {
status : {
emoji : " tooth " ,
description : " off to dentist " ,
} ,
}
expect ( response . status ) . to eq ( 200 )
user . reload
expect ( user . user_status ) . to be_nil
end
it " doesn't update user status " do
old_status = { emoji : " tooth " , description : " off to dentist " }
user . set_status! ( old_status [ :description ] , old_status [ :emoji ] )
user . reload
new_status = { emoji : " surfing_man " , description : " surfing " }
put " /u/ #{ user . username } .json " , params : { status : new_status }
expect ( response . status ) . to eq ( 200 )
user . reload
expect ( user . user_status ) . not_to be_nil
expect ( user . user_status . emoji ) . to eq ( old_status [ :emoji ] )
expect ( user . user_status . description ) . to eq ( old_status [ :description ] )
end
it " doesn't clear user status " do
user . set_status! ( " off to dentist " , " tooth " )
user . reload
put " /u/ #{ user . username } .json " , params : { status : nil }
expect ( response . status ) . to eq ( 200 )
user . reload
expect ( user . user_status ) . not_to be_nil
end
end
end
context " as a staff user " do
before do
SiteSetting . enable_user_status = true
sign_in ( moderator )
end
it " sets another user's status " do
status = { emoji : " tooth " , description : " off to dentist " }
put " /u/ #{ user . username } .json " , params : { status : status }
expect ( response . status ) . to eq ( 200 )
user . reload
expect ( user . user_status ) . not_to be_nil
expect ( user . user_status . emoji ) . to eq ( status [ :emoji ] )
expect ( user . user_status . description ) . to eq ( status [ :description ] )
end
it " updates another user's status " do
user . set_status! ( " off to dentist " , " tooth " )
user . reload
new_status = { emoji : " surfing_man " , description : " surfing " }
put " /u/ #{ user . username } .json " , params : { status : new_status }
expect ( response . status ) . to eq ( 200 )
user . reload
expect ( user . user_status ) . not_to be_nil
expect ( user . user_status . emoji ) . to eq ( new_status [ :emoji ] )
expect ( user . user_status . description ) . to eq ( new_status [ :description ] )
end
it " clears another user's status " do
user . set_status! ( " off to dentist " , " tooth " )
user . reload
put " /u/ #{ user . username } .json " , params : { status : nil }
expect ( response . status ) . to eq ( 200 )
user . reload
expect ( user . user_status ) . to be_nil
end
end
end
2023-05-25 20:26:38 -04:00
context " when a plugin introduces a users_controller_update_user_params modifier " do
before { sign_in ( user ) }
after { DiscoursePluginRegistry . clear_modifiers! }
it " allows the plugin to modify the user params " do
block_called = false
plugin = Plugin :: Instance . new
plugin . register_modifier (
:users_controller_update_user_params ,
) do | result , current_user , params |
block_called = true
expect ( current_user . id ) . to eq ( user . id )
result [ :location ] = params [ :plugin_location_alias ]
result
end
put " /u/ #{ user . username } .json " , params : { location : " abc " , plugin_location_alias : " xyz " }
expect ( response . status ) . to eq ( 200 )
expect ( user . reload . user_profile . location ) . to eq ( " xyz " )
expect ( block_called ) . to eq ( true )
end
end
2018-05-24 22:04:25 -04:00
end
describe " # badge_title " do
2019-05-06 23:12:20 -04:00
fab! ( :badge ) { Fabricate ( :badge ) }
2021-12-16 14:36:49 -05:00
let ( :user_badge ) { BadgeGranter . grant ( badge , user1 ) }
2018-05-24 22:04:25 -04:00
it " sets the user's title to the badge name if it is titleable " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2018-05-24 22:04:25 -04:00
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/badge_title.json " ,
params : {
user_badge_id : user_badge . id ,
}
2018-05-24 22:04:25 -04:00
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . title ) . not_to eq ( badge . display_name )
2019-04-29 03:32:25 -04:00
badge . update allow_title : true
2018-05-24 22:04:25 -04:00
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/badge_title.json " ,
params : {
user_badge_id : user_badge . id ,
}
2018-05-24 22:04:25 -04:00
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . title ) . to eq ( badge . display_name )
expect ( user1 . user_profile . granted_title_badge_id ) . to eq ( badge . id )
2018-05-24 22:04:25 -04:00
2019-11-08 00:34:24 -05:00
badge . update allow_title : false
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/badge_title.json " ,
params : {
user_badge_id : user_badge . id ,
}
2019-11-08 00:34:24 -05:00
2021-12-16 14:36:49 -05:00
user1 . reload
user1 . user_profile . reload
expect ( user1 . title ) . to eq ( " " )
expect ( user1 . user_profile . granted_title_badge_id ) . to eq ( nil )
2018-05-24 22:04:25 -04:00
end
2019-12-23 16:03:51 -05:00
it " is not raising an erroring when user revokes title " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2019-12-23 16:03:51 -05:00
badge . update allow_title : true
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/badge_title.json " ,
params : {
user_badge_id : user_badge . id ,
}
put " /u/ #{ user1 . username } /preferences/badge_title.json " , params : { user_badge_id : 0 }
2019-12-23 16:03:51 -05:00
expect ( response . status ) . to eq ( 200 )
end
2020-01-08 12:01:46 -05:00
context " with overridden name " do
2019-05-06 23:12:20 -04:00
fab! ( :badge ) { Fabricate ( :badge , name : " Demogorgon " , allow_title : true ) }
2021-12-16 14:36:49 -05:00
let ( :user_badge ) { BadgeGranter . grant ( badge , user1 ) }
2018-05-24 22:04:25 -04:00
before { TranslationOverride . upsert! ( " en " , " badges.demogorgon.name " , " Boss " ) }
after { TranslationOverride . revert! ( " en " , [ " badges.demogorgon.name " ] ) }
it " uses the badge display name as user title " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2018-05-24 22:04:25 -04:00
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/badge_title.json " ,
params : {
user_badge_id : user_badge . id ,
}
expect ( user1 . reload . title ) . to eq ( badge . display_name )
2018-05-24 22:04:25 -04:00
end
end
end
describe " # send_activation_email " do
before do
UsersController . any_instance . stubs ( :honeypot_value ) . returns ( nil )
UsersController . any_instance . stubs ( :challenge_value ) . returns ( nil )
end
let ( :post_user ) do
post " /u.json " ,
params : {
username : " osamatest " ,
password : " strongpassword " ,
email : " dsdsds@sasa.com " ,
}
2018-05-31 03:53:49 -04:00
User . find_by ( username : " osamatest " )
2018-05-24 22:04:25 -04:00
end
context " for an existing user " do
context " for an activated account with email confirmed " do
it " fails " do
user = post_user
2021-11-25 02:34:39 -05:00
email_token = Fabricate ( :email_token , user : user ) . token
2018-05-24 22:04:25 -04:00
EmailToken . confirm ( email_token )
post " /u/action/send_activation_email.json " , params : { username : user . username }
expect ( response . status ) . to eq ( 409 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " errors " ] ) . to include ( I18n . t ( " activation.activated " ) )
2018-05-24 22:04:25 -04:00
expect ( session [ SessionController :: ACTIVATE_USER_KEY ] ) . to eq ( nil )
end
end
context " for an activated account with unconfirmed email " do
it " should send an email " do
user = post_user
2020-07-24 05:16:52 -04:00
user . update! ( active : true )
2021-11-25 02:34:39 -05:00
Fabricate ( :email_token , user : user )
2018-05-24 22:04:25 -04:00
2020-07-24 05:16:52 -04:00
expect_enqueued_with (
job : :critical_user_email ,
args : {
type : :signup ,
to_address : user . email ,
} ,
) { post " /u/action/send_activation_email.json " , params : { username : user . username } }
2018-05-24 22:04:25 -04:00
expect ( response . status ) . to eq ( 200 )
expect ( session [ SessionController :: ACTIVATE_USER_KEY ] ) . to eq ( nil )
end
end
2022-07-27 12:14:14 -04:00
context " when approval is enabled " do
2018-05-24 22:04:25 -04:00
before { SiteSetting . must_approve_users = true }
it " should raise an error " do
user = post_user
user . update ( active : true )
user . save!
2021-12-16 14:36:49 -05:00
Fabricate ( :email_token , user : user1 )
2018-05-24 22:04:25 -04:00
post " /u/action/send_activation_email.json " , params : { username : user . username }
expect ( response . status ) . to eq ( 403 )
end
end
describe " when user does not have a valid session " do
it " should not be valid " do
post " /u/action/send_activation_email.json " , params : { username : user . username }
expect ( response . status ) . to eq ( 403 )
end
it " should allow staff regardless " do
2021-12-16 14:36:49 -05:00
sign_in ( admin )
2018-05-24 22:04:25 -04:00
user = Fabricate ( :user , active : false )
post " /u/action/send_activation_email.json " , params : { username : user . username }
expect ( response . status ) . to eq ( 200 )
end
end
context " with a valid email_token " do
it " should send the activation email " do
user = post_user
2020-07-24 05:16:52 -04:00
expect_enqueued_with ( job : :critical_user_email , args : { type : :signup } ) do
post " /u/action/send_activation_email.json " , params : { username : user . username }
end
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
expect ( session [ SessionController :: ACTIVATE_USER_KEY ] ) . to eq ( nil )
end
end
context " without an existing email_token " do
let ( :user ) { post_user }
before do
user . email_tokens . each { | t | t . destroy }
user . reload
end
it " should generate a new token " do
expect {
post " /u/action/send_activation_email.json " , params : { username : user . username }
} . to change { user . reload . email_tokens . count } . by ( 1 )
end
it " should send an email " do
2018-05-31 03:53:49 -04:00
expect do
post " /u/action/send_activation_email.json " , params : { username : user . username }
end . to change { Jobs :: CriticalUserEmail . jobs . size } . by ( 1 )
2018-05-27 23:20:47 -04:00
2018-05-24 22:04:25 -04:00
expect ( session [ SessionController :: ACTIVATE_USER_KEY ] ) . to eq ( nil )
end
end
end
context " when username does not exist " do
it " should not send an email " do
post " /u/action/send_activation_email.json " , params : { username : " nopenopenopenope " }
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 404 )
expect ( Jobs :: CriticalUserEmail . jobs . size ) . to eq ( 0 )
2018-05-24 22:04:25 -04:00
end
end
end
describe " # pick_avatar " do
it " raises an error when not logged in " do
put " /u/asdf/preferences/avatar/pick.json " , params : { avatar_id : 1 , type : " custom " }
expect ( response . status ) . to eq ( 403 )
end
context " while logged in " do
2021-12-16 14:36:49 -05:00
before { sign_in ( user1 ) }
2018-05-24 22:04:25 -04:00
2021-12-16 14:36:49 -05:00
fab! ( :upload ) { Fabricate ( :upload , user : user1 ) }
2018-05-24 22:04:25 -04:00
it " raises an error when you don't have permission to toggle the avatar " do
put " /u/ #{ another_user . username } /preferences/avatar/pick.json " ,
params : {
upload_id : upload . id ,
type : " custom " ,
}
expect ( response ) . to be_forbidden
end
2021-02-08 05:04:33 -05:00
it " raises an error when discourse_connect_overrides_avatar is disabled " do
SiteSetting . discourse_connect_overrides_avatar = true
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/pick.json " ,
params : {
2018-05-24 22:04:25 -04:00
upload_id : upload . id ,
type : " custom " ,
}
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 422 )
2018-05-24 22:04:25 -04:00
end
it " raises an error when selecting the custom/uploaded avatar and allow_uploaded_avatars is disabled " do
2021-08-24 03:46:28 -04:00
SiteSetting . allow_uploaded_avatars = " disabled "
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/pick.json " ,
params : {
2018-05-24 22:04:25 -04:00
upload_id : upload . id ,
type : " custom " ,
}
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 422 )
2018-05-24 22:04:25 -04:00
end
2021-08-24 03:46:28 -04:00
it " raises an error when selecting the custom/uploaded avatar and allow_uploaded_avatars is admin " do
SiteSetting . allow_uploaded_avatars = " admin "
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/pick.json " ,
params : {
2021-08-24 03:46:28 -04:00
upload_id : upload . id ,
type : " custom " ,
}
expect ( response . status ) . to eq ( 422 )
2021-12-16 14:36:49 -05:00
user1 . update! ( admin : true )
put " /u/ #{ user1 . username } /preferences/avatar/pick.json " ,
params : {
2021-08-24 03:46:28 -04:00
upload_id : upload . id ,
type : " custom " ,
}
expect ( response . status ) . to eq ( 200 )
end
it " raises an error when selecting the custom/uploaded avatar and allow_uploaded_avatars is staff " do
SiteSetting . allow_uploaded_avatars = " staff "
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/pick.json " ,
params : {
2021-08-24 03:46:28 -04:00
upload_id : upload . id ,
type : " custom " ,
}
expect ( response . status ) . to eq ( 422 )
2021-12-16 14:36:49 -05:00
user1 . update! ( moderator : true )
put " /u/ #{ user1 . username } /preferences/avatar/pick.json " ,
params : {
2021-08-24 03:46:28 -04:00
upload_id : upload . id ,
type : " custom " ,
}
expect ( response . status ) . to eq ( 200 )
end
it " raises an error when selecting the custom/uploaded avatar and allow_uploaded_avatars is a trust level " do
SiteSetting . allow_uploaded_avatars = " 3 "
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/pick.json " ,
params : {
2021-08-24 03:46:28 -04:00
upload_id : upload . id ,
type : " custom " ,
}
expect ( response . status ) . to eq ( 422 )
2021-12-16 14:36:49 -05:00
user1 . update! ( trust_level : 3 )
put " /u/ #{ user1 . username } /preferences/avatar/pick.json " ,
params : {
2021-08-24 03:46:28 -04:00
upload_id : upload . id ,
type : " custom " ,
}
expect ( response . status ) . to eq ( 200 )
end
2021-01-05 08:29:10 -05:00
it " ignores the upload if picking a system avatar " do
2021-08-24 03:46:28 -04:00
SiteSetting . allow_uploaded_avatars = " disabled "
2021-01-05 08:29:10 -05:00
another_upload = Fabricate ( :upload )
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/pick.json " ,
params : {
2021-01-05 08:29:10 -05:00
upload_id : another_upload . id ,
type : " system " ,
}
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . uploaded_avatar_id ) . to eq ( nil )
2021-01-05 08:29:10 -05:00
end
it " raises an error if the type is invalid " do
2021-08-24 03:46:28 -04:00
SiteSetting . allow_uploaded_avatars = " disabled "
2021-01-05 08:29:10 -05:00
another_upload = Fabricate ( :upload )
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/pick.json " ,
params : {
2021-01-05 08:29:10 -05:00
upload_id : another_upload . id ,
type : " x " ,
}
expect ( response . status ) . to eq ( 422 )
end
2018-05-24 22:04:25 -04:00
it " can successfully pick the system avatar " do
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/pick.json "
2018-05-24 22:04:25 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . uploaded_avatar_id ) . to eq ( nil )
2018-05-24 22:04:25 -04:00
end
2021-04-27 16:28:15 -04:00
it " disables the use_site_small_logo_as_system_avatar setting when picking an avatar for the system user " do
system_user = Discourse . system_user
SiteSetting . use_site_small_logo_as_system_avatar = true
another_upload = Fabricate ( :upload , user : system_user )
sign_in ( system_user )
put " /u/ #{ system_user . username } /preferences/avatar/pick.json " ,
params : {
upload_id : another_upload . id ,
type : " uploaded " ,
}
expect ( response . status ) . to eq ( 200 )
expect ( SiteSetting . use_site_small_logo_as_system_avatar ) . to eq ( false )
end
2018-05-24 22:04:25 -04:00
it " can successfully pick a gravatar " do
2021-12-16 14:36:49 -05:00
user1 . user_avatar . update_columns ( gravatar_upload_id : upload . id )
2018-09-20 01:33:10 -04:00
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/pick.json " ,
params : {
2018-05-24 22:04:25 -04:00
upload_id : upload . id ,
type : " gravatar " ,
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . uploaded_avatar_id ) . to eq ( upload . id )
expect ( user1 . user_avatar . reload . gravatar_upload_id ) . to eq ( upload . id )
2018-05-24 22:04:25 -04:00
end
2018-09-20 01:33:10 -04:00
it " can not pick uploads that were not created by user " do
upload2 = Fabricate ( :upload )
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/pick.json " ,
params : {
2018-09-20 01:33:10 -04:00
upload_id : upload2 . id ,
type : " custom " ,
}
expect ( response . status ) . to eq ( 403 )
end
2018-05-24 22:04:25 -04:00
it " can successfully pick a custom avatar " do
2019-05-27 12:12:26 -04:00
events =
DiscourseEvent . track_events do
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/pick.json " ,
params : {
2019-05-27 12:12:26 -04:00
upload_id : upload . id ,
type : " custom " ,
}
end
2018-05-24 22:04:25 -04:00
2019-05-27 12:12:26 -04:00
expect ( events . map { | event | event [ :event_name ] } ) . to include ( :user_updated )
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . uploaded_avatar_id ) . to eq ( upload . id )
expect ( user1 . user_avatar . reload . custom_upload_id ) . to eq ( upload . id )
2018-05-24 22:04:25 -04:00
end
end
end
2018-07-18 06:57:43 -04:00
describe " # select_avatar " do
it " raises an error when not logged in " do
put " /u/asdf/preferences/avatar/select.json " , params : { url : " https://meta.discourse.org " }
expect ( response . status ) . to eq ( 403 )
end
context " while logged in " do
2021-12-16 14:36:49 -05:00
before { sign_in ( user1 ) }
2021-12-07 13:45:58 -05:00
2019-05-06 23:12:20 -04:00
fab! ( :avatar1 ) { Fabricate ( :upload ) }
fab! ( :avatar2 ) { Fabricate ( :upload ) }
2018-07-18 06:57:43 -04:00
let ( :url ) { " https://www.discourse.org " }
it " raises an error when url is blank " do
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/select.json " , params : { url : " " }
2018-07-18 06:57:43 -04:00
expect ( response . status ) . to eq ( 422 )
end
it " raises an error when selectable avatars is disabled " do
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/select.json " , params : { url : url }
2018-07-18 06:57:43 -04:00
expect ( response . status ) . to eq ( 422 )
end
2022-07-27 12:14:14 -04:00
context " when selectable avatars is enabled " do
2020-06-22 09:58:26 -04:00
before do
2020-10-13 09:17:06 -04:00
SiteSetting . selectable_avatars = [ avatar1 , avatar2 ]
2022-02-24 15:57:39 -05:00
SiteSetting . selectable_avatars_mode = " no_one "
2020-06-22 09:58:26 -04:00
end
2018-07-18 06:57:43 -04:00
it " raises an error when selectable avatars is empty " do
2020-06-22 09:58:26 -04:00
SiteSetting . selectable_avatars = " "
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/select.json " , params : { url : url }
2018-07-18 06:57:43 -04:00
expect ( response . status ) . to eq ( 422 )
end
2022-07-27 12:14:14 -04:00
context " when selectable avatars is properly setup " do
2018-07-18 06:57:43 -04:00
it " raises an error when url is not in selectable avatars list " do
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/select.json " , params : { url : url }
2018-07-18 06:57:43 -04:00
expect ( response . status ) . to eq ( 422 )
end
it " can successfully select an avatar " do
2019-05-27 12:12:26 -04:00
events =
DiscourseEvent . track_events do
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/select.json " ,
params : {
url : avatar1 . url ,
}
2019-05-27 12:12:26 -04:00
end
2018-07-18 06:57:43 -04:00
2019-05-27 12:12:26 -04:00
expect ( events . map { | event | event [ :event_name ] } ) . to include ( :user_updated )
2018-07-18 06:57:43 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . uploaded_avatar_id ) . to eq ( avatar1 . id )
expect ( user1 . user_avatar . reload . custom_upload_id ) . to eq ( avatar1 . id )
2018-07-18 06:57:43 -04:00
end
2020-08-03 10:15:41 -04:00
2021-05-20 21:43:47 -04:00
it " can successfully select an avatar using a cooked URL " do
2020-08-03 10:15:41 -04:00
events =
DiscourseEvent . track_events do
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/avatar/select.json " ,
params : {
url : UrlHelper . cook_url ( avatar1 . url ) ,
}
2020-08-03 10:15:41 -04:00
end
expect ( events . map { | event | event [ :event_name ] } ) . to include ( :user_updated )
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . uploaded_avatar_id ) . to eq ( avatar1 . id )
expect ( user1 . user_avatar . reload . custom_upload_id ) . to eq ( avatar1 . id )
2020-08-03 10:15:41 -04:00
end
2021-04-27 16:28:15 -04:00
it " disables the use_site_small_logo_as_system_avatar setting when picking an avatar for the system user " do
system_user = Discourse . system_user
SiteSetting . use_site_small_logo_as_system_avatar = true
sign_in ( system_user )
put " /u/ #{ system_user . username } /preferences/avatar/select.json " ,
params : {
url : UrlHelper . cook_url ( avatar1 . url ) ,
}
expect ( response . status ) . to eq ( 200 )
expect ( SiteSetting . use_site_small_logo_as_system_avatar ) . to eq ( false )
end
2018-07-18 06:57:43 -04:00
end
end
end
end
2018-05-24 22:04:25 -04:00
describe " # destroy_user_image " do
it " raises an error when not logged in " do
delete " /u/asdf/preferences/user_image.json " , params : { type : " profile_background " }
expect ( response . status ) . to eq ( 403 )
end
context " while logged in " do
2021-12-16 14:36:49 -05:00
before { sign_in ( user1 ) }
2018-05-24 22:04:25 -04:00
it 'raises an error when you don\'t have permission to clear the profile background' do
delete " /u/ #{ another_user . username } /preferences/user_image.json " ,
params : {
type : " profile_background " ,
}
expect ( response ) . to be_forbidden
end
it " requires the `type` param " do
2021-12-16 14:36:49 -05:00
delete " /u/ #{ user1 . username } /preferences/user_image.json "
2018-05-24 22:04:25 -04:00
expect ( response . status ) . to eq ( 400 )
end
it " only allows certain `types` " do
2021-12-16 14:36:49 -05:00
delete " /u/ #{ user1 . username } /preferences/user_image.json " , params : { type : " wat " }
2018-05-24 22:04:25 -04:00
expect ( response . status ) . to eq ( 400 )
end
it " can clear the profile background " do
2021-12-16 14:36:49 -05:00
delete " /u/ #{ user1 . username } /preferences/user_image.json " ,
params : {
type : " profile_background " ,
}
2018-05-24 22:04:25 -04:00
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . profile_background_upload ) . to eq ( nil )
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
end
end
end
describe " # destroy " do
it " raises an error when not logged in " do
delete " /u/nobody.json "
expect ( response . status ) . to eq ( 403 )
end
context " while logged in " do
2021-12-16 14:36:49 -05:00
before { sign_in ( user1 ) }
2018-05-24 22:04:25 -04:00
it " raises an error when you cannot delete your account " do
UserDestroyer . any_instance . expects ( :destroy ) . never
2021-12-16 14:36:49 -05:00
stat = user1 . user_stat
2018-05-24 22:04:25 -04:00
stat . post_count = 3
stat . save!
2021-12-16 14:36:49 -05:00
delete " /u/ #{ user1 . username } .json "
2018-05-24 22:04:25 -04:00
expect ( response ) . to be_forbidden
end
it " raises an error when you try to delete someone else's account " do
UserDestroyer . any_instance . expects ( :destroy ) . never
delete " /u/ #{ another_user . username } .json "
expect ( response ) . to be_forbidden
end
it " deletes your account when you're allowed to " do
2021-12-16 14:36:49 -05:00
UserDestroyer . any_instance . expects ( :destroy ) . with ( user1 , anything ) . returns ( user1 )
delete " /u/ #{ user1 . username } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
end
end
end
2022-03-25 11:51:45 -04:00
describe " # notification_level " do
it " raises an error when `notification_level` param is not a valid value " do
sign_in ( user )
invalid_arg = " invalid "
put " /u/ #{ user . username } /notification_level.json " , params : { notification_level : invalid_arg }
expect ( response . status ) . to eq ( 422 )
expect ( response . parsed_body [ " errors " ] . first ) . to eq (
I18n . t ( " notification_level.invalid_value " , value : invalid_arg ) ,
)
end
end
2019-02-27 08:49:07 -05:00
describe " # ignore " do
it " raises an error when not logged in " do
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /notification_level.json " , params : { notification_level : " " }
2019-02-27 08:49:07 -05:00
expect ( response . status ) . to eq ( 403 )
end
context " while logged in " do
2019-05-06 23:12:20 -04:00
fab! ( :user ) { Fabricate ( :user , trust_level : 2 ) }
2019-02-27 08:49:07 -05:00
before { sign_in ( user ) }
2021-12-16 14:36:49 -05:00
fab! ( :ignored_user ) { Fabricate ( :ignored_user , user : user , ignored_user : another_user ) }
fab! ( :muted_user ) { Fabricate ( :muted_user , user : user , muted_user : another_user ) }
2019-02-27 08:49:07 -05:00
2020-06-18 13:41:27 -04:00
context " when you can't change the notification " do
2021-12-16 14:36:49 -05:00
fab! ( :staff_user ) { admin }
2020-06-18 13:41:27 -04:00
it " ignoring includes a helpful error message " do
put " /u/ #{ staff_user . username } /notification_level.json " ,
params : {
notification_level : " ignore " ,
}
expect ( response . status ) . to eq ( 422 )
expect ( response . parsed_body [ " errors " ] [ 0 ] ) . to eq ( I18n . t ( " notification_level.ignore_error " ) )
end
it " muting includes a helpful error message " do
put " /u/ #{ staff_user . username } /notification_level.json " ,
params : {
notification_level : " mute " ,
}
expect ( response . status ) . to eq ( 422 )
expect ( response . parsed_body [ " errors " ] [ 0 ] ) . to eq ( I18n . t ( " notification_level.mute_error " ) )
end
end
2019-04-10 06:54:59 -04:00
context " when changing notification level to normal " do
it " changes notification level to normal " do
put " /u/ #{ another_user . username } /notification_level.json " ,
params : {
notification_level : " normal " ,
}
expect ( IgnoredUser . count ) . to eq ( 0 )
expect ( MutedUser . count ) . to eq ( 0 )
2019-02-27 08:49:07 -05:00
end
2019-04-10 06:54:59 -04:00
end
2019-02-27 08:49:07 -05:00
2019-04-10 06:54:59 -04:00
context " when changing notification level to mute " do
it " changes notification level to mute " do
put " /u/ #{ another_user . username } /notification_level.json " ,
params : {
notification_level : " mute " ,
}
expect ( IgnoredUser . count ) . to eq ( 0 )
expect ( MutedUser . find_by ( user_id : user . id , muted_user_id : another_user . id ) ) . to be_present
2019-02-27 08:49:07 -05:00
end
2019-04-10 06:54:59 -04:00
end
2019-02-27 08:49:07 -05:00
2019-04-10 06:54:59 -04:00
context " when changing notification level to ignore " do
it " changes notification level to ignore " do
2022-03-08 23:51:30 -05:00
put " /u/ #{ another_user . username } /notification_level.json " ,
params : {
notification_level : " ignore " ,
expiring_at : 3 . days . from_now ,
}
expect ( response . status ) . to eq ( 200 )
2019-04-10 06:54:59 -04:00
expect ( MutedUser . count ) . to eq ( 0 )
expect (
IgnoredUser . find_by ( user_id : user . id , ignored_user_id : another_user . id ) ,
) . to be_present
2019-02-27 08:49:07 -05:00
end
2022-03-08 23:51:30 -05:00
it " allows admin to change the ignore status for a source user " do
ignored_user . destroy!
sign_in ( Fabricate ( :user , admin : true ) )
put " /u/ #{ another_user . username } /notification_level.json " ,
params : {
notification_level : " ignore " ,
acting_user_id : user . id ,
expiring_at : 3 . days . from_now ,
}
expect ( response . status ) . to eq ( 200 )
expect (
IgnoredUser . find_by ( user_id : user . id , ignored_user_id : another_user . id ) ,
) . to be_present
end
it " does not allow a regular user to change the ignore status for anyone but themself " do
ignored_user . destroy!
acting_user = Fabricate ( :user )
put " /u/ #{ another_user . username } /notification_level.json " ,
params : {
notification_level : " ignore " ,
acting_user_id : acting_user . id ,
expiring_at : 3 . days . from_now ,
}
expect ( response . status ) . to eq ( 422 )
expect (
IgnoredUser . find_by ( user_id : acting_user . id , ignored_user_id : another_user . id ) ,
) . to eq ( nil )
2023-01-09 06:18:21 -05:00
2022-03-08 23:51:30 -05:00
put " /u/ #{ another_user . username } /notification_level.json " ,
params : {
notification_level : " ignore " ,
expiring_at : 3 . days . from_now ,
}
expect ( response . status ) . to eq ( 200 )
expect (
IgnoredUser . find_by ( user_id : user . id , ignored_user_id : another_user . id ) ,
) . to be_present
end
2019-04-10 06:54:59 -04:00
context " when expiring_at param is set " do
2019-03-29 06:14:53 -04:00
it " changes notification level to ignore " do
2019-04-10 06:54:59 -04:00
freeze_time ( Time . now ) do
expiring_at = 3 . days . from_now
put " /u/ #{ another_user . username } /notification_level.json " ,
params : {
notification_level : " ignore " ,
expiring_at : expiring_at ,
}
ignored_user = IgnoredUser . find_by ( user_id : user . id , ignored_user_id : another_user . id )
expect ( ignored_user ) . to be_present
expect ( ignored_user . expiring_at . to_i ) . to eq ( expiring_at . to_i )
expect ( MutedUser . count ) . to eq ( 0 )
2019-03-29 06:14:53 -04:00
end
end
2019-02-27 08:49:07 -05:00
end
end
end
end
2018-11-23 12:41:41 -05:00
describe " for user with period in username " do
2019-05-06 23:12:20 -04:00
fab! ( :user_with_period ) { Fabricate ( :user , username : " myname.test " ) }
2018-11-23 12:41:41 -05:00
it " still works " do
sign_in ( user_with_period )
UserDestroyer
. any_instance
. expects ( :destroy )
. with ( user_with_period , anything )
. returns ( user_with_period )
delete " /u/ #{ user_with_period . username } " , xhr : true
expect ( response . status ) . to eq ( 200 )
end
end
2018-05-24 22:04:25 -04:00
describe " # my_redirect " do
it " redirects if the user is not logged in " do
2020-06-05 12:31:58 -04:00
get " /my/wat "
expect ( response ) . to redirect_to ( " /login-preferences " )
expect ( response . cookies ) . to have_key ( " destination_url " )
expect ( response . cookies [ " destination_url " ] ) . to eq ( " /my/wat " )
2020-05-11 01:05:42 -04:00
expect ( response . headers [ " X-Robots-Tag " ] ) . to eq ( " noindex " )
2018-05-24 22:04:25 -04:00
end
context " when the user is logged in " do
2021-12-16 14:36:49 -05:00
before { sign_in ( user1 ) }
2018-05-24 22:04:25 -04:00
it " will not redirect to an invalid path " do
get " /my/wat/..password.txt "
expect ( response ) . not_to be_redirect
end
it " will redirect to an valid path " do
2020-06-05 12:31:58 -04:00
get " /my/preferences "
2021-12-16 14:36:49 -05:00
expect ( response ) . to redirect_to ( " /u/ #{ user1 . username } /preferences " )
2018-05-24 22:04:25 -04:00
end
it " permits forward slashes " do
2020-06-05 12:31:58 -04:00
get " /my/activity/posts "
2021-12-16 14:36:49 -05:00
expect ( response ) . to redirect_to ( " /u/ #{ user1 . username } /activity/posts " )
2020-06-05 12:31:58 -04:00
end
it " correctly redirects for Unicode usernames " do
SiteSetting . unicode_usernames = true
user = sign_in ( Fabricate ( :unicode_user ) )
get " /my/preferences "
expect ( response ) . to redirect_to ( " /u/ #{ user . encoded_username } /preferences " )
2018-05-24 22:04:25 -04:00
end
end
end
describe " # check_emails " do
it " raises an error when not logged in " do
get " /u/zogstrip/emails.json "
expect ( response . status ) . to eq ( 403 )
end
context " while logged in " do
2021-12-16 14:36:49 -05:00
let ( :sign_in_admin ) { sign_in ( admin ) }
2018-05-24 22:04:25 -04:00
it " raises an error when you aren't allowed to check emails " do
sign_in ( Fabricate ( :user ) )
get " /u/ #{ Fabricate ( :user ) . username } /emails.json "
expect ( response ) . to be_forbidden
end
2019-02-05 13:01:19 -05:00
it " returns emails and associated_accounts for self " do
2021-12-16 14:36:49 -05:00
Fabricate ( :email_change_request , user : user1 )
2019-02-05 13:01:19 -05:00
sign_in ( user )
get " /u/ #{ user . username } /emails.json "
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2019-02-05 13:01:19 -05:00
expect ( json [ " email " ] ) . to eq ( user . email )
expect ( json [ " secondary_emails " ] ) . to eq ( user . secondary_emails )
2020-06-17 14:41:01 -04:00
expect ( json [ " unconfirmed_emails " ] ) . to eq ( user . unconfirmed_emails )
2019-02-05 13:01:19 -05:00
expect ( json [ " associated_accounts " ] ) . to eq ( [ ] )
end
2018-07-03 07:51:22 -04:00
it " returns emails and associated_accounts when you're allowed to see them " do
2021-12-16 14:36:49 -05:00
Fabricate ( :email_change_request , user : user1 )
2018-05-24 22:04:25 -04:00
sign_in_admin
2018-07-03 07:51:22 -04:00
get " /u/ #{ user . username } /emails.json "
2018-05-24 22:04:25 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-07-03 07:51:22 -04:00
expect ( json [ " email " ] ) . to eq ( user . email )
expect ( json [ " secondary_emails " ] ) . to eq ( user . secondary_emails )
2020-06-17 14:41:01 -04:00
expect ( json [ " unconfirmed_emails " ] ) . to eq ( user . unconfirmed_emails )
2018-07-23 11:51:57 -04:00
expect ( json [ " associated_accounts " ] ) . to eq ( [ ] )
2018-05-24 22:04:25 -04:00
end
it " works on inactive users " do
inactive_user = Fabricate ( :user , active : false )
2020-06-17 14:41:01 -04:00
Fabricate ( :email_change_request , user : inactive_user )
2018-05-24 22:04:25 -04:00
sign_in_admin
get " /u/ #{ inactive_user . username } /emails.json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-07-03 07:51:22 -04:00
expect ( json [ " email " ] ) . to eq ( inactive_user . email )
expect ( json [ " secondary_emails " ] ) . to eq ( inactive_user . secondary_emails )
2020-06-17 14:41:01 -04:00
expect ( json [ " unconfirmed_emails " ] ) . to eq ( inactive_user . unconfirmed_emails )
2018-07-23 11:51:57 -04:00
expect ( json [ " associated_accounts " ] ) . to eq ( [ ] )
2018-05-24 22:04:25 -04:00
end
end
2017-12-14 01:16:49 -05:00
end
2020-11-10 14:12:44 -05:00
describe " # check_sso_email " do
it " raises an error when not logged in " do
get " /u/zogstrip/sso-email.json "
expect ( response . status ) . to eq ( 403 )
end
context " while logged in " do
2021-12-16 14:36:49 -05:00
let ( :sign_in_admin ) { sign_in ( admin ) }
2020-11-10 14:12:44 -05:00
it " raises an error when you aren't allowed to check sso email " do
sign_in ( Fabricate ( :user ) )
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } /sso-email.json "
2020-11-10 14:12:44 -05:00
expect ( response ) . to be_forbidden
end
it " returns emails and associated_accounts when you're allowed to see them " do
2021-12-16 14:36:49 -05:00
user1 . single_sign_on_record =
SingleSignOnRecord . create (
user_id : user1 . id ,
external_email : " foobar@example.com " ,
external_id : " example " ,
last_payload : " looks good " ,
)
2020-11-10 14:12:44 -05:00
sign_in_admin
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } /sso-email.json "
2020-11-10 14:12:44 -05:00
expect ( response . status ) . to eq ( 200 )
expect ( response . parsed_body [ " email " ] ) . to eq ( " foobar@example.com " )
end
end
end
2021-02-17 10:57:51 -05:00
describe " # check_sso_payload " do
it " raises an error when not logged in " do
get " /u/zogstrip/sso-payload.json "
expect ( response . status ) . to eq ( 403 )
end
context " while logged in " do
2021-12-16 14:36:49 -05:00
let ( :sign_in_admin ) { sign_in ( admin ) }
2021-02-17 10:57:51 -05:00
it " raises an error when you aren't allowed to check sso payload " do
sign_in ( Fabricate ( :user ) )
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } /sso-payload.json "
2021-02-17 10:57:51 -05:00
expect ( response ) . to be_forbidden
end
it " returns SSO payload when you're allowed to see " do
2021-12-16 14:36:49 -05:00
user1 . single_sign_on_record =
SingleSignOnRecord . create (
user_id : user1 . id ,
external_email : " foobar@example.com " ,
external_id : " example " ,
last_payload : " foobar " ,
)
2021-02-17 10:57:51 -05:00
sign_in_admin
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } /sso-payload.json "
2021-02-17 10:57:51 -05:00
expect ( response . status ) . to eq ( 200 )
expect ( response . parsed_body [ " payload " ] ) . to eq ( " foobar " )
end
end
end
2020-06-10 12:11:49 -04:00
describe " # update_primary_email " do
2021-12-16 14:36:49 -05:00
let ( :user_email ) { user1 . primary_email }
fab! ( :other_email ) { Fabricate ( :secondary_email , user : user1 ) }
2020-06-10 12:11:49 -04:00
before do
SiteSetting . email_editable = true
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2020-06-10 12:11:49 -04:00
end
it " changes user's primary email " do
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /preferences/primary-email.json " , params : { email : user_email . email }
2020-06-10 12:11:49 -04:00
expect ( response . status ) . to eq ( 200 )
expect ( user_email . reload . primary ) . to eq ( true )
expect ( other_email . reload . primary ) . to eq ( false )
2020-07-16 08:51:30 -04:00
event =
DiscourseEvent
. track_events do
2021-12-16 14:36:49 -05:00
expect {
put " /u/ #{ user1 . username } /preferences/primary-email.json " ,
params : {
email : other_email . email ,
}
} . to change {
UserHistory . where (
action : UserHistory . actions [ :update_email ] ,
acting_user_id : user1 . id ,
) . count
} . by ( 1 )
2023-01-09 06:18:21 -05:00
end
2020-07-16 08:51:30 -04:00
. last
2020-06-10 12:11:49 -04:00
expect ( response . status ) . to eq ( 200 )
expect ( user_email . reload . primary ) . to eq ( false )
expect ( other_email . reload . primary ) . to eq ( true )
2020-07-16 08:51:30 -04:00
expect ( event [ :event_name ] ) . to eq ( :user_updated )
2021-12-16 14:36:49 -05:00
expect ( event [ :params ] . first ) . to eq ( user1 )
2020-06-10 12:11:49 -04:00
end
end
describe " # destroy_email " do
2021-12-16 14:36:49 -05:00
fab! ( :user_email ) { user1 . primary_email }
fab! ( :other_email ) { Fabricate ( :secondary_email , user : user1 ) }
2020-06-10 12:11:49 -04:00
before do
SiteSetting . email_editable = true
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2020-06-10 12:11:49 -04:00
end
it " can destroy secondary emails " do
2021-12-16 14:36:49 -05:00
delete " /u/ #{ user1 . username } /preferences/email.json " , params : { email : user_email . email }
2020-06-10 12:11:49 -04:00
expect ( response . status ) . to eq ( 428 )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . user_emails . pluck ( :email ) ) . to contain_exactly (
user_email . email ,
other_email . email ,
)
2020-06-10 12:11:49 -04:00
2020-07-16 08:51:30 -04:00
event =
DiscourseEvent
. track_events do
2021-12-16 14:36:49 -05:00
expect {
delete " /u/ #{ user1 . username } /preferences/email.json " ,
params : {
email : other_email . email ,
}
} . to change {
UserHistory . where (
action : UserHistory . actions [ :destroy_email ] ,
acting_user_id : user1 . id ,
) . count
} . by ( 1 )
2023-01-09 06:18:21 -05:00
end
2020-07-16 08:51:30 -04:00
. last
2020-06-10 12:11:49 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . user_emails . pluck ( :email ) ) . to contain_exactly ( user_email . email )
2020-07-16 08:51:30 -04:00
expect ( event [ :event_name ] ) . to eq ( :user_updated )
2021-12-16 14:36:49 -05:00
expect ( event [ :params ] . first ) . to eq ( user1 )
2020-06-10 12:11:49 -04:00
end
2021-03-10 07:49:26 -05:00
2021-05-13 02:14:00 -04:00
it " can destroy unconfirmed emails " do
request_1 =
EmailChangeRequest . create! (
2021-12-16 14:36:49 -05:00
user : user1 ,
2021-05-13 02:14:00 -04:00
new_email : user_email . email ,
change_state : EmailChangeRequest . states [ :authorizing_new ] ,
)
2021-03-10 07:49:26 -05:00
EmailChangeRequest . create! (
2021-12-16 14:36:49 -05:00
user : user1 ,
2021-05-13 02:14:00 -04:00
new_email : other_email . email ,
2021-03-10 07:49:26 -05:00
change_state : EmailChangeRequest . states [ :authorizing_new ] ,
)
2021-05-13 02:14:00 -04:00
EmailChangeRequest . create! (
2021-12-16 14:36:49 -05:00
user : user1 ,
2021-05-13 02:14:00 -04:00
new_email : other_email . email ,
change_state : EmailChangeRequest . states [ :authorizing_new ] ,
)
2021-12-16 14:36:49 -05:00
delete " /u/ #{ user1 . username } /preferences/email.json " , params : { email : other_email . email }
2021-03-10 07:49:26 -05:00
2021-12-16 14:36:49 -05:00
expect ( user1 . user_emails . pluck ( :email ) ) . to contain_exactly (
user_email . email ,
other_email . email ,
)
expect ( user1 . email_change_requests ) . to contain_exactly ( request_1 )
2021-03-10 07:49:26 -05:00
end
2021-08-04 19:14:56 -04:00
2023-01-04 17:08:55 -05:00
it " destroys associated email tokens and email change requests " do
2021-08-04 19:14:56 -04:00
new_email = " new.n.cool@example.com "
2021-12-16 14:36:49 -05:00
updater = EmailUpdater . new ( guardian : user1 . guardian , user : user1 )
2023-01-04 17:08:55 -05:00
updater . change_to ( new_email )
2021-08-04 19:14:56 -04:00
2023-01-04 17:08:55 -05:00
email_token = updater . change_req . new_email_token
expect ( email_token ) . to be_present
2021-08-04 19:14:56 -04:00
2023-01-04 17:08:55 -05:00
delete " /u/ #{ user1 . username } /preferences/email.json " , params : { email : new_email }
2021-08-04 19:14:56 -04:00
2023-01-04 17:08:55 -05:00
expect ( EmailToken . find_by ( id : email_token . id ) ) . to eq ( nil )
expect ( EmailChangeRequest . find_by ( id : updater . change_req . id ) ) . to eq ( nil )
2021-08-04 19:14:56 -04:00
end
2020-06-10 12:11:49 -04:00
end
2018-05-24 22:04:25 -04:00
describe " # topic_tracking_state " do
2022-07-27 12:14:14 -04:00
context " when anon " do
2018-05-24 22:04:25 -04:00
it " raises an error on anon for topic_tracking_state " do
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } /topic-tracking-state.json "
2018-05-24 22:04:25 -04:00
expect ( response . status ) . to eq ( 403 )
end
end
2022-07-27 12:14:14 -04:00
context " when logged on " do
2018-05-24 22:04:25 -04:00
it " detects new topic " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2018-05-24 22:04:25 -04:00
topic = Fabricate ( :topic )
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } /topic-tracking-state.json "
2018-05-24 22:04:25 -04:00
2018-05-27 23:20:47 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
states = response . parsed_body
2018-05-24 22:04:25 -04:00
expect ( states [ 0 ] [ " topic_id " ] ) . to eq ( topic . id )
end
end
end
describe " # summary " do
it " generates summary info " do
create_post ( user : user )
get " /u/ #{ user . username_lower } /summary.json "
2020-07-15 17:02:55 -04:00
expect ( response . headers [ " X-Robots-Tag " ] ) . to eq ( " noindex " )
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-24 22:04:25 -04:00
expect ( json [ " user_summary " ] [ " topic_count " ] ) . to eq ( 1 )
expect ( json [ " user_summary " ] [ " post_count " ] ) . to eq ( 0 )
end
2018-10-10 13:00:08 -04:00
2022-07-27 12:14:14 -04:00
context " when `hide_profile_and_presence` user option is checked " do
2021-12-16 14:36:49 -05:00
before_all { user1 . user_option . update_columns ( hide_profile_and_presence : true ) }
2020-10-09 17:18:44 -04:00
it " returns 404 " do
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username_lower } /summary.json "
2020-10-09 17:18:44 -04:00
expect ( response . status ) . to eq ( 404 )
end
it " returns summary info if `allow_users_to_hide_profile` is false " do
SiteSetting . allow_users_to_hide_profile = false
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username_lower } /summary.json "
2020-10-09 17:18:44 -04:00
expect ( response . status ) . to eq ( 200 )
end
2018-10-10 13:00:08 -04:00
end
2021-04-28 12:15:22 -04:00
2022-07-27 12:14:14 -04:00
context " with avatar flair in Most... sections " do
2021-04-28 12:15:22 -04:00
it " returns data for automatic groups flair " do
liker = Fabricate ( :user , admin : true , moderator : true , trust_level : 1 )
2021-12-16 14:36:49 -05:00
create_and_like_post ( user_deferred , liker )
2021-04-28 12:15:22 -04:00
2021-12-16 14:36:49 -05:00
get " /u/ #{ user_deferred . username_lower } /summary.json "
2021-04-28 12:15:22 -04:00
json = response . parsed_body
expect ( json [ " user_summary " ] [ " most_liked_by_users " ] [ 0 ] [ " admin " ] ) . to eq ( true )
expect ( json [ " user_summary " ] [ " most_liked_by_users " ] [ 0 ] [ " moderator " ] ) . to eq ( true )
expect ( json [ " user_summary " ] [ " most_liked_by_users " ] [ 0 ] [ " trust_level " ] ) . to eq ( 1 )
end
2021-07-08 03:46:21 -04:00
it " returns data for flair when an icon is used " do
2021-04-28 12:15:22 -04:00
group =
Fabricate (
:group ,
name : " Groupie " ,
flair_bg_color : " # 111111 " ,
flair_color : " # 999999 " ,
flair_icon : " icon " ,
)
2021-07-08 03:46:21 -04:00
liker = Fabricate ( :user , flair_group : group )
2021-12-16 14:36:49 -05:00
create_and_like_post ( user_deferred , liker )
2021-04-28 12:15:22 -04:00
2021-12-16 14:36:49 -05:00
get " /u/ #{ user_deferred . username_lower } /summary.json "
2021-04-28 12:15:22 -04:00
json = response . parsed_body
2021-07-08 03:46:21 -04:00
expect ( json [ " user_summary " ] [ " most_liked_by_users " ] [ 0 ] [ " flair_name " ] ) . to eq ( " Groupie " )
expect ( json [ " user_summary " ] [ " most_liked_by_users " ] [ 0 ] [ " flair_url " ] ) . to eq ( " icon " )
expect ( json [ " user_summary " ] [ " most_liked_by_users " ] [ 0 ] [ " flair_bg_color " ] ) . to eq ( " # 111111 " )
expect ( json [ " user_summary " ] [ " most_liked_by_users " ] [ 0 ] [ " flair_color " ] ) . to eq ( " # 999999 " )
2021-04-28 12:15:22 -04:00
end
2021-07-08 03:46:21 -04:00
it " returns data for flair when an image is used " do
2021-04-28 12:15:22 -04:00
upload = Fabricate ( :upload )
group = Fabricate ( :group , name : " Groupie " , flair_bg_color : " # 111111 " , flair_upload : upload )
2021-07-08 03:46:21 -04:00
liker = Fabricate ( :user , flair_group : group )
2021-12-16 14:36:49 -05:00
create_and_like_post ( user_deferred , liker )
2021-04-28 12:15:22 -04:00
2021-12-16 14:36:49 -05:00
get " /u/ #{ user_deferred . username_lower } /summary.json "
2021-04-28 12:15:22 -04:00
json = response . parsed_body
2021-07-08 03:46:21 -04:00
expect ( json [ " user_summary " ] [ " most_liked_by_users " ] [ 0 ] [ " flair_name " ] ) . to eq ( " Groupie " )
expect ( json [ " user_summary " ] [ " most_liked_by_users " ] [ 0 ] [ " flair_url " ] ) . to eq ( upload . url )
expect ( json [ " user_summary " ] [ " most_liked_by_users " ] [ 0 ] [ " flair_bg_color " ] ) . to eq ( " # 111111 " )
2021-04-28 12:15:22 -04:00
end
def create_and_like_post ( likee , liker )
UserActionManager . enable
post = create_post ( user : likee )
PostActionCreator . like ( liker , post )
end
end
2018-05-24 22:04:25 -04:00
end
describe " # confirm_admin " do
it " fails without a valid token " do
2019-07-23 13:17:44 -04:00
get " /u/confirm-admin/invalid-token.json "
2018-06-05 03:29:17 -04:00
expect ( response ) . not_to be_successful
2018-05-24 22:04:25 -04:00
end
it " fails with a missing token " do
2019-07-23 13:17:44 -04:00
get " /u/confirm-admin/a0a0a0a0a0.json "
2018-06-05 03:29:17 -04:00
expect ( response ) . to_not be_successful
2018-05-24 22:04:25 -04:00
end
it " succeeds with a valid code as anonymous " do
2021-12-16 14:36:49 -05:00
ac = AdminConfirmation . new ( user1 , admin )
2018-05-24 22:04:25 -04:00
ac . create_confirmation
2019-07-23 13:17:44 -04:00
get " /u/confirm-admin/ #{ ac . token } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
2021-12-16 14:36:49 -05:00
user1 . reload
expect ( user1 . admin? ) . to eq ( false )
2018-05-24 22:04:25 -04:00
end
it " succeeds with a valid code when logged in as that user " do
2021-12-07 13:45:58 -05:00
sign_in ( admin )
2018-05-24 22:04:25 -04:00
2021-12-16 14:36:49 -05:00
ac = AdminConfirmation . new ( user1 , admin )
2018-05-24 22:04:25 -04:00
ac . create_confirmation
2019-07-23 13:17:44 -04:00
get " /u/confirm-admin/ #{ ac . token } .json " , params : { token : ac . token }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
2021-12-16 14:36:49 -05:00
user1 . reload
expect ( user1 . admin? ) . to eq ( false )
2018-05-24 22:04:25 -04:00
end
it " fails if you're logged in as a different account " do
2021-12-07 13:45:58 -05:00
sign_in ( admin )
2018-05-24 22:04:25 -04:00
2021-12-16 14:36:49 -05:00
ac = AdminConfirmation . new ( user1 , Fabricate ( :admin ) )
2018-05-24 22:04:25 -04:00
ac . create_confirmation
2019-07-23 13:17:44 -04:00
get " /u/confirm-admin/ #{ ac . token } .json "
2018-06-05 03:29:17 -04:00
expect ( response ) . to_not be_successful
2018-05-24 22:04:25 -04:00
2021-12-16 14:36:49 -05:00
user1 . reload
expect ( user1 . admin? ) . to eq ( false )
2018-05-24 22:04:25 -04:00
end
describe " post " do
it " gives the user admin access when POSTed " do
2021-12-16 14:36:49 -05:00
ac = AdminConfirmation . new ( user1 , admin )
2018-05-24 22:04:25 -04:00
ac . create_confirmation
2019-07-23 13:17:44 -04:00
post " /u/confirm-admin/ #{ ac . token } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
2021-12-16 14:36:49 -05:00
user1 . reload
expect ( user1 . admin? ) . to eq ( true )
2018-05-24 22:04:25 -04:00
end
end
end
describe " # update_activation_email " do
before do
UsersController . any_instance . stubs ( :honeypot_value ) . returns ( nil )
UsersController . any_instance . stubs ( :challenge_value ) . returns ( nil )
end
let ( :post_user ) do
post " /u.json " ,
params : {
username : " osamatest " ,
password : " strongpassword " ,
email : " osama@example.com " ,
}
user = User . where ( username : " osamatest " ) . first
user . active = false
user . save!
user
end
context " with a session variable " do
it " raises an error with an invalid session value " do
post_user
post " /u.json " ,
params : {
username : " osamatest2 " ,
password : " strongpassword2 " ,
email : " osama22@example.com " ,
}
user = User . where ( username : " osamatest2 " ) . first
user . destroy
put " /u/update-activation-email.json " , params : { email : " osamaupdated@example.com " }
expect ( response . status ) . to eq ( 403 )
end
it " raises an error for an active user " do
user = post_user
user . update ( active : true )
user . save!
put " /u/update-activation-email.json " , params : { email : " osama@example.com " }
expect ( response . status ) . to eq ( 403 )
end
it " raises an error when logged in " do
2021-12-16 14:36:49 -05:00
sign_in ( moderator )
2018-05-24 22:04:25 -04:00
post_user
put " /u/update-activation-email.json " , params : { email : " updatedemail@example.com " }
expect ( response . status ) . to eq ( 403 )
end
it " raises an error when the new email is taken " do
active_user = Fabricate ( :user )
2018-09-20 01:33:10 -04:00
post_user
2018-05-24 22:04:25 -04:00
put " /u/update-activation-email.json " , params : { email : active_user . email }
expect ( response . status ) . to eq ( 422 )
end
2020-07-26 20:23:54 -04:00
it " raises an error when the email is blocklisted " do
2018-09-20 01:33:10 -04:00
post_user
2020-07-26 20:23:54 -04:00
SiteSetting . blocked_email_domains = " example.com "
2018-05-24 22:04:25 -04:00
put " /u/update-activation-email.json " , params : { email : " test@example.com " }
expect ( response . status ) . to eq ( 422 )
end
it " can be updated " do
user = post_user
token = user . email_tokens . first
put " /u/update-activation-email.json " , params : { email : " updatedemail@example.com " }
2018-05-31 00:15:28 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
user . reload
expect ( user . email ) . to eq ( " updatedemail@example.com " )
expect (
user . email_tokens . where ( email : " updatedemail@example.com " , expired : false ) ,
) . to be_present
2023-01-04 17:08:55 -05:00
expect ( EmailToken . find_by ( id : token . id ) ) . to eq ( nil )
2017-12-14 01:16:49 -05:00
end
2022-07-27 16:04:42 -04:00
it " tells the user to slow down after many requests " do
RateLimiter . enable
RateLimiter . clear_all!
freeze_time
user = post_user
token = user . email_tokens . first
6 . times do | n |
put " /u/update-activation-email.json " ,
params : {
email : " updatedemail #{ n } @example.com " ,
} ,
env : {
REMOTE_ADDR : " 1.2.3. #{ n } " ,
}
end
expect ( response . status ) . to eq ( 429 )
end
2017-12-14 01:16:49 -05:00
end
2018-05-24 22:04:25 -04:00
context " with a username and password " do
it " raises an error with an invalid username " do
put " /u/update-activation-email.json " ,
params : {
username : " eviltrout " ,
password : " invalid-password " ,
email : " updatedemail@example.com " ,
}
2018-05-31 00:15:28 -04:00
expect ( response . status ) . to eq ( 403 )
2018-05-24 22:04:25 -04:00
end
it " raises an error with an invalid password " do
put " /u/update-activation-email.json " ,
params : {
2021-12-16 14:36:49 -05:00
username : inactive_user . username ,
2018-05-24 22:04:25 -04:00
password : " invalid-password " ,
email : " updatedemail@example.com " ,
}
2018-05-31 00:15:28 -04:00
expect ( response . status ) . to eq ( 403 )
2018-05-24 22:04:25 -04:00
end
it " raises an error for an active user " do
put " /u/update-activation-email.json " ,
params : {
username : Fabricate ( :walter_white ) . username ,
password : " letscook " ,
email : " updatedemail@example.com " ,
}
2018-05-31 00:15:28 -04:00
expect ( response . status ) . to eq ( 403 )
2018-05-24 22:04:25 -04:00
end
it " raises an error when logged in " do
2021-12-16 14:36:49 -05:00
sign_in ( moderator )
2018-05-24 22:04:25 -04:00
put " /u/update-activation-email.json " ,
params : {
2021-12-16 14:36:49 -05:00
username : inactive_user . username ,
2018-05-24 22:04:25 -04:00
password : " qwerqwer123 " ,
email : " updatedemail@example.com " ,
}
2018-05-31 00:15:28 -04:00
expect ( response . status ) . to eq ( 403 )
2018-05-24 22:04:25 -04:00
end
it " raises an error when the new email is taken " do
put " /u/update-activation-email.json " ,
params : {
2021-12-16 14:36:49 -05:00
username : inactive_user . username ,
2018-05-24 22:04:25 -04:00
password : " qwerqwer123 " ,
email : user . email ,
}
2018-05-31 00:15:28 -04:00
expect ( response . status ) . to eq ( 422 )
2018-05-24 22:04:25 -04:00
end
it " can be updated " do
2021-12-16 14:36:49 -05:00
user = inactive_user
2018-05-24 22:04:25 -04:00
token = user . email_tokens . first
put " /u/update-activation-email.json " ,
params : {
username : user . username ,
password : " qwerqwer123 " ,
email : " updatedemail@example.com " ,
}
2018-05-31 00:15:28 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
user . reload
expect ( user . email ) . to eq ( " updatedemail@example.com " )
expect (
user . email_tokens . where ( email : " updatedemail@example.com " , expired : false ) ,
) . to be_present
2023-01-04 17:08:55 -05:00
expect ( EmailToken . find_by ( id : token . id ) ) . to eq ( nil )
2018-05-24 22:04:25 -04:00
end
2022-07-27 16:04:42 -04:00
it " tells the user to slow down after many requests " do
RateLimiter . enable
RateLimiter . clear_all!
freeze_time
user = inactive_user
token = user . email_tokens . first
6 . times do | n |
put " /u/update-activation-email.json " ,
params : {
username : user . username ,
password : " qwerqwer123 " ,
email : " updatedemail #{ n } @example.com " ,
} ,
env : {
REMOTE_ADDR : " 1.2.3. #{ n } " ,
}
end
expect ( response . status ) . to eq ( 429 )
end
2018-05-24 22:04:25 -04:00
end
2017-12-14 01:16:49 -05:00
end
2017-08-23 23:01:11 -04:00
describe " # show " do
2022-07-27 12:14:14 -04:00
context " when anon " do
2018-05-24 22:04:25 -04:00
let ( :user ) { Discourse . system_user }
it " returns success " do
get " /u/ #{ user . username } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
parsed = response . parsed_body [ " user " ]
2018-10-10 13:00:08 -04:00
expect ( parsed [ " username " ] ) . to eq ( user . username )
expect ( parsed [ " profile_hidden " ] ) . to be_blank
expect ( parsed [ " trust_level " ] ) . to be_present
end
it " returns a hidden profile " do
user . user_option . update_column ( :hide_profile_and_presence , true )
get " /u/ #{ user . username } .json "
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
parsed = response . parsed_body [ " user " ]
2018-10-10 13:00:08 -04:00
expect ( parsed [ " username " ] ) . to eq ( user . username )
expect ( parsed [ " profile_hidden " ] ) . to eq ( true )
expect ( parsed [ " trust_level " ] ) . to be_blank
2018-05-24 22:04:25 -04:00
end
it " should redirect to login page for anonymous user when profiles are hidden " do
SiteSetting . hide_user_profiles_from_public = true
get " /u/ #{ user . username } .json "
expect ( response ) . to redirect_to " /login "
end
describe " user profile views " do
it " should track a user profile view for an anon user " do
get " / "
2021-12-16 14:36:49 -05:00
UserProfileView . expects ( :add ) . with ( another_user . user_profile . id , request . remote_ip , nil )
get " /u/ #{ another_user . username } .json "
2018-05-24 22:04:25 -04:00
end
it " skips tracking " do
UserProfileView . expects ( :add ) . never
get " /u/ #{ user . username } .json " , params : { skip_track_visit : true }
end
end
end
2022-07-27 12:14:14 -04:00
context " when logged in " do
2021-12-16 14:36:49 -05:00
before { sign_in ( user1 ) }
2018-05-24 22:04:25 -04:00
it " returns success " do
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-01-08 00:56:20 -05:00
expect ( response . headers [ " X-Robots-Tag " ] ) . to eq ( " noindex " )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2018-05-24 22:04:25 -04:00
expect ( json [ " user " ] [ " has_title_badges " ] ) . to eq ( false )
end
it " returns not found when the username doesn't exist " do
get " /u/madeuppity.json "
2018-06-05 03:29:17 -04:00
expect ( response ) . not_to be_successful
2018-05-24 22:04:25 -04:00
end
it " returns not found when the user is inactive " do
inactive = Fabricate ( :user , active : false )
get " /u/ #{ inactive . username } .json "
2018-06-05 03:29:17 -04:00
expect ( response ) . not_to be_successful
2018-05-24 22:04:25 -04:00
end
it " returns success when show_inactive_accounts is true and user is logged in " do
SiteSetting . show_inactive_accounts = true
inactive = Fabricate ( :user , active : false )
get " /u/ #{ inactive . username } .json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-05-24 22:04:25 -04:00
end
it " raises an error on invalid access " do
2021-12-16 14:36:49 -05:00
Guardian . any_instance . expects ( :can_see? ) . with ( user1 ) . returns ( false )
get " /u/ #{ user1 . username } .json "
2018-05-24 22:04:25 -04:00
expect ( response ) . to be_forbidden
end
describe " user profile views " do
it " should track a user profile view for a signed in user " do
2021-12-16 14:36:49 -05:00
UserProfileView . expects ( :add ) . with (
another_user . user_profile . id ,
request . remote_ip ,
user1 . id ,
)
get " /u/ #{ another_user . username } .json "
2018-05-24 22:04:25 -04:00
end
it " should not track a user profile view for a user viewing his own profile " do
UserProfileView . expects ( :add ) . never
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } .json "
2018-05-24 22:04:25 -04:00
end
it " skips tracking " do
UserProfileView . expects ( :add ) . never
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } .json " , params : { skip_track_visit : true }
2018-05-24 22:04:25 -04:00
end
end
2022-07-27 12:14:14 -04:00
context " when fetching a user by external_id " do
2021-12-16 14:36:49 -05:00
before { user1 . create_single_sign_on_record ( external_id : " 997 " , last_payload : " " ) }
2018-05-24 22:04:25 -04:00
it " returns fetch for a matching external_id " do
get " /u/by-external/997.json "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( response . parsed_body [ " user " ] [ " username " ] ) . to eq ( user1 . username )
2018-05-24 22:04:25 -04:00
end
it " returns not found when external_id doesn't match " do
get " /u/by-external/99.json "
2018-06-05 03:29:17 -04:00
expect ( response ) . not_to be_successful
2018-05-24 22:04:25 -04:00
end
2020-11-10 05:41:46 -05:00
context " for an external provider " do
before do
2021-12-16 14:36:49 -05:00
sign_in ( admin )
2020-11-10 05:41:46 -05:00
SiteSetting . enable_google_oauth2_logins = true
2021-12-16 14:36:49 -05:00
UserAssociatedAccount . create! (
user : user1 ,
provider_uid : " myuid " ,
provider_name : " google_oauth2 " ,
)
2020-11-10 05:41:46 -05:00
end
it " doesn't work for non-admin " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2020-11-10 05:41:46 -05:00
get " /u/by-external/google_oauth2/myuid.json "
expect ( response . status ) . to eq ( 403 )
end
it " can fetch the user " do
get " /u/by-external/google_oauth2/myuid.json "
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( response . parsed_body [ " user " ] [ " username " ] ) . to eq ( user1 . username )
2020-11-10 05:41:46 -05:00
end
it " fails for disabled provider " do
SiteSetting . enable_google_oauth2_logins = false
get " /u/by-external/google_oauth2/myuid.json "
expect ( response . status ) . to eq ( 404 )
end
it " returns 404 for missing user " do
get " /u/by-external/google_oauth2/myotheruid.json "
expect ( response . status ) . to eq ( 404 )
end
end
2018-05-24 22:04:25 -04:00
end
describe " include_post_count_for " do
2019-05-06 23:12:20 -04:00
fab! ( :topic ) { Fabricate ( :topic ) }
2018-05-24 22:04:25 -04:00
2021-12-07 13:45:58 -05:00
before_all do
2021-12-16 14:36:49 -05:00
Fabricate ( :post , user : user1 , topic : topic )
2018-05-24 22:04:25 -04:00
Fabricate ( :post , user : admin , topic : topic )
Fabricate ( :post , user : admin , topic : topic , post_type : Post . types [ :whisper ] )
end
it " includes only visible posts " do
get " /u/ #{ admin . username } .json " , params : { include_post_count_for : topic . id }
2020-05-07 11:04:12 -04:00
topic_post_count = response . parsed_body . dig ( " user " , " topic_post_count " )
2018-05-24 22:04:25 -04:00
expect ( topic_post_count [ topic . id . to_s ] ) . to eq ( 1 )
end
2023-01-04 17:08:19 -05:00
it " doesn't include the post count when the signed in user doesn't have access " do
c = Fabricate ( :category , read_restricted : true )
topic . update ( category_id : c . id )
expect ( Guardian . new ( user1 ) . can_see? ( topic ) ) . to eq ( false )
get " /u/ #{ admin . username } .json " , params : { include_post_count_for : topic . id }
topic_post_count = response . parsed_body . dig ( " user " , " topic_post_count " )
expect ( topic_post_count ) . to eq ( nil )
end
2018-05-24 22:04:25 -04:00
it " includes all post types for staff members " do
2022-12-16 11:42:51 -05:00
SiteSetting . whispers_allowed_groups = " #{ Group :: AUTO_GROUPS [ :staff ] } "
2018-05-24 22:04:25 -04:00
sign_in ( admin )
get " /u/ #{ admin . username } .json " , params : { include_post_count_for : topic . id }
2020-05-07 11:04:12 -04:00
topic_post_count = response . parsed_body . dig ( " user " , " topic_post_count " )
2018-05-24 22:04:25 -04:00
expect ( topic_post_count [ topic . id . to_s ] ) . to eq ( 2 )
end
end
end
2016-12-16 13:26:22 -05:00
it " should be able to view a user " do
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } "
2016-12-16 13:26:22 -05:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( response . body ) . to include ( user1 . username )
2016-12-16 13:26:22 -05:00
end
2022-01-04 14:34:17 -05:00
it " should not be able to view a private user profile " do
user1 . user_profile . update! ( bio_raw : " Hello world! " )
user1 . user_option . update! ( hide_profile_and_presence : true )
get " /u/ #{ user1 . username } "
expect ( response . status ) . to eq ( 200 )
expect ( response . body ) . not_to include ( " Hello world! " )
end
2016-12-16 13:26:22 -05:00
describe " when username contains a period " do
2021-12-16 14:36:49 -05:00
before_all { user1 . update! ( username : " test.test " ) }
2016-12-16 13:26:22 -05:00
it " should be able to view a user " do
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } "
2016-12-16 13:26:22 -05:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( response . body ) . to include ( user1 . username )
2016-12-16 13:26:22 -05:00
end
end
end
2020-01-28 06:55:46 -05:00
describe " # show_card " do
2022-07-27 12:14:14 -04:00
context " when anon " do
2020-01-28 06:55:46 -05:00
let ( :user ) { Discourse . system_user }
it " returns success " do
get " /u/ #{ user . username } /card.json "
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
parsed = response . parsed_body [ " user " ]
2020-01-28 06:55:46 -05:00
expect ( parsed [ " username " ] ) . to eq ( user . username )
expect ( parsed [ " profile_hidden " ] ) . to be_blank
expect ( parsed [ " trust_level " ] ) . to be_present
end
it " should redirect to login page for anonymous user when profiles are hidden " do
SiteSetting . hide_user_profiles_from_public = true
get " /u/ #{ user . username } /card.json "
expect ( response ) . to redirect_to " /login "
end
end
2022-07-27 12:14:14 -04:00
context " when logged in " do
2021-12-16 14:36:49 -05:00
before { sign_in ( user1 ) }
2020-01-28 06:55:46 -05:00
it " works correctly " do
2023-05-15 14:45:26 -04:00
get " /u/ #{ user . username } /card.json "
2020-01-28 06:55:46 -05:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2020-01-28 06:55:46 -05:00
expect ( json [ " user " ] [ " associated_accounts " ] ) . to eq ( nil ) # Not serialized in card
2023-05-15 14:45:26 -04:00
expect ( json [ " user " ] [ " username " ] ) . to eq ( user . username )
2020-01-28 06:55:46 -05:00
end
it " returns not found when the username doesn't exist " do
get " /u/madeuppity/card.json "
expect ( response ) . not_to be_successful
end
2023-05-15 14:45:26 -04:00
it " returns partial response when inactive user " do
user . update! ( active : false )
get " /u/ #{ user . username } /card.json "
expect ( response ) . to be_successful
expect ( response . parsed_body [ " user " ] [ " inactive " ] ) . to eq ( true )
end
it " returns partial response when hidden users " do
user . user_option . update! ( hide_profile_and_presence : true )
get " /u/ #{ user . username } /card.json "
expect ( response ) . to be_successful
expect ( response . parsed_body [ " user " ] [ " profile_hidden " ] ) . to eq ( true )
end
2020-01-28 06:55:46 -05:00
it " raises an error on invalid access " do
2023-05-15 14:45:26 -04:00
Guardian . any_instance . expects ( :can_see? ) . with ( user ) . returns ( false )
get " /u/ #{ user . username } /card.json "
2020-01-28 06:55:46 -05:00
expect ( response ) . to be_forbidden
end
end
end
2020-03-06 07:23:22 -05:00
describe " # cards " do
fab! ( :user ) { Discourse . system_user }
fab! ( :user2 ) { Fabricate ( :user ) }
it " returns success " do
get " /user-cards.json?user_ids= #{ user . id } , #{ user2 . id } "
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
parsed = response . parsed_body [ " users " ]
2020-03-06 07:23:22 -05:00
expect ( parsed . map { | u | u [ " username " ] } ) . to contain_exactly ( user . username , user2 . username )
end
it " should redirect to login page for anonymous user when profiles are hidden " do
SiteSetting . hide_user_profiles_from_public = true
get " /user-cards.json?user_ids= #{ user . id } , #{ user2 . id } "
expect ( response ) . to redirect_to " /login "
end
2022-07-27 12:14:14 -04:00
context " when `hide_profile_and_presence` user option is checked " do
2020-10-09 17:18:44 -04:00
before { user2 . user_option . update_columns ( hide_profile_and_presence : true ) }
it " does not include hidden profiles " do
get " /user-cards.json?user_ids= #{ user . id } , #{ user2 . id } "
expect ( response . status ) . to eq ( 200 )
parsed = response . parsed_body [ " users " ]
2020-03-06 07:23:22 -05:00
2020-10-09 17:18:44 -04:00
expect ( parsed . map { | u | u [ " username " ] } ) . to contain_exactly ( user . username )
end
it " does include hidden profiles when `allow_users_to_hide_profile` is false " do
SiteSetting . allow_users_to_hide_profile = false
get " /user-cards.json?user_ids= #{ user . id } , #{ user2 . id } "
expect ( response . status ) . to eq ( 200 )
parsed = response . parsed_body [ " users " ]
expect ( parsed . map { | u | u [ " username " ] } ) . to contain_exactly ( user . username , user2 . username )
end
2020-03-06 07:23:22 -05:00
end
end
2018-05-24 22:04:25 -04:00
describe " # badges " do
2017-11-21 12:22:24 -05:00
it " renders fine by default " do
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } /badges "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2017-11-21 12:22:24 -05:00
end
it " fails if badges are disabled " do
SiteSetting . enable_badges = false
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } /badges "
2017-11-23 20:32:44 -05:00
expect ( response . status ) . to eq ( 404 )
2017-11-21 12:22:24 -05:00
end
end
2018-05-27 23:20:47 -04:00
describe " # account_created " do
2017-08-31 00:06:56 -04:00
it " returns a message when no session is present " do
get " /u/account-created "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2017-08-31 00:06:56 -04:00
body = response . body
expect ( body ) . to match ( I18n . t ( " activation.missing_session " ) )
end
it " redirects when the user is logged in " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2021-12-07 13:45:58 -05:00
2017-08-31 00:06:56 -04:00
get " /u/account-created "
expect ( response ) . to redirect_to ( " / " )
end
2018-09-04 15:16:54 -04:00
context " when cookies contains a destination URL " do
it " should redirect to the URL " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2021-12-07 13:45:58 -05:00
2018-09-04 15:16:54 -04:00
destination_url = " http://thisisasite.com/somepath "
cookies [ :destination_url ] = destination_url
get " /u/account-created "
expect ( response ) . to redirect_to ( destination_url )
end
end
2017-08-31 00:06:56 -04:00
context " when the user account is created " do
include ApplicationHelper
it " returns the message when set in the session " do
2021-12-16 14:36:49 -05:00
user1 = create_user
2017-08-31 00:06:56 -04:00
get " /u/account-created "
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2017-08-31 00:06:56 -04:00
2018-09-28 05:28:33 -04:00
expect ( response . body ) . to have_tag ( " div # data-preloaded " ) do | element |
2018-09-17 04:31:46 -04:00
json = JSON . parse ( element . current_scope . attribute ( " data-preloaded " ) . value )
expect ( json [ " accountCreated " ] ) . to include (
2021-12-16 14:36:49 -05:00
" { \" message \" : \" #{ I18n . t ( " login.activate_email " , email : user1 . email ) . gsub! ( " </ " , " < \\ / " ) } \" , \" show_controls \" :true, \" username \" : \" #{ user1 . username } \" , \" email \" : \" #{ user1 . email } \" } " ,
2018-09-17 04:31:46 -04:00
)
end
2017-08-31 00:06:56 -04:00
end
end
end
2017-10-02 05:45:58 -04:00
2018-05-24 22:04:25 -04:00
describe " # search_users " do
2019-05-06 23:12:20 -04:00
fab! ( :topic ) { Fabricate :topic }
2017-10-02 05:45:58 -04:00
let ( :user ) { Fabricate :user , username : " joecabot " , name : " Lawrence Tierney " }
let ( :post1 ) { Fabricate ( :post , user : user , topic : topic ) }
2021-05-31 12:02:32 -04:00
let ( :staged_user ) { Fabricate ( :user , staged : true ) }
2017-10-02 05:45:58 -04:00
before do
SearchIndexer . enable
post1
end
it " searches when provided the term only " do
get " /u/search/users.json " , params : { term : user . name . split ( " " ) . last }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2017-10-02 05:45:58 -04:00
expect ( json [ " users " ] . map { | u | u [ " username " ] } ) . to include ( user . username )
end
it " searches when provided the topic only " do
get " /u/search/users.json " , params : { topic_id : topic . id }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2017-10-02 05:45:58 -04:00
expect ( json [ " users " ] . map { | u | u [ " username " ] } ) . to include ( user . username )
end
it " searches when provided the term and topic " do
get " /u/search/users.json " , params : { term : user . name . split ( " " ) . last , topic_id : topic . id }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2017-10-02 05:45:58 -04:00
expect ( json [ " users " ] . map { | u | u [ " username " ] } ) . to include ( user . username )
end
it " searches only for users who have access to private topic " do
2019-10-28 08:32:56 -04:00
searching_user = Fabricate ( :user )
2017-10-02 05:45:58 -04:00
privileged_user =
Fabricate ( :user , trust_level : 4 , username : " joecabit " , name : " Lawrence Tierney " )
privileged_group = Fabricate ( :group )
2019-10-28 08:32:56 -04:00
privileged_group . add ( searching_user )
2017-10-02 05:45:58 -04:00
privileged_group . add ( privileged_user )
privileged_group . save
category = Fabricate ( :category )
category . set_permissions ( privileged_group = > :readonly )
category . save
private_topic = Fabricate ( :topic , category : category )
2019-10-28 08:32:56 -04:00
sign_in ( searching_user )
2017-10-02 05:45:58 -04:00
get " /u/search/users.json " ,
params : {
term : user . name . split ( " " ) . last ,
topic_id : private_topic . id ,
topic_allowed_users : " true " ,
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2017-10-02 05:45:58 -04:00
expect ( json [ " users " ] . map { | u | u [ " username " ] } ) . to_not include ( user . username )
expect ( json [ " users " ] . map { | u | u [ " username " ] } ) . to include ( privileged_user . username )
end
2019-10-28 09:18:47 -04:00
it " interprets blank category id correctly " do
pm_topic = Fabricate ( :private_message_post ) . topic
sign_in ( pm_topic . user )
get " /u/search/users.json " , params : { term : " " , topic_id : pm_topic . id , category_id : " " }
expect ( response . status ) . to eq ( 200 )
end
2022-07-27 12:14:14 -04:00
context " with limit " do
2021-08-24 03:45:26 -04:00
it " returns an error if value is invalid " do
get " /u/search/users.json " , params : { limit : " -1 " }
expect ( response . status ) . to eq ( 400 )
end
end
2017-10-02 05:45:58 -04:00
context " when `enable_names` is true " do
before { SiteSetting . enable_names = true }
it " returns names " do
get " /u/search/users.json " , params : { term : user . name }
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2017-10-02 05:45:58 -04:00
expect ( json [ " users " ] . map { | u | u [ " name " ] } ) . to include ( user . name )
end
end
context " when `enable_names` is false " do
before { SiteSetting . enable_names = false }
it " returns names " do
get " /u/search/users.json " , params : { term : user . name }
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2017-10-02 05:45:58 -04:00
expect ( json [ " users " ] . map { | u | u [ " name " ] } ) . not_to include ( user . name )
end
end
2022-07-27 12:14:14 -04:00
context " with groups " do
2021-12-16 14:36:49 -05:00
fab! ( :mentionable_group ) do
2017-11-03 09:39:55 -04:00
Fabricate (
:group ,
2019-12-12 06:13:40 -05:00
mentionable_level : Group :: ALIAS_LEVELS [ :everyone ] ,
messageable_level : Group :: ALIAS_LEVELS [ :nobody ] ,
visibility_level : Group . visibility_levels [ :public ] ,
2022-03-03 00:57:52 -05:00
name : " aaa1bbb " ,
2017-11-03 09:39:55 -04:00
)
end
2021-12-16 14:36:49 -05:00
fab! ( :mentionable_group_2 ) do
2017-11-03 09:39:55 -04:00
Fabricate (
:group ,
2019-12-12 06:13:40 -05:00
mentionable_level : Group :: ALIAS_LEVELS [ :everyone ] ,
messageable_level : Group :: ALIAS_LEVELS [ :nobody ] ,
visibility_level : Group . visibility_levels [ :logged_on_users ] ,
2022-03-03 00:57:52 -05:00
name : " bbb1aaa " ,
2017-11-03 09:39:55 -04:00
)
end
2021-12-16 14:36:49 -05:00
fab! ( :messageable_group ) do
2017-11-03 09:39:55 -04:00
Fabricate (
:group ,
2019-12-12 06:13:40 -05:00
mentionable_level : Group :: ALIAS_LEVELS [ :nobody ] ,
messageable_level : Group :: ALIAS_LEVELS [ :everyone ] ,
visibility_level : Group . visibility_levels [ :logged_on_users ] ,
2022-03-03 00:57:52 -05:00
name : " ccc1aaa " ,
2017-11-03 09:39:55 -04:00
)
end
2017-10-02 05:45:58 -04:00
2021-12-16 14:36:49 -05:00
fab! ( :private_group ) do
2020-02-12 03:11:10 -05:00
Fabricate (
:group ,
mentionable_level : Group :: ALIAS_LEVELS [ :members_mods_and_admins ] ,
messageable_level : Group :: ALIAS_LEVELS [ :members_mods_and_admins ] ,
visibility_level : Group . visibility_levels [ :members ] ,
2022-03-03 00:57:52 -05:00
name : " ddd1aaa " ,
2020-02-12 03:11:10 -05:00
)
end
2017-10-02 05:45:58 -04:00
describe " when signed in " do
before { sign_in ( user ) }
2022-03-03 00:57:52 -05:00
it " correctly sorts on prefix " do
get " /u/search/users.json " , params : { include_groups : " true " , term : " bbb " }
expect ( response . status ) . to eq ( 200 )
groups = response . parsed_body [ " groups " ]
expect ( groups . map { | g | g [ " name " ] } ) . to eq ( %w[ bbb1aaa aaa1bbb ] )
end
2019-02-20 01:28:12 -05:00
it " does not search for groups if there is no term " do
2017-11-03 09:39:55 -04:00
get " /u/search/users.json " , params : { include_groups : " true " }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2017-11-03 09:39:55 -04:00
2020-05-07 11:04:12 -04:00
groups = response . parsed_body [ " groups " ]
2019-02-20 01:28:12 -05:00
expect ( groups ) . to eq ( nil )
end
it " only returns visible groups " do
get " /u/search/users.json " , params : { include_groups : " true " , term : " a " }
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
groups = response . parsed_body [ " groups " ]
2017-11-03 09:39:55 -04:00
expect ( groups . map { | group | group [ " name " ] } ) . to_not include ( private_group . name )
end
2021-09-07 19:38:45 -04:00
it " allows plugins to register custom groups filter " do
get " /u/search/users.json " , params : { include_groups : " true " , term : " a " }
expect ( response . status ) . to eq ( 200 )
groups = response . parsed_body [ " groups " ]
expect ( groups . count ) . to eq ( 6 )
plugin = Plugin :: Instance . new
plugin . register_groups_callback_for_users_search_controller_action (
:admins_filter ,
) { | original_groups , user | original_groups . where ( name : " admins " ) }
get " /u/search/users.json " ,
params : {
include_groups : " true " ,
admins_filter : " true " ,
term : " a " ,
}
expect ( response . status ) . to eq ( 200 )
groups = response . parsed_body [ " groups " ]
expect ( groups ) . to eq ( [ { " name " = > " admins " , " full_name " = > nil } ] )
DiscoursePluginRegistry . reset!
end
2017-10-03 06:49:45 -04:00
it " doesn't search for groups " do
get " /u/search/users.json " ,
params : {
include_mentionable_groups : " false " ,
2019-02-20 01:28:12 -05:00
include_messageable_groups : " false " ,
term : " a " ,
2017-10-03 06:49:45 -04:00
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body ) . not_to have_key ( :groups )
2017-10-03 06:49:45 -04:00
end
2017-10-02 05:45:58 -04:00
it " searches for messageable groups " do
get " /u/search/users.json " ,
params : {
include_mentionable_groups : " false " ,
2019-02-20 01:28:12 -05:00
include_messageable_groups : " true " ,
term : " a " ,
2017-10-02 05:45:58 -04:00
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2018-01-03 01:42:16 -05:00
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " groups " ] . map { | group | group [ " name " ] } ) . to contain_exactly (
2018-01-03 01:42:16 -05:00
messageable_group . name ,
Group . find ( Group :: AUTO_GROUPS [ :moderators ] ) . name ,
)
2017-10-02 05:45:58 -04:00
end
it " searches for mentionable groups " do
get " /u/search/users.json " ,
params : {
include_messageable_groups : " false " ,
2019-02-20 01:28:12 -05:00
include_mentionable_groups : " true " ,
term : " a " ,
2017-10-02 05:45:58 -04:00
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2017-11-03 09:39:55 -04:00
2020-05-07 11:04:12 -04:00
groups = response . parsed_body [ " groups " ]
2017-11-03 09:39:55 -04:00
expect ( groups . map { | group | group [ " name " ] } ) . to contain_exactly (
2017-11-04 09:30:17 -04:00
mentionable_group . name ,
mentionable_group_2 . name ,
)
2017-10-02 05:45:58 -04:00
end
end
describe " when not signed in " do
it " should not include mentionable/messageable groups " do
2017-10-03 06:49:45 -04:00
get " /u/search/users.json " ,
params : {
include_mentionable_groups : " false " ,
2019-02-20 01:28:12 -05:00
include_messageable_groups : " false " ,
term : " a " ,
2017-10-03 06:49:45 -04:00
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body ) . not_to have_key ( :groups )
2017-10-03 07:02:04 -04:00
2017-10-02 05:45:58 -04:00
get " /u/search/users.json " ,
params : {
include_mentionable_groups : " false " ,
2019-02-20 01:28:12 -05:00
include_messageable_groups : " true " ,
term : " a " ,
2017-10-02 05:45:58 -04:00
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body ) . not_to have_key ( :groups )
2017-10-02 05:45:58 -04:00
get " /u/search/users.json " ,
params : {
include_messageable_groups : " false " ,
2019-02-20 01:28:12 -05:00
include_mentionable_groups : " true " ,
term : " a " ,
2017-10-02 05:45:58 -04:00
}
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body ) . not_to have_key ( :groups )
2017-10-02 05:45:58 -04:00
end
end
2019-05-10 11:35:36 -04:00
describe " when searching by group name " do
fab! ( :exclusive_group ) { Fabricate ( :group ) }
it " return results if the user is a group member " do
exclusive_group . add ( user )
get " /u/search/users.json " , params : { group : exclusive_group . name , term : user . username }
expect ( users_found ) . to contain_exactly ( user . username )
end
it " does not return results if the user is not a group member " do
get " /u/search/users.json " , params : { group : exclusive_group . name , term : user . username }
expect ( users_found ) . to be_empty
end
it " returns results if the user is member of one of the groups " do
exclusive_group . add ( user )
get " /u/search/users.json " ,
params : {
groups : [ exclusive_group . name ] ,
term : user . username ,
}
expect ( users_found ) . to contain_exactly ( user . username )
end
it " does not return results if the user is not a member of the groups " do
get " /u/search/users.json " ,
params : {
groups : [ exclusive_group . name ] ,
term : user . username ,
}
expect ( users_found ) . to be_empty
end
def users_found
2020-05-07 11:04:12 -04:00
response . parsed_body [ " users " ] . map { | u | u [ " username " ] }
2019-05-10 11:35:36 -04:00
end
end
2017-10-02 05:45:58 -04:00
end
2021-05-31 12:02:32 -04:00
2022-07-27 12:14:14 -04:00
context " with `include_staged_users` " do
2021-05-31 12:02:32 -04:00
it " includes staged users when the param is true " do
get " /u/search/users.json " , params : { term : staged_user . name , include_staged_users : true }
json = response . parsed_body
expect ( json [ " users " ] . map { | u | u [ " name " ] } ) . to include ( staged_user . name )
end
it " doesn't include staged users when the param is not passed " do
get " /u/search/users.json " , params : { term : staged_user . name }
json = response . parsed_body
expect ( json [ " users " ] . map { | u | u [ " name " ] } ) . not_to include ( staged_user . name )
end
it " doesn't include staged users when the param explicitly set to false " do
get " /u/search/users.json " , params : { term : staged_user . name , include_staged_users : false }
json = response . parsed_body
expect ( json [ " users " ] . map { | u | u [ " name " ] } ) . not_to include ( staged_user . name )
end
end
2021-07-21 09:14:53 -04:00
2022-07-27 12:14:14 -04:00
context " with `last_seen_users` " do
2021-07-21 09:14:53 -04:00
it " returns results when the param is true " do
get " /u/search/users.json " , params : { last_seen_users : true }
json = response . parsed_body
expect ( json [ " users " ] ) . not_to be_empty
end
it " respects limit parameter at the same time " do
limit = 3
get " /u/search/users.json " , params : { last_seen_users : true , limit : limit }
json = response . parsed_body
expect ( json [ " users " ] ) . not_to be_empty
expect ( json [ " users " ] . size ) . to eq ( limit )
end
end
2022-08-09 06:54:33 -04:00
it " returns avatar_template " do
get " /u/search/users.json " , params : { term : user . username }
expect ( response . status ) . to eq ( 200 )
json = response . parsed_body
expect ( json [ " users " ] [ 0 ] ) . to have_key ( " avatar_template " )
expect ( json [ " users " ] [ 0 ] [ " avatar_template " ] ) . to eq (
" /letter_avatar_proxy/v4/letter/j/f475e1/{size}.png " ,
)
end
describe " # status " do
it " returns user status if enabled in site settings " do
SiteSetting . enable_user_status = true
emoji = " tooth "
description = " off to dentist "
user . set_status! ( description , emoji )
get " /u/search/users.json " , params : { term : user . name }
expect ( response . status ) . to eq ( 200 )
json = response . parsed_body
expect ( json [ " users " ] [ 0 ] ) . to have_key ( " status " )
expect ( json [ " users " ] [ 0 ] [ " status " ] [ " description " ] ) . to eq ( description )
expect ( json [ " users " ] [ 0 ] [ " status " ] [ " emoji " ] ) . to eq ( emoji )
end
it " doesn't return user status if disabled in site settings " do
SiteSetting . enable_user_status = false
user . set_status! ( " off to dentist " , " tooth " )
get " /u/search/users.json " , params : { term : user . name }
expect ( response . status ) . to eq ( 200 )
json = response . parsed_body
expect ( json [ " users " ] [ 0 ] ) . not_to have_key ( " status " )
end
end
2017-10-02 05:45:58 -04:00
end
2018-01-11 22:15:10 -05:00
2017-04-20 11:17:24 -04:00
describe " # email_login " do
before { SiteSetting . enable_local_logins_via_email = true }
it " enqueues the right email " do
2021-12-16 14:36:49 -05:00
post " /u/email-login.json " , params : { login : user1 . email }
2017-04-20 11:17:24 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " user_found " ] ) . to eq ( true )
2017-04-20 11:17:24 -04:00
job_args = Jobs :: CriticalUserEmail . jobs . last [ " args " ] . first
2021-12-16 14:36:49 -05:00
expect ( job_args [ " user_id " ] ) . to eq ( user1 . id )
2017-04-20 11:17:24 -04:00
expect ( job_args [ " type " ] ) . to eq ( " email_login " )
2021-12-16 14:36:49 -05:00
expect ( EmailToken . hash_token ( job_args [ " email_token " ] ) ) . to eq (
user1 . email_tokens . last . token_hash ,
)
2017-04-20 11:17:24 -04:00
end
describe " when enable_local_logins_via_email is disabled " do
before { SiteSetting . enable_local_logins_via_email = false }
it " should return the right response " do
2021-12-16 14:36:49 -05:00
post " /u/email-login.json " , params : { login : user1 . email }
2017-04-20 11:17:24 -04:00
expect ( response . status ) . to eq ( 404 )
end
end
describe " when username or email is not valid " do
it " should not enqueue the email to login " do
post " /u/email-login.json " , params : { login : " @random " }
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2020-03-09 12:53:32 -04:00
expect ( json [ " user_found " ] ) . to eq ( false )
expect ( json [ " hide_taken " ] ) . to eq ( false )
2017-04-20 11:17:24 -04:00
expect ( Jobs :: CriticalUserEmail . jobs ) . to eq ( [ ] )
end
end
describe " when hide_email_address_taken is true " do
it " should return the right response " do
SiteSetting . hide_email_address_taken = true
2021-12-16 14:36:49 -05:00
post " /u/email-login.json " , params : { login : user1 . email }
2017-04-20 11:17:24 -04:00
2018-06-07 04:11:09 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
json = response . parsed_body
2020-03-09 12:53:32 -04:00
expect ( json . has_key? ( " user_found " ) ) . to eq ( false )
expect ( json [ " hide_taken " ] ) . to eq ( true )
2017-04-20 11:17:24 -04:00
end
end
describe " when user is already logged in " do
it " should redirect to the root path " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
post " /u/email-login.json " , params : { login : user1 . email }
2017-04-20 11:17:24 -04:00
expect ( response ) . to redirect_to ( " / " )
end
end
end
2018-02-20 01:44:51 -05:00
2019-06-26 19:58:06 -04:00
describe " # create_second_factor_totp " do
2018-02-20 01:44:51 -05:00
context " when not logged in " do
it " should return the right response " do
post " /users/second_factors.json " , params : { password : " wrongpassword " }
expect ( response . status ) . to eq ( 403 )
end
end
context " when logged in " do
2021-12-16 14:36:49 -05:00
before { sign_in ( user1 ) }
2023-01-09 06:18:21 -05:00
2018-02-20 01:44:51 -05:00
describe " create 2fa request " do
it " fails on incorrect password " do
2021-12-16 14:36:49 -05:00
ApplicationController
. any_instance
. expects ( :secure_session )
. returns ( " confirmed-password- #{ user1 . id } " = > " false " )
2019-06-26 19:58:06 -04:00
post " /users/create_second_factor_totp.json "
2018-02-20 01:44:51 -05:00
2019-06-26 19:58:06 -04:00
expect ( response . status ) . to eq ( 403 )
2018-02-20 01:44:51 -05:00
end
2018-03-01 21:37:13 -05:00
describe " when local logins are disabled " do
it " should return the right response " do
SiteSetting . enable_local_logins = false
2019-06-26 19:58:06 -04:00
post " /users/create_second_factor_totp.json "
2018-03-01 21:37:13 -05:00
expect ( response . status ) . to eq ( 404 )
end
end
describe " when SSO is enabled " do
it " should return the right response " do
2021-02-08 05:04:33 -05:00
SiteSetting . discourse_connect_url = " http://someurl.com "
SiteSetting . enable_discourse_connect = true
2018-03-01 21:37:13 -05:00
2019-06-26 19:58:06 -04:00
post " /users/create_second_factor_totp.json "
2018-03-01 21:37:13 -05:00
expect ( response . status ) . to eq ( 404 )
end
end
2018-02-20 01:44:51 -05:00
it " succeeds on correct password " do
2021-12-16 14:36:49 -05:00
ApplicationController
. any_instance
. stubs ( :secure_session )
. returns ( " confirmed-password- #{ user1 . id } " = > " true " )
2019-06-26 19:58:06 -04:00
post " /users/create_second_factor_totp.json "
2018-02-20 01:44:51 -05:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
response_body = response . parsed_body
2018-02-20 01:44:51 -05:00
2019-06-26 19:58:06 -04:00
expect ( response_body [ " key " ] ) . to be_present
2018-02-20 01:44:51 -05:00
expect ( response_body [ " qr " ] ) . to be_present
end
end
end
end
2020-03-05 23:37:40 -05:00
describe " # enable_second_factor_totp " do
2021-12-16 14:36:49 -05:00
before { sign_in ( user1 ) }
2020-03-05 23:37:40 -05:00
def create_totp
stub_secure_session_confirmed
post " /users/create_second_factor_totp.json "
end
it " creates a totp for the user successfully " do
create_totp
2021-12-16 14:36:49 -05:00
staged_totp_key = read_secure_session [ " staged-totp- #{ user1 . id } " ]
2020-03-05 23:37:40 -05:00
token = ROTP :: TOTP . new ( staged_totp_key ) . now
post " /users/enable_second_factor_totp.json " ,
params : {
name : " test " ,
second_factor_token : token ,
}
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . user_second_factors . count ) . to eq ( 1 )
2020-03-05 23:37:40 -05:00
end
2021-02-03 18:03:30 -05:00
it " rate limits by IP address " do
RateLimiter . enable
RateLimiter . clear_all!
create_totp
2021-12-16 14:36:49 -05:00
staged_totp_key = read_secure_session [ " staged-totp- #{ user1 . id } " ]
2021-02-03 18:03:30 -05:00
token = ROTP :: TOTP . new ( staged_totp_key ) . now
7 . times do | x |
post " /users/enable_second_factor_totp.json " ,
params : {
name : " test " ,
second_factor_token : token ,
}
end
expect ( response . status ) . to eq ( 429 )
end
it " rate limits by username " do
RateLimiter . enable
RateLimiter . clear_all!
create_totp
2021-12-16 14:36:49 -05:00
staged_totp_key = read_secure_session [ " staged-totp- #{ user1 . id } " ]
2021-02-03 18:03:30 -05:00
token = ROTP :: TOTP . new ( staged_totp_key ) . now
7 . times do | x |
post " /users/enable_second_factor_totp.json " ,
params : {
name : " test " ,
second_factor_token : token ,
} ,
env : {
REMOTE_ADDR : " 1.2.3. #{ x } " ,
}
end
expect ( response . status ) . to eq ( 429 )
end
2020-03-05 23:37:40 -05:00
context " when an incorrect token is provided " do
before do
create_totp
post " /users/enable_second_factor_totp.json " ,
params : {
name : " test " ,
second_factor_token : " 123456 " ,
}
end
it " shows a helpful error message to the user " do
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " error " ] ) . to eq ( I18n . t ( " login.invalid_second_factor_code " ) )
2020-03-05 23:37:40 -05:00
end
end
context " when a name is not provided " do
before do
create_totp
post " /users/enable_second_factor_totp.json " , params : { second_factor_token : " 123456 " }
end
it " shows a helpful error message to the user " do
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " error " ] ) . to eq ( I18n . t ( " login.missing_second_factor_name " ) )
2020-03-05 23:37:40 -05:00
end
end
context " when a token is not provided " do
before do
create_totp
post " /users/enable_second_factor_totp.json " , params : { name : " test " }
end
it " shows a helpful error message to the user " do
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " error " ] ) . to eq ( I18n . t ( " login.missing_second_factor_code " ) )
2020-03-05 23:37:40 -05:00
end
end
end
2018-02-20 01:44:51 -05:00
describe " # update_second_factor " do
2021-12-16 14:36:49 -05:00
fab! ( :user_second_factor ) { Fabricate ( :user_second_factor_totp , user : user1 ) }
2018-02-20 01:44:51 -05:00
context " when not logged in " do
it " should return the right response " do
2019-06-26 19:58:06 -04:00
put " /users/second_factor.json "
2018-02-20 01:44:51 -05:00
expect ( response . status ) . to eq ( 403 )
end
end
context " when logged in " do
2021-12-16 14:36:49 -05:00
before { sign_in ( user1 ) }
2023-01-09 06:18:21 -05:00
2018-02-20 01:44:51 -05:00
context " when user has totp setup " do
context " when token is missing " do
it " returns the right response " do
put " /users/second_factor.json " ,
params : {
2019-06-26 19:58:06 -04:00
disable : " true " ,
2019-02-27 04:37:33 -05:00
second_factor_target : UserSecondFactor . methods [ :totp ] ,
2019-06-26 19:58:06 -04:00
id : user_second_factor . id ,
2018-02-20 01:44:51 -05:00
}
2019-06-26 19:58:06 -04:00
expect ( response . status ) . to eq ( 403 )
2018-02-20 01:44:51 -05:00
end
end
context " when token is valid " do
2020-03-05 23:37:40 -05:00
before { stub_secure_session_confirmed }
2019-06-26 19:58:06 -04:00
it " should allow second factor for the user to be renamed " do
2018-02-20 01:44:51 -05:00
put " /users/second_factor.json " ,
params : {
2019-06-26 19:58:06 -04:00
name : " renamed " ,
second_factor_target : UserSecondFactor . methods [ :totp ] ,
id : user_second_factor . id ,
}
2018-02-20 01:44:51 -05:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . user_second_factors . totps . first . name ) . to eq ( " renamed " )
2018-02-20 01:44:51 -05:00
end
it " should allow second factor for the user to be disabled " do
put " /users/second_factor.json " ,
params : {
2019-06-26 19:58:06 -04:00
disable : " true " ,
second_factor_target : UserSecondFactor . methods [ :totp ] ,
id : user_second_factor . id ,
2018-06-28 04:12:32 -04:00
}
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . user_second_factors . totps . first ) . to eq ( nil )
2018-06-28 04:12:32 -04:00
end
end
end
context " when user is updating backup codes " do
context " when token is missing " do
it " returns the right response " do
put " /users/second_factor.json " ,
params : {
2019-02-27 04:37:33 -05:00
second_factor_target : UserSecondFactor . methods [ :backup_codes ] ,
2018-06-28 04:12:32 -04:00
}
2019-06-26 19:58:06 -04:00
expect ( response . status ) . to eq ( 403 )
2018-06-28 04:12:32 -04:00
end
end
context " when token is valid " do
2019-06-26 19:58:06 -04:00
before do
2021-12-16 14:36:49 -05:00
ApplicationController
. any_instance
. stubs ( :secure_session )
. returns ( " confirmed-password- #{ user1 . id } " = > " true " )
2019-06-26 19:58:06 -04:00
end
2018-06-28 04:12:32 -04:00
it " should allow second factor backup for the user to be disabled " do
put " /users/second_factor.json " ,
params : {
2019-06-26 19:58:06 -04:00
second_factor_target : UserSecondFactor . methods [ :backup_codes ] ,
disable : " true " ,
2018-02-20 01:44:51 -05:00
}
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . user_second_factors . backup_codes ) . to be_empty
2018-06-28 04:12:32 -04:00
end
end
end
end
end
describe " # create_second_factor_backup " do
2021-12-16 14:36:49 -05:00
fab! ( :user_second_factor ) { Fabricate ( :user_second_factor_totp , user : user1 ) }
2018-06-28 04:12:32 -04:00
context " when not logged in " do
it " should return the right response " do
put " /users/second_factors_backup.json " ,
params : {
2019-02-27 04:37:33 -05:00
second_factor_token : " wrongtoken " ,
second_factor_method : UserSecondFactor . methods [ :totp ] ,
2018-06-28 04:12:32 -04:00
}
expect ( response . status ) . to eq ( 403 )
end
end
context " when logged in " do
2021-12-16 14:36:49 -05:00
before { sign_in ( user1 ) }
2023-01-09 06:18:21 -05:00
2018-06-28 04:12:32 -04:00
describe " create 2fa request " do
it " fails on incorrect password " do
2021-12-16 14:36:49 -05:00
ApplicationController
. any_instance
. expects ( :secure_session )
. returns ( " confirmed-password- #{ user1 . id } " = > " false " )
2019-06-26 19:58:06 -04:00
put " /users/second_factors_backup.json "
2018-06-28 04:12:32 -04:00
2019-06-26 19:58:06 -04:00
expect ( response . status ) . to eq ( 403 )
2018-06-28 04:12:32 -04:00
end
describe " when local logins are disabled " do
it " should return the right response " do
SiteSetting . enable_local_logins = false
2019-06-26 19:58:06 -04:00
put " /users/second_factors_backup.json "
2018-06-28 04:12:32 -04:00
expect ( response . status ) . to eq ( 404 )
end
end
describe " when SSO is enabled " do
it " should return the right response " do
2021-02-08 05:04:33 -05:00
SiteSetting . discourse_connect_url = " http://someurl.com "
SiteSetting . enable_discourse_connect = true
2018-06-28 04:12:32 -04:00
2019-06-26 19:58:06 -04:00
put " /users/second_factors_backup.json "
2018-06-28 04:12:32 -04:00
expect ( response . status ) . to eq ( 404 )
2018-02-20 01:44:51 -05:00
end
end
2018-06-28 04:12:32 -04:00
it " succeeds on correct password " do
2021-12-16 14:36:49 -05:00
ApplicationController
. any_instance
. expects ( :secure_session )
. returns ( " confirmed-password- #{ user1 . id } " = > " true " )
2018-06-28 04:12:32 -04:00
2019-06-26 19:58:06 -04:00
put " /users/second_factors_backup.json "
2018-06-28 04:12:32 -04:00
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
response_body = response . parsed_body
2018-06-28 04:12:32 -04:00
2020-01-20 23:32:06 -05:00
# we use SecureRandom.hex(16) for backup codes, ensure this continues to be the case
expect ( response_body [ " backup_codes " ] . map ( & :length ) ) . to eq ( [ 32 ] * 10 )
2018-06-28 04:12:32 -04:00
end
2018-02-20 01:44:51 -05:00
end
end
end
2018-07-23 11:51:57 -04:00
2020-01-09 19:45:56 -05:00
describe " # create_second_factor_security_key " do
it " stores the challenge in the session and returns challenge data, user id, and supported algorithms " do
create_second_factor_security_key
secure_session = read_secure_session
2020-05-07 11:04:12 -04:00
response_parsed = response . parsed_body
2020-01-09 19:45:56 -05:00
expect ( response_parsed [ " challenge " ] ) . to eq ( Webauthn . challenge ( user1 , secure_session ) )
expect ( response_parsed [ " rp_id " ] ) . to eq ( Webauthn . rp_id ( user1 , secure_session ) )
expect ( response_parsed [ " rp_name " ] ) . to eq ( Webauthn . rp_name ( user1 , secure_session ) )
expect ( response_parsed [ " user_secure_id " ] ) . to eq (
2021-12-16 14:36:49 -05:00
user1 . reload . create_or_fetch_secure_identifier ,
2020-01-09 19:45:56 -05:00
)
2020-03-08 19:22:08 -04:00
expect ( response_parsed [ " supported_algorithms " ] ) . to eq ( :: Webauthn :: SUPPORTED_ALGORITHMS )
2020-01-09 19:45:56 -05:00
end
context " if the user has security key credentials already " do
2021-12-16 14:36:49 -05:00
fab! ( :user_security_key ) { Fabricate ( :user_security_key_with_random_credential , user : user1 ) }
2020-01-09 19:45:56 -05:00
it " returns those existing active credentials " do
create_second_factor_security_key
2020-05-07 11:04:12 -04:00
response_parsed = response . parsed_body
2020-01-09 19:45:56 -05:00
expect ( response_parsed [ " existing_active_credential_ids " ] ) . to eq (
[ user_security_key . credential_id ] ,
)
end
end
end
describe " # register_second_factor_security_key " do
context " when creation parameters are valid " do
it " creates a security key for the user " do
simulate_localhost_webauthn_challenge
create_second_factor_security_key
2022-03-03 00:57:52 -05:00
_response_parsed = response . parsed_body
2020-01-09 19:45:56 -05:00
post " /u/register_second_factor_security_key.json " ,
params : valid_security_key_create_post_data
2021-12-16 14:36:49 -05:00
expect ( user1 . security_keys . count ) . to eq ( 1 )
expect ( user1 . security_keys . last . credential_id ) . to eq (
valid_security_key_create_post_data [ :rawId ] ,
)
expect ( user1 . security_keys . last . name ) . to eq ( valid_security_key_create_post_data [ :name ] )
2020-01-09 19:45:56 -05:00
end
end
context " when the creation parameters are invalid " do
it " shows a security key error and does not create a key " do
stub_as_dev_localhost
create_second_factor_security_key
2022-03-03 00:57:52 -05:00
_response_parsed = response . parsed_body
2020-01-09 19:45:56 -05:00
post " /u/register_second_factor_security_key.json " ,
params : {
id : " bad id " ,
rawId : " bad rawId " ,
type : " public-key " ,
attestation : " bad attestation " ,
clientData : Base64 . encode64 ( '{"bad": "json"}' ) ,
name : " My Bad Key " ,
}
2021-12-16 14:36:49 -05:00
expect ( user1 . security_keys . count ) . to eq ( 0 )
2020-05-07 11:04:12 -04:00
expect ( response . parsed_body [ " error " ] ) . to eq (
I18n . t ( " webauthn.validation.invalid_type_error " ) ,
)
2020-01-09 19:45:56 -05:00
end
end
end
2020-08-31 12:56:57 -04:00
describe " # disable_second_factor " do
context " when logged in with secure session " do
before do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2020-08-31 12:56:57 -04:00
stub_secure_session_confirmed
end
context " when user has a registered totp and security key " do
before do
2022-03-03 00:57:52 -05:00
_totp_second_factor = Fabricate ( :user_second_factor_totp , user : user1 )
_security_key_second_factor =
Fabricate (
:user_security_key ,
user : user1 ,
factor_type : UserSecurityKey . factor_types [ :second_factor ] ,
)
2020-08-31 12:56:57 -04:00
end
it " should disable all totp and security keys " do
2021-12-16 14:36:49 -05:00
expect_enqueued_with (
job : :critical_user_email ,
args : {
type : :account_second_factor_disabled ,
user_id : user1 . id ,
} ,
) do
2020-08-31 12:56:57 -04:00
put " /u/disable_second_factor.json "
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . reload . user_second_factors ) . to be_empty
expect ( user1 . security_keys ) . to be_empty
2020-08-31 12:56:57 -04:00
end
end
end
end
end
2018-07-23 11:51:57 -04:00
describe " # revoke_account " do
it " errors for unauthorised users " do
2021-12-16 14:36:49 -05:00
post " /u/ #{ user1 . username } /preferences/revoke-account.json " ,
params : {
2018-07-23 11:51:57 -04:00
provider_name : " facebook " ,
}
expect ( response . status ) . to eq ( 403 )
2021-12-16 14:36:49 -05:00
sign_in ( another_user )
2018-07-23 11:51:57 -04:00
2021-12-16 14:36:49 -05:00
post " /u/ #{ user1 . username } /preferences/revoke-account.json " ,
params : {
2018-07-23 11:51:57 -04:00
provider_name : " facebook " ,
}
expect ( response . status ) . to eq ( 403 )
end
context " while logged in " do
2021-12-16 14:36:49 -05:00
before { sign_in ( user1 ) }
2018-07-23 11:51:57 -04:00
it " returns an error when there is no matching account " do
2021-12-16 14:36:49 -05:00
post " /u/ #{ user1 . username } /preferences/revoke-account.json " ,
params : {
2018-07-23 11:51:57 -04:00
provider_name : " facebook " ,
}
expect ( response . status ) . to eq ( 404 )
end
2018-07-31 11:18:50 -04:00
context " with fake provider " do
let ( :authenticator ) do
Class
. new ( Auth :: Authenticator ) do
attr_accessor :can_revoke
def name
" testprovider "
end
2018-07-23 11:51:57 -04:00
2018-07-31 11:18:50 -04:00
def enabled?
true
end
def description_for_user ( user )
" an account "
end
def can_revoke?
can_revoke
end
def revoke ( user , skip_remote : false )
true
2023-01-09 06:18:21 -05:00
end
2018-07-31 11:18:50 -04:00
end
. new
end
before do
DiscoursePluginRegistry . register_auth_provider (
Auth :: AuthProvider . new ( authenticator : authenticator ) ,
)
end
after { DiscoursePluginRegistry . reset! }
it " returns an error when revoking is not allowed " do
authenticator . can_revoke = false
2021-12-16 14:36:49 -05:00
post " /u/ #{ user1 . username } /preferences/revoke-account.json " ,
params : {
2018-07-31 11:18:50 -04:00
provider_name : " testprovider " ,
}
expect ( response . status ) . to eq ( 404 )
authenticator . can_revoke = true
2021-12-16 14:36:49 -05:00
post " /u/ #{ user1 . username } /preferences/revoke-account.json " ,
params : {
2018-07-31 11:18:50 -04:00
provider_name : " testprovider " ,
}
expect ( response . status ) . to eq ( 200 )
end
it " works " do
authenticator . can_revoke = true
2021-12-16 14:36:49 -05:00
post " /u/ #{ user1 . username } /preferences/revoke-account.json " ,
params : {
2018-07-31 11:18:50 -04:00
provider_name : " testprovider " ,
}
expect ( response . status ) . to eq ( 200 )
end
2018-07-23 11:51:57 -04:00
end
end
end
2018-09-02 03:24:54 -04:00
describe " # revoke_auth_token " do
context " while logged in " do
2021-12-16 14:36:49 -05:00
before { 2 . times { sign_in ( user1 ) } }
2018-09-02 03:24:54 -04:00
it " logs user out " do
2021-12-16 14:36:49 -05:00
ids = user1 . user_auth_tokens . order ( :created_at ) . pluck ( :id )
2018-10-14 23:42:45 -04:00
2021-12-16 14:36:49 -05:00
post " /u/ #{ user1 . username } /preferences/revoke-auth-token.json " , params : { token_id : ids [ 0 ] }
2018-10-09 10:21:41 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
user1 . user_auth_tokens . reload
expect ( user1 . user_auth_tokens . count ) . to eq ( 1 )
expect ( user1 . user_auth_tokens . first . id ) . to eq ( ids [ 1 ] )
2018-10-09 10:21:41 -04:00
end
2020-03-07 08:04:12 -05:00
it " checks if token exists " do
2021-12-16 14:36:49 -05:00
ids = user1 . user_auth_tokens . order ( :created_at ) . pluck ( :id )
2020-03-07 08:04:12 -05:00
2021-12-16 14:36:49 -05:00
post " /u/ #{ user1 . username } /preferences/revoke-auth-token.json " , params : { token_id : ids [ 0 ] }
2020-03-07 08:04:12 -05:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
post " /u/ #{ user1 . username } /preferences/revoke-auth-token.json " , params : { token_id : ids [ 0 ] }
2020-03-07 08:04:12 -05:00
expect ( response . status ) . to eq ( 400 )
end
2018-10-11 19:40:48 -04:00
it " does not let user log out of current session " do
2021-12-16 14:36:49 -05:00
token = UserAuthToken . generate! ( user_id : user1 . id )
FEATURE: Apply rate limits per user instead of IP for trusted users (#14706)
Currently, Discourse rate limits all incoming requests by the IP address they
originate from regardless of the user making the request. This can be
frustrating if there are multiple users using Discourse simultaneously while
sharing the same IP address (e.g. employees in an office).
This commit implements a new feature to make Discourse apply rate limits by
user id rather than IP address for users at or higher than the configured trust
level (1 is the default).
For example, let's say a Discourse instance is configured to allow 200 requests
per minute per IP address, and we have 10 users at trust level 4 using
Discourse simultaneously from the same IP address. Before this feature, the 10
users could only make a total of 200 requests per minute before they got rate
limited. But with the new feature, each user is allowed to make 200 requests
per minute because the rate limits are applied on user id rather than the IP
address.
The minimum trust level for applying user-id-based rate limits can be
configured by the `skip_per_ip_rate_limit_trust_level` global setting. The
default is 1, but it can be changed by either adding the
`DISCOURSE_SKIP_PER_IP_RATE_LIMIT_TRUST_LEVEL` environment variable with the
desired value to your `app.yml`, or changing the setting's value in the
`discourse.conf` file.
Requests made with API keys are still rate limited by IP address and the
relevant global settings that control API keys rate limits.
Before this commit, Discourse's auth cookie (`_t`) was simply a 32 characters
string that Discourse used to lookup the current user from the database and the
cookie contained no additional information about the user. However, we had to
change the cookie content in this commit so we could identify the user from the
cookie without making a database query before the rate limits logic and avoid
introducing a bottleneck on busy sites.
Besides the 32 characters auth token, the cookie now includes the user id,
trust level and the cookie's generation date, and we encrypt/sign the cookie to
prevent tampering.
Internal ticket number: t54739.
2021-11-17 15:27:30 -05:00
cookie =
create_auth_cookie (
token : token . unhashed_auth_token ,
2021-12-16 14:36:49 -05:00
user_id : user1 . id ,
trust_level : user1 . trust_level ,
FEATURE: Apply rate limits per user instead of IP for trusted users (#14706)
Currently, Discourse rate limits all incoming requests by the IP address they
originate from regardless of the user making the request. This can be
frustrating if there are multiple users using Discourse simultaneously while
sharing the same IP address (e.g. employees in an office).
This commit implements a new feature to make Discourse apply rate limits by
user id rather than IP address for users at or higher than the configured trust
level (1 is the default).
For example, let's say a Discourse instance is configured to allow 200 requests
per minute per IP address, and we have 10 users at trust level 4 using
Discourse simultaneously from the same IP address. Before this feature, the 10
users could only make a total of 200 requests per minute before they got rate
limited. But with the new feature, each user is allowed to make 200 requests
per minute because the rate limits are applied on user id rather than the IP
address.
The minimum trust level for applying user-id-based rate limits can be
configured by the `skip_per_ip_rate_limit_trust_level` global setting. The
default is 1, but it can be changed by either adding the
`DISCOURSE_SKIP_PER_IP_RATE_LIMIT_TRUST_LEVEL` environment variable with the
desired value to your `app.yml`, or changing the setting's value in the
`discourse.conf` file.
Requests made with API keys are still rate limited by IP address and the
relevant global settings that control API keys rate limits.
Before this commit, Discourse's auth cookie (`_t`) was simply a 32 characters
string that Discourse used to lookup the current user from the database and the
cookie contained no additional information about the user. However, we had to
change the cookie content in this commit so we could identify the user from the
cookie without making a database query before the rate limits logic and avoid
introducing a bottleneck on busy sites.
Besides the 32 characters auth token, the cookie now includes the user id,
trust level and the cookie's generation date, and we encrypt/sign the cookie to
prevent tampering.
Internal ticket number: t54739.
2021-11-17 15:27:30 -05:00
issued_at : 5 . minutes . ago ,
)
2018-10-09 10:21:41 -04:00
2021-12-16 14:36:49 -05:00
post " /u/ #{ user1 . username } /preferences/revoke-auth-token.json " ,
FEATURE: Apply rate limits per user instead of IP for trusted users (#14706)
Currently, Discourse rate limits all incoming requests by the IP address they
originate from regardless of the user making the request. This can be
frustrating if there are multiple users using Discourse simultaneously while
sharing the same IP address (e.g. employees in an office).
This commit implements a new feature to make Discourse apply rate limits by
user id rather than IP address for users at or higher than the configured trust
level (1 is the default).
For example, let's say a Discourse instance is configured to allow 200 requests
per minute per IP address, and we have 10 users at trust level 4 using
Discourse simultaneously from the same IP address. Before this feature, the 10
users could only make a total of 200 requests per minute before they got rate
limited. But with the new feature, each user is allowed to make 200 requests
per minute because the rate limits are applied on user id rather than the IP
address.
The minimum trust level for applying user-id-based rate limits can be
configured by the `skip_per_ip_rate_limit_trust_level` global setting. The
default is 1, but it can be changed by either adding the
`DISCOURSE_SKIP_PER_IP_RATE_LIMIT_TRUST_LEVEL` environment variable with the
desired value to your `app.yml`, or changing the setting's value in the
`discourse.conf` file.
Requests made with API keys are still rate limited by IP address and the
relevant global settings that control API keys rate limits.
Before this commit, Discourse's auth cookie (`_t`) was simply a 32 characters
string that Discourse used to lookup the current user from the database and the
cookie contained no additional information about the user. However, we had to
change the cookie content in this commit so we could identify the user from the
cookie without making a database query before the rate limits logic and avoid
introducing a bottleneck on busy sites.
Besides the 32 characters auth token, the cookie now includes the user id,
trust level and the cookie's generation date, and we encrypt/sign the cookie to
prevent tampering.
Internal ticket number: t54739.
2021-11-17 15:27:30 -05:00
params : {
token_id : token . id ,
} ,
headers : {
" HTTP_COOKIE " = > " _t= #{ cookie } " ,
}
2018-10-09 10:21:41 -04:00
FEATURE: Apply rate limits per user instead of IP for trusted users (#14706)
Currently, Discourse rate limits all incoming requests by the IP address they
originate from regardless of the user making the request. This can be
frustrating if there are multiple users using Discourse simultaneously while
sharing the same IP address (e.g. employees in an office).
This commit implements a new feature to make Discourse apply rate limits by
user id rather than IP address for users at or higher than the configured trust
level (1 is the default).
For example, let's say a Discourse instance is configured to allow 200 requests
per minute per IP address, and we have 10 users at trust level 4 using
Discourse simultaneously from the same IP address. Before this feature, the 10
users could only make a total of 200 requests per minute before they got rate
limited. But with the new feature, each user is allowed to make 200 requests
per minute because the rate limits are applied on user id rather than the IP
address.
The minimum trust level for applying user-id-based rate limits can be
configured by the `skip_per_ip_rate_limit_trust_level` global setting. The
default is 1, but it can be changed by either adding the
`DISCOURSE_SKIP_PER_IP_RATE_LIMIT_TRUST_LEVEL` environment variable with the
desired value to your `app.yml`, or changing the setting's value in the
`discourse.conf` file.
Requests made with API keys are still rate limited by IP address and the
relevant global settings that control API keys rate limits.
Before this commit, Discourse's auth cookie (`_t`) was simply a 32 characters
string that Discourse used to lookup the current user from the database and the
cookie contained no additional information about the user. However, we had to
change the cookie content in this commit so we could identify the user from the
cookie without making a database query before the rate limits logic and avoid
introducing a bottleneck on busy sites.
Besides the 32 characters auth token, the cookie now includes the user id,
trust level and the cookie's generation date, and we encrypt/sign the cookie to
prevent tampering.
Internal ticket number: t54739.
2021-11-17 15:27:30 -05:00
expect ( token . reload . id ) . to be_present
2018-10-11 19:51:41 -04:00
expect ( response . status ) . to eq ( 400 )
2018-10-09 10:21:41 -04:00
end
it " logs user out from everywhere if token_id is not present " do
2021-12-16 14:36:49 -05:00
post " /u/ #{ user1 . username } /preferences/revoke-auth-token.json "
2018-09-02 03:24:54 -04:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . user_auth_tokens . count ) . to eq ( 0 )
2018-09-02 03:24:54 -04:00
end
end
end
2019-10-01 22:08:41 -04:00
describe " # list_second_factors " do
2021-12-16 14:36:49 -05:00
let ( :user ) { user1 }
2019-10-01 22:08:41 -04:00
before { sign_in ( user ) }
context " when SSO is enabled " do
before do
2021-02-08 05:04:33 -05:00
SiteSetting . discourse_connect_url = " https://discourse.test/sso "
SiteSetting . enable_discourse_connect = true
2019-10-01 22:08:41 -04:00
end
it " does not allow access " do
post " /u/second_factors.json "
expect ( response . status ) . to eq ( 404 )
end
end
context " when local logins are not enabled " do
before { SiteSetting . enable_local_logins = false }
it " does not allow access " do
post " /u/second_factors.json "
expect ( response . status ) . to eq ( 404 )
end
end
context " when the site settings allow second factors " do
before do
SiteSetting . enable_local_logins = true
2021-02-08 05:04:33 -05:00
SiteSetting . enable_discourse_connect = false
2019-10-01 22:08:41 -04:00
end
context " when the password parameter is not provided " do
let ( :password ) { " " }
before { post " /u/second_factors.json " , params : { password : password } }
it " returns password required response " do
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
response_body = response . parsed_body
2019-10-01 22:08:41 -04:00
expect ( response_body [ " password_required " ] ) . to eq ( true )
end
end
context " when the password is provided " do
2021-12-16 14:36:49 -05:00
fab! ( :user ) { Fabricate ( :user , password : " 8555039dd212cc66ec68 " ) }
2019-10-01 22:08:41 -04:00
context " when the password is correct " do
let ( :password ) { " 8555039dd212cc66ec68 " }
it " returns a list of enabled totps and security_key second factors " do
totp_second_factor = Fabricate ( :user_second_factor_totp , user : user )
security_key_second_factor =
Fabricate (
:user_security_key ,
user : user ,
factor_type : UserSecurityKey . factor_types [ :second_factor ] ,
)
post " /u/second_factors.json " , params : { password : password }
expect ( response . status ) . to eq ( 200 )
2020-05-07 11:04:12 -04:00
response_body = response . parsed_body
2019-10-01 22:08:41 -04:00
expect ( response_body [ " totps " ] . map { | second_factor | second_factor [ " id " ] } ) . to include (
totp_second_factor . id ,
)
expect (
response_body [ " security_keys " ] . map { | second_factor | second_factor [ " id " ] } ,
) . to include ( security_key_second_factor . id )
end
end
context " when the password is not correct " do
let ( :password ) { " wrongpassword " }
it " returns the incorrect password response " do
post " /u/second_factors.json " , params : { password : password }
2020-05-07 11:04:12 -04:00
response_body = response . parsed_body
2019-10-01 22:08:41 -04:00
expect ( response_body [ " error " ] ) . to eq ( I18n . t ( " login.incorrect_password " ) )
end
end
end
end
end
2019-12-09 14:15:47 -05:00
describe " # feature_topic " do
fab! ( :topic ) { Fabricate ( :topic ) }
2020-01-29 11:10:23 -05:00
fab! ( :other_topic ) { Fabricate ( :topic ) }
2021-12-16 14:36:49 -05:00
fab! ( :private_message ) { Fabricate ( :private_message_topic , user : another_user ) }
2019-12-09 14:15:47 -05:00
fab! ( :category ) { Fabricate ( :category_with_definition ) }
describe " site setting enabled " do
before { SiteSetting . allow_featured_topic_on_user_profiles = true }
it " requires the user to be logged in " do
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /feature-topic.json " , params : { topic_id : topic . id }
2019-12-09 14:15:47 -05:00
expect ( response . status ) . to eq ( 403 )
end
2020-01-29 11:10:23 -05:00
it " returns an error if the user tries to set for another user " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
topic . update ( user_id : another_user . id )
put " /u/ #{ another_user . username } /feature-topic.json " , params : { topic_id : topic . id }
2019-12-09 14:15:47 -05:00
expect ( response . status ) . to eq ( 403 )
end
it " returns an error if the topic is a PM " do
2021-12-16 14:36:49 -05:00
sign_in ( another_user )
put " /u/ #{ another_user . username } /feature-topic.json " ,
params : {
topic_id : private_message . id ,
}
2019-12-09 14:15:47 -05:00
expect ( response . status ) . to eq ( 403 )
end
2020-01-30 11:00:49 -05:00
it " returns an error if the topic is not visible " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
topic . update_status ( " visible " , false , user1 )
put " /u/ #{ user1 . username } /feature-topic.json " , params : { topic_id : topic . id }
2020-01-30 11:00:49 -05:00
expect ( response . status ) . to eq ( 403 )
end
2019-12-09 14:15:47 -05:00
it " returns an error if the topic's category is read_restricted " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2019-12-09 14:15:47 -05:00
category . set_permissions ( { } )
topic . update ( category_id : category . id )
2021-12-16 14:36:49 -05:00
put " /u/ #{ another_user . username } /feature-topic.json " , params : { topic_id : topic . id }
2019-12-09 14:15:47 -05:00
expect ( response . status ) . to eq ( 403 )
end
2020-01-29 11:10:23 -05:00
it " sets featured_topic correctly for user created topic " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
topic . update ( user_id : user1 . id )
put " /u/ #{ user1 . username } /feature-topic.json " , params : { topic_id : topic . id }
2019-12-09 14:15:47 -05:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . user_profile . featured_topic ) . to eq topic
2019-12-09 14:15:47 -05:00
end
2020-01-29 11:10:23 -05:00
it " sets featured_topic correctly for non-user-created topic " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
put " /u/ #{ user1 . username } /feature-topic.json " , params : { topic_id : other_topic . id }
2020-01-29 11:10:23 -05:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . user_profile . featured_topic ) . to eq other_topic
2020-01-29 11:10:23 -05:00
end
2019-12-09 14:15:47 -05:00
describe " site setting disabled " do
before { SiteSetting . allow_featured_topic_on_user_profiles = false }
it " does not allow setting featured_topic for user_profiles " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
topic . update ( user_id : user1 . id )
put " /u/ #{ user1 . username } /feature-topic.json " , params : { topic_id : topic . id }
2019-12-09 14:15:47 -05:00
expect ( response . status ) . to eq ( 403 )
end
end
end
end
describe " # clear_featured_topic " do
fab! ( :topic ) { Fabricate ( :topic ) }
it " requires the user to be logged in " do
2021-12-16 14:36:49 -05:00
put " /u/ #{ user1 . username } /clear-featured-topic.json "
2019-12-09 14:15:47 -05:00
expect ( response . status ) . to eq ( 403 )
end
it " returns an error if the the current user does not have access " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
topic . update ( user_id : another_user . id )
put " /u/ #{ another_user . username } /clear-featured-topic.json "
2019-12-09 14:15:47 -05:00
expect ( response . status ) . to eq ( 403 )
end
it " clears the user_profiles featured_topic correctly " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
topic . update ( user : user1 )
put " /u/ #{ user1 . username } /clear-featured-topic.json "
2019-12-09 14:15:47 -05:00
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
expect ( user1 . user_profile . featured_topic ) . to eq nil
2019-12-09 14:15:47 -05:00
end
end
2020-01-09 19:45:56 -05:00
2020-03-18 20:59:32 -04:00
describe " # bookmarks " do
2022-05-22 20:07:15 -04:00
before do
register_test_bookmarkable
TopicUser . change ( user1 . id , bookmark1 . bookmarkable . topic_id , total_msecs_viewed : 1 )
TopicUser . change ( user1 . id , bookmark2 . bookmarkable_id , total_msecs_viewed : 1 )
Fabricate ( :post , topic : bookmark2 . bookmarkable )
bookmark3 && bookmark4
2020-11-18 18:10:28 -05:00
end
2023-03-07 19:39:12 -05:00
after { DiscoursePluginRegistry . reset! }
2022-04-21 18:23:42 -04:00
2022-05-22 20:07:15 -04:00
let ( :bookmark1 ) { Fabricate ( :bookmark , user : user1 , bookmarkable : Fabricate ( :post ) ) }
let ( :bookmark2 ) { Fabricate ( :bookmark , user : user1 , bookmarkable : Fabricate ( :topic ) ) }
let ( :bookmark3 ) { Fabricate ( :bookmark , user : user1 , bookmarkable : Fabricate ( :user ) ) }
let ( :bookmark4 ) { Fabricate ( :bookmark ) }
2022-04-21 18:23:42 -04:00
2022-05-22 20:07:15 -04:00
it " returns a list of serialized bookmarks for the user " do
sign_in ( user1 )
get " /u/ #{ user1 . username } /bookmarks.json "
expect ( response . status ) . to eq ( 200 )
expect (
response . parsed_body [ " user_bookmark_list " ] [ " bookmarks " ] . map { | b | b [ " id " ] } ,
) . to match_array ( [ bookmark1 . id , bookmark2 . id , bookmark3 . id ] )
end
2022-04-21 18:23:42 -04:00
2022-05-22 20:07:15 -04:00
it " returns a list of serialized bookmarks for the user including custom registered bookmarkables " do
sign_in ( user1 )
bookmark3 . bookmarkable . user_profile . update! ( bio_raw : " <p>Something cooked</p> " )
bookmark3 . bookmarkable . user_profile . rebake!
get " /u/ #{ user1 . username } /bookmarks.json "
expect ( response . status ) . to eq ( 200 )
response_bookmarks = response . parsed_body [ " user_bookmark_list " ] [ " bookmarks " ]
expect ( response_bookmarks . map { | b | b [ " id " ] } ) . to match_array (
[ bookmark1 . id , bookmark2 . id , bookmark3 . id ] ,
2023-01-09 06:18:21 -05:00
)
2022-05-22 20:07:15 -04:00
expect ( response_bookmarks . find { | b | b [ " id " ] == bookmark3 . id } [ " excerpt " ] ) . to eq (
" Something cooked " ,
)
end
2022-05-10 19:29:24 -04:00
2022-05-22 20:07:15 -04:00
it " returns an .ics file of bookmark reminders for the user in date order " do
bookmark1 . update! ( name : nil , reminder_at : 1 . day . from_now )
bookmark2 . update! ( name : " Some bookmark note " , reminder_at : 1 . week . from_now )
bookmark3 . update! ( name : nil , reminder_at : 2 . weeks . from_now )
2022-05-10 19:29:24 -04:00
2022-05-22 20:07:15 -04:00
sign_in ( user1 )
get " /u/ #{ user1 . username } /bookmarks.ics "
expect ( response . status ) . to eq ( 200 )
expect ( response . body ) . to eq ( << ~ ICS )
2022-05-10 19:29:24 -04:00
BEGIN :VCALENDAR
VERSION : 2 . 0
PRODID : - / / Discourse / / #{Discourse.current_hostname}//#{Discourse.full_version}//EN
BEGIN :VEVENT
UID : bookmark_reminder_ ##{bookmark1.id}@#{Discourse.current_hostname}
DTSTAMP : #{bookmark1.updated_at.strftime(I18n.t("datetime_formats.formats.calendar_ics"))}
DTSTART : #{bookmark1.reminder_at_ics}
DTEND : #{bookmark1.reminder_at_ics(offset: 1.hour)}
SUMMARY : #{bookmark1.bookmarkable.topic.title}
DESCRIPTION : #{bookmark1.bookmarkable.full_url}
URL : #{bookmark1.bookmarkable.full_url}
END :VEVENT
BEGIN :VEVENT
UID : bookmark_reminder_ ##{bookmark2.id}@#{Discourse.current_hostname}
DTSTAMP : #{bookmark2.updated_at.strftime(I18n.t("datetime_formats.formats.calendar_ics"))}
DTSTART : #{bookmark2.reminder_at_ics}
DTEND : #{bookmark2.reminder_at_ics(offset: 1.hour)}
SUMMARY : Some bookmark note
DESCRIPTION : #{bookmark2.bookmarkable.url}
URL : #{bookmark2.bookmarkable.url}
END :VEVENT
BEGIN :VEVENT
UID : bookmark_reminder_ ##{bookmark3.id}@#{Discourse.current_hostname}
DTSTAMP : #{bookmark3.updated_at.strftime(I18n.t("datetime_formats.formats.calendar_ics"))}
DTSTART : #{bookmark3.reminder_at_ics}
DTEND : #{bookmark3.reminder_at_ics(offset: 1.hour)}
SUMMARY : #{bookmark3.bookmarkable.username}
DESCRIPTION : #{Discourse.base_url}/u/#{bookmark3.bookmarkable.username}
URL : #{Discourse.base_url}/u/#{bookmark3.bookmarkable.username}
END :VEVENT
END :VCALENDAR
2022-05-22 20:07:15 -04:00
ICS
end
it " does not show another user's bookmarks " do
sign_in ( Fabricate ( :user ) )
get " /u/ #{ bookmark3 . user . username } /bookmarks.json "
expect ( response . status ) . to eq ( 403 )
end
it " shows a helpful message if no bookmarks are found " do
bookmark1 . destroy
bookmark2 . destroy
bookmark3 . destroy
sign_in ( user1 )
get " /u/ #{ user1 . username } /bookmarks.json "
expect ( response . status ) . to eq ( 200 )
expect ( response . parsed_body [ " bookmarks " ] ) . to eq ( [ ] )
end
it " shows a helpful message if no bookmarks are found for the search " do
sign_in ( user1 )
get " /u/ #{ user1 . username } /bookmarks.json " , params : { q : " badsearch " }
expect ( response . status ) . to eq ( 200 )
expect ( response . parsed_body [ " bookmarks " ] ) . to eq ( [ ] )
2020-11-18 18:10:28 -05:00
end
2022-08-16 21:40:24 -04:00
end
describe " # bookmarks excerpts " do
fab! ( :user ) { Fabricate ( :user ) }
let! ( :topic ) { Fabricate ( :topic , user : user ) }
let! ( :post ) { Fabricate ( :post , topic : topic ) }
let! ( :bookmark ) { Fabricate ( :bookmark , name : " Test " , user : user , bookmarkable : topic ) }
2022-08-18 19:35:25 -04:00
it " uses the first post of the topic for the bookmarks excerpt " do
2022-08-16 21:40:24 -04:00
TopicUser . change (
user . id ,
bookmark . bookmarkable . id ,
{ last_read_post_number : post . post_number } ,
)
sign_in ( user )
get " /u/ #{ user . username } /bookmarks.json "
expect ( response . status ) . to eq ( 200 )
bookmark_list = response . parsed_body [ " user_bookmark_list " ] [ " bookmarks " ]
2022-08-18 19:35:25 -04:00
expected_excerpt = PrettyText . excerpt ( topic . first_post . cooked , 300 , keep_emoji_images : true )
2022-08-16 21:40:24 -04:00
expect ( bookmark_list . first [ " excerpt " ] ) . to eq ( expected_excerpt )
end
describe " bookmarkable_url " do
context " with the link_to_first_unread_post option " do
it " is a full topic URL to the first unread post in the topic when the option is set " do
TopicUser . change (
user . id ,
bookmark . bookmarkable . id ,
{ last_read_post_number : post . post_number } ,
)
sign_in ( user )
get " /u/ #{ user . username } /user-menu-bookmarks.json "
expect ( response . status ) . to eq ( 200 )
bookmark_list = response . parsed_body [ " bookmarks " ]
expect ( bookmark_list . first [ " bookmarkable_url " ] ) . to end_with (
" /t/ #{ topic . slug } / #{ topic . id } / #{ post . post_number + 1 } " ,
)
end
it " is a full topic URL to the first post in the topic when the option isn't set " do
TopicUser . change (
user . id ,
bookmark . bookmarkable . id ,
{ last_read_post_number : post . post_number } ,
)
sign_in ( user )
get " /u/ #{ user . username } /bookmarks.json "
expect ( response . status ) . to eq ( 200 )
bookmark_list = response . parsed_body [ " user_bookmark_list " ] [ " bookmarks " ]
expect ( bookmark_list . first [ " bookmarkable_url " ] ) . to end_with (
" /t/ #{ topic . slug } / #{ topic . id } " ,
)
end
end
end
2020-03-18 20:59:32 -04:00
end
2021-08-24 23:17:56 -04:00
describe " # private_message_topic_tracking_state " do
fab! ( :user_2 ) { Fabricate ( :user ) }
fab! ( :private_message ) do
2022-10-04 20:50:20 -04:00
Group . refresh_automatic_groups!
2021-08-24 23:17:56 -04:00
create_post (
2021-12-16 14:36:49 -05:00
user : user1 ,
2021-08-24 23:17:56 -04:00
target_usernames : [ user_2 . username ] ,
archetype : Archetype . private_message ,
) . topic
end
before { sign_in ( user_2 ) }
it " does not allow an unauthorized user to access the state of another user " do
2021-12-16 14:36:49 -05:00
get " /u/ #{ user1 . username } /private-message-topic-tracking-state.json "
2021-08-24 23:17:56 -04:00
expect ( response . status ) . to eq ( 403 )
end
it " returns the right response " do
get " /u/ #{ user_2 . username } /private-message-topic-tracking-state.json "
expect ( response . status ) . to eq ( 200 )
topic_state = response . parsed_body . first
expect ( topic_state [ " topic_id " ] ) . to eq ( private_message . id )
expect ( topic_state [ " highest_post_number " ] ) . to eq ( 1 )
expect ( topic_state [ " last_read_post_number " ] ) . to eq ( nil )
expect ( topic_state [ " notification_level " ] ) . to eq ( NotificationLevels . all [ :watching ] )
expect ( topic_state [ " group_ids " ] ) . to eq ( [ ] )
end
end
2021-11-25 15:44:15 -05:00
describe " # reset_recent_searches " do
it " does nothing for anon " do
delete " /u/recent-searches.json "
expect ( response . status ) . to eq ( 403 )
end
it " works for logged in user " do
2022-02-28 01:15:13 -05:00
freeze_time
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2021-11-25 15:44:15 -05:00
delete " /u/recent-searches.json "
expect ( response . status ) . to eq ( 200 )
2021-12-16 14:36:49 -05:00
user1 . reload
expect ( user1 . user_option . oldest_search_log_date ) . to be_within ( 5 . seconds ) . of ( 1 . second . ago )
2021-11-25 15:44:15 -05:00
end
end
describe " # recent_searches " do
it " does nothing for anon " do
get " /u/recent-searches.json "
expect ( response . status ) . to eq ( 403 )
end
it " works for logged in user " do
2022-02-28 01:15:13 -05:00
freeze_time
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2021-11-25 15:44:15 -05:00
SiteSetting . log_search_queries = true
2021-12-16 14:36:49 -05:00
user1 . user_option . update! ( oldest_search_log_date : nil )
2021-11-25 15:44:15 -05:00
get " /u/recent-searches.json "
expect ( response . status ) . to eq ( 200 )
expect ( response . parsed_body [ " recent_searches " ] ) . to eq ( [ ] )
SearchLog . create! (
term : " old one " ,
2021-12-16 14:36:49 -05:00
user_id : user1 . id ,
2021-11-25 15:44:15 -05:00
search_type : 1 ,
ip_address : " 192.168.0.1 " ,
created_at : 5 . minutes . ago ,
)
SearchLog . create! (
term : " also old " ,
2021-12-16 14:36:49 -05:00
user_id : user1 . id ,
2021-11-25 15:44:15 -05:00
search_type : 1 ,
ip_address : " 192.168.0.1 " ,
created_at : 15 . minutes . ago ,
)
get " /u/recent-searches.json "
expect ( response . status ) . to eq ( 200 )
expect ( response . parsed_body [ " recent_searches " ] ) . to eq ( [ " old one " , " also old " ] )
2021-12-16 14:36:49 -05:00
user1 . user_option . update! ( oldest_search_log_date : 20 . minutes . ago )
2021-11-25 15:44:15 -05:00
get " /u/recent-searches.json "
expect ( response . status ) . to eq ( 200 )
expect ( response . parsed_body [ " recent_searches " ] ) . to eq ( [ " old one " , " also old " ] )
2021-12-16 14:36:49 -05:00
user1 . user_option . update! ( oldest_search_log_date : 10 . seconds . ago )
2021-11-25 15:44:15 -05:00
get " /u/recent-searches.json "
expect ( response . status ) . to eq ( 200 )
expect ( response . parsed_body [ " recent_searches " ] ) . to eq ( [ ] )
SearchLog . create! (
term : " new search " ,
2021-12-16 14:36:49 -05:00
user_id : user1 . id ,
2021-11-25 15:44:15 -05:00
search_type : 1 ,
ip_address : " 192.168.0.1 " ,
created_at : 2 . seconds . ago ,
)
get " /u/recent-searches.json "
expect ( response . status ) . to eq ( 200 )
expect ( response . parsed_body [ " recent_searches " ] ) . to eq ( [ " new search " ] )
end
it " shows an error message when log_search_queries are off " do
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2021-11-25 15:44:15 -05:00
SiteSetting . log_search_queries = false
get " /u/recent-searches.json "
expect ( response . status ) . to eq ( 403 )
expect ( response . parsed_body [ " error " ] ) . to eq ( I18n . t ( " user_activity.no_log_search_queries " ) )
end
end
2022-08-08 10:24:04 -04:00
describe " # user_menu_bookmarks " do
fab! ( :post ) { Fabricate ( :post ) }
fab! ( :topic ) { Fabricate ( :post ) . topic }
fab! ( :bookmark_with_reminder ) { Fabricate ( :bookmark , user : user , bookmarkable : post ) }
fab! ( :bookmark_without_reminder ) { Fabricate ( :bookmark , user : user , bookmarkable : topic ) }
before do
TopicUser . change ( user . id , post . topic . id , total_msecs_viewed : 1 )
TopicUser . change ( user . id , topic . id , total_msecs_viewed : 1 )
BookmarkReminderNotificationHandler . new ( bookmark_with_reminder ) . send_notification
end
context " when logged out " do
it " responds with 404 " do
get " /u/ #{ user . username } /user-menu-bookmarks "
expect ( response . status ) . to eq ( 404 )
end
end
context " when logged in " do
before { sign_in ( user ) }
it " responds with 403 when requesting bookmarks list of another user " do
get " /u/ #{ user1 . username } /user-menu-bookmarks "
expect ( response . status ) . to eq ( 403 )
end
it " sends an array of unread bookmark_reminder notifications " do
bookmark_with_reminder2 = Fabricate ( :bookmark , user : user , bookmarkable : Fabricate ( :post ) )
TopicUser . change ( user . id , bookmark_with_reminder2 . bookmarkable . topic , total_msecs_viewed : 1 )
BookmarkReminderNotificationHandler . new ( bookmark_with_reminder2 ) . send_notification
user
. notifications
. where ( notification_type : Notification . types [ :bookmark_reminder ] )
. where ( " data::json ->> 'bookmark_id' = ? " , bookmark_with_reminder2 . id . to_s )
. first
. update! ( read : true )
get " /u/ #{ user . username } /user-menu-bookmarks "
expect ( response . status ) . to eq ( 200 )
notifications = response . parsed_body [ " notifications " ]
expect ( notifications . size ) . to eq ( 1 )
expect ( notifications . first [ " data " ] [ " bookmark_id " ] ) . to eq ( bookmark_with_reminder . id )
end
it " responds with an array of bookmarks that are not associated with any of the unread bookmark_reminder notifications " do
get " /u/ #{ user . username } /user-menu-bookmarks "
expect ( response . status ) . to eq ( 200 )
bookmarks = response . parsed_body [ " bookmarks " ]
expect ( bookmarks . size ) . to eq ( 1 )
expect ( bookmarks . first [ " id " ] ) . to eq ( bookmark_without_reminder . id )
bookmark_reminder =
user
. notifications
. where ( notification_type : Notification . types [ :bookmark_reminder ] )
. where ( " data::json ->> 'bookmark_id' = ? " , bookmark_with_reminder . id . to_s )
. first
bookmark_reminder . update! ( read : true )
get " /u/ #{ user . username } /user-menu-bookmarks "
expect ( response . status ) . to eq ( 200 )
bookmarks = response . parsed_body [ " bookmarks " ]
expect ( bookmarks . map { | bookmark | bookmark [ " id " ] } ) . to contain_exactly (
bookmark_with_reminder . id ,
bookmark_without_reminder . id ,
)
data = bookmark_reminder . data_hash
data . delete ( :bookmark_id )
bookmark_reminder . update! ( data : data . to_json , read : false )
get " /u/ #{ user . username } /user-menu-bookmarks "
expect ( response . status ) . to eq ( 200 )
notifications = response . parsed_body [ " notifications " ]
expect ( notifications . size ) . to eq ( 1 )
expect ( notifications . first [ " data " ] [ " bookmark_id " ] ) . to be_nil
bookmarks = response . parsed_body [ " bookmarks " ]
expect ( bookmarks . map { | bookmark | bookmark [ " id " ] } ) . to contain_exactly (
bookmark_with_reminder . id ,
bookmark_without_reminder . id ,
)
end
2022-08-10 01:25:39 -04:00
it " fills up the remaining of the USER_MENU_LIST_LIMIT limit with bookmarks " do
2022-08-08 10:24:04 -04:00
bookmark2 = Fabricate ( :bookmark , user : user , bookmarkable : Fabricate ( :post , topic : topic ) )
2022-08-10 01:25:39 -04:00
stub_const ( UsersController , " USER_MENU_LIST_LIMIT " , 2 ) do
2022-08-08 10:24:04 -04:00
get " /u/ #{ user . username } /user-menu-bookmarks "
end
expect ( response . status ) . to eq ( 200 )
notifications = response . parsed_body [ " notifications " ]
expect ( notifications . size ) . to eq ( 1 )
bookmarks = response . parsed_body [ " bookmarks " ]
expect ( bookmarks . size ) . to eq ( 1 )
2022-08-10 01:25:39 -04:00
stub_const ( UsersController , " USER_MENU_LIST_LIMIT " , 3 ) do
2022-08-08 10:24:04 -04:00
get " /u/ #{ user . username } /user-menu-bookmarks "
end
expect ( response . status ) . to eq ( 200 )
notifications = response . parsed_body [ " notifications " ]
expect ( notifications . size ) . to eq ( 1 )
bookmarks = response . parsed_body [ " bookmarks " ]
expect ( bookmarks . size ) . to eq ( 2 )
BookmarkReminderNotificationHandler . new ( bookmark2 ) . send_notification
2022-08-10 01:25:39 -04:00
stub_const ( UsersController , " USER_MENU_LIST_LIMIT " , 3 ) do
2022-08-08 10:24:04 -04:00
get " /u/ #{ user . username } /user-menu-bookmarks "
end
expect ( response . status ) . to eq ( 200 )
notifications = response . parsed_body [ " notifications " ]
expect ( notifications . size ) . to eq ( 2 )
bookmarks = response . parsed_body [ " bookmarks " ]
expect ( bookmarks . size ) . to eq ( 1 )
end
end
end
2022-08-10 01:25:39 -04:00
describe " # user_menu_messages " do
2022-09-30 01:44:04 -04:00
fab! ( :group1 ) { Fabricate ( :group , has_messages : true , users : [ user ] ) }
fab! ( :group2 ) { Fabricate ( :group , has_messages : true , users : [ user , user1 ] ) }
fab! ( :group3 ) { Fabricate ( :group , has_messages : true , users : [ user1 ] ) }
2022-08-10 01:25:39 -04:00
fab! ( :message_without_notification ) { Fabricate ( :private_message_post , recipient : user ) . topic }
fab! ( :message_with_read_notification ) do
Fabricate ( :private_message_post , recipient : user ) . topic
2023-01-09 06:18:21 -05:00
end
2022-08-10 01:25:39 -04:00
fab! ( :message_with_unread_notification ) do
Fabricate ( :private_message_post , recipient : user ) . topic
2023-01-09 06:18:21 -05:00
end
2022-09-30 01:44:04 -04:00
fab! ( :archived_message ) { Fabricate ( :private_message_post , recipient : user ) . topic }
fab! ( :group_message1 ) { Fabricate ( :group_private_message_post , recipients : group1 ) . topic }
fab! ( :group_message2 ) { Fabricate ( :group_private_message_post , recipients : group2 ) . topic }
fab! ( :group_message3 ) { Fabricate ( :group_private_message_post , recipients : group3 ) . topic }
fab! ( :archived_group_message1 ) do
Fabricate ( :group_private_message_post , recipients : group1 ) . topic
2023-01-09 06:18:21 -05:00
end
2022-09-30 01:44:04 -04:00
fab! ( :archived_group_message2 ) do
Fabricate ( :group_private_message_post , recipients : group2 ) . topic
2023-01-09 06:18:21 -05:00
end
2022-08-10 01:25:39 -04:00
fab! ( :user1_message_without_notification ) do
Fabricate ( :private_message_post , recipient : user1 ) . topic
end
fab! ( :user1_message_with_read_notification ) do
Fabricate ( :private_message_post , recipient : user1 ) . topic
end
fab! ( :user1_message_with_unread_notification ) do
Fabricate ( :private_message_post , recipient : user1 ) . topic
end
2022-09-30 01:44:04 -04:00
fab! ( :user1_archived_message ) { Fabricate ( :private_message_post , recipient : user1 ) . topic }
2022-08-10 01:25:39 -04:00
2022-09-30 01:44:04 -04:00
fab! ( :unread_pm_notification ) do
2022-08-10 01:25:39 -04:00
Fabricate (
:private_message_notification ,
read : false ,
user : user ,
2022-09-30 01:44:04 -04:00
topic : message_with_unread_notification ,
created_at : 4 . minutes . ago ,
2022-08-10 01:25:39 -04:00
)
end
2022-09-30 01:44:04 -04:00
fab! ( :read_pm_notification ) do
2022-08-10 01:25:39 -04:00
Fabricate (
:private_message_notification ,
read : true ,
user : user ,
topic : message_with_read_notification ,
)
end
2022-09-30 01:44:04 -04:00
fab! ( :unread_group_message_summary_notification ) do
Fabricate (
:notification ,
read : false ,
user : user ,
notification_type : Notification . types [ :group_message_summary ] ,
created_at : 2 . minutes . ago ,
)
end
fab! ( :read_group_message_summary_notification ) do
Fabricate (
:notification ,
read : true ,
user : user ,
notification_type : Notification . types [ :group_message_summary ] ,
created_at : 1 . minutes . ago ,
)
end
fab! ( :user1_unread_pm_notification ) do
2022-08-10 01:25:39 -04:00
Fabricate (
:private_message_notification ,
read : false ,
user : user1 ,
topic : user1_message_with_unread_notification ,
)
end
2022-09-30 01:44:04 -04:00
fab! ( :user1_read_pm_notification ) do
2022-08-10 01:25:39 -04:00
Fabricate (
:private_message_notification ,
read : true ,
user : user1 ,
topic : user1_message_with_read_notification ,
)
end
2022-09-30 01:44:04 -04:00
fab! ( :user1_unread_group_message_summary_notification ) do
Fabricate (
:notification ,
read : false ,
user : user1 ,
notification_type : Notification . types [ :group_message_summary ] ,
)
end
fab! ( :user1_read_group_message_summary_notification ) do
Fabricate (
:notification ,
read : true ,
user : user1 ,
notification_type : Notification . types [ :group_message_summary ] ,
)
end
before do
UserArchivedMessage . archive! ( user . id , archived_message )
UserArchivedMessage . archive! ( user1 . id , user1_archived_message )
GroupArchivedMessage . archive! ( group1 . id , archived_group_message1 )
GroupArchivedMessage . archive! ( group2 . id , archived_group_message2 )
end
2022-08-10 01:25:39 -04:00
context " when logged out " do
it " responds with 404 " do
get " /u/ #{ user . username } /user-menu-private-messages "
expect ( response . status ) . to eq ( 404 )
end
end
context " when logged in " do
before { sign_in ( user ) }
it " responds with 403 when requesting messages list of another user " do
get " /u/ #{ user1 . username } /user-menu-private-messages "
expect ( response . status ) . to eq ( 403 )
end
2022-09-25 23:58:40 -04:00
it " responds with 403 if personal_message_enabled_groups does not include the user and the user isn't staff " do
SiteSetting . personal_message_enabled_groups = Group :: AUTO_GROUPS [ :trust_level_4 ]
user . update ( trust_level : 1 )
2022-08-10 01:25:39 -04:00
get " /u/ #{ user . username } /user-menu-private-messages "
expect ( response . status ) . to eq ( 403 )
end
it " sends an array of unread private_message notifications " do
get " /u/ #{ user . username } /user-menu-private-messages "
expect ( response . status ) . to eq ( 200 )
2022-09-30 01:44:04 -04:00
unread_notifications = response . parsed_body [ " unread_notifications " ]
expect ( unread_notifications . map { | notification | notification [ " id " ] } ) . to eq (
[ unread_pm_notification . id , unread_group_message_summary_notification . id ] ,
)
end
it " sends an array of read group_message_summary notifications " do
read_group_message_summary_notification2 =
Fabricate (
:notification ,
read : true ,
user : user ,
notification_type : Notification . types [ :group_message_summary ] ,
created_at : 5 . minutes . ago ,
2022-08-10 01:25:39 -04:00
)
2022-09-30 01:44:04 -04:00
get " /u/ #{ user . username } /user-menu-private-messages "
expect ( response . status ) . to eq ( 200 )
read_notifications = response . parsed_body [ " read_notifications " ]
expect ( read_notifications . map { | notification | notification [ " id " ] } ) . to eq (
[ read_group_message_summary_notification . id , read_group_message_summary_notification2 . id ] ,
)
2022-08-10 01:25:39 -04:00
end
2023-03-12 20:09:38 -04:00
it " responds with an array of personal messages and user watching group messages that are not associated with any of the unread private_message notifications " do
2022-09-30 01:44:04 -04:00
group_message1 . update! ( bumped_at : 1 . minutes . ago )
message_without_notification . update! ( bumped_at : 3 . minutes . ago )
group_message2 . update! ( bumped_at : 6 . minutes . ago )
message_with_read_notification . update! ( bumped_at : 10 . minutes . ago )
read_group_message_summary_notification . destroy!
2023-03-12 20:09:38 -04:00
TopicUser . create! (
user : user ,
topic : group_message1 ,
notification_level : TopicUser . notification_levels [ :watching ] ,
)
TopicUser . create! (
user : user ,
topic : group_message2 ,
notification_level : TopicUser . notification_levels [ :regular ] ,
)
2022-08-10 01:25:39 -04:00
get " /u/ #{ user . username } /user-menu-private-messages "
expect ( response . status ) . to eq ( 200 )
topics = response . parsed_body [ " topics " ]
2023-03-12 20:09:38 -04:00
2022-09-30 01:44:04 -04:00
expect ( topics . map { | topic | topic [ " id " ] } ) . to eq (
2023-03-12 20:09:38 -04:00
[ group_message1 . id , message_without_notification . id , message_with_read_notification . id ] ,
2022-09-30 01:44:04 -04:00
)
2022-08-10 01:25:39 -04:00
end
it " fills up the remaining of the USER_MENU_LIST_LIMIT limit with PM topics " do
2022-09-30 01:44:04 -04:00
stub_const ( UsersController , " USER_MENU_LIST_LIMIT " , 3 ) do
2022-08-10 01:25:39 -04:00
get " /u/ #{ user . username } /user-menu-private-messages "
end
expect ( response . status ) . to eq ( 200 )
2022-09-30 01:44:04 -04:00
unread_notifications = response . parsed_body [ " unread_notifications " ]
expect ( unread_notifications . size ) . to eq ( 2 )
2022-08-10 01:25:39 -04:00
topics = response . parsed_body [ " topics " ]
2022-09-30 01:44:04 -04:00
read_notifications = response . parsed_body [ " read_notifications " ]
2022-08-10 01:25:39 -04:00
expect ( topics . size ) . to eq ( 1 )
2022-09-30 01:44:04 -04:00
expect ( read_notifications . size ) . to eq ( 1 )
2022-08-10 01:25:39 -04:00
message2 = Fabricate ( :private_message_post , recipient : user ) . topic
Fabricate ( :private_message_notification , read : false , user : user , topic : message2 )
stub_const ( UsersController , " USER_MENU_LIST_LIMIT " , 2 ) do
get " /u/ #{ user . username } /user-menu-private-messages "
end
expect ( response . status ) . to eq ( 200 )
2022-09-30 01:44:04 -04:00
unread_notifications = response . parsed_body [ " unread_notifications " ]
expect ( unread_notifications . size ) . to eq ( 2 )
2022-08-10 01:25:39 -04:00
topics = response . parsed_body [ " topics " ]
2022-09-30 01:44:04 -04:00
read_notifications = response . parsed_body [ " read_notifications " ]
2022-08-10 01:25:39 -04:00
expect ( topics . size ) . to eq ( 0 )
2022-09-30 01:44:04 -04:00
expect ( read_notifications . size ) . to eq ( 0 )
2022-08-10 01:25:39 -04:00
end
end
end
2020-01-09 19:45:56 -05:00
def create_second_factor_security_key
2021-12-16 14:36:49 -05:00
sign_in ( user1 )
2020-03-05 23:37:40 -05:00
stub_secure_session_confirmed
2020-01-09 19:45:56 -05:00
post " /u/create_second_factor_security_key.json "
end
2020-03-05 23:37:40 -05:00
def stub_secure_session_confirmed
UsersController . any_instance . stubs ( :secure_session_confirmed? ) . returns ( true )
end
2016-12-16 11:21:28 -05:00
end