Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'spec/controllers')
-rw-r--r--spec/controllers/admin/application_settings_controller_spec.rb12
-rw-r--r--spec/controllers/admin/clusters_controller_spec.rb44
-rw-r--r--spec/controllers/admin/runner_projects_controller_spec.rb43
-rw-r--r--spec/controllers/admin/runners_controller_spec.rb2
-rw-r--r--spec/controllers/admin/topics_controller_spec.rb16
-rw-r--r--spec/controllers/application_controller_spec.rb18
-rw-r--r--spec/controllers/autocomplete_controller_spec.rb2
-rw-r--r--spec/controllers/boards/lists_controller_spec.rb4
-rw-r--r--spec/controllers/concerns/product_analytics_tracking_spec.rb171
-rw-r--r--spec/controllers/concerns/spammable_actions/akismet_mark_as_spam_action_spec.rb22
-rw-r--r--spec/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support_spec.rb2
-rw-r--r--spec/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support_spec.rb2
-rw-r--r--spec/controllers/concerns/spammable_actions/captcha_check/rest_api_actions_support_spec.rb86
-rw-r--r--spec/controllers/confirmations_controller_spec.rb2
-rw-r--r--spec/controllers/dashboard_controller_spec.rb55
-rw-r--r--spec/controllers/graphql_controller_spec.rb39
-rw-r--r--spec/controllers/groups/clusters_controller_spec.rb44
-rw-r--r--spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb22
-rw-r--r--spec/controllers/groups/group_members_controller_spec.rb118
-rw-r--r--spec/controllers/groups/releases_controller_spec.rb34
-rw-r--r--spec/controllers/groups/runners_controller_spec.rb38
-rw-r--r--spec/controllers/jira_connect/events_controller_spec.rb54
-rw-r--r--spec/controllers/passwords_controller_spec.rb2
-rw-r--r--spec/controllers/projects/blob_controller_spec.rb27
-rw-r--r--spec/controllers/projects/ci/pipeline_editor_controller_spec.rb12
-rw-r--r--spec/controllers/projects/ci/secure_files_controller_spec.rb49
-rw-r--r--spec/controllers/projects/clusters_controller_spec.rb44
-rw-r--r--spec/controllers/projects/environments_controller_spec.rb27
-rw-r--r--spec/controllers/projects/error_tracking_controller_spec.rb22
-rw-r--r--spec/controllers/projects/forks_controller_spec.rb9
-rw-r--r--spec/controllers/projects/incidents_controller_spec.rb1
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb62
-rw-r--r--spec/controllers/projects/merge_requests/diffs_controller_spec.rb40
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb29
-rw-r--r--spec/controllers/projects/pipelines_controller_spec.rb35
-rw-r--r--spec/controllers/projects/project_members_controller_spec.rb224
-rw-r--r--spec/controllers/projects/releases_controller_spec.rb162
-rw-r--r--spec/controllers/projects/runners_controller_spec.rb2
-rw-r--r--spec/controllers/projects/serverless/functions_controller_spec.rb23
-rw-r--r--spec/controllers/projects/services_controller_spec.rb11
-rw-r--r--spec/controllers/projects/tags/releases_controller_spec.rb4
-rw-r--r--spec/controllers/projects/tags_controller_spec.rb2
-rw-r--r--spec/controllers/projects_controller_spec.rb71
-rw-r--r--spec/controllers/search_controller_spec.rb30
-rw-r--r--spec/controllers/sessions_controller_spec.rb6
-rw-r--r--spec/controllers/snippets_controller_spec.rb4
46 files changed, 1112 insertions, 616 deletions
diff --git a/spec/controllers/admin/application_settings_controller_spec.rb b/spec/controllers/admin/application_settings_controller_spec.rb
index fb4c0970653..f7b2bab3615 100644
--- a/spec/controllers/admin/application_settings_controller_spec.rb
+++ b/spec/controllers/admin/application_settings_controller_spec.rb
@@ -81,6 +81,18 @@ RSpec.describe Admin::ApplicationSettingsController, :do_not_mock_admin_mode_set
expect(body).to include('counts')
expect(response).to have_gitlab_http_status(:ok)
end
+
+ describe 'usage data counter' do
+ let(:counter) { Gitlab::UsageDataCounters::ServiceUsageDataCounter }
+
+ it 'incremented when json generated' do
+ expect { get :usage_data, format: :json }.to change { counter.read(:download_payload_click) }.by(1)
+ end
+
+ it 'not incremented when html format requested' do
+ expect { get :usage_data }.not_to change { counter.read(:download_payload_click) }
+ end
+ end
end
describe 'PUT #update' do
diff --git a/spec/controllers/admin/clusters_controller_spec.rb b/spec/controllers/admin/clusters_controller_spec.rb
index 25c4830a79a..fed9d2e8588 100644
--- a/spec/controllers/admin/clusters_controller_spec.rb
+++ b/spec/controllers/admin/clusters_controller_spec.rb
@@ -27,6 +27,10 @@ RSpec.describe Admin::ClustersController do
create(:cluster, :disabled, :provided_by_gcp, :production_environment, :instance)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { get_index }
+ end
+
it 'lists available clusters and displays html' do
get_index
@@ -105,6 +109,10 @@ RSpec.describe Admin::ClustersController do
get :new, params: { provider: provider }
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality for new cluster' do
context 'when omniauth has been configured' do
let(:key) { 'secret-key' }
@@ -226,6 +234,10 @@ RSpec.describe Admin::ClustersController do
post :create_gcp, params: params
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { post_create_gcp }
+ end
+
describe 'functionality' do
context 'when access token is valid' do
before do
@@ -318,6 +330,10 @@ RSpec.describe Admin::ClustersController do
post :create_aws, params: params
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { post_create_aws }
+ end
+
it 'creates a new cluster' do
expect(ClusterProvisionWorker).to receive(:perform_async)
expect { post_create_aws }.to change { Clusters::Cluster.count }
@@ -375,6 +391,10 @@ RSpec.describe Admin::ClustersController do
post :create_user, params: params
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { post_create_user }
+ end
+
describe 'functionality' do
context 'when creates a cluster' do
it 'creates a new cluster' do
@@ -445,6 +465,10 @@ RSpec.describe Admin::ClustersController do
post :authorize_aws_role, params: params
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
before do
allow(Clusters::Aws::FetchCredentialsService).to receive(:new)
.and_return(double(execute: double))
@@ -495,6 +519,10 @@ RSpec.describe Admin::ClustersController do
delete :clear_cache, params: { id: cluster }
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
it 'deletes the namespaces associated with the cluster' do
expect { go }.to change { Clusters::KubernetesNamespace.count }
@@ -520,6 +548,10 @@ RSpec.describe Admin::ClustersController do
format: :json
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { get_cluster_status }
+ end
+
describe 'functionality' do
it 'responds with matching schema' do
get_cluster_status
@@ -555,6 +587,10 @@ RSpec.describe Admin::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { get_show }
+ end
+
describe 'functionality' do
render_views
@@ -603,6 +639,10 @@ RSpec.describe Admin::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { put_update }
+ end
+
it 'updates and redirects back to show page' do
put_update
@@ -694,6 +734,10 @@ RSpec.describe Admin::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { delete_destroy }
+ end
+
describe 'functionality' do
context 'when cluster is provided by GCP' do
context 'when cluster is created' do
diff --git a/spec/controllers/admin/runner_projects_controller_spec.rb b/spec/controllers/admin/runner_projects_controller_spec.rb
index e5f63025cf7..98f961f66bb 100644
--- a/spec/controllers/admin/runner_projects_controller_spec.rb
+++ b/spec/controllers/admin/runner_projects_controller_spec.rb
@@ -13,7 +13,7 @@ RSpec.describe Admin::RunnerProjectsController do
describe '#create' do
let(:project_id) { project.path }
- subject do
+ subject(:send_create) do
post :create, params: {
namespace_id: group.path,
project_id: project_id,
@@ -25,7 +25,7 @@ RSpec.describe Admin::RunnerProjectsController do
let(:project_runner) { create(:ci_runner, :project, projects: [project]) }
it 'redirects to the admin runner edit page' do
- subject
+ send_create
expect(response).to have_gitlab_http_status(:redirect)
expect(response).to redirect_to edit_admin_runner_url(project_runner)
@@ -37,7 +37,7 @@ RSpec.describe Admin::RunnerProjectsController do
let(:source_project) { create(:project) }
it 'redirects to the admin runner edit page' do
- subject
+ send_create
expect(response).to have_gitlab_http_status(:redirect)
expect(response).to redirect_to edit_admin_runner_url(project_runner)
@@ -50,7 +50,42 @@ RSpec.describe Admin::RunnerProjectsController do
let(:project_id) { 0 }
it 'shows 404 for unknown project' do
- subject
+ send_create
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+ end
+
+ describe '#destroy' do
+ let_it_be(:project_runner) { create(:ci_runner, :project, projects: [project]) }
+
+ let(:project_id) { project.path }
+
+ subject(:send_destroy) do
+ delete :destroy, params: {
+ namespace_id: group.path,
+ project_id: project_id,
+ id: runner_project_id
+ }
+ end
+
+ context 'unassigning runner from project' do
+ let(:runner_project_id) { project_runner.runner_projects.last.id }
+
+ it 'redirects to the admin runner edit page' do
+ send_destroy
+
+ expect(response).to have_gitlab_http_status(:redirect)
+ expect(response).to redirect_to edit_admin_runner_url(project_runner)
+ end
+ end
+
+ context 'for unknown project runner relationship' do
+ let(:runner_project_id) { 0 }
+
+ it 'shows 404 for unknown project runner relationship' do
+ send_destroy
expect(response).to have_gitlab_http_status(:not_found)
end
diff --git a/spec/controllers/admin/runners_controller_spec.rb b/spec/controllers/admin/runners_controller_spec.rb
index 74f352e8ec2..8f70cb32d3e 100644
--- a/spec/controllers/admin/runners_controller_spec.rb
+++ b/spec/controllers/admin/runners_controller_spec.rb
@@ -105,7 +105,7 @@ RSpec.describe Admin::RunnersController do
describe '#destroy' do
it 'destroys the runner' do
- expect_next_instance_of(Ci::UnregisterRunnerService, runner) do |service|
+ expect_next_instance_of(Ci::Runners::UnregisterRunnerService, runner, user) do |service|
expect(service).to receive(:execute).once.and_call_original
end
diff --git a/spec/controllers/admin/topics_controller_spec.rb b/spec/controllers/admin/topics_controller_spec.rb
index 6d66cb43338..ea510f916da 100644
--- a/spec/controllers/admin/topics_controller_spec.rb
+++ b/spec/controllers/admin/topics_controller_spec.rb
@@ -88,6 +88,13 @@ RSpec.describe Admin::TopicsController do
expect(errors).to contain_exactly(errors.full_message(:name, I18n.t('errors.messages.blank')))
end
+ it 'shows error message if topic not unique (case insensitive)' do
+ post :create, params: { projects_topic: { name: topic.name.upcase } }
+
+ errors = assigns[:topic].errors
+ expect(errors).to contain_exactly(errors.full_message(:name, I18n.t('errors.messages.taken')))
+ end
+
context 'as a normal user' do
before do
sign_in(user)
@@ -116,6 +123,15 @@ RSpec.describe Admin::TopicsController do
expect(errors).to contain_exactly(errors.full_message(:name, I18n.t('errors.messages.blank')))
end
+ it 'shows error message if topic not unique (case insensitive)' do
+ other_topic = create(:topic, name: 'other-topic')
+
+ put :update, params: { id: topic.id, projects_topic: { name: other_topic.name.upcase } }
+
+ errors = assigns[:topic].errors
+ expect(errors).to contain_exactly(errors.full_message(:name, I18n.t('errors.messages.taken')))
+ end
+
context 'as a normal user' do
before do
sign_in(user)
diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb
index 004bea02580..ddd80b67639 100644
--- a/spec/controllers/application_controller_spec.rb
+++ b/spec/controllers/application_controller_spec.rb
@@ -501,6 +501,7 @@ RSpec.describe ApplicationController do
describe '#append_info_to_payload' do
controller(described_class) do
attr_reader :last_payload
+
urgency :high, [:foo]
def index
@@ -1058,15 +1059,25 @@ RSpec.describe ApplicationController do
describe 'setting permissions-policy header' do
controller do
skip_before_action :authenticate_user!
+ before_action :redirect_to_example, only: [:redirect]
def index
render html: 'It is a flock of sheep, not a floc of sheep.'
end
+
+ def redirect
+ raise 'Should not be reached'
+ end
+
+ def redirect_to_example
+ redirect_to('https://example.com')
+ end
end
before do
routes.draw do
get 'index' => 'anonymous#index'
+ get 'redirect' => 'anonymous#redirect'
end
end
@@ -1092,6 +1103,13 @@ RSpec.describe ApplicationController do
expect(response.headers['Permissions-Policy']).to eq('interest-cohort=()')
end
+
+ it 'sets the Permissions-Policy header even when redirected before_action' do
+ get :redirect
+
+ expect(response).to have_gitlab_http_status(:redirect)
+ expect(response.headers['Permissions-Policy']).to eq('interest-cohort=()')
+ end
end
end
end
diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb
index 533d3896ee6..0a809e80fcd 100644
--- a/spec/controllers/autocomplete_controller_spec.rb
+++ b/spec/controllers/autocomplete_controller_spec.rb
@@ -235,7 +235,7 @@ RSpec.describe AutocompleteController do
end
end
- it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit do
let(:current_user) { user }
def request
diff --git a/spec/controllers/boards/lists_controller_spec.rb b/spec/controllers/boards/lists_controller_spec.rb
index 29141582c6f..95334974e66 100644
--- a/spec/controllers/boards/lists_controller_spec.rb
+++ b/spec/controllers/boards/lists_controller_spec.rb
@@ -208,7 +208,7 @@ RSpec.describe Boards::ListsController do
sign_in(user)
params = { namespace_id: project.namespace.to_param,
- project_id: project,
+ project_id: project.id,
board_id: board.to_param,
id: list.to_param,
list: { position: position },
@@ -221,7 +221,7 @@ RSpec.describe Boards::ListsController do
sign_in(user)
params = { namespace_id: project.namespace.to_param,
- project_id: project,
+ project_id: project.id,
board_id: board.to_param,
id: list.to_param,
list: setting,
diff --git a/spec/controllers/concerns/product_analytics_tracking_spec.rb b/spec/controllers/concerns/product_analytics_tracking_spec.rb
new file mode 100644
index 00000000000..250cc3cf2cf
--- /dev/null
+++ b/spec/controllers/concerns/product_analytics_tracking_spec.rb
@@ -0,0 +1,171 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe ProductAnalyticsTracking, :snowplow do
+ include TrackingHelpers
+ include SnowplowHelpers
+
+ let(:user) { create(:user) }
+ let!(:group) { create(:group) }
+
+ before do
+ allow(Gitlab::UsageDataCounters::HLLRedisCounter).to receive(:track_event)
+ end
+
+ controller(ApplicationController) do
+ include ProductAnalyticsTracking
+
+ skip_before_action :authenticate_user!, only: :show
+ track_event(:index, :show, name: 'g_analytics_valuestream', destinations: [:redis_hll, :snowplow],
+ conditions: [:custom_condition_one?, :custom_condition_two?]) { |controller| controller.get_custom_id }
+
+ def index
+ render html: 'index'
+ end
+
+ def new
+ render html: 'new'
+ end
+
+ def show
+ render html: 'show'
+ end
+
+ def get_custom_id
+ 'some_custom_id'
+ end
+
+ private
+
+ def tracking_namespace_source
+ Group.first
+ end
+
+ def custom_condition_one?
+ true
+ end
+
+ def custom_condition_two?
+ true
+ end
+ end
+
+ def expect_tracking(user: self.user)
+ expect(Gitlab::UsageDataCounters::HLLRedisCounter).to have_received(:track_event)
+ .with('g_analytics_valuestream', values: instance_of(String))
+
+ expect_snowplow_event(
+ category: anything,
+ action: 'g_analytics_valuestream',
+ namespace: group,
+ user: user
+ )
+ end
+
+ def expect_no_tracking
+ expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
+
+ expect_no_snowplow_event
+ end
+
+ context 'when user is logged in' do
+ before do
+ sign_in(user)
+ end
+
+ it 'tracks the event' do
+ get :index
+
+ expect_tracking
+ end
+
+ context 'when FF is disabled' do
+ before do
+ stub_feature_flags(route_hll_to_snowplow: false)
+ end
+
+ it 'doesnt track snowplow event' do
+ get :index
+
+ expect_no_snowplow_event
+ end
+ end
+
+ it 'tracks the event if DNT is not enabled' do
+ stub_do_not_track('0')
+
+ get :index
+
+ expect_tracking
+ end
+
+ it 'does not track the event if DNT is enabled' do
+ stub_do_not_track('1')
+
+ get :index
+
+ expect_no_tracking
+ end
+
+ it 'does not track the event if the format is not HTML' do
+ get :index, format: :json
+
+ expect_no_tracking
+ end
+
+ it 'does not track the event if a custom condition returns false' do
+ allow(controller).to receive(:custom_condition_two?).and_return(false)
+
+ get :index
+
+ expect_no_tracking
+ end
+
+ it 'does not track the event for untracked actions' do
+ get :new
+
+ expect_no_tracking
+ end
+ end
+
+ context 'when user is not logged in' do
+ let(:visitor_id) { SecureRandom.uuid }
+
+ it 'tracks the event when there is a visitor id' do
+ cookies[:visitor_id] = { value: visitor_id, expires: 24.months }
+
+ get :show, params: { id: 1 }
+
+ expect_tracking(user: nil)
+ end
+ end
+
+ context 'when user is not logged in and there is no visitor_id' do
+ it 'does not track the event' do
+ get :index
+
+ expect_no_tracking
+ end
+
+ it 'tracks the event when there is custom id' do
+ get :show, params: { id: 1 }
+
+ expect_tracking(user: nil)
+ end
+
+ it 'does not track the HLL event when there is no custom id' do
+ allow(controller).to receive(:get_custom_id).and_return(nil)
+
+ get :show, params: { id: 2 }
+
+ expect(Gitlab::UsageDataCounters::HLLRedisCounter).not_to receive(:track_event)
+ expect_snowplow_event(
+ category: anything,
+ action: 'g_analytics_valuestream',
+ namespace: group,
+ user: nil
+ )
+ end
+ end
+end
diff --git a/spec/controllers/concerns/spammable_actions/akismet_mark_as_spam_action_spec.rb b/spec/controllers/concerns/spammable_actions/akismet_mark_as_spam_action_spec.rb
index 7c10dccdcb9..caa0fa2d437 100644
--- a/spec/controllers/concerns/spammable_actions/akismet_mark_as_spam_action_spec.rb
+++ b/spec/controllers/concerns/spammable_actions/akismet_mark_as_spam_action_spec.rb
@@ -7,12 +7,6 @@ RSpec.describe SpammableActions::AkismetMarkAsSpamAction do
controller(ActionController::Base) do
include SpammableActions::AkismetMarkAsSpamAction
-
- private
-
- def spammable_path
- '/fake_spammable_path'
- end
end
let(:spammable_type) { 'SpammableType' }
@@ -22,7 +16,6 @@ RSpec.describe SpammableActions::AkismetMarkAsSpamAction do
before do
allow(Gitlab::Recaptcha).to receive(:load_configurations!) { true }
routes.draw { get 'mark_as_spam' => 'anonymous#mark_as_spam' }
- allow(controller).to receive(:spammable) { spammable }
allow(controller).to receive(:current_user) { double(:current_user, admin?: admin) }
allow(controller).to receive(:current_user).and_return(current_user)
end
@@ -31,6 +24,9 @@ RSpec.describe SpammableActions::AkismetMarkAsSpamAction do
subject { post :mark_as_spam }
before do
+ allow(controller).to receive(:spammable) { spammable }
+ allow(controller).to receive(:spammable_path) { '/fake_spammable_path' }
+
expect_next(Spam::AkismetMarkAsSpamService, target: spammable)
.to receive(:execute).and_return(execute_result)
end
@@ -68,4 +64,16 @@ RSpec.describe SpammableActions::AkismetMarkAsSpamAction do
end
end
end
+
+ describe '#spammable' do
+ it 'raises when unimplemented' do
+ expect { controller.send(:spammable) }.to raise_error(NotImplementedError)
+ end
+ end
+
+ describe '#spammable_path' do
+ it 'raises when unimplemented' do
+ expect { controller.send(:spammable_path) }.to raise_error(NotImplementedError)
+ end
+ end
end
diff --git a/spec/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support_spec.rb b/spec/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support_spec.rb
index 53a78326397..c5d17e0232c 100644
--- a/spec/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support_spec.rb
+++ b/spec/controllers/concerns/spammable_actions/captcha_check/html_format_actions_support_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe SpammableActions::CaptchaCheck::HtmlFormatActionsSupport do
include SpammableActions::CaptchaCheck::HtmlFormatActionsSupport
def create
- with_captcha_check_html_format { render :some_rendered_view }
+ with_captcha_check_html_format(spammable: spammable) { render :some_rendered_view }
end
end
diff --git a/spec/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support_spec.rb b/spec/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support_spec.rb
index d7a44351ad8..7796d9d1273 100644
--- a/spec/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support_spec.rb
+++ b/spec/controllers/concerns/spammable_actions/captcha_check/json_format_actions_support_spec.rb
@@ -7,7 +7,7 @@ RSpec.describe SpammableActions::CaptchaCheck::JsonFormatActionsSupport do
include SpammableActions::CaptchaCheck::JsonFormatActionsSupport
def some_action
- with_captcha_check_json_format { render :some_rendered_view }
+ with_captcha_check_json_format(spammable: spammable) { render :some_rendered_view }
end
end
diff --git a/spec/controllers/concerns/spammable_actions/captcha_check/rest_api_actions_support_spec.rb b/spec/controllers/concerns/spammable_actions/captcha_check/rest_api_actions_support_spec.rb
new file mode 100644
index 00000000000..07c564b555e
--- /dev/null
+++ b/spec/controllers/concerns/spammable_actions/captcha_check/rest_api_actions_support_spec.rb
@@ -0,0 +1,86 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe SpammableActions::CaptchaCheck::RestApiActionsSupport do
+ include Rack::Test::Methods
+
+ subject do
+ Class.new(Grape::API) do
+ helpers API::Helpers
+ helpers SpammableActions::CaptchaCheck::RestApiActionsSupport
+
+ get ':id' do
+ # NOTE: This was the only way that seemed to work to inject the mock spammable into the
+ # Grape rack app instance. If there's a better way, improvements are welcome.
+ spammable = Object.fake_spammable_factory
+ with_captcha_check_rest_api(spammable: spammable) do
+ render_api_error!(spammable.errors, 400)
+ end
+ end
+ end
+ end
+
+ def app
+ subject
+ end
+
+ before do
+ allow(Gitlab::Recaptcha).to receive(:load_configurations!) { true }
+ end
+
+ describe '#with_captcha_check_json_format' do
+ let(:spammable) { instance_double(Snippet) }
+
+ before do
+ expect(spammable).to receive(:render_recaptcha?).at_least(:once) { render_recaptcha }
+ allow(Object).to receive(:fake_spammable_factory) { spammable }
+ end
+
+ context 'when spammable.render_recaptcha? is true' do
+ let(:render_recaptcha) { true }
+ let(:spam_log) { instance_double(SpamLog, id: 1) }
+ let(:spammable) { instance_double(Snippet, spam?: true, render_recaptcha?: render_recaptcha, spam_log: spam_log) }
+ let(:recaptcha_site_key) { 'abc123' }
+ let(:err_msg) { 'You gotta solve the CAPTCHA' }
+ let(:spam_action_response_fields) do
+ {
+ spam: true,
+ needs_captcha_response: render_recaptcha,
+ spam_log_id: 1,
+ captcha_site_key: recaptcha_site_key
+ }
+ end
+
+ it 'renders json containing spam_action_response_fields' do
+ allow(spammable).to receive_message_chain('errors.full_messages.to_sentence') { err_msg }
+ allow(Gitlab::CurrentSettings).to receive(:recaptcha_site_key) { recaptcha_site_key }
+ response = get '/test'
+ expected_response = {
+ 'needs_captcha_response' => render_recaptcha,
+ 'spam_log_id' => 1,
+ 'captcha_site_key' => recaptcha_site_key,
+ 'message' => { 'error' => err_msg }
+ }
+ expect(Gitlab::Json.parse(response.body)).to eq(expected_response)
+ expect(response.status).to eq(409)
+ end
+ end
+
+ context 'when spammable.render_recaptcha? is false' do
+ let(:render_recaptcha) { false }
+ let(:errors) { { 'base' => "It's definitely spam" } }
+
+ it 'yields to block' do
+ allow(spammable).to receive(:errors) { errors }
+
+ response = get 'test'
+ expected_response = {
+ 'message' => errors
+ }
+ expect(Gitlab::Json.parse(response.body)).to eq(expected_response)
+ expect(response.status).to eq(400)
+ end
+ end
+ end
+end
diff --git a/spec/controllers/confirmations_controller_spec.rb b/spec/controllers/confirmations_controller_spec.rb
index 1c7f8de32bb..3b5afbcebca 100644
--- a/spec/controllers/confirmations_controller_spec.rb
+++ b/spec/controllers/confirmations_controller_spec.rb
@@ -152,7 +152,7 @@ RSpec.describe ConfirmationsController do
perform_request
expect(response).to render_template(:new)
- expect(flash[:alert]).to include 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'
+ expect(flash[:alert]).to include _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
end
it 'successfully sends password reset when reCAPTCHA is solved' do
diff --git a/spec/controllers/dashboard_controller_spec.rb b/spec/controllers/dashboard_controller_spec.rb
index 8fae617ea65..aed310531e6 100644
--- a/spec/controllers/dashboard_controller_spec.rb
+++ b/spec/controllers/dashboard_controller_spec.rb
@@ -13,7 +13,22 @@ RSpec.describe DashboardController do
end
describe 'GET issues' do
- it_behaves_like 'issuables list meta-data', :issue, :issues
+ context 'when issues_full_text_search is disabled' do
+ before do
+ stub_feature_flags(issues_full_text_search: false)
+ end
+
+ it_behaves_like 'issuables list meta-data', :issue, :issues
+ end
+
+ context 'when issues_full_text_search is enabled' do
+ before do
+ stub_feature_flags(issues_full_text_search: true)
+ end
+
+ it_behaves_like 'issuables list meta-data', :issue, :issues
+ end
+
it_behaves_like 'issuables requiring filter', :issues
end
@@ -83,25 +98,49 @@ RSpec.describe DashboardController do
context "no filters" do
let(:params) { {} }
+ shared_examples_for 'no filters are set' do
+ it 'sets @no_filters_set to true' do
+ expect(assigns[:no_filters_set]).to eq(true)
+ end
+ end
+
+ it_behaves_like 'no filters are set'
+
+ context 'when key is present but value is not' do
+ let(:params) { { author_username: nil } }
+
+ it_behaves_like 'no filters are set'
+ end
+
+ context 'when in param is set but no search' do
+ let(:params) { { in: 'title' } }
+
+ it_behaves_like 'no filters are set'
+ end
+ end
+
+ shared_examples_for 'filters are set' do
it 'sets @no_filters_set to false' do
- expect(assigns[:no_filters_set]).to eq(true)
+ expect(assigns[:no_filters_set]).to eq(false)
end
end
context "scalar filters" do
let(:params) { { author_id: user.id } }
- it 'sets @no_filters_set to false' do
- expect(assigns[:no_filters_set]).to eq(false)
- end
+ it_behaves_like 'filters are set'
end
context "array filters" do
let(:params) { { label_name: ['bug'] } }
- it 'sets @no_filters_set to false' do
- expect(assigns[:no_filters_set]).to eq(false)
- end
+ it_behaves_like 'filters are set'
+ end
+
+ context 'search' do
+ let(:params) { { search: 'test' } }
+
+ it_behaves_like 'filters are set'
end
end
end
diff --git a/spec/controllers/graphql_controller_spec.rb b/spec/controllers/graphql_controller_spec.rb
index 95f60156c40..dbaed8aaa19 100644
--- a/spec/controllers/graphql_controller_spec.rb
+++ b/spec/controllers/graphql_controller_spec.rb
@@ -139,8 +139,45 @@ RSpec.describe GraphqlController do
context 'when user uses an API token' do
let(:user) { create(:user, last_activity_on: Date.yesterday) }
let(:token) { create(:personal_access_token, user: user, scopes: [:api]) }
+ let(:query) { '{ __typename }' }
- subject { post :execute, params: { access_token: token.token } }
+ subject { post :execute, params: { query: query, access_token: token.token } }
+
+ context 'when the user is a project bot' do
+ let(:user) { create(:user, :project_bot, last_activity_on: Date.yesterday) }
+
+ it 'updates the users last_activity_on field' do
+ expect { subject }.to change { user.reload.last_activity_on }
+ end
+
+ it "sets context's sessionless value as true" do
+ subject
+
+ expect(assigns(:context)[:is_sessionless_user]).to be true
+ end
+
+ it 'executes a simple query with no errors' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to eq({ 'data' => { '__typename' => 'Query' } })
+ end
+
+ it 'can access resources the project_bot has access to' do
+ project_a, project_b = create_list(:project, 2, :private)
+ project_a.add_developer(user)
+
+ post :execute, params: { query: <<~GQL, access_token: token.token }
+ query {
+ a: project(fullPath: "#{project_a.full_path}") { name }
+ b: project(fullPath: "#{project_b.full_path}") { name }
+ }
+ GQL
+
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(json_response).to eq({ 'data' => { 'a' => { 'name' => project_a.name }, 'b' => nil } })
+ end
+ end
it 'updates the users last_activity_on field' do
expect { subject }.to change { user.reload.last_activity_on }
diff --git a/spec/controllers/groups/clusters_controller_spec.rb b/spec/controllers/groups/clusters_controller_spec.rb
index 710e983dfbd..4eeae64b760 100644
--- a/spec/controllers/groups/clusters_controller_spec.rb
+++ b/spec/controllers/groups/clusters_controller_spec.rb
@@ -32,6 +32,10 @@ RSpec.describe Groups::ClustersController do
create(:cluster, :disabled, :provided_by_gcp, :production_environment, cluster_type: :group_type, groups: [group])
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
it 'lists available clusters and renders html' do
go
@@ -116,6 +120,10 @@ RSpec.describe Groups::ClustersController do
get :new, params: { group_id: group, provider: provider }
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality for new cluster' do
context 'when omniauth has been configured' do
let(:key) { 'secret-key' }
@@ -255,6 +263,10 @@ RSpec.describe Groups::ClustersController do
post :create_gcp, params: params.merge(group_id: group)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
context 'when access token is valid' do
before do
@@ -349,6 +361,10 @@ RSpec.describe Groups::ClustersController do
post :create_user, params: params.merge(group_id: group)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
context 'when creates a cluster' do
it 'creates a new cluster' do
@@ -457,6 +473,10 @@ RSpec.describe Groups::ClustersController do
post :create_aws, params: params.merge(group_id: group)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { post_create_aws }
+ end
+
it 'creates a new cluster' do
expect(ClusterProvisionWorker).to receive(:perform_async)
expect { post_create_aws }.to change { Clusters::Cluster.count }
@@ -519,6 +539,10 @@ RSpec.describe Groups::ClustersController do
post :authorize_aws_role, params: params.merge(group_id: group)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
before do
allow(Clusters::Aws::FetchCredentialsService).to receive(:new)
.and_return(double(execute: double))
@@ -579,6 +603,10 @@ RSpec.describe Groups::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
it 'deletes the namespaces associated with the cluster' do
expect { go }.to change { Clusters::KubernetesNamespace.count }
@@ -611,6 +639,10 @@ RSpec.describe Groups::ClustersController do
format: :json
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
it 'responds with matching schema' do
go
@@ -651,6 +683,10 @@ RSpec.describe Groups::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
render_views
@@ -705,6 +741,10 @@ RSpec.describe Groups::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
it 'updates and redirects back to show page' do
go
@@ -802,6 +842,10 @@ RSpec.describe Groups::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
context 'when cluster is provided by GCP' do
context 'when cluster is created' do
diff --git a/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb b/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb
index 57a83da3425..61445603a2d 100644
--- a/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb
+++ b/spec/controllers/groups/dependency_proxy_for_containers_controller_spec.rb
@@ -170,6 +170,14 @@ RSpec.describe Groups::DependencyProxyForContainersController do
end
end
+ shared_examples 'namespace statistics refresh' do
+ it 'updates namespace statistics' do
+ expect(Groups::UpdateStatisticsWorker).to receive(:perform_async)
+
+ subject
+ end
+ end
+
before do
allow(Gitlab.config.dependency_proxy)
.to receive(:enabled).and_return(true)
@@ -403,13 +411,15 @@ RSpec.describe Groups::DependencyProxyForContainersController do
context 'with a valid user' do
before do
group.add_guest(user)
-
- expect_next_found_instance_of(Group) do |instance|
- expect(instance).to receive_message_chain(:dependency_proxy_blobs, :create!)
- end
end
it_behaves_like 'a package tracking event', described_class.name, 'pull_blob'
+
+ it 'creates a blob' do
+ expect { subject }.to change { group.dependency_proxy_blobs.count }.by(1)
+ end
+
+ it_behaves_like 'namespace statistics refresh'
end
end
@@ -473,6 +483,8 @@ RSpec.describe Groups::DependencyProxyForContainersController do
expect(manifest.digest).to eq(digest)
expect(manifest.file_name).to eq(file_name)
end
+
+ it_behaves_like 'namespace statistics refresh'
end
context 'with existing stale manifest' do
@@ -483,6 +495,8 @@ RSpec.describe Groups::DependencyProxyForContainersController do
expect { subject }.to change { group.dependency_proxy_manifests.count }.by(0)
.and change { manifest.reload.digest }.from(old_digest).to(digest)
end
+
+ it_behaves_like 'namespace statistics refresh'
end
end
end
diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb
index 04a9b9f5250..25d32436d58 100644
--- a/spec/controllers/groups/group_members_controller_spec.rb
+++ b/spec/controllers/groups/group_members_controller_spec.rb
@@ -38,12 +38,6 @@ RSpec.describe Groups::GroupMembersController do
expect(assigns(:invited_members).map(&:invite_email)).to match_array(invited.map(&:invite_email))
end
- it 'assigns skip groups' do
- get :index, params: { group_id: group }
-
- expect(assigns(:skip_groups)).to match_array(group.related_group_ids)
- end
-
it 'restricts search to one email' do
get :index, params: { group_id: group, search_invited: invited.first.invite_email }
@@ -68,11 +62,10 @@ RSpec.describe Groups::GroupMembersController do
sign_in(user)
end
- it 'does not assign invited members or skip_groups', :aggregate_failures do
+ it 'does not assign invited members' do
get :index, params: { group_id: group }
expect(assigns(:invited_members)).to be_nil
- expect(assigns(:skip_groups)).to be_nil
end
end
@@ -106,107 +99,6 @@ RSpec.describe Groups::GroupMembersController do
end
end
- describe 'POST create' do
- let_it_be(:group_user) { create(:user) }
-
- before do
- sign_in(user)
- end
-
- context 'when user does not have enough rights' do
- before do
- group.add_developer(user)
- end
-
- it 'returns 403', :aggregate_failures do
- post :create, params: {
- group_id: group,
- user_ids: group_user.id,
- access_level: Gitlab::Access::GUEST
- }
-
- expect(response).to have_gitlab_http_status(:forbidden)
- expect(group.users).not_to include group_user
- end
- end
-
- context 'when user has enough rights' do
- before do
- group.add_owner(user)
- end
-
- it 'adds user to members', :aggregate_failures, :snowplow do
- post :create, params: {
- group_id: group,
- user_ids: group_user.id,
- access_level: Gitlab::Access::GUEST
- }
-
- expect(controller).to set_flash.to 'Users were successfully added.'
- expect(response).to redirect_to(group_group_members_path(group))
- expect(group.users).to include group_user
- expect_snowplow_event(
- category: 'Members::CreateService',
- action: 'create_member',
- label: 'group-members-page',
- property: 'existing_user',
- user: user
- )
- end
-
- it 'adds no user to members', :aggregate_failures do
- post :create, params: {
- group_id: group,
- user_ids: '',
- access_level: Gitlab::Access::GUEST
- }
-
- expect(controller).to set_flash.to 'No users specified.'
- expect(response).to redirect_to(group_group_members_path(group))
- expect(group.users).not_to include group_user
- end
- end
-
- context 'access expiry date' do
- before do
- group.add_owner(user)
- end
-
- subject do
- post :create, params: {
- group_id: group,
- user_ids: group_user.id,
- access_level: Gitlab::Access::GUEST,
- expires_at: expires_at
- }
- end
-
- context 'when set to a date in the past' do
- let(:expires_at) { 2.days.ago }
-
- it 'does not add user to members', :aggregate_failures do
- subject
-
- expect(flash[:alert]).to include('Expires at cannot be a date in the past')
- expect(response).to redirect_to(group_group_members_path(group))
- expect(group.users).not_to include group_user
- end
- end
-
- context 'when set to a date in the future' do
- let(:expires_at) { 5.days.from_now }
-
- it 'adds user to members', :aggregate_failures do
- subject
-
- expect(controller).to set_flash.to 'Users were successfully added.'
- expect(response).to redirect_to(group_group_members_path(group))
- expect(group.users).to include group_user
- end
- end
- end
- end
-
describe 'PUT update' do
let_it_be(:requester) { create(:group_member, :access_request, group: group) }
@@ -515,14 +407,6 @@ RSpec.describe Groups::GroupMembersController do
end
end
- describe 'POST #create' do
- it 'is successful' do
- post :create, params: { group_id: group, users: user, access_level: Gitlab::Access::GUEST }
-
- expect(response).to have_gitlab_http_status(:found)
- end
- end
-
describe 'PUT #update' do
it 'is successful' do
put :update,
diff --git a/spec/controllers/groups/releases_controller_spec.rb b/spec/controllers/groups/releases_controller_spec.rb
index 582a77b1c50..8b08f913e10 100644
--- a/spec/controllers/groups/releases_controller_spec.rb
+++ b/spec/controllers/groups/releases_controller_spec.rb
@@ -20,11 +20,11 @@ RSpec.describe Groups::ReleasesController do
context 'as json' do
let(:format) { :json }
- subject { get :index, params: { group_id: group }, format: format }
+ subject(:index) { get :index, params: { group_id: group }, format: format }
context 'json_response' do
before do
- subject
+ index
end
it 'returns an application/json content_type' do
@@ -38,7 +38,7 @@ RSpec.describe Groups::ReleasesController do
context 'the user is not authorized' do
before do
- subject
+ index
end
it 'does not return any releases' do
@@ -54,12 +54,38 @@ RSpec.describe Groups::ReleasesController do
it "returns all group's public and private project's releases as JSON, ordered by released_at" do
sign_in(guest)
- subject
+ index
expect(json_response.map {|r| r['tag'] } ).to match_array(%w(p2 p1 v2 v1))
end
end
+ context 'group_releases_finder_inoperator feature flag' do
+ before do
+ sign_in(guest)
+ end
+
+ it 'calls old code when disabled' do
+ stub_feature_flags(group_releases_finder_inoperator: false)
+
+ allow(ReleasesFinder).to receive(:new).and_call_original
+
+ index
+
+ expect(ReleasesFinder).to have_received(:new)
+ end
+
+ it 'calls new code when enabled' do
+ stub_feature_flags(group_releases_finder_inoperator: true)
+
+ allow(Releases::GroupReleasesFinder).to receive(:new).and_call_original
+
+ index
+
+ expect(Releases::GroupReleasesFinder).to have_received(:new)
+ end
+ end
+
context 'N+1 queries' do
it 'avoids N+1 database queries' do
control_count = ActiveRecord::QueryRecorder.new { subject }.count
diff --git a/spec/controllers/groups/runners_controller_spec.rb b/spec/controllers/groups/runners_controller_spec.rb
index 9f0615a96ae..b4950b93a3f 100644
--- a/spec/controllers/groups/runners_controller_spec.rb
+++ b/spec/controllers/groups/runners_controller_spec.rb
@@ -190,7 +190,7 @@ RSpec.describe Groups::RunnersController do
end
it 'destroys the runner and redirects' do
- expect_next_instance_of(Ci::UnregisterRunnerService, runner) do |service|
+ expect_next_instance_of(Ci::Runners::UnregisterRunnerService, runner, user) do |service|
expect(service).to receive(:execute).once.and_call_original
end
@@ -208,21 +208,39 @@ RSpec.describe Groups::RunnersController do
end
end
- context 'when user is an owner and runner in multiple projects' do
- let(:project_2) { create(:project, group: group) }
+ context 'with runner associated with multiple projects' do
+ let_it_be(:project_2) { create(:project, group: group) }
+
let(:runner_project_2) { create(:ci_runner, :project, projects: [project, project_2]) }
let(:params_runner_project_2) { { group_id: group, id: runner_project_2 } }
- before do
- group.add_owner(user)
+ context 'when user is an admin', :enable_admin_mode do
+ let(:user) { create(:user, :admin) }
+
+ before do
+ sign_in(user)
+ end
+
+ it 'destroys the project runner and redirects' do
+ delete :destroy, params: params_runner_project_2
+
+ expect(response).to have_gitlab_http_status(:found)
+ expect(Ci::Runner.find_by(id: runner_project_2.id)).to be_nil
+ end
end
- it 'does not destroy the project runner' do
- delete :destroy, params: params_runner_project_2
+ context 'when user is an owner' do
+ before do
+ group.add_owner(user)
+ end
+
+ it 'does not destroy the project runner' do
+ delete :destroy, params: params_runner_project_2
- expect(response).to have_gitlab_http_status(:found)
- expect(flash[:alert]).to eq('Runner was not deleted because it is assigned to multiple projects.')
- expect(Ci::Runner.find_by(id: runner_project_2.id)).to be_present
+ expect(response).to have_gitlab_http_status(:found)
+ expect(flash[:alert]).to eq('Runner cannot be deleted, please contact your administrator.')
+ expect(Ci::Runner.find_by(id: runner_project_2.id)).to be_present
+ end
end
end
diff --git a/spec/controllers/jira_connect/events_controller_spec.rb b/spec/controllers/jira_connect/events_controller_spec.rb
index 2a70a2ea683..2129b24b2fb 100644
--- a/spec/controllers/jira_connect/events_controller_spec.rb
+++ b/spec/controllers/jira_connect/events_controller_spec.rb
@@ -43,14 +43,15 @@ RSpec.describe JiraConnect::EventsController do
end
describe '#installed' do
- let(:client_key) { '1234' }
- let(:shared_secret) { 'secret' }
+ let_it_be(:client_key) { '1234' }
+ let_it_be(:shared_secret) { 'secret' }
+ let_it_be(:base_url) { 'https://test.atlassian.net' }
let(:params) do
{
clientKey: client_key,
sharedSecret: shared_secret,
- baseUrl: 'https://test.atlassian.net'
+ baseUrl: base_url
}
end
@@ -77,11 +78,11 @@ RSpec.describe JiraConnect::EventsController do
expect(installation.base_url).to eq('https://test.atlassian.net')
end
- context 'when it is a version update and shared_secret is not sent' do
+ context 'when the shared_secret param is missing' do
let(:params) do
{
clientKey: client_key,
- baseUrl: 'https://test.atlassian.net'
+ baseUrl: base_url
}
end
@@ -90,13 +91,48 @@ RSpec.describe JiraConnect::EventsController do
expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
+ end
+
+ context 'when an installation already exists' do
+ let_it_be(:installation) { create(:jira_connect_installation, base_url: base_url, client_key: client_key, shared_secret: shared_secret) }
+
+ it 'validates the JWT token in authorization header and returns 200 without creating a new installation', :aggregate_failures do
+ expect { subject }.not_to change { JiraConnectInstallation.count }
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ context 'when parameters include a new shared secret and base_url' do
+ let(:shared_secret) { 'new_secret' }
+ let(:base_url) { 'https://new_test.atlassian.net' }
- context 'and an installation exists' do
- let!(:installation) { create(:jira_connect_installation, client_key: client_key, shared_secret: shared_secret) }
+ it 'updates the installation', :aggregate_failures do
+ subject
- it 'validates the JWT token in authorization header and returns 200 without creating a new installation' do
- expect { subject }.not_to change { JiraConnectInstallation.count }
expect(response).to have_gitlab_http_status(:ok)
+ expect(installation.reload).to have_attributes(
+ shared_secret: shared_secret,
+ 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
+ let(:base_url) { 'invalid' }
+
+ it 'renders 422', :aggregate_failures do
+ expect { subject }.not_to change { installation.reload.base_url }
+ expect(response).to have_gitlab_http_status(:unprocessable_entity)
end
end
end
diff --git a/spec/controllers/passwords_controller_spec.rb b/spec/controllers/passwords_controller_spec.rb
index 01c032d9e3b..82014282c6e 100644
--- a/spec/controllers/passwords_controller_spec.rb
+++ b/spec/controllers/passwords_controller_spec.rb
@@ -121,7 +121,7 @@ RSpec.describe PasswordsController do
perform_request
expect(response).to render_template(:new)
- expect(flash[:alert]).to include 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'
+ expect(flash[:alert]).to include _('There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.')
end
it 'successfully sends password reset when reCAPTCHA is solved' do
diff --git a/spec/controllers/projects/blob_controller_spec.rb b/spec/controllers/projects/blob_controller_spec.rb
index 53efcc65066..cc807098498 100644
--- a/spec/controllers/projects/blob_controller_spec.rb
+++ b/spec/controllers/projects/blob_controller_spec.rb
@@ -366,8 +366,8 @@ RSpec.describe Projects::BlobController do
it_behaves_like 'tracking unique hll events' do
subject(:request) { put :update, params: default_params }
- let(:target_id) { 'g_edit_by_sfe' }
- let(:expected_type) { instance_of(Integer) }
+ let(:target_event) { 'g_edit_by_sfe' }
+ let(:expected_value) { instance_of(Integer) }
end
end
@@ -516,8 +516,8 @@ RSpec.describe Projects::BlobController do
subject(:request) { post :create, params: default_params }
it_behaves_like 'tracking unique hll events' do
- let(:target_id) { 'g_edit_by_sfe' }
- let(:expected_type) { instance_of(Integer) }
+ let(:target_event) { 'g_edit_by_sfe' }
+ let(:expected_value) { instance_of(Integer) }
end
it 'redirects to blob' do
@@ -525,24 +525,5 @@ RSpec.describe Projects::BlobController do
expect(response).to redirect_to(project_blob_path(project, 'master/docs/EXAMPLE_FILE'))
end
-
- context 'when code_quality_walkthrough param is present' do
- let(:default_params) { super().merge(code_quality_walkthrough: true) }
-
- it 'redirects to the pipelines page' do
- request
-
- expect(response).to redirect_to(project_pipelines_path(project, code_quality_walkthrough: true))
- end
-
- it 'creates an "commit_created" experiment tracking event' do
- experiment = double(track: true)
- expect(controller).to receive(:experiment).with(:code_quality_walkthrough, namespace: project.root_ancestor).and_return(experiment)
-
- request
-
- expect(experiment).to have_received(:track).with(:commit_created)
- end
- end
end
end
diff --git a/spec/controllers/projects/ci/pipeline_editor_controller_spec.rb b/spec/controllers/projects/ci/pipeline_editor_controller_spec.rb
index d55aad20689..37406d704f1 100644
--- a/spec/controllers/projects/ci/pipeline_editor_controller_spec.rb
+++ b/spec/controllers/projects/ci/pipeline_editor_controller_spec.rb
@@ -36,17 +36,5 @@ RSpec.describe Projects::Ci::PipelineEditorController do
expect(response).to have_gitlab_http_status(:not_found)
end
end
-
- describe 'pipeline_editor_walkthrough experiment' do
- before do
- project.add_developer(user)
- end
-
- subject(:action) { show_request }
-
- it_behaves_like 'tracks assignment and records the subject', :pipeline_editor_walkthrough, :namespace do
- subject { project.namespace }
- end
- end
end
end
diff --git a/spec/controllers/projects/ci/secure_files_controller_spec.rb b/spec/controllers/projects/ci/secure_files_controller_spec.rb
new file mode 100644
index 00000000000..1138897bcc6
--- /dev/null
+++ b/spec/controllers/projects/ci/secure_files_controller_spec.rb
@@ -0,0 +1,49 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe Projects::Ci::SecureFilesController do
+ let_it_be(:project) { create(:project) }
+ let_it_be(:user) { create(:user) }
+
+ subject(:show_request) { get :show, params: { namespace_id: project.namespace, project_id: project } }
+
+ describe 'GET #show' do
+ context 'with enough privileges' do
+ before do
+ sign_in(user)
+ project.add_developer(user)
+ show_request
+ end
+
+ it { expect(response).to have_gitlab_http_status(:ok) }
+
+ it 'renders show page' do
+ expect(response).to render_template :show
+ end
+ end
+
+ context 'without enough privileges' do
+ before do
+ sign_in(user)
+ project.add_reporter(user)
+ show_request
+ end
+
+ it 'responds with 404' do
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'an unauthenticated user' do
+ before do
+ show_request
+ end
+
+ it 'redirects to sign in' do
+ expect(response).to have_gitlab_http_status(:found)
+ expect(response).to redirect_to('/users/sign_in')
+ end
+ end
+ end
+end
diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb
index d0bef810ec8..44bdc958805 100644
--- a/spec/controllers/projects/clusters_controller_spec.rb
+++ b/spec/controllers/projects/clusters_controller_spec.rb
@@ -26,6 +26,10 @@ RSpec.describe Projects::ClustersController do
let!(:enabled_cluster) { create(:cluster, :provided_by_gcp, projects: [project]) }
let!(:disabled_cluster) { create(:cluster, :disabled, :provided_by_gcp, :production_environment, projects: [project]) }
+ include_examples ':certificate_based_clusters feature flag index responses' do
+ let(:subject) { go }
+ end
+
it 'lists available clusters and renders html' do
go
@@ -118,6 +122,10 @@ RSpec.describe Projects::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality for new cluster' do
context 'when omniauth has been configured' do
let(:key) { 'secret-key' }
@@ -264,6 +272,10 @@ RSpec.describe Projects::ClustersController do
post :create_gcp, params: params.merge(namespace_id: project.namespace, project_id: project)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
context 'when access token is valid' do
before do
@@ -360,6 +372,10 @@ RSpec.describe Projects::ClustersController do
post :create_user, params: params.merge(namespace_id: project.namespace, project_id: project)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
context 'when creates a cluster' do
it 'creates a new cluster' do
@@ -477,6 +493,10 @@ RSpec.describe Projects::ClustersController do
post :create_aws, params: params.merge(namespace_id: project.namespace, project_id: project)
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { post_create_aws }
+ end
+
it 'creates a new cluster' do
expect(ClusterProvisionWorker).to receive(:perform_async)
expect { post_create_aws }.to change { Clusters::Cluster.count }
@@ -548,6 +568,10 @@ RSpec.describe Projects::ClustersController do
.and_return(double(execute: double))
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
it 'updates the associated role with the supplied ARN' do
go
@@ -603,6 +627,10 @@ RSpec.describe Projects::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
it 'deletes the namespaces associated with the cluster' do
expect { go }.to change { Clusters::KubernetesNamespace.count }
@@ -640,6 +668,10 @@ RSpec.describe Projects::ClustersController do
format: :json
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
it "responds with matching schema" do
go
@@ -685,6 +717,10 @@ RSpec.describe Projects::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
render_views
@@ -749,6 +785,10 @@ RSpec.describe Projects::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
it "updates and redirects back to show page" do
go
@@ -842,6 +882,10 @@ RSpec.describe Projects::ClustersController do
}
end
+ include_examples ':certificate_based_clusters feature flag controller responses' do
+ let(:subject) { go }
+ end
+
describe 'functionality' do
context 'when cluster is provided by GCP' do
context 'when cluster is created' do
diff --git a/spec/controllers/projects/environments_controller_spec.rb b/spec/controllers/projects/environments_controller_spec.rb
index 0fcdeb2edde..fdfc21887a6 100644
--- a/spec/controllers/projects/environments_controller_spec.rb
+++ b/spec/controllers/projects/environments_controller_spec.rb
@@ -6,7 +6,7 @@ RSpec.describe Projects::EnvironmentsController do
include MetricsDashboardHelpers
include KubernetesHelpers
- let_it_be(:project) { create(:project) }
+ let_it_be(:project) { create(:project, :repository) }
let_it_be(:maintainer) { create(:user, name: 'main-dos').tap { |u| project.add_maintainer(u) } }
let_it_be(:reporter) { create(:user, name: 'repo-dos').tap { |u| project.add_reporter(u) } }
@@ -55,11 +55,11 @@ RSpec.describe Projects::EnvironmentsController do
let(:environments) { json_response['environments'] }
context 'with default parameters' do
- before do
- get :index, params: environment_params(format: :json)
- end
+ subject { get :index, params: environment_params(format: :json) }
it 'responds with a flat payload describing available environments' do
+ subject
+
expect(environments.count).to eq 3
expect(environments.first).to include('name' => 'production', 'name_without_type' => 'production')
expect(environments.second).to include('name' => 'staging/review-1', 'name_without_type' => 'review-1')
@@ -69,9 +69,28 @@ RSpec.describe Projects::EnvironmentsController do
end
it 'sets the polling interval header' do
+ subject
+
expect(response).to have_gitlab_http_status(:ok)
expect(response.headers['Poll-Interval']).to eq("3000")
end
+
+ context 'validates latest deployment' do
+ let_it_be(:test_environment) do
+ create(:environment, project: project, name: 'staging/review-4', state: :available)
+ end
+
+ before do
+ create_list(:deployment, 2, :success, environment: test_environment, project: project)
+ end
+
+ it 'responds with the latest deployment for the environment' do
+ subject
+
+ environment = environments.find { |env| env['id'] == test_environment.id }
+ expect(environment['last_deployment']['id']).to eq(test_environment.deployments.last.id)
+ end
+ end
end
context 'when a folder-based nested structure is requested' do
diff --git a/spec/controllers/projects/error_tracking_controller_spec.rb b/spec/controllers/projects/error_tracking_controller_spec.rb
index 822778779eb..b4f21e070c6 100644
--- a/spec/controllers/projects/error_tracking_controller_spec.rb
+++ b/spec/controllers/projects/error_tracking_controller_spec.rb
@@ -50,9 +50,7 @@ RSpec.describe Projects::ErrorTrackingController do
let(:external_url) { 'http://example.com' }
context 'no data' do
- let(:permitted_params) do
- ActionController::Parameters.new({}).permit!
- end
+ let(:permitted_params) { permit_index_parameters!({}) }
before do
expect(ErrorTracking::ListIssuesService)
@@ -75,9 +73,7 @@ RSpec.describe Projects::ErrorTrackingController do
let(:search_term) { 'something' }
let(:sort) { 'last_seen' }
let(:params) { project_params(format: :json, search_term: search_term, sort: sort, cursor: cursor) }
- let(:permitted_params) do
- ActionController::Parameters.new(search_term: search_term, sort: sort, cursor: cursor).permit!
- end
+ let(:permitted_params) { permit_index_parameters!(search_term: search_term, sort: sort, cursor: cursor) }
before do
expect(ErrorTracking::ListIssuesService)
@@ -114,7 +110,7 @@ RSpec.describe Projects::ErrorTrackingController do
context 'without extra params' do
before do
expect(ErrorTracking::ListIssuesService)
- .to receive(:new).with(project, user, {})
+ .to receive(:new).with(project, user, permit_index_parameters!({}))
.and_return(list_issues_service)
end
@@ -179,6 +175,15 @@ RSpec.describe Projects::ErrorTrackingController do
end
end
end
+
+ private
+
+ def permit_index_parameters!(params)
+ ActionController::Parameters.new(
+ **params,
+ tracking_event: :error_tracking_view_list
+ ).permit!
+ end
end
describe 'GET #issue_details' do
@@ -188,7 +193,8 @@ RSpec.describe Projects::ErrorTrackingController do
let(:permitted_params) do
ActionController::Parameters.new(
- { issue_id: issue_id.to_s }
+ issue_id: issue_id.to_s,
+ tracking_event: :error_tracking_view_details
).permit!
end
diff --git a/spec/controllers/projects/forks_controller_spec.rb b/spec/controllers/projects/forks_controller_spec.rb
index 0f8f3b49e02..962ef93dc72 100644
--- a/spec/controllers/projects/forks_controller_spec.rb
+++ b/spec/controllers/projects/forks_controller_spec.rb
@@ -199,15 +199,6 @@ RSpec.describe Projects::ForksController do
expect(json_response['namespaces'][1]['id']).to eq(group.id)
end
- it 'responds with group only when fork_project_form feature flag is disabled' do
- stub_feature_flags(fork_project_form: false)
- do_request
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(json_response['namespaces'].length).to eq(1)
- expect(json_response['namespaces'][0]['id']).to eq(group.id)
- end
-
context 'N+1 queries' do
before do
create(:fork_network, root_project: project)
diff --git a/spec/controllers/projects/incidents_controller_spec.rb b/spec/controllers/projects/incidents_controller_spec.rb
index 460821634b0..20cf0dcfd3a 100644
--- a/spec/controllers/projects/incidents_controller_spec.rb
+++ b/spec/controllers/projects/incidents_controller_spec.rb
@@ -43,6 +43,7 @@ RSpec.describe Projects::IncidentsController do
expect(response).to have_gitlab_http_status(:ok)
expect(response).to render_template(:index)
+ expect(Gon.features).to include('incidentEscalations' => true)
end
context 'when user is unauthorized' do
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index bf0b833b311..9d3711d8a96 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -72,7 +72,21 @@ RSpec.describe Projects::IssuesController do
project.add_developer(user)
end
- it_behaves_like "issuables list meta-data", :issue
+ context 'when issues_full_text_search is disabled' do
+ before do
+ stub_feature_flags(issues_full_text_search: false)
+ end
+
+ it_behaves_like 'issuables list meta-data', :issue
+ end
+
+ context 'when issues_full_text_search is enabled' do
+ before do
+ stub_feature_flags(issues_full_text_search: true)
+ end
+
+ it_behaves_like 'issuables list meta-data', :issue
+ end
it_behaves_like 'set sort order from user preference' do
let(:sorting_param) { 'updated_asc' }
@@ -605,11 +619,11 @@ RSpec.describe Projects::IssuesController do
end
end
- context 'when the SpamVerdictService disallows' do
+ context 'when an issue is identified as spam' do
before do
stub_application_setting(recaptcha_enabled: true)
- expect_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- expect(verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
+ allow_next_instance_of(Spam::AkismetService) do |akismet_service|
+ allow(akismet_service).to receive(:spam?).and_return(true)
end
end
@@ -926,8 +940,8 @@ RSpec.describe Projects::IssuesController do
context 'when an issue is identified as spam' do
context 'when recaptcha is not verified' do
before do
- expect_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- expect(verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
+ allow_next_instance_of(Spam::AkismetService) do |akismet_service|
+ allow(akismet_service).to receive(:spam?).and_return(true)
end
end
@@ -1004,6 +1018,7 @@ RSpec.describe Projects::IssuesController do
end
it 'returns 200 status' do
+ update_verified_issue
expect(response).to have_gitlab_http_status(:ok)
end
@@ -1051,35 +1066,6 @@ RSpec.describe Projects::IssuesController do
.not_to exceed_query_limit(control_count + 2 * labels.count)
end
- context 'real-time sidebar feature flag' do
- let_it_be(:project) { create(:project, :public) }
- let_it_be(:issue) { create(:issue, project: project) }
-
- context 'when enabled' do
- before do
- stub_feature_flags(real_time_issue_sidebar: true)
- end
-
- it 'pushes the correct value to the frontend' do
- go(id: issue.to_param)
-
- expect(Gon.features).to include('realTimeIssueSidebar' => true)
- end
- end
-
- context 'when disabled' do
- before do
- stub_feature_flags(real_time_issue_sidebar: false)
- end
-
- it 'pushes the correct value to the frontend' do
- go(id: issue.to_param)
-
- expect(Gon.features).to include('realTimeIssueSidebar' => false)
- end
- end
- end
-
it 'logs the view with Gitlab::Search::RecentIssues' do
sign_in(user)
recent_issues_double = instance_double(::Gitlab::Search::RecentIssues, log_view: nil)
@@ -1260,11 +1246,11 @@ RSpec.describe Projects::IssuesController do
end
end
- context 'when SpamVerdictService requires recaptcha' do
+ context 'when an issue is identified as spam and requires recaptcha' do
context 'when captcha is not verified' do
before do
- expect_next_instance_of(Spam::SpamVerdictService) do |verdict_service|
- expect(verdict_service).to receive(:execute).and_return(CONDITIONAL_ALLOW)
+ allow_next_instance_of(Spam::AkismetService) do |akismet_service|
+ allow(akismet_service).to receive(:spam?).and_return(true)
end
end
diff --git a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
index a5c59b7e22d..367781c0e76 100644
--- a/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests/diffs_controller_spec.rb
@@ -220,29 +220,6 @@ RSpec.describe Projects::MergeRequests::DiffsController do
end
end
- context "with the :default_merge_ref_for_diffs flag on" do
- let(:diffable_merge_ref) { true }
-
- subject do
- go(diff_head: true,
- diff_id: merge_request.merge_request_diff.id,
- start_sha: merge_request.merge_request_diff.start_commit_sha)
- end
-
- it "correctly generates the right diff between versions" do
- MergeRequests::MergeToRefService.new(project: project, current_user: merge_request.author).execute(merge_request)
-
- expect_next_instance_of(CompareService) do |service|
- expect(service).to receive(:execute).with(
- project,
- merge_request.merge_request_diff.head_commit_sha,
- straight: true)
- end
-
- subject
- end
- end
-
context 'with diff_head param passed' do
before do
allow(merge_request).to receive(:diffable_merge_ref?)
@@ -259,6 +236,23 @@ RSpec.describe Projects::MergeRequests::DiffsController do
expect(response).to have_gitlab_http_status(:ok)
end
+
+ context 'when diff_id and start_sha are set' do
+ it 'correctly generates the right diff between versions' do
+ MergeRequests::MergeToRefService.new(project: project, current_user: merge_request.author).execute(merge_request)
+
+ expect_next_instance_of(CompareService) do |service|
+ expect(service).to receive(:execute).with(
+ project,
+ merge_request.merge_request_diff.head_commit_sha,
+ straight: true)
+ end
+
+ go(diff_head: true,
+ diff_id: merge_request.merge_request_diff.id,
+ start_sha: merge_request.merge_request_diff.start_commit_sha)
+ end
+ end
end
context 'the merge request cannot be compared with head' do
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 2390687c3ea..f6db809c2e3 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -68,6 +68,18 @@ RSpec.describe Projects::MergeRequestsController do
end
describe 'as html' do
+ it 'sets the endpoint_metadata_url' do
+ go
+
+ expect(assigns["endpoint_metadata_url"]).to eq(
+ diffs_metadata_project_json_merge_request_path(
+ project,
+ merge_request,
+ 'json',
+ diff_head: true,
+ view: 'inline'))
+ end
+
context 'when diff files were cleaned' do
render_views
@@ -85,23 +97,6 @@ RSpec.describe Projects::MergeRequestsController do
end
end
- context 'with `default_merge_ref_for_diffs` feature flag enabled' do
- before do
- stub_feature_flags(default_merge_ref_for_diffs: true)
- go
- end
-
- it 'adds the diff_head parameter' do
- expect(assigns["endpoint_metadata_url"]).to eq(
- diffs_metadata_project_json_merge_request_path(
- project,
- merge_request,
- 'json',
- diff_head: true,
- view: 'inline'))
- end
- end
-
context 'when diff is missing' do
render_views
diff --git a/spec/controllers/projects/pipelines_controller_spec.rb b/spec/controllers/projects/pipelines_controller_spec.rb
index 4a51e2ed5a0..8fae82d54a2 100644
--- a/spec/controllers/projects/pipelines_controller_spec.rb
+++ b/spec/controllers/projects/pipelines_controller_spec.rb
@@ -292,12 +292,8 @@ RSpec.describe Projects::PipelinesController do
subject { project.namespace }
- context 'code_quality_walkthrough experiment' do
- it_behaves_like 'tracks assignment and records the subject', :code_quality_walkthrough, :namespace
- end
-
- context 'ci_runner_templates experiment' do
- it_behaves_like 'tracks assignment and records the subject', :ci_runner_templates, :namespace
+ context 'runners_availability_section experiment' do
+ it_behaves_like 'tracks assignment and records the subject', :runners_availability_section, :namespace
end
end
@@ -936,6 +932,33 @@ RSpec.describe Projects::PipelinesController do
expect(response).to have_gitlab_http_status(:not_found)
end
end
+
+ context 'when access denied' do
+ it 'returns an error' do
+ sign_in(create(:user))
+
+ post_retry
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when service returns an error' do
+ before do
+ service_response = ServiceResponse.error(message: 'some error', http_status: 404)
+ allow_next_instance_of(::Ci::RetryPipelineService) do |service|
+ allow(service).to receive(:check_access).and_return(service_response)
+ end
+ end
+
+ it 'does not retry' do
+ post_retry
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ expect(response.body).to include('some error')
+ expect(::Ci::RetryPipelineWorker).not_to have_received(:perform_async).with(pipeline.id, user.id)
+ end
+ end
end
describe 'POST cancel.json' do
diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb
index d8ef95cf11a..20a114bbe8c 100644
--- a/spec/controllers/projects/project_members_controller_spec.rb
+++ b/spec/controllers/projects/project_members_controller_spec.rb
@@ -147,137 +147,6 @@ RSpec.describe Projects::ProjectMembersController do
end
end
- describe 'POST create' do
- let_it_be(:project_user) { create(:user) }
-
- before do
- sign_in(user)
- end
-
- context 'when user does not have enough rights' do
- before do
- project.add_developer(user)
- end
-
- it 'returns 404', :aggregate_failures do
- post :create, params: {
- namespace_id: project.namespace,
- project_id: project,
- user_ids: project_user.id,
- access_level: Gitlab::Access::GUEST
- }
-
- expect(response).to have_gitlab_http_status(:not_found)
- expect(project.users).not_to include project_user
- end
- end
-
- context 'when user has enough rights' do
- before do
- project.add_maintainer(user)
- end
-
- it 'adds user to members', :aggregate_failures, :snowplow do
- post :create, params: {
- namespace_id: project.namespace,
- project_id: project,
- user_ids: project_user.id,
- access_level: Gitlab::Access::GUEST
- }
-
- expect(controller).to set_flash.to 'Users were successfully added.'
- expect(response).to redirect_to(project_project_members_path(project))
- expect(project.users).to include project_user
- expect_snowplow_event(
- category: 'Members::CreateService',
- action: 'create_member',
- label: 'project-members-page',
- property: 'existing_user',
- user: user
- )
- end
-
- it 'adds no user to members', :aggregate_failures do
- expect_next_instance_of(Members::CreateService) do |instance|
- expect(instance).to receive(:execute).and_return(status: :failure, message: 'Message')
- end
-
- post :create, params: {
- namespace_id: project.namespace,
- project_id: project,
- user_ids: '',
- access_level: Gitlab::Access::GUEST
- }
-
- expect(controller).to set_flash.to 'Message'
- expect(response).to redirect_to(project_project_members_path(project))
- end
- end
-
- context 'adding project bot' do
- let_it_be(:project_bot) { create(:user, :project_bot) }
-
- before do
- project.add_maintainer(user)
-
- unrelated_project = create(:project)
- unrelated_project.add_maintainer(project_bot)
- end
-
- it 'returns error', :aggregate_failures do
- post :create, params: {
- namespace_id: project.namespace,
- project_id: project,
- user_ids: project_bot.id,
- access_level: Gitlab::Access::GUEST
- }
-
- expect(flash[:alert]).to include('project bots cannot be added to other groups / projects')
- expect(response).to redirect_to(project_project_members_path(project))
- end
- end
-
- context 'access expiry date' do
- before do
- project.add_maintainer(user)
- end
-
- subject do
- post :create, params: {
- namespace_id: project.namespace,
- project_id: project,
- user_ids: project_user.id,
- access_level: Gitlab::Access::GUEST,
- expires_at: expires_at
- }
- end
-
- context 'when set to a date in the past' do
- let(:expires_at) { 2.days.ago }
-
- it 'does not add user to members', :aggregate_failures do
- subject
-
- expect(flash[:alert]).to include('Expires at cannot be a date in the past')
- expect(response).to redirect_to(project_project_members_path(project))
- expect(project.users).not_to include project_user
- end
- end
-
- context 'when set to a date in the future' do
- let(:expires_at) { 5.days.from_now }
-
- it 'adds user to members', :aggregate_failures do
- subject
-
- expect(controller).to set_flash.to 'Users were successfully added.'
- expect(response).to redirect_to(project_project_members_path(project))
- expect(project.users).to include project_user
- end
- end
- end
- end
-
describe 'PUT update' do
let_it_be(:requester) { create(:project_member, :access_request, project: project) }
@@ -603,99 +472,6 @@ RSpec.describe Projects::ProjectMembersController do
end
end
- describe 'POST apply_import' do
- let_it_be(:another_project) { create(:project, :private) }
- let_it_be(:member) { create(:user) }
-
- before do
- project.add_maintainer(user)
- another_project.add_guest(member)
- sign_in(user)
- end
-
- shared_context 'import applied' do
- before do
- post(:apply_import, params: {
- namespace_id: project.namespace,
- project_id: project,
- source_project_id: another_project.id
- })
- end
- end
-
- context 'when user can admin source project members' do
- before do
- another_project.add_maintainer(user)
- end
-
- include_context 'import applied'
-
- it 'imports source project members', :aggregate_failures do
- expect(project.team_members).to include member
- expect(controller).to set_flash.to 'Successfully imported'
- expect(response).to redirect_to(
- project_project_members_path(project)
- )
- end
- end
-
- context "when user can't admin source project members" do
- before do
- another_project.add_developer(user)
- end
-
- include_context 'import applied'
-
- it 'does not import team members' do
- expect(project.team_members).not_to include member
- end
-
- it 'responds with not found' do
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
- end
-
- describe 'POST create' do
- let_it_be(:stranger) { create(:user) }
-
- context 'when creating owner' do
- before do
- project.add_maintainer(user)
- sign_in(user)
- end
-
- it 'does not create a member' do
- expect do
- post :create, params: {
- user_ids: stranger.id,
- namespace_id: project.namespace,
- access_level: Member::OWNER,
- project_id: project
- }
- end.to change { project.members.count }.by(0)
- end
- end
-
- context 'when create maintainer' do
- before do
- project.add_maintainer(user)
- sign_in(user)
- end
-
- it 'creates a member' do
- expect do
- post :create, params: {
- user_ids: stranger.id,
- namespace_id: project.namespace,
- access_level: Member::MAINTAINER,
- project_id: project
- }
- end.to change { project.members.count }.by(1)
- end
- end
- end
-
describe 'POST resend_invite' do
let_it_be(:member) { create(:project_member, project: project) }
diff --git a/spec/controllers/projects/releases_controller_spec.rb b/spec/controllers/projects/releases_controller_spec.rb
index 120020273f9..9dd18e58109 100644
--- a/spec/controllers/projects/releases_controller_spec.rb
+++ b/spec/controllers/projects/releases_controller_spec.rb
@@ -222,6 +222,168 @@ RSpec.describe Projects::ReleasesController do
end
end
+ describe 'GET #latest_permalink' do
+ # Uses default order_by=released_at parameter.
+ subject do
+ get :latest_permalink, params: { namespace_id: project.namespace, project_id: project }
+ end
+
+ before do
+ sign_in(user)
+ end
+
+ let(:release) { create(:release, project: project) }
+ let(:tag) { CGI.escape(release.tag) }
+
+ context 'when user is a guest' do
+ let(:project) { private_project }
+ let(:user) { guest }
+
+ it 'proceeds with the redirect' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:redirect)
+ end
+ end
+
+ context 'when user is an external user for the project' do
+ let(:project) { private_project }
+ let(:user) { create(:user) }
+
+ it 'behaves like not found' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when there are no releases for the project' do
+ let(:project) { create(:project, :repository, :public) }
+ let(:user) { developer }
+
+ before do
+ project.releases.destroy_all # rubocop: disable Cop/DestroyAll
+ end
+
+ it 'behaves like not found' do
+ subject
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'multiple releases' do
+ let(:user) { developer }
+
+ it 'redirects to the latest release' do
+ create(:release, project: project, released_at: 1.day.ago)
+ latest_release = create(:release, project: project, released_at: Time.current)
+
+ subject
+
+ expect(response).to redirect_to("#{project_releases_path(project)}/#{latest_release.tag}")
+ end
+ end
+
+ context 'suffix path redirection' do
+ let(:user) { developer }
+ let(:suffix_path) { 'downloads/zips/helm-hello-world.zip' }
+ let!(:latest_release) { create(:release, project: project, released_at: Time.current) }
+
+ subject do
+ get :latest_permalink, params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ suffix_path: suffix_path
+ }
+ end
+
+ it 'redirects to the latest release with suffix path and format' do
+ subject
+
+ expect(response).to redirect_to(
+ "#{project_releases_path(project)}/#{latest_release.tag}/#{suffix_path}")
+ end
+
+ context 'suffix path abuse' do
+ let(:suffix_path) { 'downloads/zips/../../../../../../../robots.txt'}
+
+ it 'raises attack error' do
+ expect do
+ subject
+ end.to raise_error(Gitlab::Utils::PathTraversalAttackError)
+ end
+ end
+
+ context 'url parameters' do
+ let(:suffix_path) { 'downloads/zips/helm-hello-world.zip' }
+
+ subject do
+ get :latest_permalink, params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ suffix_path: suffix_path,
+ order_by: 'released_at',
+ param_1: 1,
+ param_2: 2
+ }
+ end
+
+ it 'carries over query parameters without order_by parameter in the redirect' do
+ subject
+
+ expect(response).to redirect_to(
+ "#{project_releases_path(project)}/#{latest_release.tag}/#{suffix_path}?param_1=1&param_2=2")
+ end
+ end
+ end
+
+ context 'order_by parameter' do
+ let!(:latest_release) { create(:release, project: project, released_at: Time.current, tag: 'latest') }
+
+ shared_examples_for 'redirects to latest release ordered by using released_at' do
+ it do
+ expect(Release).to receive(:order_released_desc).and_call_original
+
+ subject
+
+ expect(response).to redirect_to("#{project_releases_path(project)}/#{latest_release.tag}")
+ end
+ end
+
+ before do
+ create(:release, project: project, released_at: 1.day.ago, tag: 'alpha')
+ create(:release, project: project, released_at: 2.days.ago, tag: 'beta')
+ end
+
+ context 'invalid parameter' do
+ let(:user) { developer }
+
+ subject do
+ get :latest_permalink, params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ order_by: 'unsupported'
+ }
+ end
+
+ it_behaves_like 'redirects to latest release ordered by using released_at'
+ end
+
+ context 'valid parameter' do
+ subject do
+ get :latest_permalink, params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ order_by: 'released_at'
+ }
+ end
+
+ it_behaves_like 'redirects to latest release ordered by using released_at'
+ end
+ end
+ end
+
# `GET #downloads` is addressed in spec/requests/projects/releases_controller_spec.rb
private
diff --git a/spec/controllers/projects/runners_controller_spec.rb b/spec/controllers/projects/runners_controller_spec.rb
index 246a37129d7..57d1695b842 100644
--- a/spec/controllers/projects/runners_controller_spec.rb
+++ b/spec/controllers/projects/runners_controller_spec.rb
@@ -37,7 +37,7 @@ RSpec.describe Projects::RunnersController do
describe '#destroy' do
it 'destroys the runner' do
- expect_next_instance_of(Ci::UnregisterRunnerService, runner) do |service|
+ expect_next_instance_of(Ci::Runners::UnregisterRunnerService, runner, user) do |service|
expect(service).to receive(:execute).once.and_call_original
end
diff --git a/spec/controllers/projects/serverless/functions_controller_spec.rb b/spec/controllers/projects/serverless/functions_controller_spec.rb
index 860bbc1c5cc..f8cee09006c 100644
--- a/spec/controllers/projects/serverless/functions_controller_spec.rb
+++ b/spec/controllers/projects/serverless/functions_controller_spec.rb
@@ -39,9 +39,24 @@ RSpec.describe Projects::Serverless::FunctionsController do
project_id: project.to_param)
end
+ shared_examples_for 'behind :deprecated_serverless feature flag' do
+ before do
+ stub_feature_flags(deprecated_serverless: false)
+ end
+
+ it 'returns 404' do
+ action
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
describe 'GET #index' do
let(:expected_json) { { 'knative_installed' => knative_state, 'functions' => functions } }
+ it_behaves_like 'behind :deprecated_serverless feature flag' do
+ let(:action) { get :index, params: params({ format: :json }) }
+ end
+
context 'when cache is being read' do
let(:knative_state) { 'checking' }
let(:functions) { [] }
@@ -147,6 +162,10 @@ RSpec.describe Projects::Serverless::FunctionsController do
end
describe 'GET #show' do
+ it_behaves_like 'behind :deprecated_serverless feature flag' do
+ let(:action) { get :show, params: params({ format: :json, environment_id: "*", id: "foo" }) }
+ end
+
context 'with function that does not exist' do
it 'returns 404' do
get :show, params: params({ format: :json, environment_id: "*", id: "foo" })
@@ -239,6 +258,10 @@ RSpec.describe Projects::Serverless::FunctionsController do
end
describe 'GET #metrics' do
+ it_behaves_like 'behind :deprecated_serverless feature flag' do
+ let(:action) { get :metrics, params: params({ format: :json, environment_id: "*", id: "foo" }) }
+ end
+
context 'invalid data' do
it 'has a bad function name' do
get :metrics, params: params({ format: :json, environment_id: "*", id: "foo" })
diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb
index f3c7b501faa..35e5422d072 100644
--- a/spec/controllers/projects/services_controller_spec.rb
+++ b/spec/controllers/projects/services_controller_spec.rb
@@ -353,7 +353,16 @@ RSpec.describe Projects::ServicesController do
it 'does not modify integration' do
expect { put :update, params: project_params.merge(service: integration_params) }
- .not_to change { project.prometheus_integration.reload.attributes }
+ .not_to change { prometheus_integration_as_data }
+ end
+
+ def prometheus_integration_as_data
+ pi = project.prometheus_integration.reload
+ attrs = pi.attributes.except('encrypted_properties',
+ 'encrypted_properties_iv',
+ 'encrypted_properties_tmp')
+
+ [attrs, pi.encrypted_properties_tmp]
end
end
diff --git a/spec/controllers/projects/tags/releases_controller_spec.rb b/spec/controllers/projects/tags/releases_controller_spec.rb
index b3d4d944440..1d2385f54f9 100644
--- a/spec/controllers/projects/tags/releases_controller_spec.rb
+++ b/spec/controllers/projects/tags/releases_controller_spec.rb
@@ -5,7 +5,7 @@ require 'spec_helper'
RSpec.describe Projects::Tags::ReleasesController do
let!(:project) { create(:project, :repository) }
let!(:user) { create(:user) }
- let!(:release) { create(:release, project: project) }
+ let!(:release) { create(:release, project: project, tag: "v1.1.0") }
let!(:tag) { release.tag }
before do
@@ -27,7 +27,7 @@ RSpec.describe Projects::Tags::ReleasesController do
end
it 'retrieves an existing release' do
- response = get :edit, params: { namespace_id: project.namespace, project_id: project, tag_id: release.tag }
+ response = get :edit, params: { namespace_id: project.namespace, project_id: project, tag_id: tag }
release = assigns(:release)
expect(release).not_to be_nil
diff --git a/spec/controllers/projects/tags_controller_spec.rb b/spec/controllers/projects/tags_controller_spec.rb
index f955f9d0248..d0971e96910 100644
--- a/spec/controllers/projects/tags_controller_spec.rb
+++ b/spec/controllers/projects/tags_controller_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
RSpec.describe Projects::TagsController do
let(:project) { create(:project, :public, :repository) }
- let!(:release) { create(:release, project: project) }
+ let!(:release) { create(:release, project: project, tag: "v1.1.0") }
let!(:invalid_release) { create(:release, project: project, tag: 'does-not-exist') }
let(:user) { create(:user) }
diff --git a/spec/controllers/projects_controller_spec.rb b/spec/controllers/projects_controller_spec.rb
index 08d1d88fcda..c098ea71f7a 100644
--- a/spec/controllers/projects_controller_spec.rb
+++ b/spec/controllers/projects_controller_spec.rb
@@ -1211,16 +1211,6 @@ RSpec.describe ProjectsController do
expect(response).to have_gitlab_http_status(:success)
end
-
- context 'when "strong_parameters_for_project_controller" FF is disabled' do
- before do
- stub_feature_flags(strong_parameters_for_project_controller: false)
- end
-
- it 'raises an exception' do
- expect { request }.to raise_error(TypeError)
- end
- end
end
end
@@ -1600,71 +1590,22 @@ RSpec.describe ProjectsController do
get :show, format: :atom, params: { id: public_project, namespace_id: public_project.namespace }
- expect(response).to render_template('xml.atom')
+ expect(response).to have_gitlab_http_status(:success)
+ expect(response).to render_template(:show)
+ expect(response).to render_template(layout: :xml)
expect(assigns(:events)).to eq([event])
end
it 'filters by calling event.visible_to_user?' do
get :show, format: :atom, params: { id: public_project, namespace_id: public_project.namespace }
- expect(response).to render_template('xml.atom')
+ expect(response).to have_gitlab_http_status(:success)
+ expect(response).to render_template(:show)
+ expect(response).to render_template(layout: :xml)
expect(assigns(:events)).to eq([event])
end
end
- describe 'GET resolve' do
- shared_examples 'resolvable endpoint' do
- it 'redirects to the project page' do
- get :resolve, params: { id: project.id }
-
- expect(response).to have_gitlab_http_status(:found)
- expect(response).to redirect_to(project_path(project))
- end
- end
-
- context 'with an authenticated user' do
- before do
- sign_in(user)
- end
-
- context 'when user has access to the project' do
- before do
- project.add_developer(user)
- end
-
- it_behaves_like 'resolvable endpoint'
- end
-
- context 'when user has no access to the project' do
- it 'gives 404 for existing project' do
- get :resolve, params: { id: project.id }
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- it 'gives 404 for non-existing project' do
- get :resolve, params: { id: '0' }
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
-
- context 'non authenticated user' do
- context 'with a public project' do
- let(:project) { public_project }
-
- it_behaves_like 'resolvable endpoint'
- end
-
- it 'gives 404 for private project' do
- get :resolve, params: { id: project.id }
-
- expect(response).to have_gitlab_http_status(:not_found)
- end
- end
- end
-
it 'updates Service Desk attributes' do
project.add_maintainer(user)
sign_in(user)
diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb
index 0f1501d4c3c..9482448fc03 100644
--- a/spec/controllers/search_controller_spec.rb
+++ b/spec/controllers/search_controller_spec.rb
@@ -251,8 +251,8 @@ RSpec.describe SearchController do
it_behaves_like 'tracking unique hll events' do
subject(:request) { get :show, params: { scope: 'projects', search: 'term' } }
- let(:target_id) { 'i_search_total' }
- let(:expected_type) { instance_of(String) }
+ let(:target_event) { 'i_search_total' }
+ let(:expected_value) { instance_of(String) }
end
end
@@ -291,7 +291,7 @@ RSpec.describe SearchController do
end
end
- it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit do
let(:current_user) { user }
def request
@@ -355,7 +355,7 @@ RSpec.describe SearchController do
expect(json_response).to eq({ 'count' => '0' })
end
- it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit do
let(:current_user) { user }
def request
@@ -375,7 +375,7 @@ RSpec.describe SearchController do
expect(json_response).to match_array([])
end
- it_behaves_like 'rate limited endpoint', rate_limit_key: :user_email_lookup do
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit do
let(:current_user) { user }
def request
@@ -445,6 +445,26 @@ RSpec.describe SearchController do
end
context 'unauthorized user' do
+ describe 'search rate limits' do
+ using RSpec::Parameterized::TableSyntax
+
+ let(:project) { create(:project, :public) }
+
+ where(:endpoint, :params) do
+ :show | { search: 'hello', scope: 'projects' }
+ :count | { search: 'hello', scope: 'projects' }
+ :autocomplete | { term: 'hello', scope: 'projects' }
+ end
+
+ with_them do
+ it_behaves_like 'rate limited endpoint', rate_limit_key: :search_rate_limit_unauthenticated do
+ def request
+ get endpoint, params: params.merge(project_id: project.id)
+ end
+ end
+ end
+ end
+
describe 'GET #opensearch' do
render_views
diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb
index 31de00dd8bd..03d053e6f97 100644
--- a/spec/controllers/sessions_controller_spec.rb
+++ b/spec/controllers/sessions_controller_spec.rb
@@ -235,7 +235,7 @@ RSpec.describe SessionsController do
unsuccesful_login(user_params)
expect(response).to render_template(:new)
- expect(flash[:alert]).to include 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'
+ 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
@@ -259,7 +259,7 @@ RSpec.describe SessionsController do
unsuccesful_login(user_params, sesion_params: { failed_login_attempts: 6 })
expect(response).to render_template(:new)
- expect(flash[:alert]).to include 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'
+ 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
@@ -279,7 +279,7 @@ RSpec.describe SessionsController do
unsuccesful_login(user_params)
expect(response).to render_template(:new)
- expect(flash[:alert]).to include 'There was an error with the reCAPTCHA. Please solve the reCAPTCHA again.'
+ 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/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb
index a82c44fcc44..18b2d3b14ec 100644
--- a/spec/controllers/snippets_controller_spec.rb
+++ b/spec/controllers/snippets_controller_spec.rb
@@ -176,8 +176,8 @@ RSpec.describe SnippetsController do
it_behaves_like 'tracking unique hll events' do
subject(:request) { get :show, params: { id: public_snippet.to_param } }
- let(:target_id) { 'i_snippets_show' }
- let(:expected_type) { instance_of(String) }
+ let(:target_event) { 'i_snippets_show' }
+ let(:expected_value) { instance_of(String) }
end
end