debian-mirror-gitlab/spec/requests/users_controller_spec.rb

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

969 lines
29 KiB
Ruby
Raw Normal View History

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
2023-07-09 08:55:56 +05:30
expect(response.body).to include(project_work_items_path(project, work_item.iid))
2023-03-17 16:20:25 +05:30
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
2023-07-09 08:55:56 +05:30
context 'when a project has the same name as a desired username' do
let_it_be(:project) { create(:project, name: 'project-name') }
it 'returns JSON indicating a user by that username does not exist' do
get user_exists_url 'project-name'
expected_json = { exists: false }.to_json
expect(response.body).to eq(expected_json)
end
end
2017-08-17 22:00:37 +05:30
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
2023-07-09 08:55:56 +05:30
context 'when user or followee disabled following' do
before do
sign_in(user)
end
it 'alerts and not follow if user disabled following' do
user.enabled_following = false
post user_follow_url(username: public_user.username)
expect(response).to be_redirect
expected_message = format(_('Action not allowed.'))
expect(flash[:alert]).to eq(expected_message)
expect(user).not_to be_following(public_user)
end
it 'alerts and not follow if followee disabled following' do
public_user.enabled_following = false
public_user.save!
post user_follow_url(username: public_user.username)
expect(response).to be_redirect
expected_message = format(_('Action not allowed.'))
expect(flash[:alert]).to eq(expected_message)
expect(user).not_to be_following(public_user)
end
end
2022-11-25 23:54:43 +05:30
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