2019-07-31 22:56:46 +05:30
# frozen_string_literal: true
2015-04-26 12:48:37 +05:30
require 'spec_helper'
2023-03-04 22:38:38 +05:30
RSpec . describe UsersController , feature_category : :user_management do
2021-02-22 17:27:13 +05:30
# This user should have the same e-mail address associated with the GPG key prepared for tests
let ( :user ) { create ( :user , email : GpgHelpers :: User1 . emails [ 0 ] ) }
2018-11-18 11:00:15 +05:30
let ( :private_user ) { create ( :user , private_profile : true ) }
let ( :public_user ) { create ( :user ) }
2015-04-26 12:48:37 +05:30
describe 'GET #show' do
2021-03-08 18:12:59 +05:30
shared_examples_for 'renders the show template' do
it 'renders the show template' do
get user_url user . username
2015-09-11 14:41:01 +05:30
2021-03-08 18:12:59 +05:30
expect ( response ) . to have_gitlab_http_status ( :ok )
expect ( response ) . to render_template ( 'show' )
end
end
context 'when the user exists and has public visibility' do
context 'when logged in' do
2015-11-26 14:37:03 +05:30
before do
sign_in ( user )
end
2015-09-11 14:41:01 +05:30
2021-03-08 18:12:59 +05:30
it_behaves_like 'renders the show template'
2015-11-26 14:37:03 +05:30
end
2021-03-08 18:12:59 +05:30
context 'when logged out' do
it_behaves_like 'renders the show template'
2016-06-02 11:05:42 +05:30
end
end
context 'when public visibility level is restricted' do
before do
stub_application_setting ( restricted_visibility_levels : [ Gitlab :: VisibilityLevel :: PUBLIC ] )
end
context 'when logged out' do
2017-08-17 22:00:37 +05:30
it 'redirects to login page' do
2021-03-08 18:12:59 +05:30
get user_url user . username
2017-08-17 22:00:37 +05:30
expect ( response ) . to redirect_to new_user_session_path
2016-06-02 11:05:42 +05:30
end
end
context 'when logged in' do
2017-09-10 17:25:29 +05:30
before do
sign_in ( user )
end
2016-06-02 11:05:42 +05:30
2021-03-08 18:12:59 +05:30
it_behaves_like 'renders the show template'
2015-09-11 14:41:01 +05:30
end
2015-04-26 12:48:37 +05:30
end
2017-08-17 22:00:37 +05:30
context 'when a user by that username does not exist' do
context 'when logged out' do
it 'redirects to login page' do
2021-03-08 18:12:59 +05:30
get user_url 'nonexistent'
2017-08-17 22:00:37 +05:30
expect ( response ) . to redirect_to new_user_session_path
end
end
context 'when logged in' do
2017-09-10 17:25:29 +05:30
before do
sign_in ( user )
end
2017-08-17 22:00:37 +05:30
it 'renders 404' do
2021-03-08 18:12:59 +05:30
get user_url 'nonexistent'
2020-03-13 15:44:24 +05:30
expect ( response ) . to have_gitlab_http_status ( :not_found )
2017-08-17 22:00:37 +05:30
end
end
end
2018-03-27 19:54:05 +05:30
2021-03-08 18:12:59 +05:30
context 'requested in json format' do
2018-03-27 19:54:05 +05:30
let ( :project ) { create ( :project ) }
2020-03-13 15:44:24 +05:30
2018-03-27 19:54:05 +05:30
before do
project . add_developer ( user )
Gitlab :: DataBuilder :: Push . build_sample ( project , user )
sign_in ( user )
end
2021-03-08 18:12:59 +05:30
it 'returns 404 with deprecation message' do
# Requesting "/username?format=json" instead of "/username.json"
get user_url user . username , params : { format : :json }
2018-03-27 19:54:05 +05:30
2021-03-08 18:12:59 +05:30
expect ( response ) . to have_gitlab_http_status ( :not_found )
expect ( response . media_type ) . to eq ( 'application/json' )
expect ( Gitlab :: Json . parse ( response . body ) [ 'message' ] ) . to include ( 'This endpoint is deprecated.' )
2018-03-27 19:54:05 +05:30
end
2021-03-08 18:12:59 +05:30
end
end
2018-11-18 11:00:15 +05:30
2021-03-08 18:12:59 +05:30
describe 'GET /users/:username (deprecated user top)' do
it 'redirects to /user1' do
get '/users/user1'
2018-11-18 11:00:15 +05:30
2021-03-08 18:12:59 +05:30
expect ( response ) . to redirect_to user_path ( 'user1' )
2018-03-27 19:54:05 +05:30
end
2015-04-26 12:48:37 +05:30
end
2021-02-22 17:27:13 +05:30
describe 'GET #activity' do
2021-03-08 18:12:59 +05:30
shared_examples_for 'renders the show template' do
it 'renders the show template' do
get user_activity_url user . username
2021-02-22 17:27:13 +05:30
2021-03-08 18:12:59 +05:30
expect ( response ) . to have_gitlab_http_status ( :ok )
expect ( response ) . to render_template ( 'show' )
end
end
context 'when the user exists and has public visibility' do
context 'when logged in' do
2021-02-22 17:27:13 +05:30
before do
sign_in ( user )
end
2021-03-08 18:12:59 +05:30
it_behaves_like 'renders the show template'
2021-02-22 17:27:13 +05:30
end
2021-03-08 18:12:59 +05:30
context 'when logged out' do
it_behaves_like 'renders the show template'
2021-02-22 17:27:13 +05:30
end
end
context 'when public visibility level is restricted' do
before do
stub_application_setting ( restricted_visibility_levels : [ Gitlab :: VisibilityLevel :: PUBLIC ] )
end
context 'when logged out' do
it 'redirects to login page' do
2021-03-08 18:12:59 +05:30
get user_activity_url user . username
2021-02-22 17:27:13 +05:30
expect ( response ) . to redirect_to new_user_session_path
end
end
context 'when logged in' do
before do
sign_in ( user )
end
2021-03-08 18:12:59 +05:30
it_behaves_like 'renders the show template'
2021-02-22 17:27:13 +05:30
end
end
context 'when a user by that username does not exist' do
context 'when logged out' do
it 'redirects to login page' do
2021-03-08 18:12:59 +05:30
get user_activity_url 'nonexistent'
2021-02-22 17:27:13 +05:30
expect ( response ) . to redirect_to new_user_session_path
end
end
context 'when logged in' do
before do
sign_in ( user )
end
it 'renders 404' do
2021-03-08 18:12:59 +05:30
get user_activity_url 'nonexistent'
2021-02-22 17:27:13 +05:30
expect ( response ) . to have_gitlab_http_status ( :not_found )
end
end
end
2021-03-08 18:12:59 +05:30
context 'requested in json format' do
2023-05-27 22:25:52 +05:30
context 'when profile_tabs_vue feature flag is turned OFF' do
let ( :project ) { create ( :project ) }
2021-02-22 17:27:13 +05:30
2023-05-27 22:25:52 +05:30
before do
project . add_developer ( user )
Gitlab :: DataBuilder :: Push . build_sample ( project , user )
stub_feature_flags ( profile_tabs_vue : false )
sign_in ( user )
end
2021-02-22 17:27:13 +05:30
2023-05-27 22:25:52 +05:30
it 'loads events' do
get user_activity_url user . username , format : :json
2021-02-22 17:27:13 +05:30
2023-05-27 22:25:52 +05:30
expect ( response . media_type ) . to eq ( 'application/json' )
expect ( Gitlab :: Json . parse ( response . body ) [ 'count' ] ) . to eq ( 1 )
end
2021-02-22 17:27:13 +05:30
2023-05-27 22:25:52 +05:30
it 'hides events if the user cannot read cross project' do
allow ( Ability ) . to receive ( :allowed? ) . and_call_original
expect ( Ability ) . to receive ( :allowed? ) . with ( user , :read_cross_project ) { false }
get user_activity_url user . username , format : :json
2021-02-22 17:27:13 +05:30
2023-05-27 22:25:52 +05:30
expect ( response . media_type ) . to eq ( 'application/json' )
expect ( Gitlab :: Json . parse ( response . body ) [ 'count' ] ) . to eq ( 0 )
end
2021-02-22 17:27:13 +05:30
2023-05-27 22:25:52 +05:30
it 'hides events if the user has a private profile' do
Gitlab :: DataBuilder :: Push . build_sample ( project , private_user )
2021-02-22 17:27:13 +05:30
2023-05-27 22:25:52 +05:30
get user_activity_url private_user . username , format : :json
expect ( response . media_type ) . to eq ( 'application/json' )
expect ( Gitlab :: Json . parse ( response . body ) [ 'count' ] ) . to eq ( 0 )
end
2021-02-22 17:27:13 +05:30
end
2023-05-27 22:25:52 +05:30
context 'when profile_tabs_vue feature flag is turned ON' do
let ( :project ) { create ( :project ) }
2021-02-22 17:27:13 +05:30
2023-05-27 22:25:52 +05:30
before do
project . add_developer ( user )
Gitlab :: DataBuilder :: Push . build_sample ( project , user )
stub_feature_flags ( profile_tabs_vue : true )
sign_in ( user )
end
2021-02-22 17:27:13 +05:30
2023-05-27 22:25:52 +05:30
it 'loads events' do
get user_activity_url user . username , format : :json
expect ( response . media_type ) . to eq ( 'application/json' )
expect ( Gitlab :: Json . parse ( response . body ) . count ) . to eq ( 1 )
end
it 'hides events if the user cannot read cross project' do
allow ( Ability ) . to receive ( :allowed? ) . and_call_original
expect ( Ability ) . to receive ( :allowed? ) . with ( user , :read_cross_project ) { false }
get user_activity_url user . username , format : :json
expect ( response . media_type ) . to eq ( 'application/json' )
expect ( Gitlab :: Json . parse ( response . body ) . count ) . to eq ( 0 )
end
it 'hides events if the user has a private profile' do
Gitlab :: DataBuilder :: Push . build_sample ( project , private_user )
get user_activity_url private_user . username , format : :json
expect ( response . media_type ) . to eq ( 'application/json' )
expect ( Gitlab :: Json . parse ( response . body ) . count ) . to eq ( 0 )
end
it 'hides events if the user has a private profile' do
project = create ( :project , :private )
private_event_user = create ( :user , include_private_contributions : true )
push_data = Gitlab :: DataBuilder :: Push . build_sample ( project , private_event_user )
EventCreateService . new . push ( project , private_event_user , push_data )
get user_activity_url private_event_user . username , format : :json
response_body = Gitlab :: Json . parse ( response . body )
event = response_body . first
expect ( response . media_type ) . to eq ( 'application/json' )
expect ( response_body . count ) . to eq ( 1 )
expect ( event ) . to include ( 'created_at' , 'author' , 'action' )
expect ( event [ 'action' ] ) . to eq ( 'private' )
expect ( event ) . not_to include ( 'ref' , 'commit' , 'target' , 'resource_parent' )
end
2021-02-22 17:27:13 +05:30
end
end
end
2021-03-08 18:12:59 +05:30
describe 'GET #ssh_keys' do
context 'non existent user' do
it 'does not generally work' do
get '/not-existent.keys'
2021-02-22 17:27:13 +05:30
expect ( response ) . not_to be_successful
end
end
2021-03-08 18:12:59 +05:30
context 'user with no keys' do
it 'responds the empty body with text/plain content type' do
get " / #{ user . username } .keys "
2021-02-22 17:27:13 +05:30
expect ( response ) . to be_successful
2021-03-08 18:12:59 +05:30
expect ( response . media_type ) . to eq ( " text/plain " )
2021-02-22 17:27:13 +05:30
expect ( response . body ) . to eq ( " " )
end
end
2021-03-08 18:12:59 +05:30
context 'user with keys' do
2021-02-22 17:27:13 +05:30
let! ( :key ) { create ( :key , user : user ) }
let! ( :another_key ) { create ( :another_key , user : user ) }
let! ( :deploy_key ) { create ( :deploy_key , user : user ) }
2021-03-08 18:12:59 +05:30
shared_examples_for 'renders all public keys' do
2022-08-13 15:12:31 +05:30
it 'renders all non-deploy keys terminated with a new line with text/plain content type without the comment key' do
2021-03-08 18:12:59 +05:30
get " / #{ user . username } .keys "
2021-02-22 17:27:13 +05:30
expect ( response ) . to be_successful
2021-03-08 18:12:59 +05:30
expect ( response . media_type ) . to eq ( " text/plain " )
2021-02-22 17:27:13 +05:30
expect ( response . body ) . not_to eq ( '' )
2022-08-13 15:12:31 +05:30
expect ( response . body ) . to eq ( user . all_ssh_keys . map { | key | key + " \n " } . join )
2021-02-22 17:27:13 +05:30
expect ( response . body ) . to include ( key . key . sub ( ' dummy@gitlab.com' , '' ) )
expect ( response . body ) . to include ( another_key . key . sub ( ' dummy@gitlab.com' , '' ) )
expect ( response . body ) . not_to match ( / dummy@gitlab.com / )
2021-03-08 18:12:59 +05:30
expect ( response . body ) . not_to include ( deploy_key . key )
2021-02-22 17:27:13 +05:30
end
end
2021-03-08 18:12:59 +05:30
context 'while signed in' do
2021-02-22 17:27:13 +05:30
before do
2021-03-08 18:12:59 +05:30
sign_in ( user )
2021-02-22 17:27:13 +05:30
end
2021-03-08 18:12:59 +05:30
it_behaves_like 'renders all public keys'
end
2021-02-22 17:27:13 +05:30
2021-03-08 18:12:59 +05:30
context 'when logged out' do
before do
sign_out ( user )
2021-02-22 17:27:13 +05:30
end
2021-03-08 18:12:59 +05:30
it_behaves_like 'renders all public keys'
2021-03-11 19:13:27 +05:30
context 'when public visibility is restricted' do
before do
stub_application_setting ( restricted_visibility_levels : [ Gitlab :: VisibilityLevel :: PUBLIC ] )
end
2021-09-04 01:27:46 +05:30
it 'redirects to sign in' do
get " / #{ user . username } .keys "
expect ( response ) . to redirect_to ( new_user_session_path )
end
2021-03-11 19:13:27 +05:30
end
2021-02-22 17:27:13 +05:30
end
end
end
2021-03-08 18:12:59 +05:30
describe 'GET #gpg_keys' do
context 'non existent user' do
it 'does not generally work' do
get '/not-existent.keys'
2021-02-22 17:27:13 +05:30
expect ( response ) . not_to be_successful
end
end
2021-03-08 18:12:59 +05:30
context 'user with no keys' do
it 'responds the empty body with text/plain content type' do
get " / #{ user . username } .gpg "
2021-02-22 17:27:13 +05:30
expect ( response ) . to be_successful
2021-03-08 18:12:59 +05:30
expect ( response . media_type ) . to eq ( " text/plain " )
2021-02-22 17:27:13 +05:30
expect ( response . body ) . to eq ( " " )
end
end
2021-03-08 18:12:59 +05:30
context 'user with keys' do
2021-02-22 17:27:13 +05:30
let! ( :gpg_key ) { create ( :gpg_key , user : user ) }
2021-12-11 22:18:48 +05:30
let! ( :another_gpg_key ) { create ( :another_gpg_key , user : user . reload ) }
2021-02-22 17:27:13 +05:30
2021-03-08 18:12:59 +05:30
shared_examples_for 'renders all verified GPG keys' do
2022-08-13 15:12:31 +05:30
it 'renders all verified keys terminated with a new line with text/plain content type' do
2021-03-08 18:12:59 +05:30
get " / #{ user . username } .gpg "
2021-02-22 17:27:13 +05:30
expect ( response ) . to be_successful
2021-03-08 18:12:59 +05:30
expect ( response . media_type ) . to eq ( " text/plain " )
2021-02-22 17:27:13 +05:30
expect ( response . body ) . not_to eq ( '' )
2022-08-13 15:12:31 +05:30
expect ( response . body ) . to eq ( user . gpg_keys . filter_map { | gpg_key | gpg_key . key + " \n " if gpg_key . verified? } . join )
2021-02-22 17:27:13 +05:30
expect ( response . body ) . to include ( gpg_key . key )
expect ( response . body ) . to include ( another_gpg_key . key )
end
end
2021-03-08 18:12:59 +05:30
context 'while signed in' do
2021-02-22 17:27:13 +05:30
before do
2021-03-08 18:12:59 +05:30
sign_in ( user )
2021-02-22 17:27:13 +05:30
end
2021-03-08 18:12:59 +05:30
it_behaves_like 'renders all verified GPG keys'
end
2021-02-22 17:27:13 +05:30
2021-03-08 18:12:59 +05:30
context 'when logged out' do
before do
sign_out ( user )
2021-02-22 17:27:13 +05:30
end
2021-03-08 18:12:59 +05:30
it_behaves_like 'renders all verified GPG keys'
end
2021-02-22 17:27:13 +05:30
2021-03-08 18:12:59 +05:30
context 'when revoked' do
shared_examples_for 'doesn\'t render revoked keys' do
it 'doesn\'t render revoked keys' do
get " / #{ user . username } .gpg "
2021-02-22 17:27:13 +05:30
2021-03-08 18:12:59 +05:30
expect ( response . body ) . not_to eq ( '' )
2021-02-22 17:27:13 +05:30
2021-03-08 18:12:59 +05:30
expect ( response . body ) . to include ( gpg_key . key )
expect ( response . body ) . not_to include ( another_gpg_key . key )
end
2021-02-22 17:27:13 +05:30
end
before do
sign_in ( user )
another_gpg_key . revoke
end
2021-03-08 18:12:59 +05:30
context 'while signed in' do
it_behaves_like 'doesn\'t render revoked keys'
2021-02-22 17:27:13 +05:30
end
2021-03-08 18:12:59 +05:30
context 'when logged out' do
before do
sign_out ( user )
end
2021-02-22 17:27:13 +05:30
2021-03-08 18:12:59 +05:30
it_behaves_like 'doesn\'t render revoked keys'
2021-02-22 17:27:13 +05:30
end
end
end
end
2015-04-26 12:48:37 +05:30
describe 'GET #calendar' do
2018-11-18 11:00:15 +05:30
context 'for user' do
let ( :project ) { create ( :project ) }
before do
sign_in ( user )
project . add_developer ( user )
end
context 'with public profile' do
it 'renders calendar' do
push_data = Gitlab :: DataBuilder :: Push . build_sample ( project , public_user )
EventCreateService . new . push ( project , public_user , push_data )
2021-03-08 18:12:59 +05:30
get user_calendar_url public_user . username , format : :json
2015-09-11 14:41:01 +05:30
2020-03-13 15:44:24 +05:30
expect ( response ) . to have_gitlab_http_status ( :ok )
2018-11-18 11:00:15 +05:30
end
end
context 'with private profile' do
it 'does not render calendar' do
push_data = Gitlab :: DataBuilder :: Push . build_sample ( project , private_user )
EventCreateService . new . push ( project , private_user , push_data )
2015-09-11 14:41:01 +05:30
2021-03-08 18:12:59 +05:30
get user_calendar_url private_user . username , format : :json
2018-11-18 11:00:15 +05:30
expect ( response ) . to have_gitlab_http_status ( :not_found )
end
end
2015-04-26 12:48:37 +05:30
end
2016-06-02 11:05:42 +05:30
context 'forked project' do
2017-09-10 17:25:29 +05:30
let ( :project ) { create ( :project ) }
2016-10-01 15:18:49 +05:30
let ( :forked_project ) { Projects :: ForkService . new ( project , user ) . execute }
2016-06-02 11:05:42 +05:30
before do
sign_in ( user )
2018-03-17 18:26:18 +05:30
project . add_developer ( user )
2017-09-10 17:25:29 +05:30
push_data = Gitlab :: DataBuilder :: Push . build_sample ( project , user )
fork_push_data = Gitlab :: DataBuilder :: Push
. build_sample ( forked_project , user )
EventCreateService . new . push ( project , user , push_data )
EventCreateService . new . push ( forked_project , user , fork_push_data )
2016-06-02 11:05:42 +05:30
end
it 'includes forked projects' do
2021-03-08 18:12:59 +05:30
get user_calendar_url user . username
2016-06-02 11:05:42 +05:30
expect ( assigns ( :contributions_calendar ) . projects . count ) . to eq ( 2 )
end
end
2015-04-26 12:48:37 +05:30
end
describe 'GET #calendar_activities' do
2017-09-10 17:25:29 +05:30
let! ( :project ) { create ( :project ) }
2017-08-17 22:00:37 +05:30
let ( :user ) { create ( :user ) }
2015-04-26 12:48:37 +05:30
before do
2019-12-26 22:10:19 +05:30
allow_next_instance_of ( User ) do | instance |
allow ( instance ) . to receive ( :contributed_projects_ids ) . and_return ( [ project . id ] )
end
2015-09-11 14:41:01 +05:30
sign_in ( user )
2018-03-17 18:26:18 +05:30
project . add_developer ( user )
2015-04-26 12:48:37 +05:30
end
2021-03-08 18:12:59 +05:30
it 'renders activities on the specified day' do
get user_calendar_activities_url user . username , date : '2014-07-31'
expect ( response . media_type ) . to eq ( 'text/html' )
expect ( response . body ) . to include ( 'Jul 31, 2014' )
2015-04-26 12:48:37 +05:30
end
2018-11-18 11:00:15 +05:30
context 'for user' do
context 'with public profile' do
2019-07-07 11:18:12 +05:30
let ( :issue ) { create ( :issue , project : project , author : user ) }
let ( :note ) { create ( :note , noteable : issue , author : user , project : project ) }
before do
create_push_event
create_note_event
end
2019-05-18 00:54:41 +05:30
2019-07-07 11:18:12 +05:30
it 'renders calendar_activities' do
2021-03-08 18:12:59 +05:30
get user_calendar_activities_url public_user . username
2019-07-07 11:18:12 +05:30
2021-03-08 18:12:59 +05:30
expect ( response . body ) . not_to be_empty
2019-05-18 00:54:41 +05:30
end
2019-07-07 11:18:12 +05:30
2023-03-17 16:20:25 +05:30
it 'renders the correct url for issues and work items' do
work_item = create ( :work_item , :task , project : project )
issue = create ( :issue , project : project )
EventCreateService . new . open_issue ( work_item , public_user )
EventCreateService . new . open_issue ( issue , public_user )
get user_calendar_activities_url public_user . username
expect ( response . body ) . to include ( project_work_items_path ( project , work_item . iid , iid_path : true ) )
expect ( response . body ) . to include ( project_issue_path ( project , issue ) )
end
2019-07-07 11:18:12 +05:30
it 'avoids N+1 queries' , :request_store do
2021-03-08 18:12:59 +05:30
get user_calendar_activities_url public_user . username
2019-07-07 11:18:12 +05:30
2021-03-08 18:12:59 +05:30
control = ActiveRecord :: QueryRecorder . new { get user_calendar_activities_url public_user . username }
2019-07-07 11:18:12 +05:30
create_push_event
create_note_event
2021-03-08 18:12:59 +05:30
expect { get user_calendar_activities_url public_user . username } . not_to exceed_query_limit ( control )
2019-07-07 11:18:12 +05:30
end
2018-11-18 11:00:15 +05:30
end
context 'with private profile' do
it 'does not render calendar_activities' do
push_data = Gitlab :: DataBuilder :: Push . build_sample ( project , private_user )
EventCreateService . new . push ( project , private_user , push_data )
2021-03-08 18:12:59 +05:30
get user_calendar_activities_url private_user . username
2018-11-18 11:00:15 +05:30
expect ( response ) . to have_gitlab_http_status ( :not_found )
end
end
2019-07-07 11:18:12 +05:30
context 'external authorization' do
2021-03-08 18:12:59 +05:30
subject { get user_calendar_activities_url user . username }
2019-07-07 11:18:12 +05:30
it_behaves_like 'disabled when using an external authorization service'
end
def create_push_event
push_data = Gitlab :: DataBuilder :: Push . build_sample ( project , public_user )
EventCreateService . new . push ( project , public_user , push_data )
end
def create_note_event
EventCreateService . new . leave_note ( note , public_user )
end
2015-04-26 12:48:37 +05:30
end
end
2016-06-02 11:05:42 +05:30
2019-02-02 18:00:53 +05:30
describe 'GET #contributed' do
let ( :project ) { create ( :project , :public ) }
2022-04-04 11:22:00 +05:30
let ( :aimed_for_deletion_project ) { create ( :project , :public , :archived , marked_for_deletion_at : 3 . days . ago ) }
2020-12-08 15:28:05 +05:30
subject do
2021-03-08 18:12:59 +05:30
get user_contributed_projects_url author . username , format : format
2020-12-08 15:28:05 +05:30
end
2019-02-02 18:00:53 +05:30
before do
2020-12-08 15:28:05 +05:30
sign_in ( user )
2019-02-02 18:00:53 +05:30
project . add_developer ( public_user )
project . add_developer ( private_user )
2022-04-04 11:22:00 +05:30
aimed_for_deletion_project . add_developer ( public_user )
aimed_for_deletion_project . add_developer ( private_user )
2020-12-08 15:28:05 +05:30
create ( :push_event , project : project , author : author )
2022-04-04 11:22:00 +05:30
create ( :push_event , project : aimed_for_deletion_project , author : author )
2020-12-08 15:28:05 +05:30
subject
2019-02-02 18:00:53 +05:30
end
2020-12-08 15:28:05 +05:30
shared_examples_for 'renders contributed projects' do
2019-02-02 18:00:53 +05:30
it 'renders contributed projects' do
2020-12-08 15:28:05 +05:30
expect ( response ) . to have_gitlab_http_status ( :ok )
2021-03-08 18:12:59 +05:30
expect ( response . body ) . not_to be_empty
2020-12-08 15:28:05 +05:30
end
2022-04-04 11:22:00 +05:30
it 'does not list projects aimed for deletion' do
expect ( response ) . to have_gitlab_http_status ( :ok )
expect ( assigns ( :contributed_projects ) ) . to eq ( [ project ] )
end
2020-12-08 15:28:05 +05:30
end
2019-02-02 18:00:53 +05:30
2020-12-08 15:28:05 +05:30
% i ( html json ) . each do | format |
context " format: #{ format } " do
let ( :format ) { format }
2019-02-02 18:00:53 +05:30
2020-12-08 15:28:05 +05:30
context 'with public profile' do
let ( :author ) { public_user }
it_behaves_like 'renders contributed projects'
end
context 'with private profile' do
let ( :author ) { private_user }
it 'returns 404' do
expect ( response ) . to have_gitlab_http_status ( :not_found )
end
context 'with a user that has the ability to read private profiles' , :enable_admin_mode do
let ( :user ) { create ( :admin ) }
it_behaves_like 'renders contributed projects'
end
end
end
end
end
describe 'GET #starred' do
let ( :project ) { create ( :project , :public ) }
2022-04-04 11:22:00 +05:30
let ( :aimed_for_deletion_project ) { create ( :project , :public , :archived , marked_for_deletion_at : 3 . days . ago ) }
2020-12-08 15:28:05 +05:30
subject do
2021-03-08 18:12:59 +05:30
get user_starred_projects_url author . username , format : format
2020-12-08 15:28:05 +05:30
end
before do
author . toggle_star ( project )
sign_in ( user )
subject
end
shared_examples_for 'renders starred projects' do
it 'renders starred projects' do
expect ( response ) . to have_gitlab_http_status ( :ok )
2021-03-08 18:12:59 +05:30
expect ( response . body ) . not_to be_empty
2019-02-02 18:00:53 +05:30
end
2022-04-04 11:22:00 +05:30
it 'does not list projects aimed for deletion' do
expect ( response ) . to have_gitlab_http_status ( :ok )
expect ( assigns ( :starred_projects ) ) . to eq ( [ project ] )
end
2019-02-02 18:00:53 +05:30
end
2020-12-08 15:28:05 +05:30
% i ( html json ) . each do | format |
context " format: #{ format } " do
let ( :format ) { format }
2019-02-02 18:00:53 +05:30
2020-12-08 15:28:05 +05:30
context 'with public profile' do
let ( :author ) { public_user }
it_behaves_like 'renders starred projects'
end
2019-02-02 18:00:53 +05:30
2020-12-08 15:28:05 +05:30
context 'with private profile' do
let ( :author ) { private_user }
it 'returns 404' do
expect ( response ) . to have_gitlab_http_status ( :not_found )
end
context 'with a user that has the ability to read private profiles' , :enable_admin_mode do
let ( :user ) { create ( :admin ) }
it_behaves_like 'renders starred projects'
end
end
2019-02-02 18:00:53 +05:30
end
end
end
2016-06-02 11:05:42 +05:30
describe 'GET #snippets' do
before do
sign_in ( user )
end
context 'format html' do
it 'renders snippets page' do
2021-03-08 18:12:59 +05:30
get user_snippets_url user . username
2020-03-13 15:44:24 +05:30
expect ( response ) . to have_gitlab_http_status ( :ok )
2016-06-02 11:05:42 +05:30
expect ( response ) . to render_template ( 'show' )
end
end
context 'format json' do
it 'response with snippets json data' do
2021-03-08 18:12:59 +05:30
get user_snippets_url user . username , format : :json
2020-03-13 15:44:24 +05:30
expect ( response ) . to have_gitlab_http_status ( :ok )
2019-09-30 21:07:59 +05:30
expect ( json_response ) . to have_key ( 'html' )
2016-06-02 11:05:42 +05:30
end
end
2019-07-07 11:18:12 +05:30
context 'external authorization' do
2021-03-08 18:12:59 +05:30
subject { get user_snippets_url user . username }
2019-07-07 11:18:12 +05:30
it_behaves_like 'disabled when using an external authorization service'
end
2016-06-02 11:05:42 +05:30
end
2017-08-17 22:00:37 +05:30
describe 'GET #exists' do
2022-04-04 11:22:00 +05:30
context 'when user exists' do
before do
sign_in ( user )
2022-03-02 08:16:31 +05:30
2022-04-04 11:22:00 +05:30
allow ( :: Gitlab :: ApplicationRateLimiter ) . to receive ( :throttled? ) . and_return ( false )
end
2017-08-17 22:00:37 +05:30
it 'returns JSON indicating the user exists' do
2021-03-08 18:12:59 +05:30
get user_exists_url user . username
2017-08-17 22:00:37 +05:30
expected_json = { exists : true } . to_json
expect ( response . body ) . to eq ( expected_json )
end
context 'when the casing is different' do
let ( :user ) { create ( :user , username : 'CamelCaseUser' ) }
it 'returns JSON indicating the user exists' do
2021-03-08 18:12:59 +05:30
get user_exists_url user . username . downcase
2017-08-17 22:00:37 +05:30
expected_json = { exists : true } . to_json
expect ( response . body ) . to eq ( expected_json )
end
end
end
context 'when the user does not exist' do
2022-04-04 11:22:00 +05:30
it 'will not show a signup page if registration is disabled' do
stub_application_setting ( signup_enabled : false )
get user_exists_url 'foo'
expected_json = { error : " You must be authenticated to access this path. " } . to_json
expect ( response ) . to have_gitlab_http_status ( :unauthorized )
expect ( response . body ) . to eq ( expected_json )
end
2017-08-17 22:00:37 +05:30
it 'returns JSON indicating the user does not exist' do
2021-03-08 18:12:59 +05:30
get user_exists_url 'foo'
2017-08-17 22:00:37 +05:30
expected_json = { exists : false } . to_json
expect ( response . body ) . to eq ( expected_json )
end
context 'when a user changed their username' do
2021-04-29 21:17:54 +05:30
let ( :redirect_route ) { user . namespace . redirect_routes . create! ( path : 'old-username' ) }
2017-08-17 22:00:37 +05:30
it 'returns JSON indicating a user by that username does not exist' do
2021-03-08 18:12:59 +05:30
get user_exists_url 'old-username'
2017-08-17 22:00:37 +05:30
expected_json = { exists : false } . to_json
expect ( response . body ) . to eq ( expected_json )
end
end
end
2022-03-02 08:16:31 +05:30
context 'when the rate limit has been reached' do
it 'returns status 429 Too Many Requests' , :aggregate_failures do
ip = '1.2.3.4'
expect ( :: Gitlab :: ApplicationRateLimiter ) . to receive ( :throttled? ) . with ( :username_exists , scope : ip ) . and_return ( true )
get user_exists_url ( user . username ) , env : { 'REMOTE_ADDR' : ip }
expect ( response ) . to have_gitlab_http_status ( :too_many_requests )
end
end
2017-08-17 22:00:37 +05:30
end
describe '#ensure_canonical_path' do
before do
sign_in ( user )
end
context 'for a GET request' do
context 'when requesting users at the root path' do
context 'when requesting the canonical path' do
let ( :user ) { create ( :user , username : 'CamelCaseUser' ) }
context 'with exactly matching casing' do
it 'responds with success' do
2021-03-08 18:12:59 +05:30
get user_url user . username
2017-08-17 22:00:37 +05:30
2019-12-04 20:38:33 +05:30
expect ( response ) . to be_successful
2017-08-17 22:00:37 +05:30
end
end
context 'with different casing' do
it 'redirects to the correct casing' do
2021-03-08 18:12:59 +05:30
get user_url user . username . downcase
2017-08-17 22:00:37 +05:30
expect ( response ) . to redirect_to ( user )
2021-03-08 18:12:59 +05:30
expect ( flash [ :notice ] ) . to be_nil
2017-08-17 22:00:37 +05:30
end
end
end
2021-03-08 18:12:59 +05:30
shared_examples_for 'redirects to the canonical path' do
2017-08-17 22:00:37 +05:30
it 'redirects to the canonical path' do
2021-03-08 18:12:59 +05:30
get user_url redirect_route . path
2017-08-17 22:00:37 +05:30
expect ( response ) . to redirect_to ( user )
2021-03-08 18:12:59 +05:30
expect ( flash [ :notice ] ) . to eq ( user_moved_message ( redirect_route , user ) )
2017-08-17 22:00:37 +05:30
end
2021-03-08 18:12:59 +05:30
end
context 'when requesting a redirected path' do
2021-04-29 21:17:54 +05:30
let ( :redirect_route ) { user . namespace . redirect_routes . create! ( path : 'old-path' ) }
2021-03-08 18:12:59 +05:30
it_behaves_like 'redirects to the canonical path'
2017-08-17 22:00:37 +05:30
context 'when the old path is a substring of the scheme or host' do
2021-04-29 21:17:54 +05:30
let ( :redirect_route ) { user . namespace . redirect_routes . create! ( path : 'http' ) }
2017-08-17 22:00:37 +05:30
2021-03-08 18:12:59 +05:30
# it does not modify the requested host and ...
it_behaves_like 'redirects to the canonical path'
2017-08-17 22:00:37 +05:30
end
context 'when the old path is substring of users' do
2021-04-29 21:17:54 +05:30
let ( :redirect_route ) { user . namespace . redirect_routes . create! ( path : 'ser' ) }
2017-08-17 22:00:37 +05:30
2021-03-08 18:12:59 +05:30
it_behaves_like 'redirects to the canonical path'
2017-08-17 22:00:37 +05:30
end
end
end
context 'when requesting users under the /users path' do
context 'when requesting the canonical path' do
let ( :user ) { create ( :user , username : 'CamelCaseUser' ) }
context 'with exactly matching casing' do
it 'responds with success' do
2021-03-08 18:12:59 +05:30
get user_projects_url user . username
2017-08-17 22:00:37 +05:30
2019-12-04 20:38:33 +05:30
expect ( response ) . to be_successful
2017-08-17 22:00:37 +05:30
end
end
context 'with different casing' do
it 'redirects to the correct casing' do
2021-03-08 18:12:59 +05:30
get user_projects_url user . username . downcase
2017-08-17 22:00:37 +05:30
expect ( response ) . to redirect_to ( user_projects_path ( user ) )
2021-03-08 18:12:59 +05:30
expect ( flash [ :notice ] ) . to be_nil
2017-08-17 22:00:37 +05:30
end
end
end
2021-03-08 18:12:59 +05:30
shared_examples_for 'redirects to the canonical path' do
2017-08-17 22:00:37 +05:30
it 'redirects to the canonical path' do
2021-03-08 18:12:59 +05:30
get user_projects_url redirect_route . path
2017-08-17 22:00:37 +05:30
expect ( response ) . to redirect_to ( user_projects_path ( user ) )
2021-03-08 18:12:59 +05:30
expect ( flash [ :notice ] ) . to eq ( user_moved_message ( redirect_route , user ) )
2017-08-17 22:00:37 +05:30
end
2021-03-08 18:12:59 +05:30
end
context 'when requesting a redirected path' do
2021-04-29 21:17:54 +05:30
let ( :redirect_route ) { user . namespace . redirect_routes . create! ( path : 'old-path' ) }
2021-03-08 18:12:59 +05:30
it_behaves_like 'redirects to the canonical path'
2017-08-17 22:00:37 +05:30
context 'when the old path is a substring of the scheme or host' do
2021-04-29 21:17:54 +05:30
let ( :redirect_route ) { user . namespace . redirect_routes . create! ( path : 'http' ) }
2017-08-17 22:00:37 +05:30
2021-03-08 18:12:59 +05:30
# it does not modify the requested host and ...
it_behaves_like 'redirects to the canonical path'
2017-08-17 22:00:37 +05:30
end
context 'when the old path is substring of users' do
2021-04-29 21:17:54 +05:30
let ( :redirect_route ) { user . namespace . redirect_routes . create! ( path : 'ser' ) }
2017-08-17 22:00:37 +05:30
2021-03-08 18:12:59 +05:30
# it does not modify the /users part of the path
# (i.e. /users/ser should not become /ufoos/ser) and ...
it_behaves_like 'redirects to the canonical path'
2017-08-17 22:00:37 +05:30
end
end
end
end
end
2022-11-25 23:54:43 +05:30
describe 'POST #follow' do
context 'when over followee limit' do
before do
stub_const ( 'Users::UserFollowUser::MAX_FOLLOWEE_LIMIT' , 2 )
sign_in ( user )
end
it 'alerts and not follow' do
Users :: UserFollowUser :: MAX_FOLLOWEE_LIMIT . times { user . follow ( create ( :user ) ) }
post user_follow_url ( username : public_user . username )
expect ( response ) . to be_redirect
expected_message = format ( _ ( " You can't follow more than %{limit} users. To follow more users, unfollow some others. " ) , limit : Users :: UserFollowUser :: MAX_FOLLOWEE_LIMIT )
expect ( flash [ :alert ] ) . to eq ( expected_message )
expect ( user ) . not_to be_following ( public_user )
end
end
end
2018-11-29 20:51:05 +05:30
context 'token authentication' do
2022-01-12 12:59:36 +05:30
it_behaves_like 'authenticates sessionless user for the request spec' , 'show atom' , public_resource : true do
let ( :url ) { user_url ( user , format : :atom ) }
end
2018-11-29 20:51:05 +05:30
end
2017-08-17 22:00:37 +05:30
def user_moved_message ( redirect_route , user )
" User ' #{ redirect_route . path } ' was moved to ' #{ user . full_path } '. Please update any links and bookmarks that may still have the old path. "
end
2015-04-26 12:48:37 +05:30
end