summaryrefslogtreecommitdiff
path: root/spec/controllers
diff options
context:
space:
mode:
Diffstat (limited to 'spec/controllers')
-rw-r--r--spec/controllers/concerns/import_url_params_spec.rb18
-rw-r--r--spec/controllers/explore/projects_controller_spec.rb7
-rw-r--r--spec/controllers/graphql_controller_spec.rb63
-rw-r--r--spec/controllers/groups/group_links_controller_spec.rb117
-rw-r--r--spec/controllers/groups/runners_controller_spec.rb14
-rw-r--r--spec/controllers/groups_controller_spec.rb34
-rw-r--r--spec/controllers/help_controller_spec.rb6
-rw-r--r--spec/controllers/import/bitbucket_controller_spec.rb150
-rw-r--r--spec/controllers/import/github_controller_spec.rb42
-rw-r--r--spec/controllers/jira_connect/events_controller_spec.rb11
-rw-r--r--spec/controllers/jira_connect/subscriptions_controller_spec.rb18
-rw-r--r--spec/controllers/oauth/jira_dvcs/authorizations_controller_spec.rb (renamed from spec/controllers/oauth/jira/authorizations_controller_spec.rb)6
-rw-r--r--spec/controllers/profiles/accounts_controller_spec.rb2
-rw-r--r--spec/controllers/profiles/keys_controller_spec.rb20
-rw-r--r--spec/controllers/profiles/preferences_controller_spec.rb24
-rw-r--r--spec/controllers/profiles/two_factor_auths_controller_spec.rb25
-rw-r--r--spec/controllers/projects/artifacts_controller_spec.rb3
-rw-r--r--spec/controllers/projects/branches_controller_spec.rb14
-rw-r--r--spec/controllers/projects/commit_controller_spec.rb46
-rw-r--r--spec/controllers/projects/compare_controller_spec.rb32
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb28
-rw-r--r--spec/controllers/projects/group_links_controller_spec.rb130
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb7
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb2
-rw-r--r--spec/controllers/projects/notes_controller_spec.rb16
-rw-r--r--spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb12
-rw-r--r--spec/controllers/projects/pipelines/tests_controller_spec.rb68
-rw-r--r--spec/controllers/projects/services_controller_spec.rb5
-rw-r--r--spec/controllers/projects/static_site_editor_controller_spec.rb65
-rw-r--r--spec/controllers/projects/todos_controller_spec.rb2
-rw-r--r--spec/controllers/projects/usage_quotas_controller_spec.rb37
-rw-r--r--spec/controllers/projects_controller_spec.rb63
-rw-r--r--spec/controllers/search_controller_spec.rb1
-rw-r--r--spec/controllers/sessions_controller_spec.rb10
-rw-r--r--spec/controllers/uploads_controller_spec.rb18
35 files changed, 613 insertions, 503 deletions
diff --git a/spec/controllers/concerns/import_url_params_spec.rb b/spec/controllers/concerns/import_url_params_spec.rb
index ddffb243f7a..170263d10a4 100644
--- a/spec/controllers/concerns/import_url_params_spec.rb
+++ b/spec/controllers/concerns/import_url_params_spec.rb
@@ -55,4 +55,22 @@ RSpec.describe ImportUrlParams do
end
end
end
+
+ context 'url with provided mixed credentials' do
+ let(:params) do
+ ActionController::Parameters.new(project: {
+ import_url: 'https://user@url.com',
+ import_url_user: '', import_url_password: 'password'
+ })
+ end
+
+ describe '#import_url_params' do
+ it 'returns import_url built from both url and hash credentials' do
+ expect(import_url_params).to eq(
+ import_url: 'https://user:password@url.com',
+ import_type: 'git'
+ )
+ end
+ end
+ end
end
diff --git a/spec/controllers/explore/projects_controller_spec.rb b/spec/controllers/explore/projects_controller_spec.rb
index c3f6c653376..bf578489916 100644
--- a/spec/controllers/explore/projects_controller_spec.rb
+++ b/spec/controllers/explore/projects_controller_spec.rb
@@ -112,6 +112,13 @@ RSpec.describe Explore::ProjectsController do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template('topic')
end
+
+ it 'finds topic by case insensitive name' do
+ get :topic, params: { topic_name: 'TOPIC1' }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response).to render_template('topic')
+ end
end
end
end
diff --git a/spec/controllers/graphql_controller_spec.rb b/spec/controllers/graphql_controller_spec.rb
index dbaed8aaa19..4de31e2e135 100644
--- a/spec/controllers/graphql_controller_spec.rb
+++ b/spec/controllers/graphql_controller_spec.rb
@@ -134,6 +134,47 @@ RSpec.describe GraphqlController do
post :execute
end
+
+ it 'calls the track gitlab cli when trackable method' do
+ agent = 'GLab - GitLab CLI'
+ request.env['HTTP_USER_AGENT'] = agent
+
+ expect(Gitlab::UsageDataCounters::GitLabCliActivityUniqueCounter)
+ .to receive(:track_api_request_when_trackable).with(user_agent: agent, user: user)
+
+ post :execute
+ end
+
+ it "assigns username in ApplicationContext" do
+ post :execute
+
+ expect(Gitlab::ApplicationContext.current).to include('meta.user' => user.username)
+ end
+ end
+
+ context 'when 2FA is required for the user' do
+ let(:user) { create(:user, last_activity_on: Date.yesterday) }
+
+ before do
+ group = create(:group, require_two_factor_authentication: true)
+ group.add_developer(user)
+
+ sign_in(user)
+ end
+
+ it 'does not redirect if 2FA is enabled' do
+ expect(controller).not_to receive(:redirect_to)
+
+ post :execute
+
+ expect(response).to have_gitlab_http_status(:unauthorized)
+
+ expected_message = "Authentication error: " \
+ "enable 2FA in your profile settings to continue using GitLab: %{mfa_help_page}" %
+ { mfa_help_page: EnforcesTwoFactorAuthentication::MFA_HELP_PAGE }
+
+ expect(json_response).to eq({ 'errors' => [{ 'message' => expected_message }] })
+ end
end
context 'when user uses an API token' do
@@ -189,6 +230,12 @@ RSpec.describe GraphqlController do
expect(assigns(:context)[:is_sessionless_user]).to be true
end
+ it "assigns username in ApplicationContext" do
+ subject
+
+ expect(Gitlab::ApplicationContext.current).to include('meta.user' => user.username)
+ end
+
it 'calls the track api when trackable method' do
agent = 'vs-code-gitlab-workflow/3.11.1 VSCode/1.52.1 Node.js/12.14.1 (darwin; x64)'
request.env['HTTP_USER_AGENT'] = agent
@@ -208,6 +255,16 @@ RSpec.describe GraphqlController do
subject
end
+
+ it 'calls the track gitlab cli when trackable method' do
+ agent = 'GLab - GitLab CLI'
+ request.env['HTTP_USER_AGENT'] = agent
+
+ expect(Gitlab::UsageDataCounters::GitLabCliActivityUniqueCounter)
+ .to receive(:track_api_request_when_trackable).with(user_agent: agent, user: user)
+
+ subject
+ end
end
context 'when user is not logged in' do
@@ -222,6 +279,12 @@ RSpec.describe GraphqlController do
expect(assigns(:context)[:is_sessionless_user]).to be false
end
+
+ it "does not assign a username in ApplicationContext" do
+ subject
+
+ expect(Gitlab::ApplicationContext.current.key?('meta.user')).to be false
+ end
end
it 'includes request object in context' do
diff --git a/spec/controllers/groups/group_links_controller_spec.rb b/spec/controllers/groups/group_links_controller_spec.rb
index fafe9715946..28febd786de 100644
--- a/spec/controllers/groups/group_links_controller_spec.rb
+++ b/spec/controllers/groups/group_links_controller_spec.rb
@@ -35,120 +35,6 @@ RSpec.describe Groups::GroupLinksController do
end
end
- describe '#create' do
- let(:shared_with_group_id) { shared_with_group.id }
- let(:shared_group_access) { GroupGroupLink.default_access }
-
- subject do
- post(:create,
- params: { group_id: shared_group,
- shared_with_group_id: shared_with_group_id,
- shared_group_access: shared_group_access })
- end
-
- shared_examples 'creates group group link' do
- it 'links group with selected group' do
- expect { subject }.to change { shared_with_group.shared_groups.include?(shared_group) }.from(false).to(true)
- end
-
- it 'redirects to group links page' do
- subject
-
- expect(response).to(redirect_to(group_group_members_path(shared_group)))
- end
-
- it 'allows access for group member' do
- expect { subject }.to(
- change { group_member.can?(:read_group, shared_group) }.from(false).to(true))
- end
- end
-
- context 'when user has correct access to both groups' do
- before do
- shared_with_group.add_developer(user)
- shared_group.add_owner(user)
- end
-
- context 'when default access level is requested' do
- include_examples 'creates group group link'
- end
-
- context 'when owner access is requested' do
- let(:shared_group_access) { Gitlab::Access::OWNER }
-
- before do
- shared_with_group.add_owner(group_member)
- end
-
- include_examples 'creates group group link'
-
- it 'allows admin access for group member' do
- expect { subject }.to(
- change { group_member.can?(:admin_group, shared_group) }.from(false).to(true))
- end
- end
-
- it 'updates project permissions', :sidekiq_inline do
- expect { subject }.to change { group_member.can?(:read_project, project) }.from(false).to(true)
- end
-
- context 'when shared with group id is not present' do
- let(:shared_with_group_id) { nil }
-
- it 'redirects to group links page' do
- subject
-
- expect(response).to(redirect_to(group_group_members_path(shared_group)))
- expect(flash[:alert]).to eq('Please select a group.')
- end
- end
-
- context 'when link is not persisted in the database' do
- before do
- allow(::Groups::GroupLinks::CreateService).to(
- receive_message_chain(:new, :execute)
- .and_return({ status: :error,
- http_status: 409,
- message: 'error' }))
- end
-
- it 'redirects to group links page' do
- subject
-
- expect(response).to(redirect_to(group_group_members_path(shared_group)))
- expect(flash[:alert]).to eq('error')
- end
- end
- end
-
- context 'when user does not have access to the group' do
- before do
- shared_group.add_owner(user)
- end
-
- it 'renders 404' do
- subject
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'when user does not have admin access to the shared group' do
- before do
- shared_with_group.add_developer(user)
- shared_group.add_developer(user)
- end
-
- it 'renders 404' do
- subject
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- include_examples 'placeholder is passed as `id` parameter', :create
- end
-
describe '#update' do
let!(:link) do
create(:group_group_link, { shared_group: shared_group,
@@ -193,7 +79,8 @@ RSpec.describe Groups::GroupLinksController do
subject
- expect(json_response).to eq({ "expires_in" => "about 1 month", "expires_soon" => false })
+ expect(json_response).to eq({ "expires_in" => controller.helpers.time_ago_with_tooltip(expiry_date),
+ "expires_soon" => false })
end
end
diff --git a/spec/controllers/groups/runners_controller_spec.rb b/spec/controllers/groups/runners_controller_spec.rb
index b4950b93a3f..a53f09e2afc 100644
--- a/spec/controllers/groups/runners_controller_spec.rb
+++ b/spec/controllers/groups/runners_controller_spec.rb
@@ -17,7 +17,7 @@ RSpec.describe Groups::RunnersController do
sign_in(user)
end
- describe '#index' do
+ describe '#index', :snowplow do
context 'when user is owner' do
before do
group.add_owner(user)
@@ -30,6 +30,12 @@ RSpec.describe Groups::RunnersController do
expect(response).to render_template(:index)
expect(assigns(:group_runners_limited_count)).to be(2)
end
+
+ it 'tracks the event' do
+ get :index, params: { group_id: group }
+
+ expect_snowplow_event(category: described_class.name, action: 'index', user: user, namespace: group)
+ end
end
context 'when user is not owner' do
@@ -42,6 +48,12 @@ RSpec.describe Groups::RunnersController do
expect(response).to have_gitlab_http_status(:not_found)
end
+
+ it 'does not track the event' do
+ get :index, params: { group_id: group }
+
+ expect_no_snowplow_event
+ end
end
end
diff --git a/spec/controllers/groups_controller_spec.rb b/spec/controllers/groups_controller_spec.rb
index a82c5681911..be30011905c 100644
--- a/spec/controllers/groups_controller_spec.rb
+++ b/spec/controllers/groups_controller_spec.rb
@@ -509,6 +509,14 @@ RSpec.describe GroupsController, factory_default: :keep do
expect(assigns(:issues)).to eq([issue_1])
end
end
+
+ it 'saves the sort order to user preferences' do
+ stub_feature_flags(vue_issues_list: true)
+
+ get :issues, params: { id: group.to_param, sort: 'priority' }
+
+ expect(user.reload.user_preference.issues_sort).to eq('priority')
+ end
end
describe 'GET #merge_requests', :sidekiq_might_not_need_inline do
@@ -1076,19 +1084,6 @@ RSpec.describe GroupsController, factory_default: :keep do
enable_admin_mode!(admin)
end
- context 'when the group export feature flag is not enabled' do
- before do
- sign_in(admin)
- stub_feature_flags(group_import_export: false)
- end
-
- it 'returns a not found error' do
- post :export, params: { id: group.to_param }
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
context 'when the user does not have permission to export the group' do
before do
sign_in(guest)
@@ -1189,19 +1184,6 @@ RSpec.describe GroupsController, factory_default: :keep do
end
end
- context 'when the group export feature flag is not enabled' do
- before do
- sign_in(admin)
- stub_feature_flags(group_import_export: false)
- end
-
- it 'returns a not found error' do
- post :export, params: { id: group.to_param }
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
context 'when the user does not have the required permissions' do
before do
sign_in(guest)
diff --git a/spec/controllers/help_controller_spec.rb b/spec/controllers/help_controller_spec.rb
index 4e2123c8cc4..70dc710f604 100644
--- a/spec/controllers/help_controller_spec.rb
+++ b/spec/controllers/help_controller_spec.rb
@@ -142,11 +142,11 @@ RSpec.describe HelpController do
context 'for Markdown formats' do
subject { get :show, params: { path: path }, format: :md }
- let(:path) { 'ssh/index' }
+ let(:path) { 'user/ssh' }
context 'when requested file exists' do
before do
- expect_file_read(File.join(Rails.root, 'doc/ssh/index.md'), content: fixture_file('blockquote_fence_after.md'))
+ expect_file_read(File.join(Rails.root, 'doc/user/ssh.md'), content: fixture_file('blockquote_fence_after.md'))
subject
end
@@ -257,7 +257,7 @@ RSpec.describe HelpController do
it 'always renders not found' do
get :show,
params: {
- path: 'ssh/index'
+ path: 'user/ssh'
},
format: :foo
expect(response).to be_not_found
diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb
index 91e43adc472..6d24830af27 100644
--- a/spec/controllers/import/bitbucket_controller_spec.rb
+++ b/spec/controllers/import/bitbucket_controller_spec.rb
@@ -26,31 +26,55 @@ RSpec.describe Import::BitbucketController do
session[:oauth_request_token] = {}
end
- it "updates access token" do
- expires_at = Time.current + 1.day
- expires_in = 1.day
- access_token = double(token: token,
- secret: secret,
- expires_at: expires_at,
- expires_in: expires_in,
- refresh_token: refresh_token)
- allow_any_instance_of(OAuth2::Client)
- .to receive(:get_token)
- .with(hash_including(
- 'grant_type' => 'authorization_code',
- 'code' => code,
- redirect_uri: users_import_bitbucket_callback_url),
- {})
- .and_return(access_token)
- stub_omniauth_provider('bitbucket')
-
- get :callback, params: { code: code }
-
- expect(session[:bitbucket_token]).to eq(token)
- expect(session[:bitbucket_refresh_token]).to eq(refresh_token)
- expect(session[:bitbucket_expires_at]).to eq(expires_at)
- expect(session[:bitbucket_expires_in]).to eq(expires_in)
- expect(controller).to redirect_to(status_import_bitbucket_url)
+ context "when auth state param is invalid" do
+ let(:random_key) { "pure_random" }
+ let(:external_bitbucket_auth_url) { "http://fake.bitbucket.host/url" }
+
+ it "redirects to external auth url" do
+ allow(SecureRandom).to receive(:base64).and_return(random_key)
+ allow_next_instance_of(OAuth2::Client) do |client|
+ allow(client).to receive_message_chain(:auth_code, :authorize_url)
+ .with(redirect_uri: users_import_bitbucket_callback_url, state: random_key)
+ .and_return(external_bitbucket_auth_url)
+ end
+
+ get :callback, params: { code: code, state: "invalid-token" }
+
+ expect(controller).to redirect_to(external_bitbucket_auth_url)
+ end
+ end
+
+ context "when auth state param is valid" do
+ before do
+ session[:bitbucket_auth_state] = 'state'
+ end
+
+ it "updates access token" do
+ expires_at = Time.current + 1.day
+ expires_in = 1.day
+ access_token = double(token: token,
+ secret: secret,
+ expires_at: expires_at,
+ expires_in: expires_in,
+ refresh_token: refresh_token)
+ allow_any_instance_of(OAuth2::Client)
+ .to receive(:get_token)
+ .with(hash_including(
+ 'grant_type' => 'authorization_code',
+ 'code' => code,
+ redirect_uri: users_import_bitbucket_callback_url),
+ {})
+ .and_return(access_token)
+ stub_omniauth_provider('bitbucket')
+
+ get :callback, params: { code: code, state: 'state' }
+
+ expect(session[:bitbucket_token]).to eq(token)
+ expect(session[:bitbucket_refresh_token]).to eq(refresh_token)
+ expect(session[:bitbucket_expires_at]).to eq(expires_at)
+ expect(session[:bitbucket_expires_in]).to eq(expires_in)
+ expect(controller).to redirect_to(status_import_bitbucket_url)
+ end
end
end
@@ -59,46 +83,68 @@ RSpec.describe Import::BitbucketController do
@repo = double(name: 'vim', slug: 'vim', owner: 'asd', full_name: 'asd/vim', clone_url: 'http://test.host/demo/url.git', 'valid?' => true)
@invalid_repo = double(name: 'mercurialrepo', slug: 'mercurialrepo', owner: 'asd', full_name: 'asd/mercurialrepo', clone_url: 'http://test.host/demo/mercurialrepo.git', 'valid?' => false)
allow(controller).to receive(:provider_url).and_return('http://demobitbucket.org')
+ end
- assign_session_tokens
+ context "when token does not exists" do
+ let(:random_key) { "pure_random" }
+ let(:external_bitbucket_auth_url) { "http://fake.bitbucket.host/url" }
+
+ it 'redirects to authorize url with state included' do
+ allow(SecureRandom).to receive(:base64).and_return(random_key)
+ allow_next_instance_of(OAuth2::Client) do |client|
+ allow(client).to receive_message_chain(:auth_code, :authorize_url)
+ .with(redirect_uri: users_import_bitbucket_callback_url, state: random_key)
+ .and_return(external_bitbucket_auth_url)
+ end
+
+ get :status, format: :json
+
+ expect(controller).to redirect_to(external_bitbucket_auth_url)
+ end
end
- it_behaves_like 'import controller status' do
+ context "when token is valid" do
before do
- allow(controller).to receive(:provider_url).and_return('http://demobitbucket.org')
+ assign_session_tokens
end
- let(:repo) { @repo }
- let(:repo_id) { @repo.full_name }
- let(:import_source) { @repo.full_name }
- let(:provider_name) { 'bitbucket' }
- let(:client_repos_field) { :repos }
- end
+ it_behaves_like 'import controller status' do
+ before do
+ allow(controller).to receive(:provider_url).and_return('http://demobitbucket.org')
+ end
- it 'returns invalid repos' do
- allow_any_instance_of(Bitbucket::Client).to receive(:repos).and_return([@repo, @invalid_repo])
+ let(:repo) { @repo }
+ let(:repo_id) { @repo.full_name }
+ let(:import_source) { @repo.full_name }
+ let(:provider_name) { 'bitbucket' }
+ let(:client_repos_field) { :repos }
+ end
- get :status, format: :json
+ it 'returns invalid repos' do
+ allow_any_instance_of(Bitbucket::Client).to receive(:repos).and_return([@repo, @invalid_repo])
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['incompatible_repos'].length).to eq(1)
- expect(json_response.dig("incompatible_repos", 0, "id")).to eq(@invalid_repo.full_name)
- expect(json_response['provider_repos'].length).to eq(1)
- expect(json_response.dig("provider_repos", 0, "id")).to eq(@repo.full_name)
- end
+ get :status, format: :json
- context 'when filtering' do
- let(:filter) { '<html>test</html>' }
- let(:expected_filter) { 'test' }
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['incompatible_repos'].length).to eq(1)
+ expect(json_response.dig("incompatible_repos", 0, "id")).to eq(@invalid_repo.full_name)
+ expect(json_response['provider_repos'].length).to eq(1)
+ expect(json_response.dig("provider_repos", 0, "id")).to eq(@repo.full_name)
+ end
- subject { get :status, params: { filter: filter }, as: :json }
+ context 'when filtering' do
+ let(:filter) { '<html>test</html>' }
+ let(:expected_filter) { 'test' }
- it 'passes sanitized filter param to bitbucket client' do
- expect_next_instance_of(Bitbucket::Client) do |client|
- expect(client).to receive(:repos).with(filter: expected_filter).and_return([@repo])
- end
+ subject { get :status, params: { filter: filter }, as: :json }
- subject
+ it 'passes sanitized filter param to bitbucket client' do
+ expect_next_instance_of(Bitbucket::Client) do |client|
+ expect(client).to receive(:repos).with(filter: expected_filter).and_return([@repo])
+ end
+
+ subject
+ end
end
end
end
diff --git a/spec/controllers/import/github_controller_spec.rb b/spec/controllers/import/github_controller_spec.rb
index fd380f9b763..ef66124bff1 100644
--- a/spec/controllers/import/github_controller_spec.rb
+++ b/spec/controllers/import/github_controller_spec.rb
@@ -82,11 +82,33 @@ RSpec.describe Import::GithubController do
expect(controller).to redirect_to(new_import_url)
expect(flash[:alert]).to eq('Access denied to your GitHub account.')
end
+
+ it "includes namespace_id from session if it is present" do
+ namespace_id = 1
+ session[:namespace_id] = 1
+
+ get :callback, params: { state: valid_auth_state }
+
+ expect(controller).to redirect_to(status_import_github_url(namespace_id: namespace_id))
+ end
end
end
describe "POST personal_access_token" do
it_behaves_like 'a GitHub-ish import controller: POST personal_access_token'
+
+ it 'passes namespace_id param as query param if it was present' do
+ namespace_id = 5
+ status_import_url = public_send("status_import_#{provider}_url", { namespace_id: namespace_id })
+
+ allow_next_instance_of(Gitlab::LegacyGithubImport::Client) do |client|
+ allow(client).to receive(:user).and_return(true)
+ end
+
+ post :personal_access_token, params: { personal_access_token: 'some-token', namespace_id: 5 }
+
+ expect(controller).to redirect_to(status_import_url)
+ end
end
describe "GET status" do
@@ -258,7 +280,9 @@ RSpec.describe Import::GithubController do
context 'when user input contains colons and spaces' do
before do
- allow(controller).to receive(:client_repos).and_return([])
+ allow_next_instance_of(Gitlab::GithubImport::Client) do |client|
+ allow(client).to receive(:search_repos_by_name).and_return(items: [])
+ end
end
it 'sanitizes user input' do
@@ -293,6 +317,22 @@ RSpec.describe Import::GithubController do
end
describe "GET realtime_changes" do
+ let(:user) { create(:user) }
+
it_behaves_like 'a GitHub-ish import controller: GET realtime_changes'
+
+ before do
+ assign_session_token(provider)
+ end
+
+ it 'includes stats in response' do
+ create(:project, import_type: provider, namespace: user.namespace, import_status: :finished, import_source: 'example/repo')
+
+ get :realtime_changes
+
+ expect(json_response[0]).to include('stats')
+ expect(json_response[0]['stats']).to include('fetched')
+ expect(json_response[0]['stats']).to include('imported')
+ end
end
end
diff --git a/spec/controllers/jira_connect/events_controller_spec.rb b/spec/controllers/jira_connect/events_controller_spec.rb
index 2129b24b2fb..5e90ceb0f9c 100644
--- a/spec/controllers/jira_connect/events_controller_spec.rb
+++ b/spec/controllers/jira_connect/events_controller_spec.rb
@@ -114,17 +114,6 @@ RSpec.describe JiraConnect::EventsController do
base_url: base_url
)
end
-
- context 'when the `jira_connect_installation_update` feature flag is disabled' do
- before do
- stub_feature_flags(jira_connect_installation_update: false)
- end
-
- it 'does not update the installation', :aggregate_failures do
- expect { subject }.not_to change { installation.reload.attributes }
- expect(response).to have_gitlab_http_status(:ok)
- end
- end
end
context 'when the new base_url is invalid' do
diff --git a/spec/controllers/jira_connect/subscriptions_controller_spec.rb b/spec/controllers/jira_connect/subscriptions_controller_spec.rb
index f548c1f399d..e9c94f09c99 100644
--- a/spec/controllers/jira_connect/subscriptions_controller_spec.rb
+++ b/spec/controllers/jira_connect/subscriptions_controller_spec.rb
@@ -75,6 +75,18 @@ RSpec.describe JiraConnect::SubscriptionsController do
expect(json_response).to include('login_path' => nil)
end
end
+
+ context 'with context qsh' do
+ # The JSON endpoint will be requested by frontend using a JWT that Atlassian provides via Javascript.
+ # This JWT will likely use a context-qsh because Atlassian don't know for which endpoint it will be used.
+ # Read more about context JWT here: https://developer.atlassian.com/cloud/jira/platform/understanding-jwt-for-connect-apps/
+
+ let(:qsh) { 'context-qsh' }
+
+ specify do
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
end
end
end
@@ -102,7 +114,7 @@ RSpec.describe JiraConnect::SubscriptionsController do
end
context 'with valid JWT' do
- let(:claims) { { iss: installation.client_key, sub: 1234 } }
+ let(:claims) { { iss: installation.client_key, sub: 1234, qsh: '123' } }
let(:jwt) { Atlassian::Jwt.encode(claims, installation.shared_secret) }
let(:jira_user) { { 'groups' => { 'items' => [{ 'name' => jira_group_name }] } } }
let(:jira_group_name) { 'site-admins' }
@@ -158,7 +170,7 @@ RSpec.describe JiraConnect::SubscriptionsController do
.stub_request(:get, "#{installation.base_url}/rest/api/3/user?accountId=1234&expand=groups")
.to_return(body: jira_user.to_json, status: 200, headers: { 'Content-Type' => 'application/json' })
- delete :destroy, params: { jwt: jwt, id: subscription.id }
+ delete :destroy, params: { jwt: jwt, id: subscription.id, format: :json }
end
context 'without JWT' do
@@ -170,7 +182,7 @@ RSpec.describe JiraConnect::SubscriptionsController do
end
context 'with valid JWT' do
- let(:claims) { { iss: installation.client_key, sub: 1234 } }
+ let(:claims) { { iss: installation.client_key, sub: 1234, qsh: '123' } }
let(:jwt) { Atlassian::Jwt.encode(claims, installation.shared_secret) }
it 'deletes the subscription' do
diff --git a/spec/controllers/oauth/jira/authorizations_controller_spec.rb b/spec/controllers/oauth/jira_dvcs/authorizations_controller_spec.rb
index f4a335b30f4..496ef7859f9 100644
--- a/spec/controllers/oauth/jira/authorizations_controller_spec.rb
+++ b/spec/controllers/oauth/jira_dvcs/authorizations_controller_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-RSpec.describe Oauth::Jira::AuthorizationsController do
+RSpec.describe Oauth::JiraDvcs::AuthorizationsController do
describe 'GET new' do
it 'redirects to OAuth authorization with correct params' do
get :new, params: { client_id: 'client-123', scope: 'foo', redirect_uri: 'http://example.com/' }
@@ -10,7 +10,7 @@ RSpec.describe Oauth::Jira::AuthorizationsController do
expect(response).to redirect_to(oauth_authorization_url(client_id: 'client-123',
response_type: 'code',
scope: 'foo',
- redirect_uri: oauth_jira_callback_url))
+ redirect_uri: oauth_jira_dvcs_callback_url))
end
it 'replaces the GitHub "repo" scope with "api"' do
@@ -19,7 +19,7 @@ RSpec.describe Oauth::Jira::AuthorizationsController do
expect(response).to redirect_to(oauth_authorization_url(client_id: 'client-123',
response_type: 'code',
scope: 'api',
- redirect_uri: oauth_jira_callback_url))
+ redirect_uri: oauth_jira_dvcs_callback_url))
end
end
diff --git a/spec/controllers/profiles/accounts_controller_spec.rb b/spec/controllers/profiles/accounts_controller_spec.rb
index 011528016ce..1b4b67eeaff 100644
--- a/spec/controllers/profiles/accounts_controller_spec.rb
+++ b/spec/controllers/profiles/accounts_controller_spec.rb
@@ -31,7 +31,7 @@ RSpec.describe Profiles::AccountsController do
end
end
- [:twitter, :facebook, :google_oauth2, :gitlab, :github, :bitbucket, :crowd, :auth0, :authentiq, :dingtalk].each do |provider|
+ [:twitter, :facebook, :google_oauth2, :gitlab, :github, :bitbucket, :crowd, :auth0, :authentiq, :dingtalk, :alicloud].each do |provider|
describe "#{provider} provider" do
let(:user) { create(:omniauth_user, provider: provider.to_s) }
diff --git a/spec/controllers/profiles/keys_controller_spec.rb b/spec/controllers/profiles/keys_controller_spec.rb
index 66f6135df1e..63818337722 100644
--- a/spec/controllers/profiles/keys_controller_spec.rb
+++ b/spec/controllers/profiles/keys_controller_spec.rb
@@ -17,7 +17,25 @@ RSpec.describe Profiles::KeysController do
post :create, params: { key: build(:key, expires_at: expires_at).attributes }
end.to change { Key.count }.by(1)
- expect(Key.last.expires_at).to be_like_time(expires_at)
+ key = Key.last
+ expect(key.expires_at).to be_like_time(expires_at)
+ expect(key.fingerprint_md5).to be_present
+ expect(key.fingerprint_sha256).to be_present
+ end
+
+ context 'with FIPS mode', :fips_mode do
+ it 'creates a new key without MD5 fingerprint' do
+ expires_at = 3.days.from_now
+
+ expect do
+ post :create, params: { key: build(:rsa_key_4096, expires_at: expires_at).attributes }
+ end.to change { Key.count }.by(1)
+
+ key = Key.last
+ expect(key.expires_at).to be_like_time(expires_at)
+ expect(key.fingerprint_md5).to be_nil
+ expect(key.fingerprint_sha256).to be_present
+ end
end
end
end
diff --git a/spec/controllers/profiles/preferences_controller_spec.rb b/spec/controllers/profiles/preferences_controller_spec.rb
index b7870a63f9d..7add3a72337 100644
--- a/spec/controllers/profiles/preferences_controller_spec.rb
+++ b/spec/controllers/profiles/preferences_controller_spec.rb
@@ -46,6 +46,8 @@ RSpec.describe Profiles::PreferencesController do
it "changes the user's preferences" do
prefs = {
color_scheme_id: '1',
+ diffs_deletion_color: '#123456',
+ diffs_addition_color: '#abcdef',
dashboard: 'stars',
theme_id: '2',
first_day_of_week: '1',
@@ -84,5 +86,27 @@ RSpec.describe Profiles::PreferencesController do
expect(response.parsed_body['type']).to eq('alert')
end
end
+
+ context 'on invalid diffs colors setting' do
+ it 'responds with error for diffs_deletion_color' do
+ prefs = { diffs_deletion_color: '#1234567' }
+
+ go params: prefs
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(response.parsed_body['message']).to eq _('Failed to save preferences.')
+ expect(response.parsed_body['type']).to eq('alert')
+ end
+
+ it 'responds with error for diffs_addition_color' do
+ prefs = { diffs_addition_color: '#1234567' }
+
+ go params: prefs
+
+ expect(response).to have_gitlab_http_status(:bad_request)
+ expect(response.parsed_body['message']).to eq _('Failed to save preferences.')
+ expect(response.parsed_body['type']).to eq('alert')
+ end
+ end
end
end
diff --git a/spec/controllers/profiles/two_factor_auths_controller_spec.rb b/spec/controllers/profiles/two_factor_auths_controller_spec.rb
index 47086ccdd2c..33cba675777 100644
--- a/spec/controllers/profiles/two_factor_auths_controller_spec.rb
+++ b/spec/controllers/profiles/two_factor_auths_controller_spec.rb
@@ -104,17 +104,29 @@ RSpec.describe Profiles::TwoFactorAuthsController do
expect(subject).to receive(:build_qr_code).and_return(code)
get :show
- expect(assigns[:qr_code]).to eq code
+ expect(assigns[:qr_code]).to eq(code)
end
- it 'generates a unique otp_secret every time the page is loaded' do
- expect(User).to receive(:generate_otp_secret).with(32).and_call_original.twice
+ it 'generates a single otp_secret with multiple page loads', :freeze_time do
+ expect(User).to receive(:generate_otp_secret).with(32).and_call_original.once
+
+ user.update!(otp_secret: nil, otp_secret_expires_at: nil)
2.times do
get :show
end
end
+ it 'generates a new otp_secret once the ttl has expired' do
+ expect(User).to receive(:generate_otp_secret).with(32).and_call_original.once
+
+ user.update!(otp_secret: "FT7KAVNU63YZH7PBRVPVL7CPSAENXY25", otp_secret_expires_at: 2.minutes.from_now)
+
+ travel_to(10.minutes.from_now) do
+ get :show
+ end
+ end
+
it_behaves_like 'user must first verify their primary email address' do
let(:go) { get :show }
end
@@ -183,7 +195,12 @@ RSpec.describe Profiles::TwoFactorAuthsController do
expect(subject).to receive(:build_qr_code).and_return(code)
go
- expect(assigns[:qr_code]).to eq code
+ expect(assigns[:qr_code]).to eq(code)
+ end
+
+ it 'assigns account_string' do
+ go
+ expect(assigns[:account_string]).to eq("#{Gitlab.config.gitlab.host}:#{user.email}")
end
it 'renders show' do
diff --git a/spec/controllers/projects/artifacts_controller_spec.rb b/spec/controllers/projects/artifacts_controller_spec.rb
index f410c16b30b..d51880b282d 100644
--- a/spec/controllers/projects/artifacts_controller_spec.rb
+++ b/spec/controllers/projects/artifacts_controller_spec.rb
@@ -323,6 +323,7 @@ RSpec.describe Projects::ArtifactsController do
subject
expect(response).to have_gitlab_http_status(:ok)
+ expect(response.headers['Gitlab-Workhorse-Detect-Content-Type']).to eq('true')
expect(send_data).to start_with('artifacts-entry:')
expect(params.keys).to eq(%w(Archive Entry))
@@ -338,7 +339,7 @@ RSpec.describe Projects::ArtifactsController do
def params
@params ||= begin
- base64_params = send_data.sub(/\Aartifacts\-entry:/, '')
+ base64_params = send_data.delete_prefix('artifacts-entry:')
Gitlab::Json.parse(Base64.urlsafe_decode64(base64_params))
end
end
diff --git a/spec/controllers/projects/branches_controller_spec.rb b/spec/controllers/projects/branches_controller_spec.rb
index ea22e6b6f10..1580ad9361d 100644
--- a/spec/controllers/projects/branches_controller_spec.rb
+++ b/spec/controllers/projects/branches_controller_spec.rb
@@ -688,21 +688,23 @@ RSpec.describe Projects::BranchesController do
end
context 'when gitaly is not available' do
+ let(:request) { get :index, format: :html, params: { namespace_id: project.namespace, project_id: project } }
+
before do
allow_next_instance_of(Gitlab::GitalyClient::RefService) do |ref_service|
allow(ref_service).to receive(:local_branches).and_raise(GRPC::DeadlineExceeded)
end
-
- get :index, format: :html, params: {
- namespace_id: project.namespace, project_id: project
- }
end
- it 'returns with a status 200' do
- expect(response).to have_gitlab_http_status(:ok)
+ it 'returns with a status 503' do
+ request
+
+ expect(response).to have_gitlab_http_status(:service_unavailable)
end
it 'sets gitaly_unavailable variable' do
+ request
+
expect(assigns[:gitaly_unavailable]).to be_truthy
end
end
diff --git a/spec/controllers/projects/commit_controller_spec.rb b/spec/controllers/projects/commit_controller_spec.rb
index 72fee40a6e9..a72c98552a5 100644
--- a/spec/controllers/projects/commit_controller_spec.rb
+++ b/spec/controllers/projects/commit_controller_spec.rb
@@ -60,6 +60,22 @@ RSpec.describe Projects::CommitController do
end
end
+ context 'with valid page' do
+ it 'responds with 200' do
+ go(id: commit.id, page: 1)
+
+ expect(response).to be_ok
+ end
+ end
+
+ context 'with invalid page' do
+ it 'does not return an error' do
+ go(id: commit.id, page: ['invalid'])
+
+ expect(response).to be_ok
+ end
+ end
+
it 'handles binary files' do
go(id: TestEnv::BRANCH_SHA['binary-encoding'], format: 'html')
@@ -212,6 +228,21 @@ RSpec.describe Projects::CommitController do
end
end
+ context 'when the revert commit is missing' do
+ it 'renders the 404 page' do
+ post(:revert,
+ params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ start_branch: 'master',
+ id: '1234567890'
+ })
+
+ expect(response).not_to be_successful
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
context 'when the revert was successful' do
it 'redirects to the commits page' do
post(:revert,
@@ -269,6 +300,21 @@ RSpec.describe Projects::CommitController do
end
end
+ context 'when the cherry-pick commit is missing' do
+ it 'renders the 404 page' do
+ post(:cherry_pick,
+ params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ start_branch: 'master',
+ id: '1234567890'
+ })
+
+ expect(response).not_to be_successful
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
context 'when the cherry-pick was successful' do
it 'redirects to the commits page' do
post(:cherry_pick,
diff --git a/spec/controllers/projects/compare_controller_spec.rb b/spec/controllers/projects/compare_controller_spec.rb
index 62b93a2728b..9821618df8d 100644
--- a/spec/controllers/projects/compare_controller_spec.rb
+++ b/spec/controllers/projects/compare_controller_spec.rb
@@ -58,11 +58,13 @@ RSpec.describe Projects::CompareController do
from_project_id: from_project_id,
from: from_ref,
to: to_ref,
- w: whitespace
+ w: whitespace,
+ page: page
}
end
let(:whitespace) { nil }
+ let(:page) { nil }
context 'when the refs exist in the same project' do
context 'when we set the white space param' do
@@ -196,6 +198,34 @@ RSpec.describe Projects::CompareController do
expect(response).to have_gitlab_http_status(:found)
end
end
+
+ context 'when page is valid' do
+ let(:from_project_id) { nil }
+ let(:from_ref) { '08f22f25' }
+ let(:to_ref) { '66eceea0' }
+ let(:page) { 1 }
+
+ it 'shows the diff' do
+ show_request
+
+ expect(response).to be_successful
+ expect(assigns(:diffs).diff_files.first).to be_present
+ expect(assigns(:commits).length).to be >= 1
+ end
+ end
+
+ context 'when page is not valid' do
+ let(:from_project_id) { nil }
+ let(:from_ref) { '08f22f25' }
+ let(:to_ref) { '66eceea0' }
+ let(:page) { ['invalid'] }
+
+ it 'does not return an error' do
+ show_request
+
+ expect(response).to be_successful
+ end
+ end
end
describe 'GET diff_for_path' do
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index fdfc21887a6..f4cad5790a3 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -254,38 +254,54 @@ RSpec.describe Projects::EnvironmentsController do
end
describe 'PATCH #stop' do
+ subject { patch :stop, params: environment_params(format: :json) }
+
context 'when env not available' do
it 'returns 404' do
allow_any_instance_of(Environment).to receive(:available?) { false }
- patch :stop, params: environment_params(format: :json)
+ subject
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'when stop action' do
- it 'returns action url' do
+ it 'returns action url for single stop action' do
action = create(:ci_build, :manual)
allow_any_instance_of(Environment)
- .to receive_messages(available?: true, stop_with_action!: action)
+ .to receive_messages(available?: true, stop_with_actions!: [action])
- patch :stop, params: environment_params(format: :json)
+ subject
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to eq(
{ 'redirect_url' =>
project_job_url(project, action) })
end
+
+ it 'returns environment url for multiple stop actions' do
+ actions = create_list(:ci_build, 2, :manual)
+
+ allow_any_instance_of(Environment)
+ .to receive_messages(available?: true, stop_with_actions!: actions)
+
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to eq(
+ { 'redirect_url' =>
+ project_environment_url(project, environment) })
+ end
end
context 'when no stop action' do
it 'returns env url' do
allow_any_instance_of(Environment)
- .to receive_messages(available?: true, stop_with_action!: nil)
+ .to receive_messages(available?: true, stop_with_actions!: nil)
- patch :stop, params: environment_params(format: :json)
+ subject
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to eq(
diff --git a/spec/controllers/projects/group_links_controller_spec.rb b/spec/controllers/projects/group_links_controller_spec.rb
index ea15d483c90..96705d82ac5 100644
--- a/spec/controllers/projects/group_links_controller_spec.rb
+++ b/spec/controllers/projects/group_links_controller_spec.rb
@@ -18,136 +18,6 @@ RSpec.describe Projects::GroupLinksController do
travel_back
end
- describe '#create' do
- shared_context 'link project to group' do
- before do
- post(:create, params: {
- namespace_id: project.namespace,
- project_id: project,
- link_group_id: group.id,
- link_group_access: ProjectGroupLink.default_access
- })
- end
- end
-
- context 'when project is not allowed to be shared with a group' do
- before do
- group.update!(share_with_group_lock: false)
- end
-
- include_context 'link project to group'
-
- it 'responds with status 404' do
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'when user has access to group they want to link project to' do
- before do
- group.add_developer(user)
- end
-
- include_context 'link project to group'
-
- it 'links project with selected group' do
- expect(group.shared_projects).to include project
- end
-
- it 'redirects to project group links page' do
- expect(response).to redirect_to(
- project_project_members_path(project)
- )
- end
- end
-
- context 'when user doers not have access to group they want to link to' do
- include_context 'link project to group'
-
- it 'renders 404' do
- expect(response).to have_gitlab_http_status(:not_found)
- end
-
- it 'does not share project with that group' do
- expect(group.shared_projects).not_to include project
- end
- end
-
- context 'when user does not have access to the public group' do
- let(:group) { create(:group, :public) }
-
- include_context 'link project to group'
-
- it 'renders 404' do
- expect(response).to have_gitlab_http_status(:not_found)
- end
-
- it 'does not share project with that group' do
- expect(group.shared_projects).not_to include project
- end
- end
-
- context 'when project group id equal link group id' do
- before do
- group2.add_developer(user)
-
- post(:create, params: {
- namespace_id: project.namespace,
- project_id: project,
- link_group_id: group2.id,
- link_group_access: ProjectGroupLink.default_access
- })
- end
-
- it 'does not share project with selected group' do
- expect(group2.shared_projects).not_to include project
- end
-
- it 'redirects to project group links page' do
- expect(response).to redirect_to(
- project_project_members_path(project)
- )
- end
- end
-
- context 'when link group id is not present' do
- before do
- post(:create, params: {
- namespace_id: project.namespace,
- project_id: project,
- link_group_access: ProjectGroupLink.default_access
- })
- end
-
- it 'redirects to project group links page' do
- expect(response).to redirect_to(
- project_project_members_path(project)
- )
- expect(flash[:alert]).to eq('Please select a group.')
- end
- end
-
- context 'when link is not persisted in the database' do
- before do
- allow(::Projects::GroupLinks::CreateService).to receive_message_chain(:new, :execute)
- .and_return({ status: :error, http_status: 409, message: 'error' })
-
- post(:create, params: {
- namespace_id: project.namespace,
- project_id: project,
- link_group_id: group.id,
- link_group_access: ProjectGroupLink.default_access
- })
- end
-
- it 'redirects to project group links page' do
- expect(response).to redirect_to(
- project_project_members_path(project)
- )
- expect(flash[:alert]).to eq('error')
- end
- end
- end
-
describe '#update' do
let_it_be(:link) do
create(
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index 9d3711d8a96..ce0af784cdf 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -148,6 +148,13 @@ RSpec.describe Projects::IssuesController do
allow(Kaminari.config).to receive(:default_per_page).and_return(1)
end
+ it 'redirects to last page when out of bounds on non-html requests' do
+ get :index, params: params.merge(page: last_page + 1), format: 'atom'
+
+ expect(response).to have_gitlab_http_status(:redirect)
+ expect(response).to redirect_to(action: 'index', format: 'atom', page: last_page, state: 'opened')
+ end
+
it 'does not use pagination if disabled' do
allow(controller).to receive(:pagination_disabled?).and_return(true)
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index ed68d6a87b8..e9f1232b5e7 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -796,7 +796,7 @@ RSpec.describe Projects::JobsController, :clean_gitlab_redis_shared_state do
retried_build = Ci::Build.last
- Ci::RetryBuildService.clone_accessors.each do |accessor|
+ Ci::Build.clone_accessors.each do |accessor|
expect(job.read_attribute(accessor))
.to eq(retried_build.read_attribute(accessor)),
"Mismatched attribute on \"#{accessor}\". " \
diff --git a/spec/controllers/projects/notes_controller_spec.rb b/spec/controllers/projects/notes_controller_spec.rb
index 2df31904380..07874c8a8af 100644
--- a/spec/controllers/projects/notes_controller_spec.rb
+++ b/spec/controllers/projects/notes_controller_spec.rb
@@ -423,7 +423,21 @@ RSpec.describe Projects::NotesController do
end
context 'when creating a confidential note' do
- let(:extra_request_params) { { format: :json } }
+ let(:project) { create(:project) }
+ let(:note_params) do
+ { note: note_text, noteable_id: issue.id, noteable_type: 'Issue' }.merge(extra_note_params)
+ end
+
+ let(:request_params) do
+ {
+ note: note_params,
+ namespace_id: project.namespace,
+ project_id: project,
+ target_type: 'issue',
+ target_id: issue.id,
+ format: :json
+ }
+ end
context 'when `confidential` parameter is not provided' do
it 'sets `confidential` to `false` in JSON response' do
diff --git a/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb b/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb
index a655c742973..fc741d0f3f6 100644
--- a/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb
+++ b/spec/controllers/projects/packages/infrastructure_registry_controller_spec.rb
@@ -41,17 +41,5 @@ RSpec.describe Projects::Packages::InfrastructureRegistryController do
it_behaves_like 'returning response status', :not_found
end
-
- context 'with package file pending destruction' do
- let_it_be(:package_file_pending_destruction) { create(:package_file, :pending_destruction, package: terraform_module) }
-
- let(:terraform_module_package_file) { terraform_module.package_files.first }
-
- it 'does not return them' do
- subject
-
- expect(assigns(:package_files)).to contain_exactly(terraform_module_package_file)
- end
- end
end
end
diff --git a/spec/controllers/projects/pipelines/tests_controller_spec.rb b/spec/controllers/projects/pipelines/tests_controller_spec.rb
index e6ff3a487ac..113781bab7c 100644
--- a/spec/controllers/projects/pipelines/tests_controller_spec.rb
+++ b/spec/controllers/projects/pipelines/tests_controller_spec.rb
@@ -40,28 +40,56 @@ RSpec.describe Projects::Pipelines::TestsController do
let(:suite_name) { 'test' }
let(:build_ids) { pipeline.latest_builds.pluck(:id) }
- before do
- build = main_pipeline.builds.last
- build.update_column(:finished_at, 1.day.ago) # Just to be sure we are included in the report window
-
- # The JUnit fixture for the given build has 3 failures.
- # This service will create 1 test case failure record for each.
- Ci::TestFailureHistoryService.new(main_pipeline).execute
+ context 'when artifacts are expired' do
+ before do
+ pipeline.job_artifacts.first.update!(expire_at: Date.yesterday)
+ end
+
+ it 'renders not_found errors', :aggregate_failures do
+ get_tests_show_json(build_ids)
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(json_response['errors']).to eq('Test report artifacts have expired')
+ end
+
+ context 'when ci_test_report_artifacts_expired is disabled' do
+ before do
+ stub_feature_flags(ci_test_report_artifacts_expired: false)
+ end
+ it 'renders test suite', :aggregate_failures do
+ get_tests_show_json(build_ids)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['name']).to eq('test')
+ end
+ end
end
- it 'renders test suite data' do
- get_tests_show_json(build_ids)
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['name']).to eq('test')
-
- # Each test failure in this pipeline has a matching failure in the default branch
- recent_failures = json_response['test_cases'].map { |tc| tc['recent_failures'] }
- expect(recent_failures).to eq([
- { 'count' => 1, 'base_branch' => 'master' },
- { 'count' => 1, 'base_branch' => 'master' },
- { 'count' => 1, 'base_branch' => 'master' }
- ])
+ context 'when artifacts are not expired' do
+ before do
+ build = main_pipeline.builds.last
+ build.update_column(:finished_at, 1.day.ago) # Just to be sure we are included in the report window
+
+ # The JUnit fixture for the given build has 3 failures.
+ # This service will create 1 test case failure record for each.
+ Ci::TestFailureHistoryService.new(main_pipeline).execute
+ end
+
+ it 'renders test suite data', :aggregate_failures do
+ get_tests_show_json(build_ids)
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response['name']).to eq('test')
+ expect(json_response['artifacts_expired']).to be_falsey
+
+ # Each test failure in this pipeline has a matching failure in the default branch
+ recent_failures = json_response['test_cases'].map { |tc| tc['recent_failures'] }
+ expect(recent_failures).to eq([
+ { 'count' => 1, 'base_branch' => 'master' },
+ { 'count' => 1, 'base_branch' => 'master' },
+ { 'count' => 1, 'base_branch' => 'master' }
+ ])
+ end
end
end
diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb
index 35e5422d072..7e96c59fbb1 100644
--- a/spec/controllers/projects/services_controller_spec.rb
+++ b/spec/controllers/projects/services_controller_spec.rb
@@ -359,10 +359,9 @@ RSpec.describe Projects::ServicesController do
def prometheus_integration_as_data
pi = project.prometheus_integration.reload
attrs = pi.attributes.except('encrypted_properties',
- 'encrypted_properties_iv',
- 'encrypted_properties_tmp')
+ 'encrypted_properties_iv')
- [attrs, pi.encrypted_properties_tmp]
+ [attrs, pi.properties]
end
end
diff --git a/spec/controllers/projects/static_site_editor_controller_spec.rb b/spec/controllers/projects/static_site_editor_controller_spec.rb
index 26161b5fb5c..e1f25589eeb 100644
--- a/spec/controllers/projects/static_site_editor_controller_spec.rb
+++ b/spec/controllers/projects/static_site_editor_controller_spec.rb
@@ -76,12 +76,11 @@ RSpec.describe Projects::StaticSiteEditorController do
get :show, params: default_params
end
- it 'increases the views counter' do
- expect(Gitlab::UsageDataCounters::StaticSiteEditorCounter).to have_received(:increment_views_count)
- end
+ it 'redirects to the Web IDE' do
+ get :show, params: default_params
- it 'renders the edit page' do
- expect(response).to render_template(:show)
+ expected_path_regex = %r[-/ide/project/#{project.full_path}/edit/master/-/README.md]
+ expect(response).to redirect_to(expected_path_regex)
end
it 'assigns ref and path variables' do
@@ -96,62 +95,6 @@ RSpec.describe Projects::StaticSiteEditorController do
expect(response).to have_gitlab_http_status(:not_found)
end
end
-
- context 'when invalid config file' do
- let(:service_response) { ServiceResponse.error(message: 'invalid') }
-
- it 'redirects to project page and flashes error message' do
- expect(response).to redirect_to(project_path(project))
- expect(controller).to set_flash[:alert].to('invalid')
- end
- end
-
- context 'with a service response payload containing multiple data types' do
- let(:data) do
- {
- a_string: 'string',
- an_array: [
- {
- foo: 'bar'
- }
- ],
- an_integer: 123,
- a_hash: {
- a_deeper_hash: {
- foo: 'bar'
- }
- },
- a_boolean: true,
- a_nil: nil
- }
- end
-
- let(:assigns_data) { assigns(:data) }
-
- it 'leaves data values which are strings as strings' do
- expect(assigns_data[:a_string]).to eq('string')
- end
-
- it 'leaves data values which are integers as integers' do
- expect(assigns_data[:an_integer]).to eq(123)
- end
-
- it 'serializes data values which are booleans to JSON' do
- expect(assigns_data[:a_boolean]).to eq('true')
- end
-
- it 'serializes data values which are arrays to JSON' do
- expect(assigns_data[:an_array]).to eq('[{"foo":"bar"}]')
- end
-
- it 'serializes data values which are hashes to JSON' do
- expect(assigns_data[:a_hash]).to eq('{"a_deeper_hash":{"foo":"bar"}}')
- end
-
- it 'serializes data values which are nil to an empty string' do
- expect(assigns_data[:a_nil]).to eq('')
- end
- end
end
end
end
diff --git a/spec/controllers/projects/todos_controller_spec.rb b/spec/controllers/projects/todos_controller_spec.rb
index 9a73417ffdb..d87f4258b9c 100644
--- a/spec/controllers/projects/todos_controller_spec.rb
+++ b/spec/controllers/projects/todos_controller_spec.rb
@@ -8,7 +8,7 @@ RSpec.describe Projects::TodosController do
let(:issue) { create(:issue, project: project) }
let(:merge_request) { create(:merge_request, source_project: project) }
- let(:design) { create(:design, project: project, issue: issue) }
+ let(:design) { create(:design, :with_versions, project: project, issue: issue) }
let(:parent) { project }
shared_examples 'issuable todo actions' do
diff --git a/spec/controllers/projects/usage_quotas_controller_spec.rb b/spec/controllers/projects/usage_quotas_controller_spec.rb
index 6125ba13f96..2831de00348 100644
--- a/spec/controllers/projects/usage_quotas_controller_spec.rb
+++ b/spec/controllers/projects/usage_quotas_controller_spec.rb
@@ -4,17 +4,44 @@ require 'spec_helper'
RSpec.describe Projects::UsageQuotasController do
let_it_be(:user) { create(:user) }
- let_it_be(:project) { create(:project, namespace: user.namespace) }
+ let_it_be(:group) { create(:group) }
+ let_it_be(:project) { create(:project, group: group) }
describe 'GET #index' do
render_views
- it 'does not render search settings partial' do
+ subject { get(:index, params: { namespace_id: project.namespace, project_id: project }) }
+
+ before do
sign_in(user)
- get(:index, params: { namespace_id: user.namespace, project_id: project })
+ end
+
+ context 'when user does not have read_usage_quotas permission' do
+ before do
+ project.add_developer(user)
+ end
+
+ it 'renders not_found' do
+ subject
+
+ expect(response).to render_template('errors/not_found')
+ expect(response).not_to render_template('shared/search_settings')
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when user has read_usage_quotas permission' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ it 'renders index with 200 status code' do
+ subject
- expect(response).to render_template('index')
- expect(response).not_to render_template('shared/search_settings')
+ expect(response).to render_template('index')
+ expect(response).not_to render_template('shared/search_settings')
+ expect(response).to have_gitlab_http_status(:ok)
+ end
end
end
end
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index c098ea71f7a..07bd198137a 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -473,28 +473,6 @@ RSpec.describe ProjectsController do
end
end
end
-
- context 'with new_project_sast_enabled', :experiment do
- let(:params) do
- {
- path: 'foo',
- description: 'bar',
- namespace_id: user.namespace.id,
- initialize_with_sast: '1'
- }
- end
-
- it 'tracks an event on project creation' do
- expect(experiment(:new_project_sast_enabled)).to track(:created,
- property: 'blank',
- checked: true,
- project: an_instance_of(Project),
- namespace: user.namespace
- ).on_next_instance.with_context(user: user)
-
- post :create, params: { project: params }
- end
- end
end
describe 'GET edit' do
@@ -1159,16 +1137,15 @@ RSpec.describe ProjectsController do
context 'when gitaly is unavailable' do
before do
expect_next_instance_of(TagsFinder) do |finder|
- allow(finder).to receive(:execute).and_raise(Gitlab::Git::CommandError)
+ allow(finder).to receive(:execute).and_raise(Gitlab::Git::CommandError, 'something went wrong')
end
end
- it 'gets an empty list of tags' do
+ it 'responds with 503 error' do
get :refs, params: { namespace_id: project.namespace, id: project, ref: "123456" }
- expect(json_response["Branches"]).to include("master")
- expect(json_response["Tags"]).to eq([])
- expect(json_response["Commits"]).to include("123456")
+ expect(response).to have_gitlab_http_status(:service_unavailable)
+ expect(json_response['error']).to eq 'Unable to load refs'
end
end
@@ -1466,14 +1443,15 @@ RSpec.describe ProjectsController do
end
describe '#download_export', :clean_gitlab_redis_rate_limiting do
+ let(:project) { create(:project, :with_export, service_desk_enabled: false) }
let(:action) { :download_export }
context 'object storage enabled' do
context 'when project export is enabled' do
- it 'returns 302' do
+ it 'returns 200' do
get action, params: { namespace_id: project.namespace, id: project }
- expect(response).to have_gitlab_http_status(:found)
+ expect(response).to have_gitlab_http_status(:ok)
end
end
@@ -1513,14 +1491,37 @@ RSpec.describe ProjectsController do
expect(response.body).to eq('This endpoint has been requested too many times. Try again later.')
expect(response).to have_gitlab_http_status(:too_many_requests)
end
+ end
+
+ context 'applies correct scope when throttling', :clean_gitlab_redis_rate_limiting do
+ before do
+ stub_application_setting(project_download_export_limit: 1)
+ end
- it 'applies correct scope when throttling' do
+ it 'applies throttle per namespace' do
expect(Gitlab::ApplicationRateLimiter)
.to receive(:throttled?)
- .with(:project_download_export, scope: [user, project])
+ .with(:project_download_export, scope: [user, project.namespace])
post action, params: { namespace_id: project.namespace, id: project }
end
+
+ it 'throttles downloads within same namespaces' do
+ # simulate prior request to the same namespace, which increments the rate limit counter for that scope
+ Gitlab::ApplicationRateLimiter.throttled?(:project_download_export, scope: [user, project.namespace])
+
+ get action, params: { namespace_id: project.namespace, id: project }
+ expect(response).to have_gitlab_http_status(:too_many_requests)
+ end
+
+ it 'allows downloads from different namespaces' do
+ # simulate prior request to a different namespace, which increments the rate limit counter for that scope
+ Gitlab::ApplicationRateLimiter.throttled?(:project_download_export,
+ scope: [user, create(:project, :with_export).namespace])
+
+ get action, params: { namespace_id: project.namespace, id: project }
+ expect(response).to have_gitlab_http_status(:ok)
+ end
end
end
end
diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb
index 9482448fc03..4abcd414e51 100644
--- a/spec/controllers/search_controller_spec.rb
+++ b/spec/controllers/search_controller_spec.rb
@@ -211,6 +211,7 @@ RSpec.describe SearchController do
:global_search_merge_requests_tab | 'merge_requests'
:global_search_wiki_tab | 'wiki_blobs'
:global_search_commits_tab | 'commits'
+ :global_search_users_tab | 'users'
end
with_them do
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index 03d053e6f97..877ca7cd6c6 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -193,6 +193,10 @@ RSpec.describe SessionsController do
end
context 'with reCAPTCHA' do
+ before do
+ stub_feature_flags(arkose_labs_login_challenge: false)
+ end
+
def unsuccesful_login(user_params, sesion_params: {})
# Without this, `verify_recaptcha` arbitrarily returns true in test env
Recaptcha.configuration.skip_verify_env.delete('test')
@@ -234,7 +238,7 @@ RSpec.describe SessionsController do
unsuccesful_login(user_params)
- expect(response).to render_template(:new)
+ expect(response).to redirect_to new_user_session_path
expect(flash[:alert]).to include _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
expect(subject.current_user).to be_nil
end
@@ -258,7 +262,7 @@ RSpec.describe SessionsController do
it 'displays an error when the reCAPTCHA is not solved' do
unsuccesful_login(user_params, sesion_params: { failed_login_attempts: 6 })
- expect(response).to render_template(:new)
+ expect(response).to redirect_to new_user_session_path
expect(flash[:alert]).to include _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
expect(subject.current_user).to be_nil
end
@@ -278,7 +282,7 @@ RSpec.describe SessionsController do
it 'displays an error when the reCAPTCHA is not solved' do
unsuccesful_login(user_params)
- expect(response).to render_template(:new)
+ expect(response).to redirect_to new_user_session_path
expect(flash[:alert]).to include _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
expect(subject.current_user).to be_nil
end
diff --git a/spec/controllers/uploads_controller_spec.rb b/spec/controllers/uploads_controller_spec.rb
index 8442c214cd3..ffcd759435c 100644
--- a/spec/controllers/uploads_controller_spec.rb
+++ b/spec/controllers/uploads_controller_spec.rb
@@ -701,6 +701,24 @@ RSpec.describe UploadsController do
end
end
end
+
+ context 'when viewing alert metric images' do
+ let!(:user) { create(:user) }
+ let!(:project) { create(:project) }
+ let(:alert) { create(:alert_management_alert, project: project) }
+ let(:metric_image) { create(:alert_metric_image, alert: alert) }
+
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ it "responds with status 200" do
+ get :show, params: { model: "alert_management_metric_image", mounted_as: 'file', id: metric_image.id, filename: metric_image.filename }
+
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
end
def post_authorize(verified: true)