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
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/groups/group_members_controller_spec.rb10
-rw-r--r--spec/controllers/groups/settings/ci_cd_controller_spec.rb55
-rw-r--r--spec/controllers/projects/avatars_controller_spec.rb36
-rw-r--r--spec/controllers/projects/clusters_controller_spec.rb4
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb4
-rw-r--r--spec/controllers/projects/jobs_controller_spec.rb35
-rw-r--r--spec/controllers/projects/merge_requests_controller_spec.rb95
-rw-r--r--spec/controllers/projects/project_members_controller_spec.rb18
-rw-r--r--spec/controllers/projects/raw_controller_spec.rb75
-rw-r--r--spec/controllers/projects/refs_controller_spec.rb14
-rw-r--r--spec/controllers/projects/tags/releases_controller_spec.rb7
-rw-r--r--spec/controllers/projects/wikis_controller_spec.rb85
-rw-r--r--spec/controllers/snippets_controller_spec.rb22
-rw-r--r--spec/factories/appearances.rb4
-rw-r--r--spec/factories/notes.rb15
-rw-r--r--spec/features/admin/admin_disables_git_access_protocol_spec.rb59
-rw-r--r--spec/features/group_variables_spec.rb2
-rw-r--r--spec/features/groups/show_spec.rb4
-rw-r--r--spec/features/issues/gfm_autocomplete_spec.rb44
-rw-r--r--spec/features/issues/user_creates_issue_spec.rb6
-rw-r--r--spec/features/projects/clusters/gcp_spec.rb2
-rw-r--r--spec/features/projects/jobs_spec.rb8
-rw-r--r--spec/features/runners_spec.rb3
-rw-r--r--spec/features/users/overview_spec.rb6
-rw-r--r--spec/fixtures/api/schemas/entities/issuable_sidebar_todo.json8
-rw-r--r--spec/fixtures/api/schemas/entities/issue_sidebar.json54
-rw-r--r--spec/fixtures/api/schemas/entities/issue_sidebar_extras.json18
-rw-r--r--spec/fixtures/api/schemas/entities/merge_request_basic.json6
-rw-r--r--spec/fixtures/api/schemas/entities/merge_request_sidebar.json56
-rw-r--r--spec/fixtures/api/schemas/entities/merge_request_sidebar_extras.json21
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/milestone.json22
-rw-r--r--spec/fixtures/api/schemas/public_api/v4/milestones.json21
-rw-r--r--spec/fixtures/symlink_export.tar.gzbin0 -> 435 bytes
-rw-r--r--spec/helpers/issuables_helper_spec.rb36
-rw-r--r--spec/helpers/projects_helper_spec.rb110
-rw-r--r--spec/initializers/active_record_locking_spec.rb44
-rw-r--r--spec/initializers/zz_metrics_spec.rb (renamed from spec/initializers/8_metrics_spec.rb)2
-rw-r--r--spec/javascripts/ci_variable_list/ci_variable_list_spec.js2
-rw-r--r--spec/javascripts/diffs/store/utils_spec.js20
-rw-r--r--spec/javascripts/environments/environment_terminal_button_spec.js48
-rw-r--r--spec/javascripts/fixtures/blob.rb9
-rw-r--r--spec/javascripts/fixtures/boards.rb7
-rw-r--r--spec/javascripts/fixtures/branches.rb3
-rw-r--r--spec/javascripts/fixtures/clusters.rb3
-rw-r--r--spec/javascripts/fixtures/commit.rb2
-rw-r--r--spec/javascripts/fixtures/deploy_keys.rb6
-rw-r--r--spec/javascripts/fixtures/groups.rb6
-rw-r--r--spec/javascripts/fixtures/issues.rb6
-rw-r--r--spec/javascripts/fixtures/jobs.rb13
-rw-r--r--spec/javascripts/fixtures/labels.rb12
-rw-r--r--spec/javascripts/fixtures/merge_requests.rb12
-rw-r--r--spec/javascripts/fixtures/merge_requests_diffs.rb4
-rw-r--r--spec/javascripts/fixtures/pipeline_schedules.rb6
-rw-r--r--spec/javascripts/fixtures/pipelines.rb6
-rw-r--r--spec/javascripts/fixtures/projects.rb15
-rw-r--r--spec/javascripts/fixtures/prometheus_service.rb3
-rw-r--r--spec/javascripts/fixtures/services.rb3
-rw-r--r--spec/javascripts/fixtures/snippet.rb2
-rw-r--r--spec/javascripts/fixtures/todos.rb6
-rw-r--r--spec/javascripts/fixtures/u2f.rb2
-rw-r--r--spec/javascripts/jobs/components/artifacts_block_spec.js13
-rw-r--r--spec/javascripts/jobs/components/sidebar_spec.js8
-rw-r--r--spec/javascripts/notes/components/noteable_discussion_spec.js73
-rw-r--r--spec/javascripts/releases/components/app_spec.js79
-rw-r--r--spec/javascripts/releases/components/release_block_spec.js34
-rw-r--r--spec/javascripts/releases/mock_data.js128
-rw-r--r--spec/javascripts/releases/store/actions_spec.js98
-rw-r--r--spec/javascripts/releases/store/helpers.js6
-rw-r--r--spec/javascripts/releases/store/mutations_spec.js47
-rw-r--r--spec/javascripts/sidebar/mock_data.js4
-rw-r--r--spec/javascripts/sidebar/sidebar_mediator_spec.js4
-rw-r--r--spec/javascripts/vue_mr_widget/mr_widget_options_spec.js49
-rw-r--r--spec/javascripts/vue_shared/components/user_popover/user_popover_spec.js14
-rw-r--r--spec/lib/banzai/filter/milestone_reference_filter_spec.rb30
-rw-r--r--spec/lib/gitlab/bare_repository_import/importer_spec.rb2
-rw-r--r--spec/lib/gitlab/current_settings_spec.rb80
-rw-r--r--spec/lib/gitlab/discussions_diff/file_collection_spec.rb61
-rw-r--r--spec/lib/gitlab/discussions_diff/highlight_cache_spec.rb102
-rw-r--r--spec/lib/gitlab/gitaly_client_spec.rb82
-rw-r--r--spec/lib/gitlab/import_export/command_line_util_spec.rb38
-rw-r--r--spec/lib/gitlab/import_export/file_importer_spec.rb13
-rw-r--r--spec/lib/gitlab/object_hierarchy_spec.rb (renamed from spec/lib/gitlab/group_hierarchy_spec.rb)10
-rw-r--r--spec/lib/gitlab/project_authorizations_spec.rb4
-rw-r--r--spec/lib/gitlab/prometheus/query_variables_spec.rb4
-rw-r--r--spec/lib/gitlab/upgrader_spec.rb40
-rw-r--r--spec/lib/gitlab/utils/override_spec.rb32
-rw-r--r--spec/mailers/notify_spec.rb12
-rw-r--r--spec/migrations/migrate_cluster_configure_worker_sidekiq_queue_spec.rb68
-rw-r--r--spec/models/appearance_spec.rb30
-rw-r--r--spec/models/clusters/platforms/kubernetes_spec.rb7
-rw-r--r--spec/models/concerns/avatarable_spec.rb37
-rw-r--r--spec/models/concerns/cacheable_attributes_spec.rb8
-rw-r--r--spec/models/concerns/discussion_on_diff_spec.rb10
-rw-r--r--spec/models/diff_note_spec.rb17
-rw-r--r--spec/models/merge_request_spec.rb51
-rw-r--r--spec/models/milestone_spec.rb9
-rw-r--r--spec/models/namespace_spec.rb54
-rw-r--r--spec/models/project_spec.rb77
-rw-r--r--spec/models/user_spec.rb4
-rw-r--r--spec/policies/group_policy_spec.rb8
-rw-r--r--spec/requests/api/branches_spec.rb12
-rw-r--r--spec/requests/api/events_spec.rb4
-rw-r--r--spec/requests/api/files_spec.rb12
-rw-r--r--spec/requests/api/jobs_spec.rb32
-rw-r--r--spec/requests/openid_connect_spec.rb2
-rw-r--r--spec/requests/rack_attack_global_spec.rb2
-rw-r--r--spec/serializers/entity_date_helper_spec.rb12
-rw-r--r--spec/serializers/environment_entity_spec.rb30
-rw-r--r--spec/serializers/issue_serializer_spec.rb10
-rw-r--r--spec/serializers/merge_request_basic_serializer_spec.rb16
-rw-r--r--spec/serializers/merge_request_serializer_spec.rb12
-rw-r--r--spec/services/ci/register_job_service_spec.rb4
-rw-r--r--spec/services/clusters/gcp/finalize_creation_service_spec.rb6
-rw-r--r--spec/services/clusters/update_service_spec.rb2
-rw-r--r--spec/services/groups/create_service_spec.rb4
-rw-r--r--spec/services/groups/nested_create_service_spec.rb2
-rw-r--r--spec/services/groups/transfer_service_spec.rb2
-rw-r--r--spec/services/notification_service_spec.rb8
-rw-r--r--spec/services/projects/after_rename_service_spec.rb20
-rw-r--r--spec/services/projects/lfs_pointers/lfs_download_service_spec.rb59
-rw-r--r--spec/services/projects/transfer_service_spec.rb20
-rw-r--r--spec/spec_helper.rb6
-rw-r--r--spec/support/api/boards_shared_examples.rb15
-rw-r--r--spec/support/api/milestones_shared_examples.rb31
-rw-r--r--spec/support/api/scopes/read_user_shared_examples.rb2
-rw-r--r--spec/support/api/time_tracking_shared_examples.rb22
-rw-r--r--spec/support/controllers/githubish_import_controller_shared_examples.rb34
-rw-r--r--spec/support/features/variable_list_shared_examples.rb46
-rw-r--r--spec/support/helpers/git_http_helpers.rb8
-rw-r--r--spec/support/helpers/graphql_helpers.rb2
-rw-r--r--spec/support/helpers/kubernetes_helpers.rb20
-rw-r--r--spec/support/helpers/migrations_helpers.rb16
-rw-r--r--spec/support/import_export/export_file_helper.rb2
-rw-r--r--spec/support/issuables_requiring_filter_shared_examples.rb2
-rw-r--r--spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb11
-rw-r--r--spec/support/shared_examples/milestone_tabs_examples.rb2
-rw-r--r--spec/support/shared_examples/requests/api/diff_discussions.rb8
-rw-r--r--spec/support/shared_examples/requests/api/discussions.rb16
-rw-r--r--spec/support/shared_examples/requests/api/merge_requests_list.rb16
-rw-r--r--spec/support/shared_examples/requests/api/notes.rb26
-rw-r--r--spec/support/shared_examples/requests/api/resolvable_discussions.rb16
-rw-r--r--spec/views/notify/changed_milestone_email.html.haml_spec.rb35
-rw-r--r--spec/views/projects/merge_requests/show.html.haml_spec.rb5
-rw-r--r--spec/workers/cluster_configure_worker_spec.rb (renamed from spec/workers/cluster_platform_configure_worker_spec.rb)2
-rw-r--r--spec/workers/cluster_provision_worker_spec.rb4
145 files changed, 2404 insertions, 868 deletions
diff --git a/spec/controllers/groups/group_members_controller_spec.rb b/spec/controllers/groups/group_members_controller_spec.rb
index 00a00306ff9..ed38dadfd6b 100644
--- a/spec/controllers/groups/group_members_controller_spec.rb
+++ b/spec/controllers/groups/group_members_controller_spec.rb
@@ -78,9 +78,11 @@ describe Groups::GroupMembersController do
Gitlab::Access.options.each do |label, value|
it "can change the access level to #{label}" do
- xhr :put, :update, group_member: { access_level: value },
- group_id: group,
- id: requester
+ put :update, params: {
+ group_member: { access_level: value },
+ group_id: group,
+ id: requester
+ }, xhr: true
expect(requester.reload.human_access).to eq(label)
end
@@ -130,7 +132,7 @@ describe Groups::GroupMembersController do
end
it '[JS] removes user from members' do
- xhr :delete, :destroy, group_id: group, id: member
+ delete :destroy, params: { group_id: group, id: member }, xhr: true
expect(response).to be_success
expect(group.members).not_to include member
diff --git a/spec/controllers/groups/settings/ci_cd_controller_spec.rb b/spec/controllers/groups/settings/ci_cd_controller_spec.rb
index b7f04f732b9..40673d10b91 100644
--- a/spec/controllers/groups/settings/ci_cd_controller_spec.rb
+++ b/spec/controllers/groups/settings/ci_cd_controller_spec.rb
@@ -5,30 +5,65 @@ describe Groups::Settings::CiCdController do
let(:user) { create(:user) }
before do
- group.add_maintainer(user)
sign_in(user)
end
describe 'GET #show' do
- it 'renders show with 200 status code' do
- get :show, params: { group_id: group }
+ context 'when user is owner' do
+ before do
+ group.add_owner(user)
+ end
- expect(response).to have_gitlab_http_status(200)
- expect(response).to render_template(:show)
+ it 'renders show with 200 status code' do
+ get :show, params: { group_id: group }
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to render_template(:show)
+ end
+ end
+
+ context 'when user is not owner' do
+ before do
+ group.add_maintainer(user)
+ end
+
+ it 'renders a 404' do
+ get :show, params: { group_id: group }
+
+ expect(response).to have_gitlab_http_status(404)
+ end
end
end
describe 'PUT #reset_registration_token' do
subject { put :reset_registration_token, params: { group_id: group } }
- it 'resets runner registration token' do
- expect { subject }.to change { group.reload.runners_token }
+ context 'when user is owner' do
+ before do
+ group.add_owner(user)
+ end
+
+ it 'resets runner registration token' do
+ expect { subject }.to change { group.reload.runners_token }
+ end
+
+ it 'redirects the user to admin runners page' do
+ subject
+
+ expect(response).to redirect_to(group_settings_ci_cd_path)
+ end
end
- it 'redirects the user to admin runners page' do
- subject
+ context 'when user is not owner' do
+ before do
+ group.add_maintainer(user)
+ end
+
+ it 'renders a 404' do
+ subject
- expect(response).to redirect_to(group_settings_ci_cd_path)
+ expect(response).to have_gitlab_http_status(404)
+ end
end
end
end
diff --git a/spec/controllers/projects/avatars_controller_spec.rb b/spec/controllers/projects/avatars_controller_spec.rb
index 40ab81395ea..95b7ae5885a 100644
--- a/spec/controllers/projects/avatars_controller_spec.rb
+++ b/spec/controllers/projects/avatars_controller_spec.rb
@@ -26,37 +26,13 @@ describe Projects::AvatarsController do
context 'when the avatar is stored in the repository' do
let(:filepath) { 'files/images/logo-white.png' }
- context 'when feature flag workhorse_set_content_type is' do
- before do
- stub_feature_flags(workhorse_set_content_type: flag_value)
- end
+ it 'sends the avatar' do
+ subject
- context 'enabled' do
- let(:flag_value) { true }
-
- it 'sends the avatar' do
- subject
-
- expect(response).to have_gitlab_http_status(200)
- expect(response.header['Content-Disposition']).to eq('inline')
- expect(response.header['Content-Type']).to eq 'image/png'
- expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:')
- expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
- end
- end
-
- context 'disabled' do
- let(:flag_value) { false }
-
- it 'sends the avatar' do
- subject
-
- expect(response).to have_gitlab_http_status(200)
- expect(response.header['Content-Type']).to eq('image/png')
- expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:')
- expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq nil
- end
- end
+ expect(response).to have_gitlab_http_status(200)
+ expect(response.header['Content-Disposition']).to eq('inline')
+ expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:')
+ expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
end
end
diff --git a/spec/controllers/projects/clusters_controller_spec.rb b/spec/controllers/projects/clusters_controller_spec.rb
index ea266384446..d94c18ddc02 100644
--- a/spec/controllers/projects/clusters_controller_spec.rb
+++ b/spec/controllers/projects/clusters_controller_spec.rb
@@ -311,7 +311,7 @@ describe Projects::ClustersController do
describe 'security' do
before do
- allow(ClusterPlatformConfigureWorker).to receive(:perform_async)
+ allow(ClusterConfigureWorker).to receive(:perform_async)
stub_kubeclient_get_namespace('https://kubernetes.example.com', namespace: 'my-namespace')
end
@@ -409,7 +409,7 @@ describe Projects::ClustersController do
end
before do
- allow(ClusterPlatformConfigureWorker).to receive(:perform_async)
+ allow(ClusterConfigureWorker).to receive(:perform_async)
stub_kubeclient_get_namespace('https://kubernetes.example.com', namespace: 'my-namespace')
end
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index f9193513a6a..a239ac16c0d 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -206,12 +206,12 @@ describe Projects::IssuesController do
describe 'Redirect after sign in' do
context 'with an AJAX request' do
it 'does not store the visited URL' do
- xhr :get,
- :show,
+ get :show, params: {
format: :json,
namespace_id: project.namespace,
project_id: project,
id: issue.iid
+ }, xhr: true
expect(session['user_return_to']).to be_blank
end
diff --git a/spec/controllers/projects/jobs_controller_spec.rb b/spec/controllers/projects/jobs_controller_spec.rb
index e1133fdd562..7f65fe551e9 100644
--- a/spec/controllers/projects/jobs_controller_spec.rb
+++ b/spec/controllers/projects/jobs_controller_spec.rb
@@ -892,36 +892,13 @@ describe Projects::JobsController, :clean_gitlab_redis_shared_state do
context "when job has a trace artifact" do
let(:job) { create(:ci_build, :trace_artifact, pipeline: pipeline) }
- context 'when feature flag workhorse_set_content_type is' do
- before do
- stub_feature_flags(workhorse_set_content_type: flag_value)
- end
-
- context 'enabled' do
- let(:flag_value) { true }
-
- it "sets #{Gitlab::Workhorse::DETECT_HEADER} header" do
- response = subject
-
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.headers["Content-Type"]).to eq("text/plain; charset=utf-8")
- expect(response.body).to eq(job.job_artifacts_trace.open.read)
- expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
- end
- end
-
- context 'disabled' do
- let(:flag_value) { false }
-
- it 'returns a trace' do
- response = subject
+ it "sets #{Gitlab::Workhorse::DETECT_HEADER} header" do
+ response = subject
- expect(response).to have_gitlab_http_status(:ok)
- expect(response.headers["Content-Type"]).to eq("text/plain; charset=utf-8")
- expect(response.body).to eq(job.job_artifacts_trace.open.read)
- expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to be nil
- end
- end
+ expect(response).to have_gitlab_http_status(:ok)
+ expect(response.headers["Content-Type"]).to eq("text/plain; charset=utf-8")
+ expect(response.body).to eq(job.job_artifacts_trace.open.read)
+ expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
end
end
diff --git a/spec/controllers/projects/merge_requests_controller_spec.rb b/spec/controllers/projects/merge_requests_controller_spec.rb
index 962dfb91c9f..d46b9ffb3ce 100644
--- a/spec/controllers/projects/merge_requests_controller_spec.rb
+++ b/spec/controllers/projects/merge_requests_controller_spec.rb
@@ -30,19 +30,6 @@ describe Projects::MergeRequestsController do
end
end
- shared_examples "loads labels" do |action|
- it "loads labels into the @labels variable" do
- get action,
- params: {
- namespace_id: project.namespace.to_param,
- project_id: project,
- id: merge_request.iid
- },
- format: 'html'
- expect(assigns(:labels)).not_to be_nil
- end
- end
-
describe "GET show" do
def go(extra_params = {})
params = {
@@ -54,8 +41,6 @@ describe Projects::MergeRequestsController do
get :show, params: params.merge(extra_params)
end
- it_behaves_like "loads labels", :show
-
describe 'as html' do
context 'when diff files were cleaned' do
render_views
@@ -333,7 +318,7 @@ describe Projects::MergeRequestsController do
before do
project.add_reporter(user)
- xhr :post, :merge, params: base_params
+ post :merge, params: base_params, xhr: true
end
it 'returns 404' do
@@ -681,13 +666,14 @@ describe Projects::MergeRequestsController do
merge_request.title = merge_request.wip_title
merge_request.save
- xhr :post, :remove_wip,
- format: :json,
+ post :remove_wip,
params: {
+ format: :json,
namespace_id: merge_request.project.namespace.to_param,
project_id: merge_request.project,
id: merge_request.iid
- }
+ },
+ xhr: true
end
it 'removes the wip status' do
@@ -701,13 +687,14 @@ describe Projects::MergeRequestsController do
describe 'POST cancel_merge_when_pipeline_succeeds' do
subject do
- xhr :post, :cancel_merge_when_pipeline_succeeds,
- format: :json,
+ post :cancel_merge_when_pipeline_succeeds,
params: {
+ format: :json,
namespace_id: merge_request.project.namespace.to_param,
project_id: merge_request.project,
id: merge_request.iid
- }
+ },
+ xhr: true
end
it 'calls MergeRequests::MergeWhenPipelineSucceedsService' do
@@ -955,6 +942,70 @@ describe Projects::MergeRequestsController do
end
end
+ describe 'GET discussions' do
+ context 'when authenticated' do
+ before do
+ project.add_developer(user)
+ sign_in(user)
+ end
+
+ it 'returns 200' do
+ get :discussions, namespace_id: project.namespace, project_id: project, id: merge_request.iid
+
+ expect(response.status).to eq(200)
+ end
+
+ context 'highlight preloading' do
+ context 'with commit diff notes' do
+ let!(:commit_diff_note) do
+ create(:diff_note_on_commit, project: merge_request.project)
+ end
+
+ it 'preloads notes diffs highlights' do
+ expect_next_instance_of(Gitlab::DiscussionsDiff::FileCollection) do |collection|
+ note_diff_file = commit_diff_note.note_diff_file
+
+ expect(collection).to receive(:load_highlight).with([note_diff_file.id]).and_call_original
+ expect(collection).to receive(:find_by_id).with(note_diff_file.id).and_call_original
+ end
+
+ get :discussions, namespace_id: project.namespace, project_id: project, id: merge_request.iid
+ end
+ end
+
+ context 'with diff notes' do
+ let!(:diff_note) do
+ create(:diff_note_on_merge_request, noteable: merge_request, project: merge_request.project)
+ end
+
+ it 'preloads notes diffs highlights' do
+ expect_next_instance_of(Gitlab::DiscussionsDiff::FileCollection) do |collection|
+ note_diff_file = diff_note.note_diff_file
+
+ expect(collection).to receive(:load_highlight).with([note_diff_file.id]).and_call_original
+ expect(collection).to receive(:find_by_id).with(note_diff_file.id).and_call_original
+ end
+
+ get :discussions, namespace_id: project.namespace, project_id: project, id: merge_request.iid
+ end
+
+ it 'does not preload highlights when diff note is resolved' do
+ Notes::ResolveService.new(diff_note.project, user).execute(diff_note)
+
+ expect_next_instance_of(Gitlab::DiscussionsDiff::FileCollection) do |collection|
+ note_diff_file = diff_note.note_diff_file
+
+ expect(collection).to receive(:load_highlight).with([]).and_call_original
+ expect(collection).to receive(:find_by_id).with(note_diff_file.id).and_call_original
+ end
+
+ get :discussions, namespace_id: project.namespace, project_id: project, id: merge_request.iid
+ end
+ end
+ end
+ end
+ end
+
describe 'GET edit' do
it 'responds successfully' do
get :edit, params: { namespace_id: project.namespace, project_id: project, id: merge_request }
diff --git a/spec/controllers/projects/project_members_controller_spec.rb b/spec/controllers/projects/project_members_controller_spec.rb
index 009f85903b5..3cc3fe69fba 100644
--- a/spec/controllers/projects/project_members_controller_spec.rb
+++ b/spec/controllers/projects/project_members_controller_spec.rb
@@ -82,10 +82,12 @@ describe Projects::ProjectMembersController do
Gitlab::Access.options.each do |label, value|
it "can change the access level to #{label}" do
- xhr :put, :update, project_member: { access_level: value },
- namespace_id: project.namespace,
- project_id: project,
- id: requester
+ put :update, params: {
+ project_member: { access_level: value },
+ namespace_id: project.namespace,
+ project_id: project,
+ id: requester
+ }, xhr: true
expect(requester.reload.human_access).to eq(label)
end
@@ -148,9 +150,11 @@ describe Projects::ProjectMembersController do
end
it '[JS] removes user from members' do
- xhr :delete, :destroy, namespace_id: project.namespace,
- project_id: project,
- id: member
+ delete :destroy, params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ id: member
+ }, xhr: true
expect(response).to be_success
expect(project.members).not_to include member
diff --git a/spec/controllers/projects/raw_controller_spec.rb b/spec/controllers/projects/raw_controller_spec.rb
index 24e2441cf9d..cffdf30da6b 100644
--- a/spec/controllers/projects/raw_controller_spec.rb
+++ b/spec/controllers/projects/raw_controller_spec.rb
@@ -16,74 +16,27 @@ describe Projects::RawController do
context 'regular filename' do
let(:filepath) { 'master/README.md' }
- context 'when feature flag workhorse_set_content_type is' do
- before do
- stub_feature_flags(workhorse_set_content_type: flag_value)
-
- subject
- end
-
- context 'enabled' do
- let(:flag_value) { true }
-
- it 'delivers ASCII file' do
- expect(response).to have_gitlab_http_status(200)
- expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8')
- expect(response.header['Content-Disposition']).to eq('inline')
- expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
- expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:')
- end
- end
-
- context 'disabled' do
- let(:flag_value) { false }
-
- it 'delivers ASCII file' do
- expect(response).to have_gitlab_http_status(200)
- expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8')
- expect(response.header['Content-Disposition']).to eq('inline')
- expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq nil
- expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:')
- end
- end
+ it 'delivers ASCII file' do
+ subject
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response.header['Content-Type']).to eq('text/plain; charset=utf-8')
+ expect(response.header['Content-Disposition']).to eq('inline')
+ expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
+ expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:')
end
end
context 'image header' do
let(:filepath) { 'master/files/images/6049019_460s.jpg' }
- context 'when feature flag workhorse_set_content_type is' do
- before do
- stub_feature_flags(workhorse_set_content_type: flag_value)
- end
-
- context 'enabled' do
- let(:flag_value) { true }
-
- it 'leaves image content disposition' do
- subject
-
- expect(response).to have_gitlab_http_status(200)
- expect(response.header['Content-Type']).to eq('image/jpeg')
- expect(response.header['Content-Disposition']).to eq('inline')
- expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
- expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:')
- end
- end
-
- context 'disabled' do
- let(:flag_value) { false }
-
- it 'sets image content type header' do
- subject
+ it 'leaves image content disposition' do
+ subject
- expect(response).to have_gitlab_http_status(200)
- expect(response.header['Content-Type']).to eq('image/jpeg')
- expect(response.header['Content-Disposition']).to eq('inline')
- expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq nil
- expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:')
- end
- end
+ expect(response).to have_gitlab_http_status(200)
+ expect(response.header['Content-Disposition']).to eq('inline')
+ expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
+ expect(response.header[Gitlab::Workhorse::SEND_DATA_HEADER]).to start_with('git-blob:')
end
end
diff --git a/spec/controllers/projects/refs_controller_spec.rb b/spec/controllers/projects/refs_controller_spec.rb
index ea299e1e8c5..62f2af947e4 100644
--- a/spec/controllers/projects/refs_controller_spec.rb
+++ b/spec/controllers/projects/refs_controller_spec.rb
@@ -22,13 +22,13 @@ describe Projects::RefsController do
end
def xhr_get(format = :html)
- xhr :get,
- :logs_tree,
- namespace_id: project.namespace.to_param,
- project_id: project,
- id: 'master',
- path: 'foo/bar/baz.html',
- format: format
+ get :logs_tree, params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ id: 'master',
+ path: 'foo/bar/baz.html',
+ format: format
+ }, xhr: true
end
it 'never throws MissingTemplate' do
diff --git a/spec/controllers/projects/tags/releases_controller_spec.rb b/spec/controllers/projects/tags/releases_controller_spec.rb
index 6bf4ac65a45..29f206c574b 100644
--- a/spec/controllers/projects/tags/releases_controller_spec.rb
+++ b/spec/controllers/projects/tags/releases_controller_spec.rb
@@ -18,7 +18,7 @@ describe Projects::Tags::ReleasesController do
tag_id = release.tag
project.releases.destroy_all # rubocop: disable DestroyAll
- get :edit, namespace_id: project.namespace, project_id: project, tag_id: tag_id
+ get :edit, params: { namespace_id: project.namespace, project_id: project, tag_id: tag_id }
release = assigns(:release)
expect(release).not_to be_nil
@@ -26,7 +26,7 @@ describe Projects::Tags::ReleasesController do
end
it 'retrieves an existing release' do
- get :edit, namespace_id: project.namespace, project_id: project, tag_id: release.tag
+ get :edit, params: { namespace_id: project.namespace, project_id: project, tag_id: release.tag }
release = assigns(:release)
expect(release).not_to be_nil
@@ -48,10 +48,11 @@ describe Projects::Tags::ReleasesController do
end
def update_release(description)
- put :update,
+ put :update, params: {
namespace_id: project.namespace.to_param,
project_id: project,
tag_id: release.tag,
release: { description: description }
+ }
end
end
diff --git a/spec/controllers/projects/wikis_controller_spec.rb b/spec/controllers/projects/wikis_controller_spec.rb
index 341bf244397..b2f40231796 100644
--- a/spec/controllers/projects/wikis_controller_spec.rb
+++ b/spec/controllers/projects/wikis_controller_spec.rb
@@ -52,56 +52,24 @@ describe Projects::WikisController do
let(:path) { upload_file_to_wiki(project, user, file_name) }
- subject { get :show, params: { namespace_id: project.namespace, project_id: project, id: path } }
+ before do
+ get :show, params: { namespace_id: project.namespace, project_id: project, id: path }
+ end
context 'when file is an image' do
let(:file_name) { 'dk.png' }
- context 'when feature flag workhorse_set_content_type is' do
- before do
- stub_feature_flags(workhorse_set_content_type: flag_value)
-
- subject
- end
-
- context 'enabled' do
- let(:flag_value) { true }
-
- it 'delivers the image' do
- expect(response.headers['Content-Type']).to eq('image/png')
- expect(response.headers['Content-Disposition']).to match(/^inline/)
- expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
- end
-
- context 'when file is a svg' do
- let(:file_name) { 'unsanitized.svg' }
-
- it 'delivers the image' do
- expect(response.headers['Content-Type']).to eq('image/svg+xml')
- expect(response.headers['Content-Disposition']).to match(/^attachment/)
- expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
- end
- end
- end
-
- context 'disabled' do
- let(:flag_value) { false }
-
- it 'renders the content inline' do
- expect(response.headers['Content-Type']).to eq('image/png')
- expect(response.headers['Content-Disposition']).to match(/^inline/)
- expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq nil
- end
+ it 'delivers the image' do
+ expect(response.headers['Content-Disposition']).to match(/^inline/)
+ expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
+ end
- context 'when file is a svg' do
- let(:file_name) { 'unsanitized.svg' }
+ context 'when file is a svg' do
+ let(:file_name) { 'unsanitized.svg' }
- it 'renders the content as an attachment' do
- expect(response.headers['Content-Type']).to eq('image/svg+xml')
- expect(response.headers['Content-Disposition']).to match(/^attachment/)
- expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq nil
- end
- end
+ it 'delivers the image' do
+ expect(response.headers['Content-Disposition']).to match(/^inline/)
+ expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
end
end
end
@@ -109,32 +77,9 @@ describe Projects::WikisController do
context 'when file is a pdf' do
let(:file_name) { 'git-cheat-sheet.pdf' }
- context 'when feature flag workhorse_set_content_type is' do
- before do
- stub_feature_flags(workhorse_set_content_type: flag_value)
-
- subject
- end
-
- context 'enabled' do
- let(:flag_value) { true }
-
- it 'sets the content type to sets the content response headers' do
- expect(response.headers['Content-Type']).to eq 'application/octet-stream'
- expect(response.headers['Content-Disposition']).to match(/^inline/)
- expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
- end
- end
-
- context 'disabled' do
- let(:flag_value) { false }
-
- it 'sets the content response headers' do
- expect(response.headers['Content-Type']).to eq 'application/octet-stream'
- expect(response.headers['Content-Disposition']).to match(/^inline/)
- expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq nil
- end
- end
+ it 'sets the content type to sets the content response headers' do
+ expect(response.headers['Content-Disposition']).to match(/^inline/)
+ expect(response.headers[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
end
end
end
diff --git a/spec/controllers/snippets_controller_spec.rb b/spec/controllers/snippets_controller_spec.rb
index af44598bfe4..d762531da7e 100644
--- a/spec/controllers/snippets_controller_spec.rb
+++ b/spec/controllers/snippets_controller_spec.rb
@@ -456,10 +456,7 @@ describe SnippetsController do
end
context 'when signed in user is the author' do
- let(:flag_value) { false }
-
before do
- stub_feature_flags(workhorse_set_content_type: flag_value)
get :raw, params: { id: personal_snippet.to_param }
end
@@ -474,22 +471,9 @@ describe SnippetsController do
expect(response.header['Content-Disposition']).to match(/inline/)
end
- context 'when feature flag workhorse_set_content_type is' do
- context 'enabled' do
- let(:flag_value) { true }
-
- it "sets #{Gitlab::Workhorse::DETECT_HEADER} header" do
- expect(response).to have_gitlab_http_status(200)
- expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
- end
- end
-
- context 'disabled' do
- it "does not set #{Gitlab::Workhorse::DETECT_HEADER} header" do
- expect(response).to have_gitlab_http_status(200)
- expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to be nil
- end
- end
+ it "sets #{Gitlab::Workhorse::DETECT_HEADER} header" do
+ expect(response).to have_gitlab_http_status(200)
+ expect(response.header[Gitlab::Workhorse::DETECT_HEADER]).to eq "true"
end
end
end
diff --git a/spec/factories/appearances.rb b/spec/factories/appearances.rb
index 18c7453bd1b..dd5129229d4 100644
--- a/spec/factories/appearances.rb
+++ b/spec/factories/appearances.rb
@@ -15,6 +15,10 @@ FactoryBot.define do
header_logo { fixture_file_upload('spec/fixtures/dk.png') }
end
+ trait :with_favicon do
+ favicon { fixture_file_upload('spec/fixtures/dk.png') }
+ end
+
trait :with_logos do
with_logo
with_header_logo
diff --git a/spec/factories/notes.rb b/spec/factories/notes.rb
index 2d1f48bf249..c51f2f958f9 100644
--- a/spec/factories/notes.rb
+++ b/spec/factories/notes.rb
@@ -64,6 +64,21 @@ FactoryBot.define do
resolved_at { Time.now }
resolved_by { create(:user) }
end
+
+ factory :image_diff_note_on_merge_request do
+ position do
+ Gitlab::Diff::Position.new(
+ old_path: "files/images/any_image.png",
+ new_path: "files/images/any_image.png",
+ width: 10,
+ height: 10,
+ x: 1,
+ y: 1,
+ diff_refs: diff_refs,
+ position_type: "image"
+ )
+ end
+ end
end
factory :diff_note_on_commit, traits: [:on_commit], class: DiffNote do
diff --git a/spec/features/admin/admin_disables_git_access_protocol_spec.rb b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
index 91c22e7ad82..f066b088800 100644
--- a/spec/features/admin/admin_disables_git_access_protocol_spec.rb
+++ b/spec/features/admin/admin_disables_git_access_protocol_spec.rb
@@ -1,7 +1,8 @@
require 'rails_helper'
-describe 'Admin disables Git access protocol' do
+describe 'Admin disables Git access protocol', :js do
include StubENV
+ include MobileHelpers
let(:project) { create(:project, :empty_repo) }
let(:admin) { create(:admin) }
@@ -20,7 +21,24 @@ describe 'Admin disables Git access protocol' do
visit_project
expect(page).to have_content("git clone #{project.ssh_url_to_repo}")
- expect(page).not_to have_selector('#clone-dropdown')
+
+ find('.clone-dropdown-btn').click
+
+ within('.git-clone-holder') do
+ expect(page).to have_content('Clone with SSH')
+ expect(page).not_to have_content('Clone with HTTP')
+ end
+ end
+
+ context 'mobile component' do
+ it 'shows only the SSH clone information' do
+ resize_screen_xs
+ visit_project
+ find('.dropdown-toggle').click
+
+ expect(page).to have_content('Copy SSH clone URL')
+ expect(page).not_to have_content('Copy HTTP clone URL')
+ end
end
end
@@ -31,9 +49,25 @@ describe 'Admin disables Git access protocol' do
it 'shows only HTTP url' do
visit_project
+ find('.clone-dropdown-btn').click
expect(page).to have_content("git clone #{project.http_url_to_repo}")
- expect(page).not_to have_selector('#clone-dropdown')
+
+ within('.git-clone-holder') do
+ expect(page).to have_content('Clone with HTTP')
+ expect(page).not_to have_content('Clone with SSH')
+ end
+ end
+
+ context 'mobile component' do
+ it 'shows only the HTTP clone information' do
+ resize_screen_xs
+ visit_project
+ find('.dropdown-toggle').click
+
+ expect(page).to have_content('Copy HTTP clone URL')
+ expect(page).not_to have_content('Copy SSH clone URL')
+ end
end
end
@@ -46,7 +80,24 @@ describe 'Admin disables Git access protocol' do
visit_project
expect(page).to have_content("git clone #{project.ssh_url_to_repo}")
- expect(page).to have_selector('#clone-dropdown')
+
+ find('.clone-dropdown-btn').click
+
+ within('.git-clone-holder') do
+ expect(page).to have_content('Clone with SSH')
+ expect(page).to have_content('Clone with HTTP')
+ end
+ end
+
+ context 'mobile component' do
+ it 'shows both SSH and HTTP clone information' do
+ resize_screen_xs
+ visit_project
+ find('.dropdown-toggle').click
+
+ expect(page).to have_content('Copy HTTP clone URL')
+ expect(page).to have_content('Copy SSH clone URL')
+ end
end
end
diff --git a/spec/features/group_variables_spec.rb b/spec/features/group_variables_spec.rb
index 89e0cdd8ed7..57e3ddfb39c 100644
--- a/spec/features/group_variables_spec.rb
+++ b/spec/features/group_variables_spec.rb
@@ -7,7 +7,7 @@ describe 'Group variables', :js do
let(:page_path) { group_settings_ci_cd_path(group) }
before do
- group.add_maintainer(user)
+ group.add_owner(user)
gitlab_sign_in(user)
visit page_path
diff --git a/spec/features/groups/show_spec.rb b/spec/features/groups/show_spec.rb
index 4e6f73ef58a..9671a4d8c49 100644
--- a/spec/features/groups/show_spec.rb
+++ b/spec/features/groups/show_spec.rb
@@ -65,7 +65,7 @@ describe 'Group show page' do
context 'when subgroups are supported', :js, :nested_groups do
before do
- allow(Group).to receive(:supports_nested_groups?) { true }
+ allow(Group).to receive(:supports_nested_objects?) { true }
visit path
end
@@ -76,7 +76,7 @@ describe 'Group show page' do
context 'when subgroups are not supported' do
before do
- allow(Group).to receive(:supports_nested_groups?) { false }
+ allow(Group).to receive(:supports_nested_objects?) { false }
visit path
end
diff --git a/spec/features/issues/gfm_autocomplete_spec.rb b/spec/features/issues/gfm_autocomplete_spec.rb
index d7531d5fcd9..3b7a17ef355 100644
--- a/spec/features/issues/gfm_autocomplete_spec.rb
+++ b/spec/features/issues/gfm_autocomplete_spec.rb
@@ -3,6 +3,8 @@ require 'rails_helper'
describe 'GFM autocomplete', :js do
let(:issue_xss_title) { 'This will execute alert<img src=x onerror=alert(2)&lt;img src=x onerror=alert(1)&gt;' }
let(:user_xss_title) { 'eve <img src=x onerror=alert(2)&lt;img src=x onerror=alert(1)&gt;' }
+ let(:label_xss_title) { 'alert label &lt;img src=x onerror="alert(\'Hello xss\');" a'}
+ let(:milestone_xss_title) { 'alert milestone &lt;img src=x onerror="alert(\'Hello xss\');" a' }
let(:user_xss) { create(:user, name: user_xss_title, username: 'xss.user') }
let(:user) { create(:user, name: '💃speciąl someone💃', username: 'someone.special') }
@@ -25,10 +27,14 @@ describe 'GFM autocomplete', :js do
simulate_input('#issue-description', "@#{user.name[0...3]}")
+ wait_for_requests
+
find('.atwho-view .cur').click
click_button 'Save changes'
+ wait_for_requests
+
expect(find('.description')).to have_content(user.to_reference)
end
@@ -47,6 +53,8 @@ describe 'GFM autocomplete', :js do
find('#note-body').native.send_keys('#')
end
+ wait_for_requests
+
expect(page).to have_selector('.atwho-container')
page.within '.atwho-container #at-view-issues' do
@@ -59,6 +67,8 @@ describe 'GFM autocomplete', :js do
find('#note-body').native.send_keys('@ev')
end
+ wait_for_requests
+
expect(page).to have_selector('.atwho-container')
page.within '.atwho-container #at-view-users' do
@@ -66,6 +76,22 @@ describe 'GFM autocomplete', :js do
end
end
+ it 'opens autocomplete menu for Milestone when field starts with text with item escaping HTML characters' do
+ create(:milestone, project: project, title: milestone_xss_title)
+
+ page.within '.timeline-content-form' do
+ find('#note-body').native.send_keys('%')
+ end
+
+ wait_for_requests
+
+ expect(page).to have_selector('.atwho-container')
+
+ page.within '.atwho-container #at-view-milestones' do
+ expect(find('li').text).to have_content('alert milestone')
+ end
+ end
+
it 'doesnt open autocomplete menu character is prefixed with text' do
page.within '.timeline-content-form' do
find('#note-body').native.send_keys('testing')
@@ -258,12 +284,28 @@ describe 'GFM autocomplete', :js do
let!(:bug) { create(:label, project: project, title: 'bug') }
let!(:feature_proposal) { create(:label, project: project, title: 'feature proposal') }
+ it 'opens autocomplete menu for Labels when field starts with text with item escaping HTML characters' do
+ create(:label, project: project, title: label_xss_title)
+
+ note = find('#note-body')
+
+ # It should show all the labels on "~".
+ type(note, '~')
+
+ wait_for_requests
+
+ page.within '.atwho-container #at-view-labels' do
+ expect(find('.atwho-view-ul').text).to have_content('alert label')
+ end
+ end
+
context 'when no labels are assigned' do
it 'shows labels' do
note = find('#note-body')
# It should show all the labels on "~".
type(note, '~')
+ wait_for_requests
expect_labels(shown: [backend, bug, feature_proposal])
# It should show all the labels on "/label ~".
@@ -290,6 +332,7 @@ describe 'GFM autocomplete', :js do
# It should show all the labels on "~".
type(note, '~')
+ wait_for_requests
expect_labels(shown: [backend, bug, feature_proposal])
# It should show only unset labels on "/label ~".
@@ -316,6 +359,7 @@ describe 'GFM autocomplete', :js do
# It should show all the labels on "~".
type(note, '~')
+ wait_for_requests
expect_labels(shown: [backend, bug, feature_proposal])
# It should show no labels on "/label ~".
diff --git a/spec/features/issues/user_creates_issue_spec.rb b/spec/features/issues/user_creates_issue_spec.rb
index 830d56035aa..e60486f6dcb 100644
--- a/spec/features/issues/user_creates_issue_spec.rb
+++ b/spec/features/issues/user_creates_issue_spec.rb
@@ -14,7 +14,7 @@ describe "User creates issue" do
visit(new_project_issue_path(project))
end
- it "creates issue" do
+ it "creates issue", :js do
page.within(".issue-form") do
expect(page).to have_no_content("Assign to")
.and have_no_content("Labels")
@@ -27,11 +27,15 @@ describe "User creates issue" do
issue_title = "500 error on profile"
fill_in("Title", with: issue_title)
+ first('.js-md').click
+ first('.qa-issuable-form-description').native.send_keys('Description')
+
click_button("Submit issue")
expect(page).to have_content(issue_title)
.and have_content(user.name)
.and have_content(project.name)
+ expect(page).to have_selector('strong', text: 'Description')
end
end
diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb
index 3d17eb3a73a..06e30571336 100644
--- a/spec/features/projects/clusters/gcp_spec.rb
+++ b/spec/features/projects/clusters/gcp_spec.rb
@@ -130,7 +130,7 @@ describe 'Gcp Cluster', :js do
context 'when user changes cluster parameters' do
before do
- allow(ClusterPlatformConfigureWorker).to receive(:perform_async)
+ allow(ClusterConfigureWorker).to receive(:perform_async)
fill_in 'cluster_platform_kubernetes_attributes_namespace', with: 'my-namespace'
page.within('#js-cluster-details') { click_button 'Save changes' }
end
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index 651c02c7ecc..60f37f4b74a 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -351,8 +351,8 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
context 'when user is a maintainer' do
shared_examples 'no reveal button variables behavior' do
it 'renders a hidden value with no reveal values button', :js do
- expect(page).to have_content('Token')
- expect(page).to have_content('Variables')
+ expect(page).to have_content('Trigger token')
+ expect(page).to have_content('Trigger variables')
expect(page).not_to have_css('.js-reveal-variables')
@@ -389,8 +389,8 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
shared_examples 'reveal button variables behavior' do
it 'renders a hidden value with a reveal values button', :js do
- expect(page).to have_content('Token')
- expect(page).to have_content('Variables')
+ expect(page).to have_content('Trigger token')
+ expect(page).to have_content('Trigger variables')
expect(page).to have_css('.js-reveal-variables')
diff --git a/spec/features/runners_spec.rb b/spec/features/runners_spec.rb
index cb7a912946c..09de983f669 100644
--- a/spec/features/runners_spec.rb
+++ b/spec/features/runners_spec.rb
@@ -259,8 +259,9 @@ describe 'Runners' do
context 'group runners in group settings' do
let(:group) { create(:group) }
+
before do
- group.add_maintainer(user)
+ group.add_owner(user)
end
context 'group with no runners' do
diff --git a/spec/features/users/overview_spec.rb b/spec/features/users/overview_spec.rb
index 34ed771340f..873de85708a 100644
--- a/spec/features/users/overview_spec.rb
+++ b/spec/features/users/overview_spec.rb
@@ -119,6 +119,12 @@ describe 'Overview tab on a user profile', :js do
it 'shows a link to the project list' do
expect(find('#js-overview .projects-block')).to have_selector('.js-view-all', visible: true)
end
+
+ it 'shows projects in "compact mode"' do
+ page.within('#js-overview .projects-block') do
+ expect(find('.js-projects-list-holder')).to have_selector('.compact')
+ end
+ end
end
describe 'user has more than ten personal projects' do
diff --git a/spec/fixtures/api/schemas/entities/issuable_sidebar_todo.json b/spec/fixtures/api/schemas/entities/issuable_sidebar_todo.json
new file mode 100644
index 00000000000..b77e60ece12
--- /dev/null
+++ b/spec/fixtures/api/schemas/entities/issuable_sidebar_todo.json
@@ -0,0 +1,8 @@
+{
+ "type": ["object", "null"],
+ "properties" : {
+ "id": { "type": "integer" },
+ "delete_path": { "type": "string" }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/api/schemas/entities/issue_sidebar.json b/spec/fixtures/api/schemas/entities/issue_sidebar.json
index 682e345d5f5..93adb493d1b 100644
--- a/spec/fixtures/api/schemas/entities/issue_sidebar.json
+++ b/spec/fixtures/api/schemas/entities/issue_sidebar.json
@@ -2,20 +2,46 @@
"type": "object",
"properties" : {
"id": { "type": "integer" },
- "iid": { "type": "integer" },
- "subscribed": { "type": "boolean" },
- "time_estimate": { "type": "integer" },
- "total_time_spent": { "type": "integer" },
- "human_time_estimate": { "type": ["integer", "null"] },
- "human_total_time_spent": { "type": ["integer", "null"] },
- "participants": {
- "type": "array",
- "items": { "$ref": "../public_api/v4/user/basic.json" }
+ "type": { "type": "string" },
+ "author_id": { "type": "integer" },
+ "project_id": { "type": "integer" },
+ "discussion_locked": { "type": ["boolean", "null"] },
+ "due_date": { "type": "date" },
+ "confidential": { "type": "boolean" },
+ "reference": { "type": "string" },
+ "current_user": {
+ "allOf": [
+ { "$ref": "../public_api/v4/user/basic.json" },
+ { "type": "object",
+ "properties" : {
+ "todo": { "$ref": "issuable_sidebar_todo.json" },
+ "can_edit": { "type": "boolean" },
+ "can_move": { "type": "boolean" },
+ "can_admin_label": { "type": "boolean" }
+ }
+ }
+ ]
+ },
+ "milestone": {
+ "oneOf": [
+ { "type": "null" },
+ { "$ref": "../public_api/v4/milestone.json" }
+ ]
},
- "assignees": {
+ "labels": {
"type": "array",
- "items": { "$ref": "../public_api/v4/user/basic.json" }
- }
- },
- "additionalProperties": false
+ "items": { "$ref": "label.json" }
+ },
+ "issuable_json_path": { "type": "string" },
+ "namespace_path": { "type": "string" },
+ "project_path": { "type": "string" },
+ "project_full_path": { "type": "string" },
+ "project_issuables_path": { "type": "string" },
+ "create_todo_path": { "type": "string" },
+ "project_milestones_path": { "type": "string" },
+ "project_labels_path": { "type": "string" },
+ "toggle_subscription_path": { "type": "string" },
+ "move_issue_path": { "type": "string" },
+ "projects_autocomplete_path": { "type": "string" }
+ }
}
diff --git a/spec/fixtures/api/schemas/entities/issue_sidebar_extras.json b/spec/fixtures/api/schemas/entities/issue_sidebar_extras.json
new file mode 100644
index 00000000000..11be903b083
--- /dev/null
+++ b/spec/fixtures/api/schemas/entities/issue_sidebar_extras.json
@@ -0,0 +1,18 @@
+{
+ "type": "object",
+ "properties" : {
+ "subscribed": { "type": "boolean" },
+ "time_estimate": { "type": "integer" },
+ "total_time_spent": { "type": "integer" },
+ "human_time_estimate": { "type": ["integer", "null"] },
+ "human_total_time_spent": { "type": ["integer", "null"] },
+ "participants": {
+ "type": "array",
+ "items": { "$ref": "../public_api/v4/user/basic.json" }
+ },
+ "assignees": {
+ "type": "array",
+ "items": { "$ref": "../public_api/v4/user/basic.json" }
+ }
+ }
+}
diff --git a/spec/fixtures/api/schemas/entities/merge_request_basic.json b/spec/fixtures/api/schemas/entities/merge_request_basic.json
index cf257ac00de..4c04c838cb8 100644
--- a/spec/fixtures/api/schemas/entities/merge_request_basic.json
+++ b/spec/fixtures/api/schemas/entities/merge_request_basic.json
@@ -4,15 +4,9 @@
"state": { "type": "string" },
"merge_status": { "type": "string" },
"source_branch_exists": { "type": "boolean" },
- "time_estimate": { "type": "integer" },
- "total_time_spent": { "type": "integer" },
- "human_time_estimate": { "type": ["string", "null"] },
- "human_total_time_spent": { "type": ["string", "null"] },
"merge_error": { "type": ["string", "null"] },
"rebase_in_progress": { "type": "boolean" },
"assignee_id": { "type": ["integer", "null"] },
- "subscribed": { "type": ["boolean", "null"] },
- "participants": { "type": "array" },
"allow_collaboration": { "type": "boolean"},
"allow_maintainer_to_push": { "type": "boolean"},
"assignee": {
diff --git a/spec/fixtures/api/schemas/entities/merge_request_sidebar.json b/spec/fixtures/api/schemas/entities/merge_request_sidebar.json
new file mode 100644
index 00000000000..7e9e048a9fd
--- /dev/null
+++ b/spec/fixtures/api/schemas/entities/merge_request_sidebar.json
@@ -0,0 +1,56 @@
+{
+ "type": "object",
+ "properties" : {
+ "id": { "type": "integer" },
+ "type": { "type": "string" },
+ "author_id": { "type": "integer" },
+ "project_id": { "type": "integer" },
+ "discussion_locked": { "type": ["boolean", "null"] },
+ "reference": { "type": "string" },
+ "current_user": {
+ "allOf": [
+ { "$ref": "../public_api/v4/user/basic.json" },
+ { "type": "object",
+ "properties" : {
+ "todo": { "$ref": "issuable_sidebar_todo.json" },
+ "can_edit": { "type": "boolean" },
+ "can_move": { "type": "boolean" },
+ "can_admin_label": { "type": "boolean" }
+ }
+ }
+ ]
+ },
+ "milestone": {
+ "oneOf": [
+ { "type": "null" },
+ { "$ref": "../public_api/v4/milestones.json" }
+ ]
+ },
+ "labels": {
+ "type": "array",
+ "items": { "$ref": "label.json" }
+ },
+ "assignee": {
+ "allOf": [
+ { "$ref": "../public_api/v4/user/basic.json" },
+ { "type": "object",
+ "properties" : {
+ "can_merge": { "type": "boolean" }
+ }
+ }
+ ]
+ },
+ "issuable_json_path": { "type": "string" },
+ "namespace_path": { "type": "string" },
+ "project_path": { "type": "string" },
+ "project_full_path": { "type": "string" },
+ "project_issuables_path": { "type": "string" },
+ "create_todo_path": { "type": "string" },
+ "project_milestones_path": { "type": "string" },
+ "project_labels_path": { "type": "string" },
+ "toggle_subscription_path": { "type": "string" },
+ "move_issue_path": { "type": "string" },
+ "projects_autocomplete_path": { "type": "string" }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/api/schemas/entities/merge_request_sidebar_extras.json b/spec/fixtures/api/schemas/entities/merge_request_sidebar_extras.json
new file mode 100644
index 00000000000..682e345d5f5
--- /dev/null
+++ b/spec/fixtures/api/schemas/entities/merge_request_sidebar_extras.json
@@ -0,0 +1,21 @@
+{
+ "type": "object",
+ "properties" : {
+ "id": { "type": "integer" },
+ "iid": { "type": "integer" },
+ "subscribed": { "type": "boolean" },
+ "time_estimate": { "type": "integer" },
+ "total_time_spent": { "type": "integer" },
+ "human_time_estimate": { "type": ["integer", "null"] },
+ "human_total_time_spent": { "type": ["integer", "null"] },
+ "participants": {
+ "type": "array",
+ "items": { "$ref": "../public_api/v4/user/basic.json" }
+ },
+ "assignees": {
+ "type": "array",
+ "items": { "$ref": "../public_api/v4/user/basic.json" }
+ }
+ },
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/api/schemas/public_api/v4/milestone.json b/spec/fixtures/api/schemas/public_api/v4/milestone.json
new file mode 100644
index 00000000000..6ca2e88ae91
--- /dev/null
+++ b/spec/fixtures/api/schemas/public_api/v4/milestone.json
@@ -0,0 +1,22 @@
+{
+ "type": "object",
+ "properties" : {
+ "id": { "type": "integer" },
+ "iid": { "type": "integer" },
+ "project_id": { "type": ["integer", "null"] },
+ "group_id": { "type": ["integer", "null"] },
+ "title": { "type": "string" },
+ "description": { "type": ["string", "null"] },
+ "state": { "type": "string" },
+ "created_at": { "type": "date" },
+ "updated_at": { "type": "date" },
+ "start_date": { "type": "date" },
+ "due_date": { "type": "date" },
+ "web_url": { "type": "string" }
+ },
+ "required": [
+ "id", "iid", "title", "description", "state",
+ "state", "created_at", "updated_at", "start_date", "due_date"
+ ],
+ "additionalProperties": false
+}
diff --git a/spec/fixtures/api/schemas/public_api/v4/milestones.json b/spec/fixtures/api/schemas/public_api/v4/milestones.json
index 448e97d6c85..dcbc1910bfe 100644
--- a/spec/fixtures/api/schemas/public_api/v4/milestones.json
+++ b/spec/fixtures/api/schemas/public_api/v4/milestones.json
@@ -1,25 +1,6 @@
{
"type": "array",
"items": {
- "type": "object",
- "properties" : {
- "id": { "type": "integer" },
- "iid": { "type": "integer" },
- "project_id": { "type": ["integer", "null"] },
- "group_id": { "type": ["integer", "null"] },
- "title": { "type": "string" },
- "description": { "type": ["string", "null"] },
- "state": { "type": "string" },
- "created_at": { "type": "date" },
- "updated_at": { "type": "date" },
- "start_date": { "type": "date" },
- "due_date": { "type": "date" },
- "web_url": { "type": "string" }
- },
- "required": [
- "id", "iid", "title", "description", "state",
- "state", "created_at", "updated_at", "start_date", "due_date"
- ],
- "additionalProperties": false
+ "$ref": "./milestone.json"
}
}
diff --git a/spec/fixtures/symlink_export.tar.gz b/spec/fixtures/symlink_export.tar.gz
new file mode 100644
index 00000000000..f295f69c56c
--- /dev/null
+++ b/spec/fixtures/symlink_export.tar.gz
Binary files differ
diff --git a/spec/helpers/issuables_helper_spec.rb b/spec/helpers/issuables_helper_spec.rb
index 4af98bc3678..81231cca085 100644
--- a/spec/helpers/issuables_helper_spec.rb
+++ b/spec/helpers/issuables_helper_spec.rb
@@ -43,16 +43,19 @@ describe IssuablesHelper do
end
describe '#issuable_labels_tooltip' do
+ let(:label_entity) { LabelEntity.represent(label).as_json }
+ let(:label2_entity) { LabelEntity.represent(label2).as_json }
+
it 'returns label text with no labels' do
expect(issuable_labels_tooltip([])).to eq("Labels")
end
it 'returns label text with labels within max limit' do
- expect(issuable_labels_tooltip([label])).to eq(label.title)
+ expect(issuable_labels_tooltip([label_entity])).to eq(label[:title])
end
it 'returns label text with labels exceeding max limit' do
- expect(issuable_labels_tooltip([label, label2], limit: 1)).to eq("#{label.title}, and 1 more")
+ expect(issuable_labels_tooltip([label_entity, label2_entity], limit: 1)).to eq("#{label[:title]}, and 1 more")
end
end
@@ -197,33 +200,4 @@ describe IssuablesHelper do
expect(helper.issuable_initial_data(issue)).to eq(expected_data)
end
end
-
- describe '#selected_labels' do
- context 'if label_name param is a string' do
- it 'returns a new label with title' do
- allow(helper).to receive(:params)
- .and_return(ActionController::Parameters.new(label_name: 'test label'))
-
- labels = helper.selected_labels
-
- expect(labels).to be_an(Array)
- expect(labels.size).to eq(1)
- expect(labels.first.title).to eq('test label')
- end
- end
-
- context 'if label_name param is an array' do
- it 'returns a new label with title for each element' do
- allow(helper).to receive(:params)
- .and_return(ActionController::Parameters.new(label_name: ['test label 1', 'test label 2']))
-
- labels = helper.selected_labels
-
- expect(labels).to be_an(Array)
- expect(labels.size).to eq(2)
- expect(labels.first.title).to eq('test label 1')
- expect(labels.second.title).to eq('test label 2')
- end
- end
- end
end
diff --git a/spec/helpers/projects_helper_spec.rb b/spec/helpers/projects_helper_spec.rb
index 486416c3370..edd680ee1d1 100644
--- a/spec/helpers/projects_helper_spec.rb
+++ b/spec/helpers/projects_helper_spec.rb
@@ -519,4 +519,114 @@ describe ProjectsHelper do
expect(helper.legacy_render_context({})).to be_empty
end
end
+
+ describe '#explore_projects_tab?' do
+ subject { helper.explore_projects_tab? }
+
+ it 'returns true when on the "All" tab under "Explore projects"' do
+ allow(@request).to receive(:path) { explore_projects_path }
+
+ expect(subject).to be_truthy
+ end
+
+ it 'returns true when on the "Trending" tab under "Explore projects"' do
+ allow(@request).to receive(:path) { trending_explore_projects_path }
+
+ expect(subject).to be_truthy
+ end
+
+ it 'returns true when on the "Starred" tab under "Explore projects"' do
+ allow(@request).to receive(:path) { starred_explore_projects_path }
+
+ expect(subject).to be_truthy
+ end
+
+ it 'returns false when on the "Your projects" tab' do
+ allow(@request).to receive(:path) { dashboard_projects_path }
+
+ expect(subject).to be_falsey
+ end
+ end
+
+ describe '#show_merge_request_count' do
+ context 'when the feature flag is enabled' do
+ before do
+ stub_feature_flags(project_list_show_mr_count: true)
+ end
+
+ it 'returns true if compact mode is disabled' do
+ expect(helper.show_merge_request_count?).to be_truthy
+ end
+
+ it 'returns false if compact mode is enabled' do
+ expect(helper.show_merge_request_count?(compact_mode: true)).to be_falsey
+ end
+ end
+
+ context 'when the feature flag is disabled' do
+ before do
+ stub_feature_flags(project_list_show_mr_count: false)
+ end
+
+ it 'always returns false' do
+ expect(helper.show_merge_request_count?(disabled: false)).to be_falsy
+ expect(helper.show_merge_request_count?(disabled: true)).to be_falsy
+ end
+ end
+
+ context 'disabled flag' do
+ before do
+ stub_feature_flags(project_list_show_mr_count: true)
+ end
+
+ it 'returns false if disabled flag is true' do
+ expect(helper.show_merge_request_count?(disabled: true)).to be_falsey
+ end
+
+ it 'returns true if disabled flag is false' do
+ expect(helper.show_merge_request_count?).to be_truthy
+ end
+ end
+ end
+
+ describe '#show_issue_count?' do
+ context 'when the feature flag is enabled' do
+ before do
+ stub_feature_flags(project_list_show_issue_count: true)
+ end
+
+ it 'returns true if compact mode is disabled' do
+ expect(helper.show_issue_count?).to be_truthy
+ end
+
+ it 'returns false if compact mode is enabled' do
+ expect(helper.show_issue_count?(compact_mode: true)).to be_falsey
+ end
+ end
+
+ context 'when the feature flag is disabled' do
+ before do
+ stub_feature_flags(project_list_show_issue_count: false)
+ end
+
+ it 'always returns false' do
+ expect(helper.show_issue_count?(disabled: false)).to be_falsy
+ expect(helper.show_issue_count?(disabled: true)).to be_falsy
+ end
+ end
+
+ context 'disabled flag' do
+ before do
+ stub_feature_flags(project_list_show_issue_count: true)
+ end
+
+ it 'returns false if disabled flag is true' do
+ expect(helper.show_issue_count?(disabled: true)).to be_falsey
+ end
+
+ it 'returns true if disabled flag is false' do
+ expect(helper.show_issue_count?).to be_truthy
+ end
+ end
+ end
end
diff --git a/spec/initializers/active_record_locking_spec.rb b/spec/initializers/active_record_locking_spec.rb
new file mode 100644
index 00000000000..5a16aef78e6
--- /dev/null
+++ b/spec/initializers/active_record_locking_spec.rb
@@ -0,0 +1,44 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'ActiveRecord locking' do
+ let(:issue) { create(:issue) }
+
+ shared_examples 'locked model' do
+ before do
+ issue.update_column(:lock_version, start_lock_version)
+ end
+
+ it 'can be updated' do
+ issue.update(title: "New title")
+
+ expect(issue.reload.lock_version).to eq(new_lock_version)
+ end
+
+ it 'can be deleted' do
+ expect { issue.destroy }.to change { Issue.count }.by(-1)
+ end
+ end
+
+ context 'when lock_version is NULL' do
+ let(:start_lock_version) { nil }
+ let(:new_lock_version) { 1 }
+
+ it_behaves_like 'locked model'
+ end
+
+ context 'when lock_version is 0' do
+ let(:start_lock_version) { 0 }
+ let(:new_lock_version) { 1 }
+
+ it_behaves_like 'locked model'
+ end
+
+ context 'when lock_version is 1' do
+ let(:start_lock_version) { 1 }
+ let(:new_lock_version) { 2 }
+
+ it_behaves_like 'locked model'
+ end
+end
diff --git a/spec/initializers/8_metrics_spec.rb b/spec/initializers/zz_metrics_spec.rb
index 80c77057065..3eaccfe8d8b 100644
--- a/spec/initializers/8_metrics_spec.rb
+++ b/spec/initializers/zz_metrics_spec.rb
@@ -16,7 +16,7 @@ describe 'instrument_classes' do
end
it 'can autoload and instrument all files' do
- require_relative '../../config/initializers/8_metrics'
+ require_relative '../../config/initializers/zz_metrics'
expect { instrument_classes(config) }.not_to raise_error
end
end
diff --git a/spec/javascripts/ci_variable_list/ci_variable_list_spec.js b/spec/javascripts/ci_variable_list/ci_variable_list_spec.js
index 30b15011def..bef59b86d0c 100644
--- a/spec/javascripts/ci_variable_list/ci_variable_list_spec.js
+++ b/spec/javascripts/ci_variable_list/ci_variable_list_spec.js
@@ -118,6 +118,8 @@ describe('VariableList', () => {
loadFixtures('projects/ci_cd_settings.html.raw');
$wrapper = $('.js-ci-variable-list-section');
+ $wrapper.find('.js-ci-variable-input-protected').attr('data-default', 'false');
+
variableList = new VariableList({
container: $wrapper,
formField: 'variables',
diff --git a/spec/javascripts/diffs/store/utils_spec.js b/spec/javascripts/diffs/store/utils_spec.js
index f096638e3d6..4268634d302 100644
--- a/spec/javascripts/diffs/store/utils_spec.js
+++ b/spec/javascripts/diffs/store/utils_spec.js
@@ -294,10 +294,14 @@ describe('DiffsStoreUtils', () => {
});
describe('prepareDiffData', () => {
- it('sets the renderIt and collapsed attribute on files', () => {
- const preparedDiff = { diff_files: [getDiffFileMock()] };
+ let preparedDiff;
+
+ beforeEach(() => {
+ preparedDiff = { diff_files: [getDiffFileMock()] };
utils.prepareDiffData(preparedDiff);
+ });
+ it('sets the renderIt and collapsed attribute on files', () => {
const firstParallelDiffLine = preparedDiff.diff_files[0].parallel_diff_lines[2];
expect(firstParallelDiffLine.left.discussions.length).toBe(0);
@@ -323,6 +327,18 @@ describe('DiffsStoreUtils', () => {
expect(preparedDiff.diff_files[0].renderIt).toBeTruthy();
expect(preparedDiff.diff_files[0].collapsed).toBeFalsy();
});
+
+ it('adds line_code to all lines', () => {
+ expect(
+ preparedDiff.diff_files[0].parallel_diff_lines.filter(line => !line.line_code),
+ ).toHaveLength(0);
+ });
+
+ it('uses right line code if left has none', () => {
+ const firstLine = preparedDiff.diff_files[0].parallel_diff_lines[0];
+
+ expect(firstLine.line_code).toEqual(firstLine.right.line_code);
+ });
});
describe('isDiscussionApplicableToLine', () => {
diff --git a/spec/javascripts/environments/environment_terminal_button_spec.js b/spec/javascripts/environments/environment_terminal_button_spec.js
index f1576b19d1b..56e18db59c5 100644
--- a/spec/javascripts/environments/environment_terminal_button_spec.js
+++ b/spec/javascripts/environments/environment_terminal_button_spec.js
@@ -2,30 +2,46 @@ import Vue from 'vue';
import terminalComp from '~/environments/components/environment_terminal_button.vue';
describe('Stop Component', () => {
- let TerminalComponent;
let component;
const terminalPath = '/path';
- beforeEach(() => {
- TerminalComponent = Vue.extend(terminalComp);
-
+ const mountWithProps = props => {
+ const TerminalComponent = Vue.extend(terminalComp);
component = new TerminalComponent({
- propsData: {
- terminalPath,
- },
+ propsData: props,
}).$mount();
- });
+ };
+
+ describe('enabled', () => {
+ beforeEach(() => {
+ mountWithProps({ terminalPath });
+ });
+
+ describe('computed', () => {
+ it('title', () => {
+ expect(component.title).toEqual('Terminal');
+ });
+ });
- describe('computed', () => {
- it('title', () => {
- expect(component.title).toEqual('Terminal');
+ it('should render a link to open a web terminal with the provided path', () => {
+ expect(component.$el.tagName).toEqual('A');
+ expect(component.$el.getAttribute('data-original-title')).toEqual('Terminal');
+ expect(component.$el.getAttribute('aria-label')).toEqual('Terminal');
+ expect(component.$el.getAttribute('href')).toEqual(terminalPath);
+ });
+
+ it('should render a non-disabled button', () => {
+ expect(component.$el.classList).not.toContain('disabled');
});
});
- it('should render a link to open a web terminal with the provided path', () => {
- expect(component.$el.tagName).toEqual('A');
- expect(component.$el.getAttribute('data-original-title')).toEqual('Terminal');
- expect(component.$el.getAttribute('aria-label')).toEqual('Terminal');
- expect(component.$el.getAttribute('href')).toEqual(terminalPath);
+ describe('disabled', () => {
+ beforeEach(() => {
+ mountWithProps({ terminalPath, disabled: true });
+ });
+
+ it('should render a disabled button', () => {
+ expect(component.$el.classList).toContain('disabled');
+ });
});
});
diff --git a/spec/javascripts/fixtures/blob.rb b/spec/javascripts/fixtures/blob.rb
index 81e8a51a902..1b2a3b484bb 100644
--- a/spec/javascripts/fixtures/blob.rb
+++ b/spec/javascripts/fixtures/blob.rb
@@ -22,10 +22,11 @@ describe Projects::BlobController, '(JavaScript fixtures)', type: :controller do
end
it 'blob/show.html.raw' do |example|
- get(:show,
- namespace_id: project.namespace,
- project_id: project,
- id: 'add-ipython-files/files/ipython/basic.ipynb')
+ get(:show, params: {
+ namespace_id: project.namespace,
+ project_id: project,
+ id: 'add-ipython-files/files/ipython/basic.ipynb'
+ })
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/boards.rb b/spec/javascripts/fixtures/boards.rb
index 494c9cabdcc..1d675e008ba 100644
--- a/spec/javascripts/fixtures/boards.rb
+++ b/spec/javascripts/fixtures/boards.rb
@@ -18,9 +18,10 @@ describe Projects::BoardsController, '(JavaScript fixtures)', type: :controller
end
it 'boards/show.html.raw' do |example|
- get(:index,
- namespace_id: project.namespace,
- project_id: project)
+ get(:index, params: {
+ namespace_id: project.namespace,
+ project_id: project
+ })
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/branches.rb b/spec/javascripts/fixtures/branches.rb
index 4fc072d2585..3cc713ef90f 100644
--- a/spec/javascripts/fixtures/branches.rb
+++ b/spec/javascripts/fixtures/branches.rb
@@ -22,9 +22,10 @@ describe Projects::BranchesController, '(JavaScript fixtures)', type: :controlle
end
it 'branches/new_branch.html.raw' do |example|
- get :new,
+ get :new, params: {
namespace_id: project.namespace.to_param,
project_id: project
+ }
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/clusters.rb b/spec/javascripts/fixtures/clusters.rb
index 8e74c4f859c..69dbe54ffc2 100644
--- a/spec/javascripts/fixtures/clusters.rb
+++ b/spec/javascripts/fixtures/clusters.rb
@@ -23,10 +23,11 @@ describe Projects::ClustersController, '(JavaScript fixtures)', type: :controlle
end
it 'clusters/show_cluster.html.raw' do |example|
- get :show,
+ get :show, params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: cluster
+ }
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/commit.rb b/spec/javascripts/fixtures/commit.rb
index 24ab8159a18..f0e4bb50c67 100644
--- a/spec/javascripts/fixtures/commit.rb
+++ b/spec/javascripts/fixtures/commit.rb
@@ -25,7 +25,7 @@ describe Projects::CommitController, '(JavaScript fixtures)', type: :controller
id: commit.id
}
- get :show, params
+ get :show, params: params
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/deploy_keys.rb b/spec/javascripts/fixtures/deploy_keys.rb
index 24699c3043a..efbda955972 100644
--- a/spec/javascripts/fixtures/deploy_keys.rb
+++ b/spec/javascripts/fixtures/deploy_keys.rb
@@ -33,10 +33,10 @@ describe Projects::DeployKeysController, '(JavaScript fixtures)', type: :control
create(:deploy_keys_project, project: project3, deploy_key: project_key)
create(:deploy_keys_project, project: project4, deploy_key: project_key)
- get :index,
+ get :index, params: {
namespace_id: project.namespace.to_param,
- project_id: project,
- format: :json
+ project_id: project
+ }, format: :json
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/groups.rb b/spec/javascripts/fixtures/groups.rb
index b42f442557c..f8d55fc97c3 100644
--- a/spec/javascripts/fixtures/groups.rb
+++ b/spec/javascripts/fixtures/groups.rb
@@ -19,8 +19,7 @@ describe 'Groups (JavaScript fixtures)', type: :controller do
describe GroupsController, '(JavaScript fixtures)', type: :controller do
it 'groups/edit.html.raw' do |example|
- get :edit,
- id: group
+ get :edit, params: { id: group }
expect(response).to be_success
store_frontend_fixture(response, example.description)
@@ -29,8 +28,7 @@ describe 'Groups (JavaScript fixtures)', type: :controller do
describe Groups::Settings::CiCdController, '(JavaScript fixtures)', type: :controller do
it 'groups/ci_cd_settings.html.raw' do |example|
- get :show,
- group_id: group
+ get :show, params: { group_id: group }
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/issues.rb b/spec/javascripts/fixtures/issues.rb
index 0ee2f82dfd6..18fb1bebf8b 100644
--- a/spec/javascripts/fixtures/issues.rb
+++ b/spec/javascripts/fixtures/issues.rb
@@ -43,9 +43,10 @@ describe Projects::IssuesController, '(JavaScript fixtures)', type: :controller
it 'issues/issue_list.html.raw' do |example|
create(:issue, project: project)
- get :index,
+ get :index, params: {
namespace_id: project.namespace.to_param,
project_id: project
+ }
expect(response).to be_success
store_frontend_fixture(response, example.description)
@@ -54,10 +55,11 @@ describe Projects::IssuesController, '(JavaScript fixtures)', type: :controller
private
def render_issue(fixture_file_name, issue)
- get :show,
+ get :show, params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: issue.to_param
+ }
expect(response).to be_success
store_frontend_fixture(response, fixture_file_name)
diff --git a/spec/javascripts/fixtures/jobs.rb b/spec/javascripts/fixtures/jobs.rb
index 82d7a5e394e..d6b5349594d 100644
--- a/spec/javascripts/fixtures/jobs.rb
+++ b/spec/javascripts/fixtures/jobs.rb
@@ -34,21 +34,22 @@ describe Projects::JobsController, '(JavaScript fixtures)', type: :controller do
end
it 'builds/build-with-artifacts.html.raw' do |example|
- get :show,
+ get :show, params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: build_with_artifacts.to_param
+ }
expect(response).to be_success
store_frontend_fixture(response, example.description)
end
it 'jobs/delayed.json' do |example|
- get :show,
- namespace_id: project.namespace.to_param,
- project_id: project,
- id: delayed_job.to_param,
- format: :json
+ get :show, params: {
+ namespace_id: project.namespace.to_param,
+ project_id: project,
+ id: delayed_job.to_param
+ }, format: :json
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/labels.rb b/spec/javascripts/fixtures/labels.rb
index b730d557e21..9420194e675 100644
--- a/spec/javascripts/fixtures/labels.rb
+++ b/spec/javascripts/fixtures/labels.rb
@@ -31,9 +31,9 @@ describe 'Labels (JavaScript fixtures)' do
end
it 'labels/group_labels.json' do |example|
- get :index,
- group_id: group,
- format: 'json'
+ get :index, params: {
+ group_id: group
+ }, format: 'json'
expect(response).to be_success
store_frontend_fixture(response, example.description)
@@ -48,10 +48,10 @@ describe 'Labels (JavaScript fixtures)' do
end
it 'labels/project_labels.json' do |example|
- get :index,
+ get :index, params: {
namespace_id: group,
- project_id: project,
- format: 'json'
+ project_id: project
+ }, format: 'json'
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/merge_requests.rb b/spec/javascripts/fixtures/merge_requests.rb
index 7257d0c8556..26e81f06c0b 100644
--- a/spec/javascripts/fixtures/merge_requests.rb
+++ b/spec/javascripts/fixtures/merge_requests.rb
@@ -112,21 +112,21 @@ describe Projects::MergeRequestsController, '(JavaScript fixtures)', type: :cont
private
def render_discussions_json(merge_request, fixture_file_name)
- get :discussions,
+ get :discussions, params: {
namespace_id: project.namespace.to_param,
project_id: project,
- id: merge_request.to_param,
- format: :json
+ id: merge_request.to_param
+ }, format: :json
store_frontend_fixture(response, fixture_file_name)
end
def render_merge_request(fixture_file_name, merge_request)
- get :show,
+ get :show, params: {
namespace_id: project.namespace.to_param,
project_id: project,
- id: merge_request.to_param,
- format: :html
+ id: merge_request.to_param
+ }, format: :html
expect(response).to be_success
store_frontend_fixture(response, fixture_file_name)
diff --git a/spec/javascripts/fixtures/merge_requests_diffs.rb b/spec/javascripts/fixtures/merge_requests_diffs.rb
index afe34b834b0..57462e74bb2 100644
--- a/spec/javascripts/fixtures/merge_requests_diffs.rb
+++ b/spec/javascripts/fixtures/merge_requests_diffs.rb
@@ -57,13 +57,13 @@ describe Projects::MergeRequests::DiffsController, '(JavaScript fixtures)', type
private
def render_merge_request(fixture_file_name, merge_request, view: 'inline', **extra_params)
- get :show,
+ get :show, params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: merge_request.to_param,
- format: :json,
view: view,
**extra_params
+ }, format: :json
expect(response).to be_success
store_frontend_fixture(response, fixture_file_name)
diff --git a/spec/javascripts/fixtures/pipeline_schedules.rb b/spec/javascripts/fixtures/pipeline_schedules.rb
index 56f27ea7df1..05d79ec8de9 100644
--- a/spec/javascripts/fixtures/pipeline_schedules.rb
+++ b/spec/javascripts/fixtures/pipeline_schedules.rb
@@ -22,20 +22,22 @@ describe Projects::PipelineSchedulesController, '(JavaScript fixtures)', type: :
end
it 'pipeline_schedules/edit.html.raw' do |example|
- get :edit,
+ get :edit, params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: pipeline_schedule.id
+ }
expect(response).to be_success
store_frontend_fixture(response, example.description)
end
it 'pipeline_schedules/edit_with_variables.html.raw' do |example|
- get :edit,
+ get :edit, params: {
namespace_id: project.namespace.to_param,
project_id: project,
id: pipeline_schedule_populated.id
+ }
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/pipelines.rb b/spec/javascripts/fixtures/pipelines.rb
index bb85da50f0f..42b552e81c0 100644
--- a/spec/javascripts/fixtures/pipelines.rb
+++ b/spec/javascripts/fixtures/pipelines.rb
@@ -24,10 +24,10 @@ describe Projects::PipelinesController, '(JavaScript fixtures)', type: :controll
end
it 'pipelines/pipelines.json' do |example|
- get :index,
+ get :index, params: {
namespace_id: namespace,
- project_id: project,
- format: :json
+ project_id: project
+ }, format: :json
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/projects.rb b/spec/javascripts/fixtures/projects.rb
index d98f7f55b20..9b48646f8f0 100644
--- a/spec/javascripts/fixtures/projects.rb
+++ b/spec/javascripts/fixtures/projects.rb
@@ -28,27 +28,30 @@ describe 'Projects (JavaScript fixtures)', type: :controller do
describe ProjectsController, '(JavaScript fixtures)', type: :controller do
it 'projects/dashboard.html.raw' do |example|
- get :show,
+ get :show, params: {
namespace_id: project.namespace.to_param,
id: project
+ }
expect(response).to be_success
store_frontend_fixture(response, example.description)
end
it 'projects/overview.html.raw' do |example|
- get :show,
+ get :show, params: {
namespace_id: project_with_repo.namespace.to_param,
id: project_with_repo
+ }
expect(response).to be_success
store_frontend_fixture(response, example.description)
end
it 'projects/edit.html.raw' do |example|
- get :edit,
+ get :edit, params: {
namespace_id: project.namespace.to_param,
id: project
+ }
expect(response).to be_success
store_frontend_fixture(response, example.description)
@@ -57,18 +60,20 @@ describe 'Projects (JavaScript fixtures)', type: :controller do
describe Projects::Settings::CiCdController, '(JavaScript fixtures)', type: :controller do
it 'projects/ci_cd_settings.html.raw' do |example|
- get :show,
+ get :show, params: {
namespace_id: project.namespace.to_param,
project_id: project
+ }
expect(response).to be_success
store_frontend_fixture(response, example.description)
end
it 'projects/ci_cd_settings_with_variables.html.raw' do |example|
- get :show,
+ get :show, params: {
namespace_id: project_variable_populated.namespace.to_param,
project_id: project_variable_populated
+ }
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/prometheus_service.rb b/spec/javascripts/fixtures/prometheus_service.rb
index f95f8038ffb..746fbfd66dd 100644
--- a/spec/javascripts/fixtures/prometheus_service.rb
+++ b/spec/javascripts/fixtures/prometheus_service.rb
@@ -23,10 +23,11 @@ describe Projects::ServicesController, '(JavaScript fixtures)', type: :controlle
end
it 'services/prometheus/prometheus_service.html.raw' do |example|
- get :edit,
+ get :edit, params: {
namespace_id: namespace,
project_id: project,
id: service.to_param
+ }
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/services.rb b/spec/javascripts/fixtures/services.rb
index 9280ed5a7f1..6ccd74a07ff 100644
--- a/spec/javascripts/fixtures/services.rb
+++ b/spec/javascripts/fixtures/services.rb
@@ -23,10 +23,11 @@ describe Projects::ServicesController, '(JavaScript fixtures)', type: :controlle
end
it 'services/edit_service.html.raw' do |example|
- get :edit,
+ get :edit, params: {
namespace_id: namespace,
project_id: project,
id: service.to_param
+ }
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/snippet.rb b/spec/javascripts/fixtures/snippet.rb
index 38fc963caf7..a14837e4d4a 100644
--- a/spec/javascripts/fixtures/snippet.rb
+++ b/spec/javascripts/fixtures/snippet.rb
@@ -24,7 +24,7 @@ describe SnippetsController, '(JavaScript fixtures)', type: :controller do
end
it 'snippets/show.html.raw' do |example|
- get(:show, id: snippet.to_param)
+ get(:show, params: { id: snippet.to_param })
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/todos.rb b/spec/javascripts/fixtures/todos.rb
index 426b854fe8b..b5f6620873b 100644
--- a/spec/javascripts/fixtures/todos.rb
+++ b/spec/javascripts/fixtures/todos.rb
@@ -42,12 +42,12 @@ describe 'Todos (JavaScript fixtures)' do
end
it 'todos/todos.json' do |example|
- post :create,
+ post :create, params: {
namespace_id: namespace,
project_id: project,
issuable_type: 'issue',
- issuable_id: issue_2.id,
- format: 'json'
+ issuable_id: issue_2.id
+ }, format: 'json'
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/fixtures/u2f.rb b/spec/javascripts/fixtures/u2f.rb
index e3d7986f2cf..f0aa874bf75 100644
--- a/spec/javascripts/fixtures/u2f.rb
+++ b/spec/javascripts/fixtures/u2f.rb
@@ -21,7 +21,7 @@ context 'U2F' do
it 'u2f/authenticate.html.raw' do |example|
allow(controller).to receive(:find_user).and_return(user)
- post :create, user: { login: user.username, password: user.password }
+ post :create, params: { user: { login: user.username, password: user.password } }
expect(response).to be_success
store_frontend_fixture(response, example.description)
diff --git a/spec/javascripts/jobs/components/artifacts_block_spec.js b/spec/javascripts/jobs/components/artifacts_block_spec.js
index 2fa7ff653fe..27d480ef2ea 100644
--- a/spec/javascripts/jobs/components/artifacts_block_spec.js
+++ b/spec/javascripts/jobs/components/artifacts_block_spec.js
@@ -2,6 +2,7 @@ import Vue from 'vue';
import { getTimeago } from '~/lib/utils/datetime_utility';
import component from '~/jobs/components/artifacts_block.vue';
import mountComponent from '../../helpers/vue_mount_component_helper';
+import { trimText } from '../../helpers/vue_component_helper';
describe('Artifacts block', () => {
const Component = Vue.extend(component);
@@ -9,7 +10,7 @@ describe('Artifacts block', () => {
const expireAt = '2018-08-14T09:38:49.157Z';
const timeago = getTimeago();
- const formatedDate = timeago.format(expireAt);
+ const formattedDate = timeago.format(expireAt);
const expiredArtifact = {
expire_at: expireAt,
@@ -36,9 +37,8 @@ describe('Artifacts block', () => {
expect(vm.$el.querySelector('.js-artifacts-removed')).not.toBeNull();
expect(vm.$el.querySelector('.js-artifacts-will-be-removed')).toBeNull();
- expect(vm.$el.textContent).toContain(formatedDate);
- expect(vm.$el.querySelector('.js-artifacts-removed').textContent.trim()).toEqual(
- 'The artifacts were removed',
+ expect(trimText(vm.$el.querySelector('.js-artifacts-removed').textContent)).toEqual(
+ `The artifacts were removed ${formattedDate}`,
);
});
});
@@ -51,9 +51,8 @@ describe('Artifacts block', () => {
expect(vm.$el.querySelector('.js-artifacts-removed')).toBeNull();
expect(vm.$el.querySelector('.js-artifacts-will-be-removed')).not.toBeNull();
- expect(vm.$el.textContent).toContain(formatedDate);
- expect(vm.$el.querySelector('.js-artifacts-will-be-removed').textContent.trim()).toEqual(
- 'The artifacts will be removed in',
+ expect(trimText(vm.$el.querySelector('.js-artifacts-will-be-removed').textContent)).toEqual(
+ `The artifacts will be removed ${formattedDate}`,
);
});
});
diff --git a/spec/javascripts/jobs/components/sidebar_spec.js b/spec/javascripts/jobs/components/sidebar_spec.js
index 424092d2d88..b0bc16d7c64 100644
--- a/spec/javascripts/jobs/components/sidebar_spec.js
+++ b/spec/javascripts/jobs/components/sidebar_spec.js
@@ -79,14 +79,6 @@ describe('Sidebar details block', () => {
});
describe('information', () => {
- it('should render merge request link', () => {
- expect(trimText(vm.$el.querySelector('.js-job-mr').textContent)).toEqual('Merge Request: !2');
-
- expect(vm.$el.querySelector('.js-job-mr a').getAttribute('href')).toEqual(
- job.merge_request.path,
- );
- });
-
it('should render job duration', () => {
expect(trimText(vm.$el.querySelector('.js-job-duration').textContent)).toEqual(
'Duration: 6 seconds',
diff --git a/spec/javascripts/notes/components/noteable_discussion_spec.js b/spec/javascripts/notes/components/noteable_discussion_spec.js
index 106a4ac2546..3aff2dd0641 100644
--- a/spec/javascripts/notes/components/noteable_discussion_spec.js
+++ b/spec/javascripts/notes/components/noteable_discussion_spec.js
@@ -133,8 +133,10 @@ describe('noteable_discussion component', () => {
});
});
- describe('commit discussion', () => {
+ describe('action text', () => {
const commitId = 'razupaltuff';
+ const truncatedCommitId = commitId.substr(0, 8);
+ let commitElement;
beforeEach(() => {
vm.$destroy();
@@ -143,7 +145,6 @@ describe('noteable_discussion component', () => {
projectPath: 'something',
};
- vm.$destroy();
vm = new Component({
propsData: {
discussion: {
@@ -159,17 +160,73 @@ describe('noteable_discussion component', () => {
},
store,
}).$mount();
+
+ commitElement = vm.$el.querySelector('.commit-sha');
+ });
+
+ describe('for commit discussions', () => {
+ it('should display a monospace started a discussion on commit', () => {
+ expect(vm.$el).toContainText(`started a discussion on commit ${truncatedCommitId}`);
+ expect(commitElement).not.toBe(null);
+ expect(commitElement).toHaveText(truncatedCommitId);
+ });
});
- it('displays a monospace started a discussion on commit', () => {
- const truncatedCommitId = commitId.substr(0, 8);
+ describe('for diff discussion with a commit id', () => {
+ it('should display started discussion on commit header', done => {
+ vm.discussion.for_commit = false;
- expect(vm.$el).toContainText(`started a discussion on commit ${truncatedCommitId}`);
+ vm.$nextTick(() => {
+ expect(vm.$el).toContainText(`started a discussion on commit ${truncatedCommitId}`);
+ expect(commitElement).not.toBe(null);
- const commitElement = vm.$el.querySelector('.commit-sha');
+ done();
+ });
+ });
- expect(commitElement).not.toBe(null);
- expect(commitElement).toHaveText(truncatedCommitId);
+ it('should display outdated change on commit header', done => {
+ vm.discussion.for_commit = false;
+ vm.discussion.active = false;
+
+ vm.$nextTick(() => {
+ expect(vm.$el).toContainText(
+ `started a discussion on an outdated change in commit ${truncatedCommitId}`,
+ );
+
+ expect(commitElement).not.toBe(null);
+
+ done();
+ });
+ });
+ });
+
+ describe('for diff discussions without a commit id', () => {
+ it('should show started a discussion on the diff text', done => {
+ Object.assign(vm.discussion, {
+ for_commit: false,
+ commit_id: null,
+ });
+
+ vm.$nextTick(() => {
+ expect(vm.$el).toContainText('started a discussion on the diff');
+
+ done();
+ });
+ });
+
+ it('should show discussion on older version text', done => {
+ Object.assign(vm.discussion, {
+ for_commit: false,
+ commit_id: null,
+ active: false,
+ });
+
+ vm.$nextTick(() => {
+ expect(vm.$el).toContainText('started a discussion on an old version of the diff');
+
+ done();
+ });
+ });
});
});
});
diff --git a/spec/javascripts/releases/components/app_spec.js b/spec/javascripts/releases/components/app_spec.js
new file mode 100644
index 00000000000..f30c7685e34
--- /dev/null
+++ b/spec/javascripts/releases/components/app_spec.js
@@ -0,0 +1,79 @@
+import Vue from 'vue';
+import app from '~/releases/components/app.vue';
+import createStore from '~/releases/store';
+import api from '~/api';
+import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+import { resetStore } from '../store/helpers';
+import { releases } from '../mock_data';
+
+describe('Releases App ', () => {
+ const Component = Vue.extend(app);
+ let store;
+ let vm;
+
+ const props = {
+ projectId: 'gitlab-ce',
+ documentationLink: 'help/releases',
+ illustrationPath: 'illustration/path',
+ };
+
+ beforeEach(() => {
+ store = createStore();
+ });
+
+ afterEach(() => {
+ resetStore(store);
+ vm.$destroy();
+ });
+
+ describe('while loading', () => {
+ beforeEach(() => {
+ spyOn(api, 'releases').and.returnValue(Promise.resolve({ data: [] }));
+ vm = mountComponentWithStore(Component, { props, store });
+ });
+
+ it('renders loading icon', done => {
+ expect(vm.$el.querySelector('.js-loading')).not.toBeNull();
+ expect(vm.$el.querySelector('.js-empty-state')).toBeNull();
+ expect(vm.$el.querySelector('.js-success-state')).toBeNull();
+
+ setTimeout(() => {
+ done();
+ }, 0);
+ });
+ });
+
+ describe('with successful request', () => {
+ beforeEach(() => {
+ spyOn(api, 'releases').and.returnValue(Promise.resolve({ data: releases }));
+ vm = mountComponentWithStore(Component, { props, store });
+ });
+
+ it('renders success state', done => {
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-loading')).toBeNull();
+ expect(vm.$el.querySelector('.js-empty-state')).toBeNull();
+ expect(vm.$el.querySelector('.js-success-state')).not.toBeNull();
+
+ done();
+ }, 0);
+ });
+ });
+
+ describe('with empty request', () => {
+ beforeEach(() => {
+ spyOn(api, 'releases').and.returnValue(Promise.resolve({ data: [] }));
+ vm = mountComponentWithStore(Component, { props, store });
+ });
+
+ it('renders empty state', done => {
+ setTimeout(() => {
+ expect(vm.$el.querySelector('.js-loading')).toBeNull();
+ expect(vm.$el.querySelector('.js-empty-state')).not.toBeNull();
+ expect(vm.$el.querySelector('.js-success-state')).toBeNull();
+
+ done();
+ }, 0);
+ });
+ });
+});
diff --git a/spec/javascripts/releases/components/release_block_spec.js b/spec/javascripts/releases/components/release_block_spec.js
index c0cd15b7507..29420216bc4 100644
--- a/spec/javascripts/releases/components/release_block_spec.js
+++ b/spec/javascripts/releases/components/release_block_spec.js
@@ -15,6 +15,16 @@ describe('Release block', () => {
author_name: 'Release bot',
author_email: 'release-bot@example.com',
created_at: '2012-05-28T05:00:00-07:00',
+ author: {
+ avatar_url: 'uploads/-/system/user/avatar/johndoe/avatar.png',
+ id: 482476,
+ name: 'John Doe',
+ path: '/johndoe',
+ state: 'active',
+ status_tooltip_html: null,
+ username: 'johndoe',
+ web_url: 'https://gitlab.com/johndoe',
+ },
commit: {
id: '2695effb5807a22ff3d138d593fd856244e155e7',
short_id: '2695effb',
@@ -66,32 +76,10 @@ describe('Release block', () => {
],
},
};
-
- const props = {
- name: release.name,
- tag: release.tag_name,
- commit: release.commit,
- description: release.description_html,
- author: {
- avatar_url: 'uploads/-/system/user/avatar/johndoe/avatar.png',
- id: 482476,
- name: 'John Doe',
- path: '/johndoe',
- state: 'active',
- status_tooltip_html: null,
- username: 'johndoe',
- web_url: 'https://gitlab.com/johndoe',
- },
- createdAt: release.created_at,
- assetsCount: release.assets.count,
- sources: release.assets.sources,
- links: release.assets.links,
- };
-
let vm;
beforeEach(() => {
- vm = mountComponent(Component, props);
+ vm = mountComponent(Component, { release });
});
afterEach(() => {
diff --git a/spec/javascripts/releases/mock_data.js b/spec/javascripts/releases/mock_data.js
new file mode 100644
index 00000000000..2855eca1711
--- /dev/null
+++ b/spec/javascripts/releases/mock_data.js
@@ -0,0 +1,128 @@
+export const release = {
+ name: 'Bionic Beaver',
+ tag_name: '18.04',
+ description: '## changelog\n\n* line 1\n* line2',
+ description_html: '<div><h2>changelog</h2><ul><li>line1</li<li>line 2</li></ul></div>',
+ author_name: 'Release bot',
+ author_email: 'release-bot@example.com',
+ created_at: '2012-05-28T05:00:00-07:00',
+ commit: {
+ id: '2695effb5807a22ff3d138d593fd856244e155e7',
+ short_id: '2695effb',
+ title: 'Initial commit',
+ created_at: '2017-07-26T11:08:53.000+02:00',
+ parent_ids: ['2a4b78934375d7f53875269ffd4f45fd83a84ebe'],
+ message: 'Initial commit',
+ author: {
+ avatar_url: 'uploads/-/system/user/avatar/johndoe/avatar.png',
+ id: 482476,
+ name: 'John Doe',
+ path: '/johndoe',
+ state: 'active',
+ status_tooltip_html: null,
+ username: 'johndoe',
+ web_url: 'https://gitlab.com/johndoe',
+ },
+ authored_date: '2012-05-28T04:42:42-07:00',
+ committer_name: 'Jack Smith',
+ committer_email: 'jack@example.com',
+ committed_date: '2012-05-28T04:42:42-07:00',
+ },
+ assets: {
+ count: 6,
+ sources: [
+ {
+ format: 'zip',
+ url: 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.zip',
+ },
+ {
+ format: 'tar.gz',
+ url: 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.gz',
+ },
+ {
+ format: 'tar.bz2',
+ url:
+ 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.bz2',
+ },
+ {
+ format: 'tar',
+ url: 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar',
+ },
+ ],
+ links: [
+ {
+ name: 'release-18.04.dmg',
+ url: 'https://my-external-hosting.example.com/scrambled-url/',
+ external: true,
+ },
+ {
+ name: 'binary-linux-amd64',
+ url:
+ 'https://gitlab.com/gitlab-org/gitlab-ce/-/jobs/artifacts/v11.6.0-rc4/download?job=rspec-mysql+41%2F50',
+ external: false,
+ },
+ ],
+ },
+};
+
+export const releases = [
+ release,
+ {
+ name: 'JoJos Bizarre Adventure',
+ tag_name: '19.00',
+ description: '## changelog\n\n* line 1\n* line2',
+ description_html: '<div><h2>changelog</h2><ul><li>line1</li<li>line 2</li></ul></div>',
+ author_name: 'Release bot',
+ author_email: 'release-bot@example.com',
+ created_at: '2012-05-28T05:00:00-07:00',
+ commit: {
+ id: '2695effb5807a22ff3d138d593fd856244e155e7',
+ short_id: '2695effb',
+ title: 'Initial commit',
+ created_at: '2017-07-26T11:08:53.000+02:00',
+ parent_ids: ['2a4b78934375d7f53875269ffd4f45fd83a84ebe'],
+ message: 'Initial commit',
+ author: {
+ avatar_url: 'uploads/-/system/user/avatar/johndoe/avatar.png',
+ id: 482476,
+ name: 'John Doe',
+ path: '/johndoe',
+ state: 'active',
+ status_tooltip_html: null,
+ username: 'johndoe',
+ web_url: 'https://gitlab.com/johndoe',
+ },
+ authored_date: '2012-05-28T04:42:42-07:00',
+ committer_name: 'Jack Smith',
+ committer_email: 'jack@example.com',
+ committed_date: '2012-05-28T04:42:42-07:00',
+ },
+ assets: {
+ count: 4,
+ sources: [
+ {
+ format: 'tar.gz',
+ url:
+ 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.gz',
+ },
+ {
+ format: 'tar.bz2',
+ url:
+ 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar.bz2',
+ },
+ {
+ format: 'tar',
+ url: 'https://gitlab.com/gitlab-org/gitlab-ce/-/archive/v11.3.12/gitlab-ce-v11.3.12.tar',
+ },
+ ],
+ links: [
+ {
+ name: 'binary-linux-amd64',
+ url:
+ 'https://gitlab.com/gitlab-org/gitlab-ce/-/jobs/artifacts/v11.6.0-rc4/download?job=rspec-mysql+41%2F50',
+ external: false,
+ },
+ ],
+ },
+ },
+];
diff --git a/spec/javascripts/releases/store/actions_spec.js b/spec/javascripts/releases/store/actions_spec.js
new file mode 100644
index 00000000000..6eb8e681be9
--- /dev/null
+++ b/spec/javascripts/releases/store/actions_spec.js
@@ -0,0 +1,98 @@
+import {
+ requestReleases,
+ fetchReleases,
+ receiveReleasesSuccess,
+ receiveReleasesError,
+} from '~/releases/store/actions';
+import state from '~/releases/store/state';
+import * as types from '~/releases/store/mutation_types';
+import api from '~/api';
+import testAction from 'spec/helpers/vuex_action_helper';
+import { releases } from '../mock_data';
+
+describe('Releases State actions', () => {
+ let mockedState;
+
+ beforeEach(() => {
+ mockedState = state();
+ });
+
+ describe('requestReleases', () => {
+ it('should commit REQUEST_RELEASES mutation', done => {
+ testAction(requestReleases, null, mockedState, [{ type: types.REQUEST_RELEASES }], [], done);
+ });
+ });
+
+ describe('fetchReleases', () => {
+ describe('success', () => {
+ it('dispatches requestReleases and receiveReleasesSuccess ', done => {
+ spyOn(api, 'releases').and.returnValue(Promise.resolve({ data: releases }));
+
+ testAction(
+ fetchReleases,
+ releases,
+ mockedState,
+ [],
+ [
+ {
+ type: 'requestReleases',
+ },
+ {
+ payload: releases,
+ type: 'receiveReleasesSuccess',
+ },
+ ],
+ done,
+ );
+ });
+ });
+
+ describe('error', () => {
+ it('dispatches requestReleases and receiveReleasesError ', done => {
+ spyOn(api, 'releases').and.returnValue(Promise.reject());
+
+ testAction(
+ fetchReleases,
+ null,
+ mockedState,
+ [],
+ [
+ {
+ type: 'requestReleases',
+ },
+ {
+ type: 'receiveReleasesError',
+ },
+ ],
+ done,
+ );
+ });
+ });
+ });
+
+ describe('receiveReleasesSuccess', () => {
+ it('should commit RECEIVE_RELEASES_SUCCESS mutation', done => {
+ testAction(
+ receiveReleasesSuccess,
+ releases,
+ mockedState,
+ [{ type: types.RECEIVE_RELEASES_SUCCESS, payload: releases }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('receiveReleasesError', () => {
+ it('should commit RECEIVE_RELEASES_ERROR mutation', done => {
+ testAction(
+ receiveReleasesError,
+ null,
+ mockedState,
+ [{ type: types.RECEIVE_RELEASES_ERROR }],
+ [],
+ done,
+ );
+ });
+ });
+});
diff --git a/spec/javascripts/releases/store/helpers.js b/spec/javascripts/releases/store/helpers.js
new file mode 100644
index 00000000000..e962b254377
--- /dev/null
+++ b/spec/javascripts/releases/store/helpers.js
@@ -0,0 +1,6 @@
+import state from '~/releases/store/state';
+
+// eslint-disable-next-line import/prefer-default-export
+export const resetStore = store => {
+ store.replaceState(state());
+};
diff --git a/spec/javascripts/releases/store/mutations_spec.js b/spec/javascripts/releases/store/mutations_spec.js
new file mode 100644
index 00000000000..72b98529fe9
--- /dev/null
+++ b/spec/javascripts/releases/store/mutations_spec.js
@@ -0,0 +1,47 @@
+import state from '~/releases/store/state';
+import mutations from '~/releases/store/mutations';
+import * as types from '~/releases/store/mutation_types';
+import { releases } from '../mock_data';
+
+describe('Releases Store Mutations', () => {
+ let stateCopy;
+
+ beforeEach(() => {
+ stateCopy = state();
+ });
+
+ describe('REQUEST_RELEASES', () => {
+ it('sets isLoading to true', () => {
+ mutations[types.REQUEST_RELEASES](stateCopy);
+
+ expect(stateCopy.isLoading).toEqual(true);
+ });
+ });
+
+ describe('RECEIVE_RELEASES_SUCCESS', () => {
+ beforeEach(() => {
+ mutations[types.RECEIVE_RELEASES_SUCCESS](stateCopy, releases);
+ });
+
+ it('sets is loading to false', () => {
+ expect(stateCopy.isLoading).toEqual(false);
+ });
+
+ it('sets hasError to false', () => {
+ expect(stateCopy.hasError).toEqual(false);
+ });
+
+ it('sets data', () => {
+ expect(stateCopy.releases).toEqual(releases);
+ });
+ });
+
+ describe('RECEIVE_RELEASES_ERROR', () => {
+ it('resets data', () => {
+ mutations[types.RECEIVE_RELEASES_ERROR](stateCopy);
+
+ expect(stateCopy.isLoading).toEqual(false);
+ expect(stateCopy.releases).toEqual([]);
+ });
+ });
+});
diff --git a/spec/javascripts/sidebar/mock_data.js b/spec/javascripts/sidebar/mock_data.js
index fcd7bea3f6d..7f20b0da991 100644
--- a/spec/javascripts/sidebar/mock_data.js
+++ b/spec/javascripts/sidebar/mock_data.js
@@ -66,7 +66,7 @@ const RESPONSE_MAP = {
},
labels: [],
},
- '/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar': {
+ '/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras': {
assignees: [
{
name: 'User 0',
@@ -181,7 +181,7 @@ const RESPONSE_MAP = {
const mockData = {
responseMap: RESPONSE_MAP,
mediator: {
- endpoint: '/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar',
+ endpoint: '/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras',
toggleSubscriptionEndpoint: '/gitlab-org/gitlab-shell/issues/5/toggle_subscription',
moveIssueEndpoint: '/gitlab-org/gitlab-shell/issues/5/move',
projectsAutocompleteEndpoint: '/autocomplete/projects?project_id=15',
diff --git a/spec/javascripts/sidebar/sidebar_mediator_spec.js b/spec/javascripts/sidebar/sidebar_mediator_spec.js
index 2d853970fc4..6c69c08e733 100644
--- a/spec/javascripts/sidebar/sidebar_mediator_spec.js
+++ b/spec/javascripts/sidebar/sidebar_mediator_spec.js
@@ -37,7 +37,7 @@ describe('Sidebar mediator', function() {
it('fetches the data', done => {
const mockData =
- Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar'];
+ Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras'];
spyOn(this.mediator, 'processFetchedData').and.callThrough();
this.mediator
@@ -51,7 +51,7 @@ describe('Sidebar mediator', function() {
it('processes fetched data', () => {
const mockData =
- Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar'];
+ Mock.responseMap.GET['/gitlab-org/gitlab-shell/issues/5.json?serializer=sidebar_extras'];
this.mediator.processFetchedData(mockData);
expect(this.mediator.store.assignees).toEqual(mockData.assignees);
diff --git a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
index f72bf627c10..99b80df766a 100644
--- a/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
+++ b/spec/javascripts/vue_mr_widget/mr_widget_options_spec.js
@@ -18,6 +18,8 @@ describe('mrWidgetOptions', () => {
let vm;
let MrWidgetOptions;
+ const COLLABORATION_MESSAGE = 'Allows commits from members who can merge to the target branch';
+
beforeEach(() => {
// Prevent component mounting
delete mrWidgetOptions.el;
@@ -132,6 +134,53 @@ describe('mrWidgetOptions', () => {
expect(vm.shouldRenderSourceBranchRemovalStatus).toEqual(false);
});
});
+
+ describe('shouldRenderCollaborationStatus', () => {
+ describe('when collaboration is allowed', () => {
+ beforeEach(() => {
+ vm.mr.allowCollaboration = true;
+ });
+
+ describe('when merge request is opened', () => {
+ beforeEach(done => {
+ vm.mr.isOpen = true;
+ vm.$nextTick(done);
+ });
+
+ it('should render collaboration status', () => {
+ expect(vm.$el.textContent).toContain(COLLABORATION_MESSAGE);
+ });
+ });
+
+ describe('when merge request is not opened', () => {
+ beforeEach(done => {
+ vm.mr.isOpen = false;
+ vm.$nextTick(done);
+ });
+
+ it('should not render collaboration status', () => {
+ expect(vm.$el.textContent).not.toContain(COLLABORATION_MESSAGE);
+ });
+ });
+ });
+
+ describe('when collaboration is not allowed', () => {
+ beforeEach(() => {
+ vm.mr.allowCollaboration = false;
+ });
+
+ describe('when merge request is opened', () => {
+ beforeEach(done => {
+ vm.mr.isOpen = true;
+ vm.$nextTick(done);
+ });
+
+ it('should not render collaboration status', () => {
+ expect(vm.$el.textContent).not.toContain(COLLABORATION_MESSAGE);
+ });
+ });
+ });
+ });
});
describe('methods', () => {
diff --git a/spec/javascripts/vue_shared/components/user_popover/user_popover_spec.js b/spec/javascripts/vue_shared/components/user_popover/user_popover_spec.js
index e16ab156679..25b6e3b6bc8 100644
--- a/spec/javascripts/vue_shared/components/user_popover/user_popover_spec.js
+++ b/spec/javascripts/vue_shared/components/user_popover/user_popover_spec.js
@@ -89,7 +89,7 @@ describe('User Popover Component', () => {
expect(vm.$el.textContent).toContain('GitLab');
});
- it('should have full job line when we have bio and organization', () => {
+ it('should display bio and organization in separate lines', () => {
const testProps = Object.assign({}, DEFAULT_PROPS);
testProps.user.bio = 'Engineer';
testProps.user.organization = 'GitLab';
@@ -99,20 +99,24 @@ describe('User Popover Component', () => {
target: document.querySelector('.js-user-link'),
});
- expect(vm.$el.textContent).toContain('Engineer at GitLab');
+ expect(vm.$el.querySelector('.js-bio').textContent).toContain('Engineer');
+ expect(vm.$el.querySelector('.js-organization').textContent).toContain('GitLab');
});
- it('should not encode special characters when we have bio and organization', () => {
+ it('should not encode special characters in bio and organization', () => {
const testProps = Object.assign({}, DEFAULT_PROPS);
testProps.user.bio = 'Manager & Team Lead';
- testProps.user.organization = 'GitLab';
+ testProps.user.organization = 'Me & my <funky> Company';
vm = mountComponent(UserPopover, {
...DEFAULT_PROPS,
target: document.querySelector('.js-user-link'),
});
- expect(vm.$el.textContent).toContain('Manager & Team Lead at GitLab');
+ expect(vm.$el.querySelector('.js-bio').textContent).toContain('Manager & Team Lead');
+ expect(vm.$el.querySelector('.js-organization').textContent).toContain(
+ 'Me & my <funky> Company',
+ );
});
});
diff --git a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb
index 1a87cfa5b45..4c94e4fdae0 100644
--- a/spec/lib/banzai/filter/milestone_reference_filter_spec.rb
+++ b/spec/lib/banzai/filter/milestone_reference_filter_spec.rb
@@ -59,7 +59,7 @@ describe Banzai::Filter::MilestoneReferenceFilter do
it 'links with adjacent text' do
doc = reference_filter("Milestone (#{reference}.)")
- expect(doc.to_html).to match(%r(\(<a.+>#{milestone.name}</a>\.\)))
+ expect(doc.to_html).to match(%r(\(<a.+>#{milestone.reference_link_text}</a>\.\)))
end
it 'ignores invalid milestone IIDs' do
@@ -80,12 +80,12 @@ describe Banzai::Filter::MilestoneReferenceFilter do
doc = reference_filter("See #{reference}")
expect(doc.css('a').first.attr('href')).to eq urls.milestone_url(milestone)
- expect(doc.text).to eq 'See gfm'
+ expect(doc.text).to eq "See #{milestone.reference_link_text}"
end
it 'links with adjacent text' do
doc = reference_filter("Milestone (#{reference}.)")
- expect(doc.to_html).to match(%r(\(<a.+>#{milestone.name}</a>\.\)))
+ expect(doc.to_html).to match(%r(\(<a.+>#{milestone.reference_link_text}</a>\.\)))
end
it 'ignores invalid milestone names' do
@@ -106,12 +106,12 @@ describe Banzai::Filter::MilestoneReferenceFilter do
doc = reference_filter("See #{reference}")
expect(doc.css('a').first.attr('href')).to eq urls.milestone_url(milestone)
- expect(doc.text).to eq 'See gfm references'
+ expect(doc.text).to eq "See #{milestone.reference_link_text}"
end
it 'links with adjacent text' do
doc = reference_filter("Milestone (#{reference}.)")
- expect(doc.to_html).to match(%r(\(<a.+>#{milestone.name}</a>\.\)))
+ expect(doc.to_html).to match(%r(\(<a.+>#{milestone.reference_link_text}</a>\.\)))
end
it 'ignores invalid milestone names' do
@@ -201,14 +201,14 @@ describe Banzai::Filter::MilestoneReferenceFilter do
doc = reference_filter("See (#{reference}.)")
expect(doc.css('a').first.text)
- .to eq("#{milestone.name} in #{another_project.full_path}")
+ .to eq("#{milestone.reference_link_text} in #{another_project.full_path}")
end
it 'has valid text' do
doc = reference_filter("See (#{reference}.)")
expect(doc.text)
- .to eq("See (#{milestone.name} in #{another_project.full_path}.)")
+ .to eq("See (#{milestone.reference_link_text} in #{another_project.full_path}.)")
end
it 'escapes the name attribute' do
@@ -217,7 +217,7 @@ describe Banzai::Filter::MilestoneReferenceFilter do
doc = reference_filter("See #{reference}")
expect(doc.css('a').first.text)
- .to eq "#{milestone.name} in #{another_project.full_path}"
+ .to eq "#{milestone.reference_link_text} in #{another_project.full_path}"
end
end
@@ -238,14 +238,14 @@ describe Banzai::Filter::MilestoneReferenceFilter do
doc = reference_filter("See (#{reference}.)")
expect(doc.css('a').first.text)
- .to eq("#{milestone.name} in #{another_project.path}")
+ .to eq("#{milestone.reference_link_text} in #{another_project.path}")
end
it 'has valid text' do
doc = reference_filter("See (#{reference}.)")
expect(doc.text)
- .to eq("See (#{milestone.name} in #{another_project.path}.)")
+ .to eq("See (#{milestone.reference_link_text} in #{another_project.path}.)")
end
it 'escapes the name attribute' do
@@ -254,7 +254,7 @@ describe Banzai::Filter::MilestoneReferenceFilter do
doc = reference_filter("See #{reference}")
expect(doc.css('a').first.text)
- .to eq "#{milestone.name} in #{another_project.path}"
+ .to eq "#{milestone.reference_link_text} in #{another_project.path}"
end
end
@@ -275,14 +275,14 @@ describe Banzai::Filter::MilestoneReferenceFilter do
doc = reference_filter("See (#{reference}.)")
expect(doc.css('a').first.text)
- .to eq("#{milestone.name} in #{another_project.path}")
+ .to eq("#{milestone.reference_link_text} in #{another_project.path}")
end
it 'has valid text' do
doc = reference_filter("See (#{reference}.)")
expect(doc.text)
- .to eq("See (#{milestone.name} in #{another_project.path}.)")
+ .to eq("See (#{milestone.reference_link_text} in #{another_project.path}.)")
end
it 'escapes the name attribute' do
@@ -291,7 +291,7 @@ describe Banzai::Filter::MilestoneReferenceFilter do
doc = reference_filter("See #{reference}")
expect(doc.css('a').first.text)
- .to eq "#{milestone.name} in #{another_project.path}"
+ .to eq "#{milestone.reference_link_text} in #{another_project.path}"
end
end
@@ -346,7 +346,7 @@ describe Banzai::Filter::MilestoneReferenceFilter do
milestone.update!(group: parent_group)
doc = reference_filter("See #{reference}")
- expect(doc.css('a').first.text).to eq(milestone.name)
+ expect(doc.css('a').first.text).to eq(milestone.reference_link_text)
end
end
diff --git a/spec/lib/gitlab/bare_repository_import/importer_spec.rb b/spec/lib/gitlab/bare_repository_import/importer_spec.rb
index 3c63e601abc..f4759b69538 100644
--- a/spec/lib/gitlab/bare_repository_import/importer_spec.rb
+++ b/spec/lib/gitlab/bare_repository_import/importer_spec.rb
@@ -192,7 +192,7 @@ describe Gitlab::BareRepositoryImport::Importer, :seed_helper do
let(:project_path) { 'a-group/a-sub-group/a-project' }
before do
- expect(Group).to receive(:supports_nested_groups?) { false }
+ expect(Group).to receive(:supports_nested_objects?) { false }
end
describe '#create_project_if_needed' do
diff --git a/spec/lib/gitlab/current_settings_spec.rb b/spec/lib/gitlab/current_settings_spec.rb
index 55490f37ac7..caf9fc5442c 100644
--- a/spec/lib/gitlab/current_settings_spec.rb
+++ b/spec/lib/gitlab/current_settings_spec.rb
@@ -54,7 +54,7 @@ describe Gitlab::CurrentSettings do
expect(ApplicationSetting).not_to receive(:current)
end
- it 'returns an in-memory ApplicationSetting object' do
+ it 'returns a FakeApplicationSettings object' do
expect(described_class.current_application_settings).to be_a(Gitlab::FakeApplicationSettings)
end
@@ -91,6 +91,14 @@ describe Gitlab::CurrentSettings do
allow(ActiveRecord::Base.connection).to receive(:cached_table_exists?).with('application_settings').and_return(true)
end
+ context 'with RequestStore enabled', :request_store do
+ it 'fetches the settings from DB only once' do
+ described_class.current_application_settings # warm the cache
+
+ expect(ActiveRecord::QueryRecorder.new { described_class.current_application_settings }.count).to eq(0)
+ end
+ end
+
it 'creates default ApplicationSettings if none are present' do
settings = described_class.current_application_settings
@@ -99,34 +107,45 @@ describe Gitlab::CurrentSettings do
expect(settings).to have_attributes(settings_from_defaults)
end
- context 'with migrations pending' do
+ context 'with pending migrations' do
before do
expect(ActiveRecord::Migrator).to receive(:needs_migration?).and_return(true)
end
- it 'returns an in-memory ApplicationSetting object' do
- settings = described_class.current_application_settings
+ shared_examples 'a non-persisted ApplicationSetting object' do
+ let(:current_settings) { described_class.current_application_settings }
+
+ it 'returns a non-persisted ApplicationSetting object' do
+ expect(current_settings).to be_a(ApplicationSetting)
+ expect(current_settings).not_to be_persisted
+ end
+
+ it 'uses the default value from ApplicationSetting.defaults' do
+ expect(current_settings.signup_enabled).to eq(ApplicationSetting.defaults[:signup_enabled])
+ end
+
+ it 'uses the default value from custom ApplicationSetting accessors' do
+ expect(current_settings.commit_email_hostname).to eq(ApplicationSetting.default_commit_email_hostname)
+ end
+
+ it 'responds to predicate methods' do
+ expect(current_settings.signup_enabled?).to eq(current_settings.signup_enabled)
+ end
+ end
- expect(settings).to be_a(Gitlab::FakeApplicationSettings)
- expect(settings.sign_in_enabled?).to eq(settings.sign_in_enabled)
- expect(settings.sign_up_enabled?).to eq(settings.sign_up_enabled)
+ context 'with no ApplicationSetting DB record' do
+ it_behaves_like 'a non-persisted ApplicationSetting object'
end
- it 'uses the existing database settings and falls back to defaults' do
- db_settings = create(:application_setting,
- home_page_url: 'http://mydomain.com',
- signup_enabled: false)
- settings = described_class.current_application_settings
- app_defaults = ApplicationSetting.last
-
- expect(settings).to be_a(Gitlab::FakeApplicationSettings)
- expect(settings.home_page_url).to eq(db_settings.home_page_url)
- expect(settings.signup_enabled?).to be_falsey
- expect(settings.signup_enabled).to be_falsey
-
- # Check that unspecified values use the defaults
- settings.reject! { |key, _| [:home_page_url, :signup_enabled].include? key }
- settings.each { |key, _| expect(settings[key]).to eq(app_defaults[key]) }
+ context 'with an existing ApplicationSetting DB record' do
+ let!(:db_settings) { ApplicationSetting.build_from_defaults(home_page_url: 'http://mydomain.com').save! && ApplicationSetting.last }
+ let(:current_settings) { described_class.current_application_settings }
+
+ it_behaves_like 'a non-persisted ApplicationSetting object'
+
+ it 'uses the value from the DB attribute if present and not overriden by an accessor' do
+ expect(current_settings.home_page_url).to eq(db_settings.home_page_url)
+ end
end
end
@@ -138,17 +157,12 @@ describe Gitlab::CurrentSettings do
end
end
- context 'when the application_settings table does not exists' do
- it 'returns an in-memory ApplicationSetting object' do
- expect(ApplicationSetting).to receive(:create_from_defaults).and_raise(ActiveRecord::StatementInvalid)
-
- expect(described_class.current_application_settings).to be_a(Gitlab::FakeApplicationSettings)
- end
- end
-
- context 'when the application_settings table is not fully migrated' do
- it 'returns an in-memory ApplicationSetting object' do
- expect(ApplicationSetting).to receive(:create_from_defaults).and_raise(ActiveRecord::UnknownAttributeError)
+ context 'when the application_settings table does not exist' do
+ it 'returns a FakeApplicationSettings object' do
+ expect(Gitlab::Database)
+ .to receive(:cached_table_exists?)
+ .with('application_settings')
+ .and_return(false)
expect(described_class.current_application_settings).to be_a(Gitlab::FakeApplicationSettings)
end
diff --git a/spec/lib/gitlab/discussions_diff/file_collection_spec.rb b/spec/lib/gitlab/discussions_diff/file_collection_spec.rb
new file mode 100644
index 00000000000..0489206458b
--- /dev/null
+++ b/spec/lib/gitlab/discussions_diff/file_collection_spec.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::DiscussionsDiff::FileCollection do
+ let(:merge_request) { create(:merge_request) }
+ let!(:diff_note_a) { create(:diff_note_on_merge_request, project: merge_request.project, noteable: merge_request) }
+ let!(:diff_note_b) { create(:diff_note_on_merge_request, project: merge_request.project, noteable: merge_request) }
+ let(:note_diff_file_a) { diff_note_a.note_diff_file }
+ let(:note_diff_file_b) { diff_note_b.note_diff_file }
+
+ subject { described_class.new([note_diff_file_a, note_diff_file_b]) }
+
+ describe '#load_highlight', :clean_gitlab_redis_shared_state do
+ it 'writes uncached diffs highlight' do
+ file_a_caching_content = diff_note_a.diff_file.highlighted_diff_lines.map(&:to_hash)
+ file_b_caching_content = diff_note_b.diff_file.highlighted_diff_lines.map(&:to_hash)
+
+ expect(Gitlab::DiscussionsDiff::HighlightCache)
+ .to receive(:write_multiple)
+ .with({ note_diff_file_a.id => file_a_caching_content,
+ note_diff_file_b.id => file_b_caching_content })
+ .and_call_original
+
+ subject.load_highlight([note_diff_file_a.id, note_diff_file_b.id])
+ end
+
+ it 'does not write cache for already cached file' do
+ subject.load_highlight([note_diff_file_a.id])
+
+ file_b_caching_content = diff_note_b.diff_file.highlighted_diff_lines.map(&:to_hash)
+
+ expect(Gitlab::DiscussionsDiff::HighlightCache)
+ .to receive(:write_multiple)
+ .with({ note_diff_file_b.id => file_b_caching_content })
+ .and_call_original
+
+ subject.load_highlight([note_diff_file_a.id, note_diff_file_b.id])
+ end
+
+ it 'does not err when given ID does not exist in @collection' do
+ expect { subject.load_highlight([999]) }.not_to raise_error
+ end
+
+ it 'loaded diff files have highlighted lines loaded' do
+ subject.load_highlight([note_diff_file_a.id])
+
+ diff_file = subject.find_by_id(note_diff_file_a.id)
+
+ expect(diff_file.highlight_loaded?).to be(true)
+ end
+
+ it 'not loaded diff files does not have highlighted lines loaded' do
+ subject.load_highlight([note_diff_file_a.id])
+
+ diff_file = subject.find_by_id(note_diff_file_b.id)
+
+ expect(diff_file.highlight_loaded?).to be(false)
+ end
+ end
+end
diff --git a/spec/lib/gitlab/discussions_diff/highlight_cache_spec.rb b/spec/lib/gitlab/discussions_diff/highlight_cache_spec.rb
new file mode 100644
index 00000000000..fe26ebb8796
--- /dev/null
+++ b/spec/lib/gitlab/discussions_diff/highlight_cache_spec.rb
@@ -0,0 +1,102 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::DiscussionsDiff::HighlightCache, :clean_gitlab_redis_cache do
+ describe '#write_multiple' do
+ it 'sets multiple keys serializing content as JSON' do
+ mapping = {
+ 3 => [
+ {
+ text: 'foo',
+ type: 'new',
+ index: 2,
+ old_pos: 10,
+ new_pos: 11,
+ line_code: 'xpto',
+ rich_text: '<blips>blops</blips>'
+ },
+ {
+ text: 'foo',
+ type: 'new',
+ index: 3,
+ old_pos: 11,
+ new_pos: 12,
+ line_code: 'xpto',
+ rich_text: '<blops>blips</blops>'
+ }
+ ]
+ }
+
+ described_class.write_multiple(mapping)
+
+ mapping.each do |key, value|
+ full_key = described_class.cache_key_for(key)
+ found = Gitlab::Redis::Cache.with { |r| r.get(full_key) }
+
+ expect(found).to eq(value.to_json)
+ end
+ end
+ end
+
+ describe '#read_multiple' do
+ it 'reads multiple keys and serializes content into Gitlab::Diff::Line objects' do
+ mapping = {
+ 3 => [
+ {
+ text: 'foo',
+ type: 'new',
+ index: 2,
+ old_pos: 11,
+ new_pos: 12,
+ line_code: 'xpto',
+ rich_text: '<blips>blops</blips>'
+ },
+ {
+ text: 'foo',
+ type: 'new',
+ index: 3,
+ old_pos: 10,
+ new_pos: 11,
+ line_code: 'xpto',
+ rich_text: '<blips>blops</blips>'
+ }
+ ]
+ }
+
+ described_class.write_multiple(mapping)
+
+ found = described_class.read_multiple(mapping.keys)
+
+ expect(found.size).to eq(1)
+ expect(found.first.size).to eq(2)
+ expect(found.first).to all(be_a(Gitlab::Diff::Line))
+ end
+
+ it 'returns nil when cached key is not found' do
+ mapping = {
+ 3 => [
+ {
+ text: 'foo',
+ type: 'new',
+ index: 2,
+ old_pos: 11,
+ new_pos: 12,
+ line_code: 'xpto',
+ rich_text: '<blips>blops</blips>'
+ }
+ ]
+ }
+
+ described_class.write_multiple(mapping)
+
+ found = described_class.read_multiple([2, 3])
+
+ expect(found.size).to eq(2)
+
+ expect(found.first).to eq(nil)
+ expect(found.second.size).to eq(1)
+ expect(found.second).to all(be_a(Gitlab::Diff::Line))
+ end
+ end
+end
diff --git a/spec/lib/gitlab/gitaly_client_spec.rb b/spec/lib/gitlab/gitaly_client_spec.rb
index 5eda4d041a8..e41a75c37a7 100644
--- a/spec/lib/gitlab/gitaly_client_spec.rb
+++ b/spec/lib/gitlab/gitaly_client_spec.rb
@@ -3,6 +3,20 @@ require 'spec_helper'
# We stub Gitaly in `spec/support/gitaly.rb` for other tests. We don't want
# those stubs while testing the GitalyClient itself.
describe Gitlab::GitalyClient do
+ let(:sample_cert) { Rails.root.join('spec/fixtures/clusters/sample_cert.pem').to_s }
+
+ before do
+ allow(described_class)
+ .to receive(:stub_cert_paths)
+ .and_return([sample_cert])
+ end
+
+ def stub_repos_storages(address)
+ allow(Gitlab.config.repositories).to receive(:storages).and_return({
+ 'default' => { 'gitaly_address' => address }
+ })
+ end
+
describe '.stub_class' do
it 'returns the gRPC health check stub' do
expect(described_class.stub_class(:health_check)).to eq(::Grpc::Health::V1::Health::Stub)
@@ -15,12 +29,8 @@ describe Gitlab::GitalyClient do
describe '.stub_address' do
it 'returns the same result after being called multiple times' do
- address = 'localhost:9876'
- prefixed_address = "tcp://#{address}"
-
- allow(Gitlab.config.repositories).to receive(:storages).and_return({
- 'default' => { 'gitaly_address' => prefixed_address }
- })
+ address = 'tcp://localhost:9876'
+ stub_repos_storages address
2.times do
expect(described_class.stub_address('default')).to eq('localhost:9876')
@@ -28,6 +38,45 @@ describe Gitlab::GitalyClient do
end
end
+ describe '.stub_certs' do
+ it 'skips certificates if OpenSSLError is raised and report it' do
+ expect(Rails.logger).to receive(:error).at_least(:once)
+ expect(Gitlab::Sentry)
+ .to receive(:track_exception)
+ .with(
+ a_kind_of(OpenSSL::X509::CertificateError),
+ extra: { cert_file: a_kind_of(String) }).at_least(:once)
+
+ expect(OpenSSL::X509::Certificate)
+ .to receive(:new)
+ .and_raise(OpenSSL::X509::CertificateError).at_least(:once)
+
+ expect(described_class.stub_certs).to be_a(String)
+ end
+ end
+ describe '.stub_creds' do
+ it 'returns :this_channel_is_insecure if unix' do
+ address = 'unix:/tmp/gitaly.sock'
+ stub_repos_storages address
+
+ expect(described_class.stub_creds('default')).to eq(:this_channel_is_insecure)
+ end
+
+ it 'returns :this_channel_is_insecure if tcp' do
+ address = 'tcp://localhost:9876'
+ stub_repos_storages address
+
+ expect(described_class.stub_creds('default')).to eq(:this_channel_is_insecure)
+ end
+
+ it 'returns Credentials object if tls' do
+ address = 'tls://localhost:9876'
+ stub_repos_storages address
+
+ expect(described_class.stub_creds('default')).to be_a(GRPC::Core::ChannelCredentials)
+ end
+ end
+
describe '.stub' do
# Notice that this is referring to gRPC "stubs", not rspec stubs
before do
@@ -37,9 +86,19 @@ describe Gitlab::GitalyClient do
context 'when passed a UNIX socket address' do
it 'passes the address as-is to GRPC' do
address = 'unix:/tmp/gitaly.sock'
- allow(Gitlab.config.repositories).to receive(:storages).and_return({
- 'default' => { 'gitaly_address' => address }
- })
+ stub_repos_storages address
+
+ expect(Gitaly::CommitService::Stub).to receive(:new).with(address, any_args)
+
+ described_class.stub(:commit_service, 'default')
+ end
+ end
+
+ context 'when passed a TLS address' do
+ it 'strips tls:// prefix before passing it to GRPC::Core::Channel initializer' do
+ address = 'localhost:9876'
+ prefixed_address = "tls://#{address}"
+ stub_repos_storages prefixed_address
expect(Gitaly::CommitService::Stub).to receive(:new).with(address, any_args)
@@ -51,10 +110,7 @@ describe Gitlab::GitalyClient do
it 'strips tcp:// prefix before passing it to GRPC::Core::Channel initializer' do
address = 'localhost:9876'
prefixed_address = "tcp://#{address}"
-
- allow(Gitlab.config.repositories).to receive(:storages).and_return({
- 'default' => { 'gitaly_address' => prefixed_address }
- })
+ stub_repos_storages prefixed_address
expect(Gitaly::CommitService::Stub).to receive(:new).with(address, any_args)
diff --git a/spec/lib/gitlab/import_export/command_line_util_spec.rb b/spec/lib/gitlab/import_export/command_line_util_spec.rb
new file mode 100644
index 00000000000..8e5e0aefac0
--- /dev/null
+++ b/spec/lib/gitlab/import_export/command_line_util_spec.rb
@@ -0,0 +1,38 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::ImportExport::CommandLineUtil do
+ include ExportFileHelper
+
+ let(:path) { "#{Dir.tmpdir}/symlink_test" }
+ let(:archive) { 'spec/fixtures/symlink_export.tar.gz' }
+ let(:shared) { Gitlab::ImportExport::Shared.new(nil) }
+
+ subject do
+ Class.new do
+ include Gitlab::ImportExport::CommandLineUtil
+
+ def initialize
+ @shared = Gitlab::ImportExport::Shared.new(nil)
+ end
+ end.new
+ end
+
+ before do
+ FileUtils.mkdir_p(path)
+ subject.untar_zxf(archive: archive, dir: path)
+ end
+
+ after do
+ FileUtils.rm_rf(path)
+ end
+
+ it 'has the right mask for project.json' do
+ expect(file_permissions("#{path}/project.json")).to eq(0755) # originally 777
+ end
+
+ it 'has the right mask for uploads' do
+ expect(file_permissions("#{path}/uploads")).to eq(0755) # originally 555
+ end
+end
diff --git a/spec/lib/gitlab/import_export/file_importer_spec.rb b/spec/lib/gitlab/import_export/file_importer_spec.rb
index bf34cefe18f..fbc9bcd2df5 100644
--- a/spec/lib/gitlab/import_export/file_importer_spec.rb
+++ b/spec/lib/gitlab/import_export/file_importer_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe Gitlab::ImportExport::FileImporter do
+ include ExportFileHelper
+
let(:shared) { Gitlab::ImportExport::Shared.new(nil) }
let(:storage_path) { "#{Dir.tmpdir}/file_importer_spec" }
let(:valid_file) { "#{shared.export_path}/valid.json" }
@@ -8,6 +10,7 @@ describe Gitlab::ImportExport::FileImporter do
let(:hidden_symlink_file) { "#{shared.export_path}/.hidden" }
let(:subfolder_symlink_file) { "#{shared.export_path}/subfolder/invalid.json" }
let(:evil_symlink_file) { "#{shared.export_path}/.\nevil" }
+ let(:custom_mode_symlink_file) { "#{shared.export_path}/symlink.mode" }
before do
stub_const('Gitlab::ImportExport::FileImporter::MAX_RETRIES', 0)
@@ -45,10 +48,18 @@ describe Gitlab::ImportExport::FileImporter do
expect(File.exist?(subfolder_symlink_file)).to be false
end
+ it 'removes symlinks without any file permissions' do
+ expect(File.exist?(custom_mode_symlink_file)).to be false
+ end
+
it 'does not remove a valid file' do
expect(File.exist?(valid_file)).to be true
end
+ it 'does not change a valid file permissions' do
+ expect(file_permissions(valid_file)).not_to eq(0000)
+ end
+
it 'creates the file in the right subfolder' do
expect(shared.export_path).to include('test/abcd')
end
@@ -84,5 +95,7 @@ describe Gitlab::ImportExport::FileImporter do
FileUtils.ln_s(valid_file, subfolder_symlink_file)
FileUtils.ln_s(valid_file, hidden_symlink_file)
FileUtils.ln_s(valid_file, evil_symlink_file)
+ FileUtils.ln_s(valid_file, custom_mode_symlink_file)
+ FileUtils.chmod_R(0000, custom_mode_symlink_file)
end
end
diff --git a/spec/lib/gitlab/group_hierarchy_spec.rb b/spec/lib/gitlab/object_hierarchy_spec.rb
index f3de7adcec7..4700a7ad2e1 100644
--- a/spec/lib/gitlab/group_hierarchy_spec.rb
+++ b/spec/lib/gitlab/object_hierarchy_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Gitlab::GroupHierarchy, :postgresql do
+describe Gitlab::ObjectHierarchy, :postgresql do
let!(:parent) { create(:group) }
let!(:child1) { create(:group, parent: parent) }
let!(:child2) { create(:group, parent: child1) }
@@ -105,9 +105,9 @@ describe Gitlab::GroupHierarchy, :postgresql do
end
end
- describe '#all_groups' do
+ describe '#all_objects' do
let(:relation) do
- described_class.new(Group.where(id: child1.id)).all_groups
+ described_class.new(Group.where(id: child1.id)).all_objects
end
it 'includes the base rows' do
@@ -123,13 +123,13 @@ describe Gitlab::GroupHierarchy, :postgresql do
end
it 'uses ancestors_base #initialize argument for ancestors' do
- relation = described_class.new(Group.where(id: child1.id), Group.where(id: Group.maximum(:id).succ)).all_groups
+ relation = described_class.new(Group.where(id: child1.id), Group.where(id: Group.maximum(:id).succ)).all_objects
expect(relation).to include(parent)
end
it 'uses descendants_base #initialize argument for descendants' do
- relation = described_class.new(Group.where(id: Group.maximum(:id).succ), Group.where(id: child1.id)).all_groups
+ relation = described_class.new(Group.where(id: Group.maximum(:id).succ), Group.where(id: child1.id)).all_objects
expect(relation).to include(child2)
end
diff --git a/spec/lib/gitlab/project_authorizations_spec.rb b/spec/lib/gitlab/project_authorizations_spec.rb
index 00c62c7bf96..bd0bc2c9044 100644
--- a/spec/lib/gitlab/project_authorizations_spec.rb
+++ b/spec/lib/gitlab/project_authorizations_spec.rb
@@ -20,7 +20,7 @@ describe Gitlab::ProjectAuthorizations do
end
let(:authorizations) do
- klass = if Group.supports_nested_groups?
+ klass = if Group.supports_nested_objects?
Gitlab::ProjectAuthorizations::WithNestedGroups
else
Gitlab::ProjectAuthorizations::WithoutNestedGroups
@@ -46,7 +46,7 @@ describe Gitlab::ProjectAuthorizations do
expect(mapping[group_project.id]).to eq(Gitlab::Access::DEVELOPER)
end
- if Group.supports_nested_groups?
+ if Group.supports_nested_objects?
context 'with nested groups' do
let!(:nested_group) { create(:group, parent: group) }
let!(:nested_project) { create(:project, namespace: nested_group) }
diff --git a/spec/lib/gitlab/prometheus/query_variables_spec.rb b/spec/lib/gitlab/prometheus/query_variables_spec.rb
index 78974cadb69..78c74266c61 100644
--- a/spec/lib/gitlab/prometheus/query_variables_spec.rb
+++ b/spec/lib/gitlab/prometheus/query_variables_spec.rb
@@ -4,7 +4,7 @@ require 'spec_helper'
describe Gitlab::Prometheus::QueryVariables do
describe '.call' do
- set(:environment) { create(:environment) }
+ let(:environment) { create(:environment) }
let(:slug) { environment.slug }
subject { described_class.call(environment) }
@@ -20,7 +20,7 @@ describe Gitlab::Prometheus::QueryVariables do
it { is_expected.to include(kube_namespace: '') }
end
- context 'with deplyoment platform' do
+ context 'with deployment platform' do
let(:kube_namespace) { environment.deployment_platform.actual_namespace }
before do
diff --git a/spec/lib/gitlab/upgrader_spec.rb b/spec/lib/gitlab/upgrader_spec.rb
deleted file mode 100644
index 6106f13c774..00000000000
--- a/spec/lib/gitlab/upgrader_spec.rb
+++ /dev/null
@@ -1,40 +0,0 @@
-require 'spec_helper'
-
-describe Gitlab::Upgrader do
- let(:upgrader) { described_class.new }
- let(:current_version) { Gitlab::VERSION }
-
- describe 'current_version_raw' do
- it { expect(upgrader.current_version_raw).to eq(current_version) }
- end
-
- describe 'latest_version?' do
- it 'is true if newest version' do
- allow(upgrader).to receive(:latest_version_raw).and_return(current_version)
- expect(upgrader.latest_version?).to be_truthy
- end
- end
-
- describe 'latest_version_raw' do
- it 'is the latest version for GitLab 5' do
- allow(upgrader).to receive(:current_version_raw).and_return("5.3.0")
- expect(upgrader.latest_version_raw).to eq("v5.4.2")
- end
-
- it 'gets the latest version from tags' do
- allow(upgrader).to receive(:fetch_git_tags).and_return([
- '6f0733310546402c15d3ae6128a95052f6c8ea96 refs/tags/v7.1.1',
- 'facfec4b242ce151af224e20715d58e628aa5e74 refs/tags/v7.1.1^{}',
- 'f7068d99c79cf79befbd388030c051bb4b5e86d4 refs/tags/v7.10.4',
- '337225a4fcfa9674e2528cb6d41c46556bba9dfa refs/tags/v7.10.4^{}',
- '880e0ba0adbed95d087f61a9a17515e518fc6440 refs/tags/v7.11.1',
- '6584346b604f981f00af8011cd95472b2776d912 refs/tags/v7.11.1^{}',
- '43af3e65a486a9237f29f56d96c3b3da59c24ae0 refs/tags/v7.11.2',
- 'dac18e7728013a77410e926a1e64225703754a2d refs/tags/v7.11.2^{}',
- '0bf21fd4b46c980c26fd8c90a14b86a4d90cc950 refs/tags/v7.9.4',
- 'b10de29edbaff7219547dc506cb1468ee35065c3 refs/tags/v7.9.4^{}'
- ])
- expect(upgrader.latest_version_raw).to eq("v7.11.2")
- end
- end
-end
diff --git a/spec/lib/gitlab/utils/override_spec.rb b/spec/lib/gitlab/utils/override_spec.rb
index fc08ebcfc6d..9e7c97f8095 100644
--- a/spec/lib/gitlab/utils/override_spec.rb
+++ b/spec/lib/gitlab/utils/override_spec.rb
@@ -25,11 +25,21 @@ describe Gitlab::Utils::Override do
let(:klass) { subject }
- def good(mod)
+ def good(mod, bad_arity: false, negative_arity: false)
mod.module_eval do
override :good
- def good
- super.succ
+
+ if bad_arity
+ def good(num)
+ end
+ elsif negative_arity
+ def good(*args)
+ super.succ
+ end
+ else
+ def good
+ super.succ
+ end
end
end
@@ -56,6 +66,14 @@ describe Gitlab::Utils::Override do
described_class.verify!
end
+ it 'checks ok for overriding method using negative arity' do
+ good(subject, negative_arity: true)
+ result = instance.good
+
+ expect(result).to eq(1)
+ described_class.verify!
+ end
+
it 'raises NotImplementedError when it is not overriding anything' do
expect do
bad(subject)
@@ -63,6 +81,14 @@ describe Gitlab::Utils::Override do
described_class.verify!
end.to raise_error(NotImplementedError)
end
+
+ it 'raises NotImplementedError when overriding a method with different arity' do
+ expect do
+ good(subject, bad_arity: true)
+ instance.good(1)
+ described_class.verify!
+ end.to raise_error(NotImplementedError)
+ end
end
shared_examples 'checking as intended, nothing was overridden' do
diff --git a/spec/mailers/notify_spec.rb b/spec/mailers/notify_spec.rb
index f6e5c9d33ac..f2d99872401 100644
--- a/spec/mailers/notify_spec.rb
+++ b/spec/mailers/notify_spec.rb
@@ -890,22 +890,14 @@ describe Notify do
shared_examples 'an email for a note on a diff discussion' do |model|
let(:note) { create(model, author: note_author) }
- context 'when note is on image' do
+ context 'when note is not on text' do
before do
- allow_any_instance_of(DiffDiscussion).to receive(:on_image?).and_return(true)
+ allow_any_instance_of(DiffDiscussion).to receive(:on_text?).and_return(false)
end
it 'does not include diffs with character-level highlighting' do
is_expected.not_to have_body_text '<span class="p">}</span></span>'
end
-
- it 'ends the intro with a dot' do
- is_expected.to have_body_text "#{note.diff_file.file_path}</a>."
- end
- end
-
- it 'ends the intro with a colon' do
- is_expected.to have_body_text "#{note.diff_file.file_path}</a>:"
end
it 'includes diffs with character-level highlighting' do
diff --git a/spec/migrations/migrate_cluster_configure_worker_sidekiq_queue_spec.rb b/spec/migrations/migrate_cluster_configure_worker_sidekiq_queue_spec.rb
new file mode 100644
index 00000000000..b2d8f476bb2
--- /dev/null
+++ b/spec/migrations/migrate_cluster_configure_worker_sidekiq_queue_spec.rb
@@ -0,0 +1,68 @@
+require 'spec_helper'
+require Rails.root.join('db', 'post_migrate', '20181219145520_migrate_cluster_configure_worker_sidekiq_queue.rb')
+
+describe MigrateClusterConfigureWorkerSidekiqQueue, :sidekiq, :redis do
+ include Gitlab::Database::MigrationHelpers
+
+ context 'when there are jobs in the queue' do
+ it 'correctly migrates queue when migrating up' do
+ Sidekiq::Testing.disable! do
+ stubbed_worker(queue: 'gcp_cluster:cluster_platform_configure').perform_async('Something', [1])
+ stubbed_worker(queue: 'gcp_cluster:cluster_configure').perform_async('Something', [1])
+
+ described_class.new.up
+
+ expect(sidekiq_queue_length('gcp_cluster:cluster_platform_configure')).to eq 0
+ expect(sidekiq_queue_length('gcp_cluster:cluster_configure')).to eq 2
+ end
+ end
+
+ it 'does not affect other queues under the same namespace' do
+ Sidekiq::Testing.disable! do
+ stubbed_worker(queue: 'gcp_cluster:cluster_install_app').perform_async('Something', [1])
+ stubbed_worker(queue: 'gcp_cluster:cluster_provision').perform_async('Something', [1])
+ stubbed_worker(queue: 'gcp_cluster:cluster_wait_for_app_installation').perform_async('Something', [1])
+ stubbed_worker(queue: 'gcp_cluster:wait_for_cluster_creation').perform_async('Something', [1])
+ stubbed_worker(queue: 'gcp_cluster:cluster_wait_for_ingress_ip_address').perform_async('Something', [1])
+ stubbed_worker(queue: 'gcp_cluster:cluster_project_configure').perform_async('Something', [1])
+
+ described_class.new.up
+
+ expect(sidekiq_queue_length('gcp_cluster:cluster_install_app')).to eq 1
+ expect(sidekiq_queue_length('gcp_cluster:cluster_provision')).to eq 1
+ expect(sidekiq_queue_length('gcp_cluster:cluster_wait_for_app_installation')).to eq 1
+ expect(sidekiq_queue_length('gcp_cluster:wait_for_cluster_creation')).to eq 1
+ expect(sidekiq_queue_length('gcp_cluster:cluster_wait_for_ingress_ip_address')).to eq 1
+ expect(sidekiq_queue_length('gcp_cluster:cluster_project_configure')).to eq 1
+ end
+ end
+
+ it 'correctly migrates queue when migrating down' do
+ Sidekiq::Testing.disable! do
+ stubbed_worker(queue: 'gcp_cluster:cluster_configure').perform_async('Something', [1])
+
+ described_class.new.down
+
+ expect(sidekiq_queue_length('gcp_cluster:cluster_platform_configure')).to eq 1
+ expect(sidekiq_queue_length('gcp_cluster:cluster_configure')).to eq 0
+ end
+ end
+ end
+
+ context 'when there are no jobs in the queues' do
+ it 'does not raise error when migrating up' do
+ expect { described_class.new.up }.not_to raise_error
+ end
+
+ it 'does not raise error when migrating down' do
+ expect { described_class.new.down }.not_to raise_error
+ end
+ end
+
+ def stubbed_worker(queue:)
+ Class.new do
+ include Sidekiq::Worker
+ sidekiq_options queue: queue
+ end
+ end
+end
diff --git a/spec/models/appearance_spec.rb b/spec/models/appearance_spec.rb
index 35415030154..ec2e7d672f0 100644
--- a/spec/models/appearance_spec.rb
+++ b/spec/models/appearance_spec.rb
@@ -26,4 +26,34 @@ describe Appearance do
let(:uploader_class) { AttachmentUploader }
end
end
+
+ shared_examples 'logo paths' do |logo_type|
+ let(:appearance) { create(:appearance, "with_#{logo_type}".to_sym) }
+ let(:filename) { 'dk.png' }
+ let(:expected_path) { "/uploads/-/system/appearance/#{logo_type}/#{appearance.id}/#{filename}" }
+
+ it 'returns nil when there is no upload' do
+ expect(subject.send("#{logo_type}_path")).to be_nil
+ end
+
+ it 'returns a local path using the system route' do
+ expect(appearance.send("#{logo_type}_path")).to eq(expected_path)
+ end
+
+ describe 'with asset host configured' do
+ let(:asset_host) { 'https://gitlab-assets.example.com' }
+
+ before do
+ allow(ActionController::Base).to receive(:asset_host) { asset_host }
+ end
+
+ it 'returns a full URL with the system path' do
+ expect(appearance.send("#{logo_type}_path")).to eq("#{asset_host}#{expected_path}")
+ end
+ end
+ end
+
+ %i(logo header_logo favicon).each do |logo_type|
+ it_behaves_like 'logo paths', logo_type
+ end
end
diff --git a/spec/models/clusters/platforms/kubernetes_spec.rb b/spec/models/clusters/platforms/kubernetes_spec.rb
index 062d2fd0768..e6b076adc76 100644
--- a/spec/models/clusters/platforms/kubernetes_spec.rb
+++ b/spec/models/clusters/platforms/kubernetes_spec.rb
@@ -325,12 +325,13 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching
context 'with valid pods' do
let(:pod) { kube_pod(app: environment.slug) }
+ let(:pod_with_no_terminal) { kube_pod(app: environment.slug, status: "Pending") }
let(:terminals) { kube_terminals(service, pod) }
before do
stub_reactive_cache(
service,
- pods: [pod, pod, kube_pod(app: "should-be-filtered-out")]
+ pods: [pod, pod, pod_with_no_terminal, kube_pod(app: "should-be-filtered-out")]
)
end
@@ -394,7 +395,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching
context 'when namespace is updated' do
it 'should call ConfigureWorker' do
- expect(ClusterPlatformConfigureWorker).to receive(:perform_async).with(cluster.id).once
+ expect(ClusterConfigureWorker).to receive(:perform_async).with(cluster.id).once
platform.namespace = 'new-namespace'
platform.save
@@ -403,7 +404,7 @@ describe Clusters::Platforms::Kubernetes, :use_clean_rails_memory_store_caching
context 'when namespace is not updated' do
it 'should not call ConfigureWorker' do
- expect(ClusterPlatformConfigureWorker).not_to receive(:perform_async)
+ expect(ClusterConfigureWorker).not_to receive(:perform_async)
platform.username = "new-username"
platform.save
diff --git a/spec/models/concerns/avatarable_spec.rb b/spec/models/concerns/avatarable_spec.rb
index 7d617cb7b19..1ea7f2b9985 100644
--- a/spec/models/concerns/avatarable_spec.rb
+++ b/spec/models/concerns/avatarable_spec.rb
@@ -33,6 +33,43 @@ describe Avatarable do
end
describe '#avatar_path' do
+ context 'with caching enabled', :request_store do
+ let!(:avatar_path) { [relative_url_root, project.avatar.local_url].join }
+ let!(:avatar_url) { [gitlab_host, relative_url_root, project.avatar.local_url].join }
+
+ it 'only calls local_url once' do
+ expect(project.avatar).to receive(:local_url).once.and_call_original
+
+ 2.times do
+ expect(project.avatar_path).to eq(avatar_path)
+ end
+ end
+
+ it 'calls local_url twice for path and URLs' do
+ expect(project.avatar).to receive(:local_url).exactly(2).times.and_call_original
+
+ expect(project.avatar_path(only_path: true)).to eq(avatar_path)
+ expect(project.avatar_path(only_path: false)).to eq(avatar_url)
+ end
+
+ it 'calls local_url twice for different sizes' do
+ expect(project.avatar).to receive(:local_url).exactly(2).times.and_call_original
+
+ expect(project.avatar_path).to eq(avatar_path)
+ expect(project.avatar_path(size: 40)).to eq(avatar_path + "?width=40")
+ end
+
+ it 'handles unpersisted objects' do
+ new_project = build(:project, :with_avatar)
+ path = [relative_url_root, new_project.avatar.local_url].join
+ expect(new_project.avatar).to receive(:local_url).exactly(2).times.and_call_original
+
+ 2.times do
+ expect(new_project.avatar_path).to eq(path)
+ end
+ end
+ end
+
using RSpec::Parameterized::TableSyntax
where(:has_asset_host, :visibility_level, :only_path, :avatar_path_prefix) do
diff --git a/spec/models/concerns/cacheable_attributes_spec.rb b/spec/models/concerns/cacheable_attributes_spec.rb
index 827fbc9d7d5..689e7d3058f 100644
--- a/spec/models/concerns/cacheable_attributes_spec.rb
+++ b/spec/models/concerns/cacheable_attributes_spec.rb
@@ -20,6 +20,10 @@ describe CacheableAttributes do
@_last ||= new('foo' => 'a', 'bar' => 'b')
end
+ def self.column_names
+ %w[foo bar baz]
+ end
+
attr_accessor :attributes
def initialize(attrs = {}, *)
@@ -75,13 +79,13 @@ describe CacheableAttributes do
context 'without any attributes given' do
it 'intializes a new object with the defaults' do
- expect(minimal_test_class.build_from_defaults.attributes).to eq(minimal_test_class.defaults)
+ expect(minimal_test_class.build_from_defaults.attributes).to eq(minimal_test_class.defaults.stringify_keys)
end
end
context 'with attributes given' do
it 'intializes a new object with the given attributes merged into the defaults' do
- expect(minimal_test_class.build_from_defaults(foo: 'd').attributes[:foo]).to eq('d')
+ expect(minimal_test_class.build_from_defaults(foo: 'd').attributes['foo']).to eq('d')
end
end
diff --git a/spec/models/concerns/discussion_on_diff_spec.rb b/spec/models/concerns/discussion_on_diff_spec.rb
index 73eb7a1160d..4b16e6e3902 100644
--- a/spec/models/concerns/discussion_on_diff_spec.rb
+++ b/spec/models/concerns/discussion_on_diff_spec.rb
@@ -50,11 +50,17 @@ describe DiscussionOnDiff do
end
context "when the diff line does not exist on a legacy diff note" do
+ subject { create(:legacy_diff_note_on_merge_request).to_discussion }
+
it "returns an empty array" do
- legacy_note = LegacyDiffNote.new
+ expect(truncated_lines).to eq([])
+ end
+ end
- allow(subject).to receive(:first_note).and_return(legacy_note)
+ context 'when the discussion is on an image' do
+ subject { create(:image_diff_note_on_merge_request).to_discussion }
+ it 'returns an empty array' do
expect(truncated_lines).to eq([])
end
end
diff --git a/spec/models/diff_note_spec.rb b/spec/models/diff_note_spec.rb
index 40ce8ab736a..fda00a693f0 100644
--- a/spec/models/diff_note_spec.rb
+++ b/spec/models/diff_note_spec.rb
@@ -337,24 +337,9 @@ describe DiffNote do
end
describe "image diff notes" do
- let(:path) { "files/images/any_image.png" }
-
- let!(:position) do
- Gitlab::Diff::Position.new(
- old_path: path,
- new_path: path,
- width: 10,
- height: 10,
- x: 1,
- y: 1,
- diff_refs: merge_request.diff_refs,
- position_type: "image"
- )
- end
+ subject { build(:image_diff_note_on_merge_request, project: project, noteable: merge_request) }
describe "validations" do
- subject { build(:diff_note_on_merge_request, project: project, position: position, noteable: merge_request) }
-
it { is_expected.not_to validate_presence_of(:line_code) }
it "does not validate diff line" do
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 6793d4e8718..4cc3a6a3644 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -559,6 +559,57 @@ describe MergeRequest do
end
end
+ describe '#preload_discussions_diff_highlight' do
+ let(:merge_request) { create(:merge_request) }
+
+ context 'with commit diff note' do
+ let(:other_merge_request) { create(:merge_request) }
+
+ let!(:diff_note) do
+ create(:diff_note_on_commit, project: merge_request.project)
+ end
+
+ let!(:other_mr_diff_note) do
+ create(:diff_note_on_commit, project: other_merge_request.project)
+ end
+
+ it 'preloads diff highlighting' do
+ expect_next_instance_of(Gitlab::DiscussionsDiff::FileCollection) do |collection|
+ note_diff_file = diff_note.note_diff_file
+
+ expect(collection)
+ .to receive(:load_highlight)
+ .with([note_diff_file.id]).and_call_original
+ end
+
+ merge_request.preload_discussions_diff_highlight
+ end
+ end
+
+ context 'with merge request diff note' do
+ let!(:unresolved_diff_note) do
+ create(:diff_note_on_merge_request, project: merge_request.project, noteable: merge_request)
+ end
+
+ let!(:resolved_diff_note) do
+ create(:diff_note_on_merge_request, :resolved, project: merge_request.project, noteable: merge_request)
+ end
+
+ it 'preloads diff highlighting' do
+ expect_next_instance_of(Gitlab::DiscussionsDiff::FileCollection) do |collection|
+ note_diff_file = unresolved_diff_note.note_diff_file
+
+ expect(collection)
+ .to receive(:load_highlight)
+ .with([note_diff_file.id])
+ .and_call_original
+ end
+
+ merge_request.preload_discussions_diff_highlight
+ end
+ end
+ end
+
describe '#diff_size' do
let(:merge_request) do
build(:merge_request, source_branch: 'expand-collapse-files', target_branch: 'master')
diff --git a/spec/models/milestone_spec.rb b/spec/models/milestone_spec.rb
index d11eb46159e..b3d31e65c85 100644
--- a/spec/models/milestone_spec.rb
+++ b/spec/models/milestone_spec.rb
@@ -316,6 +316,15 @@ describe Milestone do
end
end
+ describe '#reference_link_text' do
+ let(:project) { build_stubbed(:project, name: 'sample-project') }
+ let(:milestone) { build_stubbed(:milestone, iid: 1, project: project, name: 'milestone') }
+
+ it 'returns the title with the reference prefix' do
+ expect(milestone.reference_link_text).to eq '%milestone'
+ end
+ end
+
describe '#participants' do
let(:project) { build(:project, name: 'sample-project') }
let(:milestone) { build(:milestone, iid: 1, project: project) }
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 18b54cce834..475fbe56e4d 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -337,32 +337,40 @@ describe Namespace do
end
end
- it 'updates project full path in .git/config for each project inside namespace' do
- parent = create(:group, name: 'mygroup', path: 'mygroup')
- subgroup = create(:group, name: 'mysubgroup', path: 'mysubgroup', parent: parent)
- project_in_parent_group = create(:project, :legacy_storage, :repository, namespace: parent, name: 'foo1')
- hashed_project_in_subgroup = create(:project, :repository, namespace: subgroup, name: 'foo2')
- legacy_project_in_subgroup = create(:project, :legacy_storage, :repository, namespace: subgroup, name: 'foo3')
-
- parent.update(path: 'mygroup_new')
-
- # Routes are loaded when creating the projects, so we need to manually
- # reload them for the below code to be aware of the above UPDATE.
- [
- project_in_parent_group,
- hashed_project_in_subgroup,
- legacy_project_in_subgroup
- ].each do |project|
- project.route.reload
+ context 'for each project inside the namespace' do
+ let!(:parent) { create(:group, name: 'mygroup', path: 'mygroup') }
+ let!(:subgroup) { create(:group, name: 'mysubgroup', path: 'mysubgroup', parent: parent) }
+ let!(:project_in_parent_group) { create(:project, :legacy_storage, :repository, namespace: parent, name: 'foo1') }
+ let!(:hashed_project_in_subgroup) { create(:project, :repository, namespace: subgroup, name: 'foo2') }
+ let!(:legacy_project_in_subgroup) { create(:project, :legacy_storage, :repository, namespace: subgroup, name: 'foo3') }
+
+ it 'updates project full path in .git/config' do
+ parent.update(path: 'mygroup_new')
+
+ expect(project_rugged(project_in_parent_group).config['gitlab.fullpath']).to eq "mygroup_new/#{project_in_parent_group.path}"
+ expect(project_rugged(hashed_project_in_subgroup).config['gitlab.fullpath']).to eq "mygroup_new/mysubgroup/#{hashed_project_in_subgroup.path}"
+ expect(project_rugged(legacy_project_in_subgroup).config['gitlab.fullpath']).to eq "mygroup_new/mysubgroup/#{legacy_project_in_subgroup.path}"
end
- expect(project_rugged(project_in_parent_group).config['gitlab.fullpath']).to eq "mygroup_new/#{project_in_parent_group.path}"
- expect(project_rugged(hashed_project_in_subgroup).config['gitlab.fullpath']).to eq "mygroup_new/mysubgroup/#{hashed_project_in_subgroup.path}"
- expect(project_rugged(legacy_project_in_subgroup).config['gitlab.fullpath']).to eq "mygroup_new/mysubgroup/#{legacy_project_in_subgroup.path}"
- end
+ it 'updates the project storage location' do
+ repository_project_in_parent_group = create(:project_repository, project: project_in_parent_group)
+ repository_hashed_project_in_subgroup = create(:project_repository, project: hashed_project_in_subgroup)
+ repository_legacy_project_in_subgroup = create(:project_repository, project: legacy_project_in_subgroup)
+
+ parent.update(path: 'mygroup_moved')
+
+ expect(repository_project_in_parent_group.reload.disk_path).to eq "mygroup_moved/#{project_in_parent_group.path}"
+ expect(repository_hashed_project_in_subgroup.reload.disk_path).to eq hashed_project_in_subgroup.disk_path
+ expect(repository_legacy_project_in_subgroup.reload.disk_path).to eq "mygroup_moved/mysubgroup/#{legacy_project_in_subgroup.path}"
+ end
+
+ def project_rugged(project)
+ # Routes are loaded when creating the projects, so we need to manually
+ # reload them for the below code to be aware of the above UPDATE.
+ project.route.reload
- def project_rugged(project)
- rugged_repo(project.repository)
+ rugged_repo(project.repository)
+ end
end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 5e63f14b720..a01f76a5bab 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -145,25 +145,10 @@ describe Project do
end
describe 'ci_pipelines association' do
- context 'when feature flag pipeline_ci_sources_only is enabled' do
- it 'returns only pipelines from ci_sources' do
- stub_feature_flags(pipeline_ci_sources_only: true)
+ it 'returns only pipelines from ci_sources' do
+ expect(Ci::Pipeline).to receive(:ci_sources).and_call_original
- expect(Ci::Pipeline).to receive(:ci_sources).and_call_original
-
- subject.ci_pipelines
- end
- end
-
- context 'when feature flag pipeline_ci_sources_only is disabled' do
- it 'returns all pipelines' do
- stub_feature_flags(pipeline_ci_sources_only: false)
-
- expect(Ci::Pipeline).not_to receive(:ci_sources).and_call_original
- expect(Ci::Pipeline).to receive(:all).and_call_original.at_least(:once)
-
- subject.ci_pipelines
- end
+ subject.ci_pipelines
end
end
end
@@ -1666,26 +1651,54 @@ describe Project do
end
describe '#track_project_repository' do
- let(:project) { create(:project, :repository) }
+ shared_examples 'tracks storage location' do
+ context 'when a project repository entry does not exist' do
+ it 'creates a new entry' do
+ expect { project.track_project_repository }.to change(project, :project_repository)
+ end
+
+ it 'tracks the project storage location' do
+ project.track_project_repository
+
+ expect(project.project_repository).to have_attributes(
+ disk_path: project.disk_path,
+ shard_name: project.repository_storage
+ )
+ end
+ end
+
+ context 'when a tracking entry exists' do
+ let!(:project_repository) { create(:project_repository, project: project) }
+ let!(:shard) { create(:shard, name: 'foo') }
+
+ it 'does not create a new entry in the database' do
+ expect { project.track_project_repository }.not_to change(project, :project_repository)
+ end
+
+ it 'updates the project storage location' do
+ allow(project).to receive(:disk_path).and_return('fancy/new/path')
+ allow(project).to receive(:repository_storage).and_return('foo')
- it 'creates a project_repository' do
- project.track_project_repository
+ project.track_project_repository
- expect(project.reload.project_repository).to be_present
- expect(project.project_repository.disk_path).to eq(project.disk_path)
- expect(project.project_repository.shard_name).to eq(project.repository_storage)
+ expect(project.project_repository).to have_attributes(
+ disk_path: 'fancy/new/path',
+ shard_name: 'foo'
+ )
+ end
+ end
end
- it 'updates the project_repository' do
- project.track_project_repository
+ context 'with projects on legacy storage' do
+ let(:project) { create(:project, :repository, :legacy_storage) }
- allow(project).to receive(:disk_path).and_return('@fancy/new/path')
+ it_behaves_like 'tracks storage location'
+ end
- expect do
- project.track_project_repository
- end.not_to change(ProjectRepository, :count)
+ context 'with projects on hashed storage' do
+ let(:project) { create(:project, :repository) }
- expect(project.reload.project_repository.disk_path).to eq(project.disk_path)
+ it_behaves_like 'tracks storage location'
end
end
@@ -3690,7 +3703,7 @@ describe Project do
expect(project.badges.count).to eq 3
end
- if Group.supports_nested_groups?
+ if Group.supports_nested_objects?
context 'with nested_groups' do
let(:parent_group) { create(:group) }
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 8b3021113bc..33842e74b92 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -1966,7 +1966,7 @@ describe User do
subject { user.membership_groups }
- if Group.supports_nested_groups?
+ if Group.supports_nested_objects?
it { is_expected.to contain_exactly parent_group, child_group }
else
it { is_expected.to contain_exactly parent_group }
@@ -2347,7 +2347,7 @@ describe User do
group.add_owner(user)
end
- if Group.supports_nested_groups?
+ if Group.supports_nested_objects?
it 'returns all groups' do
is_expected.to match_array [
group,
diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb
index 9d0093e8159..baf21efa75c 100644
--- a/spec/policies/group_policy_spec.rb
+++ b/spec/policies/group_policy_spec.rb
@@ -147,7 +147,7 @@ describe GroupPolicy do
let(:current_user) { owner }
it do
- allow(Group).to receive(:supports_nested_groups?).and_return(true)
+ allow(Group).to receive(:supports_nested_objects?).and_return(true)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
@@ -161,7 +161,7 @@ describe GroupPolicy do
let(:current_user) { admin }
it do
- allow(Group).to receive(:supports_nested_groups?).and_return(true)
+ allow(Group).to receive(:supports_nested_objects?).and_return(true)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
@@ -173,7 +173,7 @@ describe GroupPolicy do
describe 'when nested group support feature is disabled' do
before do
- allow(Group).to receive(:supports_nested_groups?).and_return(false)
+ allow(Group).to receive(:supports_nested_objects?).and_return(false)
end
context 'admin' do
@@ -282,7 +282,7 @@ describe GroupPolicy do
let(:current_user) { owner }
it do
- allow(Group).to receive(:supports_nested_groups?).and_return(true)
+ allow(Group).to receive(:supports_nested_objects?).and_return(true)
expect_allowed(*guest_permissions)
expect_allowed(*reporter_permissions)
diff --git a/spec/requests/api/branches_spec.rb b/spec/requests/api/branches_spec.rb
index 93c411476bb..b38cd66986f 100644
--- a/spec/requests/api/branches_spec.rb
+++ b/spec/requests/api/branches_spec.rb
@@ -20,6 +20,12 @@ describe API::Branches do
let(:route) { "/projects/#{project_id}/repository/branches" }
shared_examples_for 'repository branches' do
+ RSpec::Matchers.define :has_merged_branch_names_count do |expected|
+ match do |actual|
+ actual[:merged_branch_names].count == expected
+ end
+ end
+
it 'returns the repository branches' do
get api(route, current_user), params: { per_page: 100 }
@@ -30,6 +36,12 @@ describe API::Branches do
expect(branch_names).to match_array(project.repository.branch_names)
end
+ it 'determines only a limited number of merged branch names' do
+ expect(API::Entities::Branch).to receive(:represent).with(anything, has_merged_branch_names_count(2))
+
+ get api(route, current_user), params: { per_page: 2 }
+ end
+
context 'when repository is disabled' do
include_context 'disabled repository'
diff --git a/spec/requests/api/events_spec.rb b/spec/requests/api/events_spec.rb
index 8c58ba45ce9..0ac23505de7 100644
--- a/spec/requests/api/events_spec.rb
+++ b/spec/requests/api/events_spec.rb
@@ -226,7 +226,7 @@ describe API::Events do
end
it 'correctly returns the second page without inaccessible events' do
- get api("/projects/#{public_project.id}/events", user), per_page: 2, page: 2
+ get api("/projects/#{public_project.id}/events", user), params: { per_page: 2, page: 2 }
titles = json_response.map { |event| event['target_title'] }
@@ -235,7 +235,7 @@ describe API::Events do
end
it 'correctly returns the first page without inaccessible events' do
- get api("/projects/#{public_project.id}/events", user), per_page: 2, page: 1
+ get api("/projects/#{public_project.id}/events", user), params: { per_page: 2, page: 1 }
titles = json_response.map { |event| event['target_title'] }
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index e6d82448c0d..0ba1f2d7a2b 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -54,7 +54,7 @@ describe API::Files do
describe "HEAD /projects/:id/repository/files/:file_path" do
shared_examples_for 'repository files' do
it 'returns file attributes in headers' do
- head api(route(file_path), current_user), params
+ head api(route(file_path), current_user), params: params
expect(response).to have_gitlab_http_status(200)
expect(response.headers['X-Gitlab-File-Path']).to eq(CGI.unescape(file_path))
@@ -68,7 +68,7 @@ describe API::Files do
file_path = "files%2Fjs%2Fcommit%2Ejs%2Ecoffee"
params[:ref] = "6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9"
- head api(route(file_path), current_user), params
+ head api(route(file_path), current_user), params: params
expect(response).to have_gitlab_http_status(200)
expect(response.headers['X-Gitlab-File-Name']).to eq('commit.js.coffee')
@@ -87,7 +87,7 @@ describe API::Files do
it "responds with a 404 status" do
params[:ref] = 'master'
- head api(route('app%2Fmodels%2Fapplication%2Erb'), current_user), params
+ head api(route('app%2Fmodels%2Fapplication%2Erb'), current_user), params: params
expect(response).to have_gitlab_http_status(404)
end
@@ -97,7 +97,7 @@ describe API::Files do
include_context 'disabled repository'
it "responds with a 403 status" do
- head api(route(file_path), current_user), params
+ head api(route(file_path), current_user), params: params
expect(response).to have_gitlab_http_status(403)
end
@@ -115,7 +115,7 @@ describe API::Files do
it "responds with a 404 status" do
current_user = nil
- head api(route(file_path), current_user), params
+ head api(route(file_path), current_user), params: params
expect(response).to have_gitlab_http_status(404)
end
@@ -136,7 +136,7 @@ describe API::Files do
context 'when authenticated', 'as a guest' do
it_behaves_like '403 response' do
- let(:request) { head api(route(file_path), guest), params }
+ let(:request) { head api(route(file_path), guest), params: params }
end
end
end
diff --git a/spec/requests/api/jobs_spec.rb b/spec/requests/api/jobs_spec.rb
index 73131dba542..97aa71bf231 100644
--- a/spec/requests/api/jobs_spec.rb
+++ b/spec/requests/api/jobs_spec.rb
@@ -142,10 +142,20 @@ describe API::Jobs do
end
context 'unauthorized user' do
- let(:api_user) { nil }
+ context 'when user is not logged in' do
+ let(:api_user) { nil }
- it 'does not return project jobs' do
- expect(response).to have_gitlab_http_status(401)
+ it 'does not return project jobs' do
+ expect(response).to have_gitlab_http_status(401)
+ end
+ end
+
+ context 'when user is guest' do
+ let(:api_user) { guest }
+
+ it 'does not return project jobs' do
+ expect(response).to have_gitlab_http_status(403)
+ end
end
end
@@ -241,10 +251,20 @@ describe API::Jobs do
end
context 'unauthorized user' do
- let(:api_user) { nil }
+ context 'when user is not logged in' do
+ let(:api_user) { nil }
- it 'does not return jobs' do
- expect(response).to have_gitlab_http_status(401)
+ it 'does not return jobs' do
+ expect(response).to have_gitlab_http_status(401)
+ end
+ end
+
+ context 'when user is guest' do
+ let(:api_user) { guest }
+
+ it 'does not return jobs' do
+ expect(response).to have_gitlab_http_status(403)
+ end
end
end
end
diff --git a/spec/requests/openid_connect_spec.rb b/spec/requests/openid_connect_spec.rb
index ec546db335a..2b148c1b563 100644
--- a/spec/requests/openid_connect_spec.rb
+++ b/spec/requests/openid_connect_spec.rb
@@ -104,7 +104,7 @@ describe 'OpenID Connect requests' do
expect(json_response).to match(id_token_claims.merge(user_info_claims))
expected_groups = [group1.full_path, group3.full_path]
- expected_groups << group4.full_path if Group.supports_nested_groups?
+ expected_groups << group4.full_path if Group.supports_nested_objects?
expect(json_response['groups']).to match_array(expected_groups)
end
diff --git a/spec/requests/rack_attack_global_spec.rb b/spec/requests/rack_attack_global_spec.rb
index c27e27d3648..49021f5d1b7 100644
--- a/spec/requests/rack_attack_global_spec.rb
+++ b/spec/requests/rack_attack_global_spec.rb
@@ -345,7 +345,7 @@ describe 'Rack Attack global throttles' do
end
def api_get_args_with_token_headers(partial_url, token_headers)
- ["/api/#{API::API.version}#{partial_url}", nil, token_headers]
+ ["/api/#{API::API.version}#{partial_url}", params: nil, headers: token_headers]
end
def rss_url(user)
diff --git a/spec/serializers/entity_date_helper_spec.rb b/spec/serializers/entity_date_helper_spec.rb
index 36da8d33a44..ae0f917415c 100644
--- a/spec/serializers/entity_date_helper_spec.rb
+++ b/spec/serializers/entity_date_helper_spec.rb
@@ -50,7 +50,7 @@ describe EntityDateHelper do
end
context 'when less than 31 days remaining' do
- let(:milestone_remaining) { date_helper_class.remaining_days_in_words(build_stubbed(:milestone, due_date: 12.days.from_now.utc)) }
+ let(:milestone_remaining) { date_helper_class.remaining_days_in_words(12.days.from_now.utc.to_date) }
it 'returns days remaining' do
expect(milestone_remaining).to eq("<strong>12</strong> days remaining")
@@ -58,7 +58,7 @@ describe EntityDateHelper do
end
context 'when less than 1 year and more than 30 days remaining' do
- let(:milestone_remaining) { date_helper_class.remaining_days_in_words(build_stubbed(:milestone, due_date: 2.months.from_now.utc)) }
+ let(:milestone_remaining) { date_helper_class.remaining_days_in_words(2.months.from_now.utc.to_date) }
it 'returns months remaining' do
expect(milestone_remaining).to eq("<strong>2</strong> months remaining")
@@ -66,7 +66,7 @@ describe EntityDateHelper do
end
context 'when more than 1 year remaining' do
- let(:milestone_remaining) { date_helper_class.remaining_days_in_words(build_stubbed(:milestone, due_date: (1.year.from_now + 2.days).utc)) }
+ let(:milestone_remaining) { date_helper_class.remaining_days_in_words((1.year.from_now + 2.days).utc.to_date) }
it 'returns years remaining' do
expect(milestone_remaining).to eq("<strong>1</strong> year remaining")
@@ -74,7 +74,7 @@ describe EntityDateHelper do
end
context 'when milestone is expired' do
- let(:milestone_remaining) { date_helper_class.remaining_days_in_words(build_stubbed(:milestone, due_date: 2.days.ago.utc)) }
+ let(:milestone_remaining) { date_helper_class.remaining_days_in_words(2.days.ago.utc.to_date) }
it 'returns "Past due"' do
expect(milestone_remaining).to eq("<strong>Past due</strong>")
@@ -82,7 +82,7 @@ describe EntityDateHelper do
end
context 'when milestone has start_date in the future' do
- let(:milestone_remaining) { date_helper_class.remaining_days_in_words(build_stubbed(:milestone, start_date: 2.days.from_now.utc)) }
+ let(:milestone_remaining) { date_helper_class.remaining_days_in_words(nil, 2.days.from_now.utc.to_date) }
it 'returns "Upcoming"' do
expect(milestone_remaining).to eq("<strong>Upcoming</strong>")
@@ -90,7 +90,7 @@ describe EntityDateHelper do
end
context 'when milestone has start_date in the past' do
- let(:milestone_remaining) { date_helper_class.remaining_days_in_words(build_stubbed(:milestone, start_date: 2.days.ago.utc)) }
+ let(:milestone_remaining) { date_helper_class.remaining_days_in_words(nil, 2.days.ago.utc.to_date) }
it 'returns days elapsed' do
expect(milestone_remaining).to eq("<strong>2</strong> days elapsed")
diff --git a/spec/serializers/environment_entity_spec.rb b/spec/serializers/environment_entity_spec.rb
index b7324a26ed2..791b64dc356 100644
--- a/spec/serializers/environment_entity_spec.rb
+++ b/spec/serializers/environment_entity_spec.rb
@@ -40,4 +40,34 @@ describe EnvironmentEntity do
expect(subject).to include(:metrics_path)
end
end
+
+ context 'with deployment platform' do
+ let(:project) { create(:project, :repository) }
+ let(:environment) { create(:environment, project: project) }
+
+ context 'when deployment platform is a cluster' do
+ before do
+ create(:cluster,
+ :provided_by_gcp,
+ :project,
+ environment_scope: '*',
+ projects: [project])
+ end
+
+ it 'should include cluster_type' do
+ expect(subject).to include(:cluster_type)
+ expect(subject[:cluster_type]).to eq('project_type')
+ end
+ end
+
+ context 'when deployment platform is a Kubernetes Service' do
+ before do
+ create(:kubernetes_service, project: project)
+ end
+
+ it 'should not include cluster_type' do
+ expect(subject).not_to include(:cluster_type)
+ end
+ end
+ end
end
diff --git a/spec/serializers/issue_serializer_spec.rb b/spec/serializers/issue_serializer_spec.rb
index e8c46c0cdee..b8255e004d0 100644
--- a/spec/serializers/issue_serializer_spec.rb
+++ b/spec/serializers/issue_serializer_spec.rb
@@ -20,11 +20,19 @@ describe IssueSerializer do
context 'sidebar issue serialization' do
let(:serializer) { 'sidebar' }
- it 'matches sidebar issue json schema' do
+ it 'matches issue_sidebar json schema' do
expect(json_entity).to match_schema('entities/issue_sidebar')
end
end
+ context 'sidebar extras issue serialization' do
+ let(:serializer) { 'sidebar_extras' }
+
+ it 'matches issue_sidebar_extras json schema' do
+ expect(json_entity).to match_schema('entities/issue_sidebar_extras')
+ end
+ end
+
context 'board issue serialization' do
let(:serializer) { 'board' }
diff --git a/spec/serializers/merge_request_basic_serializer_spec.rb b/spec/serializers/merge_request_basic_serializer_spec.rb
deleted file mode 100644
index 1fad8e6bc5d..00000000000
--- a/spec/serializers/merge_request_basic_serializer_spec.rb
+++ /dev/null
@@ -1,16 +0,0 @@
-require 'spec_helper'
-
-describe MergeRequestBasicSerializer do
- let(:resource) { create(:merge_request) }
- let(:user) { create(:user) }
-
- let(:json_entity) do
- described_class.new(current_user: user)
- .represent(resource, serializer: 'basic')
- .with_indifferent_access
- end
-
- it 'matches basic merge request json' do
- expect(json_entity).to match_schema('entities/merge_request_basic')
- end
-end
diff --git a/spec/serializers/merge_request_serializer_spec.rb b/spec/serializers/merge_request_serializer_spec.rb
index b259cb92962..276e0f6ff3d 100644
--- a/spec/serializers/merge_request_serializer_spec.rb
+++ b/spec/serializers/merge_request_serializer_spec.rb
@@ -20,8 +20,16 @@ describe MergeRequestSerializer do
context 'sidebar merge request serialization' do
let(:serializer) { 'sidebar' }
- it 'matches basic merge request json schema' do
- expect(json_entity).to match_schema('entities/merge_request_basic')
+ it 'matches merge_request_sidebar json schema' do
+ expect(json_entity).to match_schema('entities/merge_request_sidebar')
+ end
+ end
+
+ context 'sidebar_extras merge request serialization' do
+ let(:serializer) { 'sidebar_extras' }
+
+ it 'matches merge_request_sidebar_extras json schema' do
+ expect(json_entity).to match_schema('entities/merge_request_sidebar_extras')
end
end
diff --git a/spec/services/ci/register_job_service_spec.rb b/spec/services/ci/register_job_service_spec.rb
index 56e2a405bcd..9d65ac15213 100644
--- a/spec/services/ci/register_job_service_spec.rb
+++ b/spec/services/ci/register_job_service_spec.rb
@@ -244,7 +244,9 @@ module Ci
context 'when first build is stalled' do
before do
- pending_job.update(lock_version: 0)
+ allow_any_instance_of(Ci::RegisterJobService).to receive(:assign_runner!).and_call_original
+ allow_any_instance_of(Ci::RegisterJobService).to receive(:assign_runner!)
+ .with(pending_job, anything).and_raise(ActiveRecord::StaleObjectError)
end
subject { described_class.new(specific_runner).execute }
diff --git a/spec/services/clusters/gcp/finalize_creation_service_spec.rb b/spec/services/clusters/gcp/finalize_creation_service_spec.rb
index d69678c1277..2664649df47 100644
--- a/spec/services/clusters/gcp/finalize_creation_service_spec.rb
+++ b/spec/services/clusters/gcp/finalize_creation_service_spec.rb
@@ -20,7 +20,7 @@ describe Clusters::Gcp::FinalizeCreationService, '#execute' do
subject { described_class.new.execute(provider) }
before do
- allow(ClusterPlatformConfigureWorker).to receive(:perform_async)
+ allow(ClusterConfigureWorker).to receive(:perform_async)
end
shared_examples 'success' do
@@ -43,8 +43,8 @@ describe Clusters::Gcp::FinalizeCreationService, '#execute' do
expect(platform.token).to eq(token)
end
- it 'calls ClusterPlatformConfigureWorker in a ascync fashion' do
- expect(ClusterPlatformConfigureWorker).to receive(:perform_async).with(cluster.id)
+ it 'calls ClusterConfigureWorker in a ascync fashion' do
+ expect(ClusterConfigureWorker).to receive(:perform_async).with(cluster.id)
subject
end
diff --git a/spec/services/clusters/update_service_spec.rb b/spec/services/clusters/update_service_spec.rb
index 73f9be242a3..b2e6ebecd4a 100644
--- a/spec/services/clusters/update_service_spec.rb
+++ b/spec/services/clusters/update_service_spec.rb
@@ -37,7 +37,7 @@ describe Clusters::UpdateService do
end
before do
- allow(ClusterPlatformConfigureWorker).to receive(:perform_async)
+ allow(ClusterConfigureWorker).to receive(:perform_async)
stub_kubeclient_get_namespace('https://kubernetes.example.com', namespace: 'my-namespace')
end
diff --git a/spec/services/groups/create_service_spec.rb b/spec/services/groups/create_service_spec.rb
index 224e933bebc..fe6a8691ae0 100644
--- a/spec/services/groups/create_service_spec.rb
+++ b/spec/services/groups/create_service_spec.rb
@@ -55,7 +55,7 @@ describe Groups::CreateService, '#execute' do
context 'when nested groups feature is disabled' do
it 'does not save group and returns an error' do
- allow(Group).to receive(:supports_nested_groups?).and_return(false)
+ allow(Group).to receive(:supports_nested_objects?).and_return(false)
is_expected.not_to be_persisted
expect(subject.errors[:parent_id]).to include('You don’t have permission to create a subgroup in this group.')
@@ -66,7 +66,7 @@ describe Groups::CreateService, '#execute' do
context 'when nested groups feature is enabled' do
before do
- allow(Group).to receive(:supports_nested_groups?).and_return(true)
+ allow(Group).to receive(:supports_nested_objects?).and_return(true)
end
context 'as guest' do
diff --git a/spec/services/groups/nested_create_service_spec.rb b/spec/services/groups/nested_create_service_spec.rb
index 86fdd43c1e5..75d6ddb0a2c 100644
--- a/spec/services/groups/nested_create_service_spec.rb
+++ b/spec/services/groups/nested_create_service_spec.rb
@@ -30,7 +30,7 @@ describe Groups::NestedCreateService do
let(:params) { { group_path: 'a-group' } }
before do
- allow(Group).to receive(:supports_nested_groups?) { false }
+ allow(Group).to receive(:supports_nested_objects?) { false }
end
it 'creates the group' do
diff --git a/spec/services/groups/transfer_service_spec.rb b/spec/services/groups/transfer_service_spec.rb
index dd8a1cee074..6b48c993c57 100644
--- a/spec/services/groups/transfer_service_spec.rb
+++ b/spec/services/groups/transfer_service_spec.rb
@@ -9,7 +9,7 @@ describe Groups::TransferService, :postgresql do
shared_examples 'ensuring allowed transfer for a group' do
context 'with other database than PostgreSQL' do
before do
- allow(Group).to receive(:supports_nested_groups?).and_return(false)
+ allow(Group).to receive(:supports_nested_objects?).and_return(false)
end
it 'should return false' do
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 68ac3a00ab0..d20e712d365 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -2250,7 +2250,7 @@ describe NotificationService, :mailer do
# Creates a nested group only if supported
# to avoid errors on MySQL
def create_nested_group
- if Group.supports_nested_groups?
+ if Group.supports_nested_objects?
parent_group = create(:group, :public)
child_group = create(:group, :public, parent: parent_group)
@@ -2277,7 +2277,7 @@ describe NotificationService, :mailer do
end
def add_member_for_parent_group(user, project)
- return unless Group.supports_nested_groups?
+ return unless Group.supports_nested_objects?
project.reload
@@ -2285,13 +2285,13 @@ describe NotificationService, :mailer do
end
def should_email_nested_group_user(user, times: 1, recipients: email_recipients)
- return unless Group.supports_nested_groups?
+ return unless Group.supports_nested_objects?
should_email(user, times: 1, recipients: email_recipients)
end
def should_not_email_nested_group_user(user, recipients: email_recipients)
- return unless Group.supports_nested_groups?
+ return unless Group.supports_nested_objects?
should_not_email(user, recipients: email_recipients)
end
diff --git a/spec/services/projects/after_rename_service_spec.rb b/spec/services/projects/after_rename_service_spec.rb
index b4718a07204..59c08b30f9f 100644
--- a/spec/services/projects/after_rename_service_spec.rb
+++ b/spec/services/projects/after_rename_service_spec.rb
@@ -99,6 +99,17 @@ describe Projects::AfterRenameService do
expect(rugged_config['gitlab.fullpath']).to eq(project.full_path)
end
+
+ it 'updates storage location' do
+ allow(project_storage).to receive(:rename_repo).and_return(true)
+
+ described_class.new(project).execute
+
+ expect(project.project_repository).to have_attributes(
+ disk_path: project.disk_path,
+ shard_name: project.repository_storage
+ )
+ end
end
context 'using hashed storage' do
@@ -193,6 +204,15 @@ describe Projects::AfterRenameService do
expect(rugged_config['gitlab.fullpath']).to eq(project.full_path)
end
+
+ it 'updates storage location' do
+ described_class.new(project).execute
+
+ expect(project.project_repository).to have_attributes(
+ disk_path: project.disk_path,
+ shard_name: project.repository_storage
+ )
+ end
end
end
end
diff --git a/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb b/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb
index d7d7f1874eb..95c9b6e63b8 100644
--- a/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb
+++ b/spec/services/projects/lfs_pointers/lfs_download_service_spec.rb
@@ -4,17 +4,15 @@ describe Projects::LfsPointers::LfsDownloadService do
let(:project) { create(:project) }
let(:oid) { '9e548e25631dd9ce6b43afd6359ab76da2819d6a5b474e66118c7819e1d8b3e8' }
let(:download_link) { "http://gitlab.com/#{oid}" }
- let(:lfs_content) do
- <<~HEREDOC
- whatever
- HEREDOC
- end
+ let(:lfs_content) { SecureRandom.random_bytes(10) }
subject { described_class.new(project) }
before do
allow(project).to receive(:lfs_enabled?).and_return(true)
WebMock.stub_request(:get, download_link).to_return(body: lfs_content)
+
+ allow(Gitlab::CurrentSettings).to receive(:allow_local_requests_from_hooks_and_services?).and_return(false)
end
describe '#execute' do
@@ -32,7 +30,7 @@ describe Projects::LfsPointers::LfsDownloadService do
it 'stores the content' do
subject.execute(oid, download_link)
- expect(File.read(LfsObject.first.file.file.file)).to eq lfs_content
+ expect(File.binread(LfsObject.first.file.file.file)).to eq lfs_content
end
end
@@ -54,18 +52,61 @@ describe Projects::LfsPointers::LfsDownloadService do
end
end
+ context 'when localhost requests are allowed' do
+ let(:download_link) { 'http://192.168.2.120' }
+
+ before do
+ allow(Gitlab::CurrentSettings).to receive(:allow_local_requests_from_hooks_and_services?).and_return(true)
+ end
+
+ it 'downloads the file' do
+ expect(subject).to receive(:download_and_save_file).and_call_original
+
+ expect { subject.execute(oid, download_link) }.to change { LfsObject.count }.by(1)
+ end
+ end
+
context 'when a bad URL is used' do
- where(download_link: ['/etc/passwd', 'ftp://example.com', 'http://127.0.0.2'])
+ where(download_link: ['/etc/passwd', 'ftp://example.com', 'http://127.0.0.2', 'http://192.168.2.120'])
with_them do
it 'does not download the file' do
- expect(subject).not_to receive(:download_and_save_file)
-
expect { subject.execute(oid, download_link) }.not_to change { LfsObject.count }
end
end
end
+ context 'when the URL points to a redirected URL' do
+ context 'that is blocked' do
+ where(redirect_link: ['ftp://example.com', 'http://127.0.0.2', 'http://192.168.2.120'])
+
+ with_them do
+ before do
+ WebMock.stub_request(:get, download_link).to_return(status: 301, headers: { 'Location' => redirect_link })
+ end
+
+ it 'does not follow the redirection' do
+ expect(Rails.logger).to receive(:error).with(/LFS file with oid #{oid} couldn't be downloaded/)
+
+ expect { subject.execute(oid, download_link) }.not_to change { LfsObject.count }
+ end
+ end
+ end
+
+ context 'that is valid' do
+ let(:redirect_link) { "http://example.com/"}
+
+ before do
+ WebMock.stub_request(:get, download_link).to_return(status: 301, headers: { 'Location' => redirect_link })
+ WebMock.stub_request(:get, redirect_link).to_return(body: lfs_content)
+ end
+
+ it 'follows the redirection' do
+ expect { subject.execute(oid, download_link) }.to change { LfsObject.count }.from(0).to(1)
+ end
+ end
+ end
+
context 'when an lfs object with the same oid already exists' do
before do
create(:lfs_object, oid: 'oid')
diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb
index 132ad9a2646..766276fdba3 100644
--- a/spec/services/projects/transfer_service_spec.rb
+++ b/spec/services/projects/transfer_service_spec.rb
@@ -63,6 +63,15 @@ describe Projects::TransferService do
expect(rugged_config['gitlab.fullpath']).to eq "#{group.full_path}/#{project.path}"
end
+ it 'updates storage location' do
+ transfer_project(project, user, group)
+
+ expect(project.project_repository).to have_attributes(
+ disk_path: "#{group.full_path}/#{project.path}",
+ shard_name: project.repository_storage
+ )
+ end
+
context 'new group has a kubernetes cluster' do
let(:group_cluster) { create(:cluster, :group, :provided_by_gcp) }
let(:group) { group_cluster.group }
@@ -139,6 +148,17 @@ describe Projects::TransferService do
expect(service).not_to receive(:execute_system_hooks)
end
end
+
+ it 'does not update storage location' do
+ create(:project_repository, project: project)
+
+ attempt_project_transfer
+
+ expect(project.project_repository).to have_attributes(
+ disk_path: project.disk_path,
+ shard_name: project.repository_storage
+ )
+ end
end
context 'namespace -> no namespace' do
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index fb3421b61d3..89357056c93 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -216,15 +216,19 @@ RSpec.configure do |config|
# Each example may call `migrate!`, so we must ensure we are migrated down every time
config.before(:each, :migration) do
+ use_fake_application_settings
+
schema_migrate_down!
end
config.after(:context, :migration) do
schema_migrate_up!
+
+ Gitlab::CurrentSettings.clear_in_memory_application_settings!
end
config.around(:each, :nested_groups) do |example|
- example.run if Group.supports_nested_groups?
+ example.run if Group.supports_nested_objects?
end
config.around(:each, :postgresql) do |example|
diff --git a/spec/support/api/boards_shared_examples.rb b/spec/support/api/boards_shared_examples.rb
index 943c1f6ffd7..592962ebf7c 100644
--- a/spec/support/api/boards_shared_examples.rb
+++ b/spec/support/api/boards_shared_examples.rb
@@ -88,7 +88,7 @@ shared_examples_for 'group and project boards' do |route_definition, ee = false|
let(:url) { "#{root_url}/#{board.id}/lists" }
it 'creates a new issue board list for labels' do
- post api(url, user), label_id: ux_label.id
+ post api(url, user), params: { label_id: ux_label.id }
expect(response).to have_gitlab_http_status(201)
expect(json_response['label']['name']).to eq(ux_label.title)
@@ -96,13 +96,13 @@ shared_examples_for 'group and project boards' do |route_definition, ee = false|
end
it 'returns 400 when creating a new list if label_id is invalid' do
- post api(url, user), label_id: 23423
+ post api(url, user), params: { label_id: 23423 }
expect(response).to have_gitlab_http_status(400)
end
it 'returns 403 for members with guest role' do
- put api("#{url}/#{test_list.id}", guest), position: 1
+ put api("#{url}/#{test_list.id}", guest), params: { position: 1 }
expect(response).to have_gitlab_http_status(403)
end
@@ -112,23 +112,20 @@ shared_examples_for 'group and project boards' do |route_definition, ee = false|
let(:url) { "#{root_url}/#{board.id}/lists" }
it "updates a list" do
- put api("#{url}/#{test_list.id}", user),
- position: 1
+ put api("#{url}/#{test_list.id}", user), params: { position: 1 }
expect(response).to have_gitlab_http_status(200)
expect(json_response['position']).to eq(1)
end
it "returns 404 error if list id not found" do
- put api("#{url}/44444", user),
- position: 1
+ put api("#{url}/44444", user), params: { position: 1 }
expect(response).to have_gitlab_http_status(404)
end
it "returns 403 for members with guest role" do
- put api("#{url}/#{test_list.id}", guest),
- position: 1
+ put api("#{url}/#{test_list.id}", guest), params: { position: 1 }
expect(response).to have_gitlab_http_status(403)
end
diff --git a/spec/support/api/milestones_shared_examples.rb b/spec/support/api/milestones_shared_examples.rb
index 3bebb7aae90..5f709831ce1 100644
--- a/spec/support/api/milestones_shared_examples.rb
+++ b/spec/support/api/milestones_shared_examples.rb
@@ -45,7 +45,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'returns an array of milestones specified by iids' do
other_milestone = create(:milestone, project: try(:project), group: try(:group))
- get api(route, user), iids: [closed_milestone.iid, other_milestone.iid]
+ get api(route, user), params: { iids: [closed_milestone.iid, other_milestone.iid] }
expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
@@ -54,7 +54,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
end
it 'does not return any milestone if none found' do
- get api(route, user), iids: [Milestone.maximum(:iid).succ]
+ get api(route, user), params: { iids: [Milestone.maximum(:iid).succ] }
expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
@@ -73,7 +73,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
end
it 'returns a milestone by searching for title' do
- get api(route, user), search: 'version2'
+ get api(route, user), params: { search: 'version2' }
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
@@ -83,7 +83,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
end
it 'returns a milestones by searching for description' do
- get api(route, user), search: 'open'
+ get api(route, user), params: { search: 'open' }
expect(response).to have_gitlab_http_status(200)
expect(response).to include_pagination_headers
@@ -117,7 +117,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
describe "POST #{route_definition}" do
it 'creates a new milestone' do
- post api(route, user), title: 'new milestone'
+ post api(route, user), params: { title: 'new milestone' }
expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('new milestone')
@@ -125,8 +125,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
end
it 'creates a new milestone with description and dates' do
- post api(route, user),
- title: 'new milestone', description: 'release', due_date: '2013-03-02', start_date: '2013-02-02'
+ post api(route, user), params: { title: 'new milestone', description: 'release', due_date: '2013-03-02', start_date: '2013-02-02' }
expect(response).to have_gitlab_http_status(201)
expect(json_response['description']).to eq('release')
@@ -141,14 +140,13 @@ shared_examples_for 'group and project milestones' do |route_definition|
end
it 'returns a 400 error if params are invalid (duplicate title)' do
- post api(route, user),
- title: milestone.title, description: 'release', due_date: '2013-03-02'
+ post api(route, user), params: { title: milestone.title, description: 'release', due_date: '2013-03-02' }
expect(response).to have_gitlab_http_status(400)
end
it 'creates a new milestone with reserved html characters' do
- post api(route, user), title: 'foo & bar 1.1 -> 2.2'
+ post api(route, user), params: { title: 'foo & bar 1.1 -> 2.2' }
expect(response).to have_gitlab_http_status(201)
expect(json_response['title']).to eq('foo & bar 1.1 -> 2.2')
@@ -158,8 +156,7 @@ shared_examples_for 'group and project milestones' do |route_definition|
describe "PUT #{route_definition}/:milestone_id" do
it 'updates a milestone' do
- put api(resource_route, user),
- title: 'updated title'
+ put api(resource_route, user), params: { title: 'updated title' }
expect(response).to have_gitlab_http_status(200)
expect(json_response['title']).to eq('updated title')
@@ -168,29 +165,27 @@ shared_examples_for 'group and project milestones' do |route_definition|
it 'removes a due date if nil is passed' do
milestone.update!(due_date: "2016-08-05")
- put api(resource_route, user), due_date: nil
+ put api(resource_route, user), params: { due_date: nil }
expect(response).to have_gitlab_http_status(200)
expect(json_response['due_date']).to be_nil
end
it 'returns a 404 error if milestone id not found' do
- put api("#{route}/1234", user),
- title: 'updated title'
+ put api("#{route}/1234", user), params: { title: 'updated title' }
expect(response).to have_gitlab_http_status(404)
end
it 'closes milestone' do
- put api(resource_route, user),
- state_event: 'close'
+ put api(resource_route, user), params: { state_event: 'close' }
expect(response).to have_gitlab_http_status(200)
expect(json_response['state']).to eq('closed')
end
it 'updates milestone with only start date' do
- put api(resource_route, user), start_date: Date.tomorrow
+ put api(resource_route, user), params: { start_date: Date.tomorrow }
expect(response).to have_gitlab_http_status(200)
end
diff --git a/spec/support/api/scopes/read_user_shared_examples.rb b/spec/support/api/scopes/read_user_shared_examples.rb
index d7cef137989..683234264a8 100644
--- a/spec/support/api/scopes/read_user_shared_examples.rb
+++ b/spec/support/api/scopes/read_user_shared_examples.rb
@@ -77,7 +77,7 @@ shared_examples_for 'does not allow the "read_user" scope' do
let(:token) { create(:personal_access_token, scopes: ['read_user'], user: user) }
it 'returns a "403" response' do
- post api_call.call(path, user, personal_access_token: token), attributes_for(:user, projects_limit: 3)
+ post api_call.call(path, user, personal_access_token: token), params: attributes_for(:user, projects_limit: 3)
expect(response).to have_gitlab_http_status(403)
end
diff --git a/spec/support/api/time_tracking_shared_examples.rb b/spec/support/api/time_tracking_shared_examples.rb
index fee464c15a3..e883d33f671 100644
--- a/spec/support/api/time_tracking_shared_examples.rb
+++ b/spec/support/api/time_tracking_shared_examples.rb
@@ -7,13 +7,13 @@ shared_examples 'time tracking endpoints' do |issuable_name|
describe "POST /projects/:id/#{issuable_collection_name}/:#{issuable_name}_id/time_estimate" do
context 'with an unauthorized user' do
- subject { post(api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", non_member), duration: '1w') }
+ subject { post(api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", non_member), params: { duration: '1w' }) }
it_behaves_like 'an unauthorized API user'
end
it "sets the time estimate for #{issuable_name}" do
- post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), duration: '1w'
+ post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), params: { duration: '1w' }
expect(response).to have_gitlab_http_status(200)
expect(json_response['human_time_estimate']).to eq('1w')
@@ -21,12 +21,12 @@ shared_examples 'time tracking endpoints' do |issuable_name|
describe 'updating the current estimate' do
before do
- post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), duration: '1w'
+ post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), params: { duration: '1w' }
end
context 'when duration has a bad format' do
it 'does not modify the original estimate' do
- post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), duration: 'foo'
+ post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), params: { duration: 'foo' }
expect(response).to have_gitlab_http_status(400)
expect(issuable.reload.human_time_estimate).to eq('1w')
@@ -35,7 +35,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
context 'with a valid duration' do
it 'updates the estimate' do
- post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), duration: '3w1h'
+ post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/time_estimate", user), params: { duration: '3w1h' }
expect(response).to have_gitlab_http_status(200)
expect(issuable.reload.human_time_estimate).to eq('3w 1h')
@@ -62,8 +62,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
describe "POST /projects/:id/#{issuable_collection_name}/:#{issuable_name}_id/add_spent_time" do
context 'with an unauthorized user' do
subject do
- post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", non_member),
- duration: '2h'
+ post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", non_member), params: { duration: '2h' }
end
it_behaves_like 'an unauthorized API user'
@@ -72,8 +71,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
it "add spent time for #{issuable_name}" do
Timecop.travel(1.minute.from_now) do
expect do
- post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user),
- duration: '2h'
+ post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '2h' }
end.to change { issuable.reload.updated_at }
end
@@ -89,8 +87,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
end.to change { issuable.reload.updated_at }
end
- post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user),
- duration: '-1h'
+ post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '-1h' }
expect(response).to have_gitlab_http_status(201)
expect(json_response['total_time_spent']).to eq(3600)
@@ -103,8 +100,7 @@ shared_examples 'time tracking endpoints' do |issuable_name|
Timecop.travel(1.minute.from_now) do
expect do
- post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user),
- duration: '-1w'
+ post api("/projects/#{project.id}/#{issuable_collection_name}/#{issuable.iid}/add_spent_time", user), params: { duration: '-1w' }
end.not_to change { issuable.reload.updated_at }
end
diff --git a/spec/support/controllers/githubish_import_controller_shared_examples.rb b/spec/support/controllers/githubish_import_controller_shared_examples.rb
index 140490f2dc2..697f999e4c4 100644
--- a/spec/support/controllers/githubish_import_controller_shared_examples.rb
+++ b/spec/support/controllers/githubish_import_controller_shared_examples.rb
@@ -17,7 +17,7 @@ shared_examples 'a GitHub-ish import controller: POST personal_access_token' do
allow_any_instance_of(Gitlab::LegacyGithubImport::Client)
.to receive(:user).and_return(true)
- post :personal_access_token, personal_access_token: token
+ post :personal_access_token, params: { personal_access_token: token }
expect(session[:"#{provider}_access_token"]).to eq(token)
expect(controller).to redirect_to(status_import_url)
@@ -29,7 +29,7 @@ shared_examples 'a GitHub-ish import controller: POST personal_access_token' do
allow_any_instance_of(Gitlab::LegacyGithubImport::Client)
.to receive(:user).and_return(true)
- post :personal_access_token, personal_access_token: " #{token} "
+ post :personal_access_token, params: { personal_access_token: " #{token} " }
expect(session[:"#{provider}_access_token"]).to eq(token)
expect(controller).to redirect_to(status_import_url)
@@ -214,7 +214,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
expect(Gitlab::LegacyGithubImport::ProjectCreator)
.to receive(:new).and_return(double(execute: project))
- expect { post :create, target_namespace: provider_repo.name, format: :json }.to change(Namespace, :count).by(1)
+ expect { post :create, params: { target_namespace: provider_repo.name }, format: :json }.to change(Namespace, :count).by(1)
end
it "takes the new namespace" do
@@ -222,7 +222,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
.to receive(:new).with(provider_repo, provider_repo.name, an_instance_of(Group), user, access_params, type: provider)
.and_return(double(execute: project))
- post :create, target_namespace: provider_repo.name, format: :json
+ post :create, params: { target_namespace: provider_repo.name }, format: :json
end
end
@@ -261,7 +261,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
.to receive(:new).with(provider_repo, test_name, test_namespace, user, access_params, type: provider)
.and_return(double(execute: project))
- post :create, { target_namespace: test_namespace.name, new_name: test_name, format: :json }
+ post :create, params: { target_namespace: test_namespace.name, new_name: test_name }, format: :json
end
it 'takes the selected name and default namespace' do
@@ -269,7 +269,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
.to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider)
.and_return(double(execute: project))
- post :create, { new_name: test_name, format: :json }
+ post :create, params: { new_name: test_name }, format: :json
end
end
@@ -288,7 +288,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
.to receive(:new).with(provider_repo, test_name, nested_namespace, user, access_params, type: provider)
.and_return(double(execute: project))
- post :create, { target_namespace: nested_namespace.full_path, new_name: test_name, format: :json }
+ post :create, params: { target_namespace: nested_namespace.full_path, new_name: test_name }, format: :json
end
end
@@ -300,7 +300,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
.to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider)
.and_return(double(execute: project))
- post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :json }
+ post :create, params: { target_namespace: 'foo/bar', new_name: test_name }, format: :json
end
it 'creates the namespaces' do
@@ -308,7 +308,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
.to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider)
.and_return(double(execute: project))
- expect { post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :json } }
+ expect { post :create, params: { target_namespace: 'foo/bar', new_name: test_name }, format: :json }
.to change { Namespace.count }.by(2)
end
@@ -317,7 +317,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
.to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider)
.and_return(double(execute: project))
- post :create, { target_namespace: 'foo/bar', new_name: test_name, format: :json }
+ post :create, params: { target_namespace: 'foo/bar', new_name: test_name }, format: :json
expect(Namespace.find_by_path_or_name('bar').parent.path).to eq('foo')
end
@@ -336,7 +336,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
.to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider)
.and_return(double(execute: project))
- post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :json }
+ post :create, params: { target_namespace: 'foo/foobar/bar', new_name: test_name }, format: :json
end
it 'creates the namespaces' do
@@ -344,7 +344,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
.to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider)
.and_return(double(execute: project))
- expect { post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :json } }
+ expect { post :create, params: { target_namespace: 'foo/foobar/bar', new_name: test_name }, format: :json }
.to change { Namespace.count }.by(2)
end
@@ -353,7 +353,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
.to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider)
.and_return(double(execute: build_stubbed(:project)))
- expect { post :create, { target_namespace: "#{user.namespace_path}/test_group", new_name: test_name, format: :js } }
+ expect { post :create, params: { target_namespace: "#{user.namespace_path}/test_group", new_name: test_name }, format: :js }
.not_to change { Namespace.count }
end
end
@@ -367,7 +367,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
.to receive(:new).with(provider_repo, test_name, user.namespace, user, access_params, type: provider)
.and_return(double(execute: build_stubbed(:project)))
- post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :js }
+ post :create, params: { target_namespace: 'foo/foobar/bar', new_name: test_name }, format: :js
end
it 'does not create the namespaces' do
@@ -375,7 +375,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
.to receive(:new).with(provider_repo, test_name, kind_of(Namespace), user, access_params, type: provider)
.and_return(double(execute: build_stubbed(:project)))
- expect { post :create, { target_namespace: 'foo/foobar/bar', new_name: test_name, format: :js } }
+ expect { post :create, params: { target_namespace: 'foo/foobar/bar', new_name: test_name }, format: :js }
.not_to change { Namespace.count }
end
end
@@ -392,7 +392,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
.to receive(:new).with(provider_repo, test_name, group, user, access_params, type: provider)
.and_return(double(execute: build_stubbed(:project)))
- post :create, { target_namespace: 'foo', new_name: test_name, format: :js }
+ post :create, params: { target_namespace: 'foo', new_name: test_name }, format: :js
end
end
@@ -400,7 +400,7 @@ shared_examples 'a GitHub-ish import controller: POST create' do
it 'returns 422 response' do
other_namespace = create(:group, name: 'other_namespace')
- post :create, { target_namespace: other_namespace.name, format: :json }
+ post :create, params: { target_namespace: other_namespace.name }, format: :json
expect(response).to have_gitlab_http_status(422)
end
diff --git a/spec/support/features/variable_list_shared_examples.rb b/spec/support/features/variable_list_shared_examples.rb
index bce1fb01355..0a464d77cb7 100644
--- a/spec/support/features/variable_list_shared_examples.rb
+++ b/spec/support/features/variable_list_shared_examples.rb
@@ -63,6 +63,52 @@ shared_examples 'variable list' do
end
end
+ context 'defaults to the application setting' do
+ context 'application setting is true' do
+ before do
+ stub_application_setting(protected_ci_variables: true)
+
+ visit page_path
+ end
+
+ it 'defaults to protected' do
+ page.within('.js-ci-variable-list-section .js-row:last-child') do
+ find('.js-ci-variable-input-key').set('key')
+ end
+
+ values = all('.js-ci-variable-input-protected', visible: false).map(&:value)
+
+ expect(values).to eq %w(false true true)
+ end
+
+ it 'shows a message regarding the changed default' do
+ expect(page).to have_content 'Environment variables are configured by your administrator to be protected by default'
+ end
+ end
+
+ context 'application setting is false' do
+ before do
+ stub_application_setting(protected_ci_variables: false)
+
+ visit page_path
+ end
+
+ it 'defaults to unprotected' do
+ page.within('.js-ci-variable-list-section .js-row:last-child') do
+ find('.js-ci-variable-input-key').set('key')
+ end
+
+ values = all('.js-ci-variable-input-protected', visible: false).map(&:value)
+
+ expect(values).to eq %w(false false false)
+ end
+
+ it 'does not show a message regarding the default' do
+ expect(page).not_to have_content 'Environment variables are configured by your administrator to be protected by default'
+ end
+ end
+ end
+
it 'reveals and hides variables' do
page.within('.js-ci-variable-list-section') do
expect(first('.js-ci-variable-input-key').value).to eq(variable.key)
diff --git a/spec/support/helpers/git_http_helpers.rb b/spec/support/helpers/git_http_helpers.rb
index 9a5845af90c..cd49bb148f2 100644
--- a/spec/support/helpers/git_http_helpers.rb
+++ b/spec/support/helpers/git_http_helpers.rb
@@ -1,18 +1,18 @@
module GitHttpHelpers
def clone_get(project, options = {})
- get "/#{project}/info/refs", { service: 'git-upload-pack' }, auth_env(*options.values_at(:user, :password, :spnego_request_token))
+ get "/#{project}/info/refs", params: { service: 'git-upload-pack' }, headers: auth_env(*options.values_at(:user, :password, :spnego_request_token))
end
def clone_post(project, options = {})
- post "/#{project}/git-upload-pack", {}, auth_env(*options.values_at(:user, :password, :spnego_request_token))
+ post "/#{project}/git-upload-pack", headers: auth_env(*options.values_at(:user, :password, :spnego_request_token))
end
def push_get(project, options = {})
- get "/#{project}/info/refs", { service: 'git-receive-pack' }, auth_env(*options.values_at(:user, :password, :spnego_request_token))
+ get "/#{project}/info/refs", params: { service: 'git-receive-pack' }, headers: auth_env(*options.values_at(:user, :password, :spnego_request_token))
end
def push_post(project, options = {})
- post "/#{project}/git-receive-pack", {}, auth_env(*options.values_at(:user, :password, :spnego_request_token))
+ post "/#{project}/git-receive-pack", headers: auth_env(*options.values_at(:user, :password, :spnego_request_token))
end
def download(project, user: nil, password: nil, spnego_request_token: nil)
diff --git a/spec/support/helpers/graphql_helpers.rb b/spec/support/helpers/graphql_helpers.rb
index 75827df80dc..dd32ea3985f 100644
--- a/spec/support/helpers/graphql_helpers.rb
+++ b/spec/support/helpers/graphql_helpers.rb
@@ -107,7 +107,7 @@ module GraphqlHelpers
end
def post_graphql(query, current_user: nil, variables: nil)
- post api('/', current_user, version: 'graphql'), query: query, variables: variables
+ post api('/', current_user, version: 'graphql'), params: { query: query, variables: variables }
end
def post_graphql_mutation(mutation, current_user: nil)
diff --git a/spec/support/helpers/kubernetes_helpers.rb b/spec/support/helpers/kubernetes_helpers.rb
index 39bd305d88a..e7d97561bfc 100644
--- a/spec/support/helpers/kubernetes_helpers.rb
+++ b/spec/support/helpers/kubernetes_helpers.rb
@@ -58,6 +58,11 @@ module KubernetesHelpers
.to_return(status: [status, "Internal Server Error"])
end
+ def stub_kubeclient_get_service_account(api_url, name, namespace: 'default')
+ WebMock.stub_request(:get, api_url + "/api/v1/namespaces/#{namespace}/serviceaccounts/#{name}")
+ .to_return(kube_response({}))
+ end
+
def stub_kubeclient_get_service_account_error(api_url, name, namespace: 'default', status: 404)
WebMock.stub_request(:get, api_url + "/api/v1/namespaces/#{namespace}/serviceaccounts/#{name}")
.to_return(status: [status, "Internal Server Error"])
@@ -73,6 +78,11 @@ module KubernetesHelpers
.to_return(status: [500, "Internal Server Error"])
end
+ def stub_kubeclient_put_service_account(api_url, name, namespace: 'default')
+ WebMock.stub_request(:put, api_url + "/api/v1/namespaces/#{namespace}/serviceaccounts/#{name}")
+ .to_return(kube_response({}))
+ end
+
def stub_kubeclient_create_secret(api_url, namespace: 'default')
WebMock.stub_request(:post, api_url + "/api/v1/namespaces/#{namespace}/secrets")
.to_return(kube_response({}))
@@ -93,6 +103,11 @@ module KubernetesHelpers
.to_return(kube_response({}))
end
+ def stub_kubeclient_get_role_binding(api_url, name, namespace: 'default')
+ WebMock.stub_request(:get, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{name}")
+ .to_return(kube_response({}))
+ end
+
def stub_kubeclient_get_role_binding_error(api_url, name, namespace: 'default', status: 404)
WebMock.stub_request(:get, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{name}")
.to_return(status: [status, "Internal Server Error"])
@@ -103,6 +118,11 @@ module KubernetesHelpers
.to_return(kube_response({}))
end
+ def stub_kubeclient_put_role_binding(api_url, name, namespace: 'default')
+ WebMock.stub_request(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{name}")
+ .to_return(kube_response({}))
+ end
+
def stub_kubeclient_create_namespace(api_url)
WebMock.stub_request(:post, api_url + "/api/v1/namespaces")
.to_return(kube_response({}))
diff --git a/spec/support/helpers/migrations_helpers.rb b/spec/support/helpers/migrations_helpers.rb
index 5887c3eab74..cc1a28cb264 100644
--- a/spec/support/helpers/migrations_helpers.rb
+++ b/spec/support/helpers/migrations_helpers.rb
@@ -62,6 +62,22 @@ module MigrationsHelpers
klass.reset_column_information
end
+ # In some migration tests, we're using factories to create records,
+ # however those models might be depending on a schema version which
+ # doesn't have the columns we want in application_settings.
+ # In these cases, we'll need to use the fake application settings
+ # as if we have migrations pending
+ def use_fake_application_settings
+ # We stub this way because we can't stub on
+ # `current_application_settings` due to `method_missing` is
+ # depending on current_application_settings...
+ allow(ActiveRecord::Base.connection)
+ .to receive(:active?)
+ .and_return(false)
+
+ stub_env('IN_MEMORY_APPLICATION_SETTINGS', 'false')
+ end
+
def previous_migration
migrations.each_cons(2) do |previous, migration|
break previous if migration.name == described_class.name
diff --git a/spec/support/import_export/export_file_helper.rb b/spec/support/import_export/export_file_helper.rb
index a49036c3b80..ac320934f5a 100644
--- a/spec/support/import_export/export_file_helper.rb
+++ b/spec/support/import_export/export_file_helper.rb
@@ -133,6 +133,6 @@ module ExportFileHelper
end
def file_permissions(file)
- File.stat(file).mode & 0777
+ File.lstat(file).mode & 0777
end
end
diff --git a/spec/support/issuables_requiring_filter_shared_examples.rb b/spec/support/issuables_requiring_filter_shared_examples.rb
index 439ef5ed92e..71bcc82ee58 100644
--- a/spec/support/issuables_requiring_filter_shared_examples.rb
+++ b/spec/support/issuables_requiring_filter_shared_examples.rb
@@ -10,6 +10,6 @@ shared_examples 'issuables requiring filter' do |action|
it "loads issuables if at least one filter is set" do
expect_any_instance_of(described_class).to receive(:issuables_collection).and_call_original
- get action, author_id: user.id
+ get action, params: { author_id: user.id }
end
end
diff --git a/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb b/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb
index 7088fb1e5fb..59708173716 100644
--- a/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb
+++ b/spec/support/shared_examples/controllers/uploads_actions_shared_examples.rb
@@ -8,8 +8,7 @@ shared_examples 'handle uploads' do
describe "POST #create" do
context 'when a user is not authorized to upload a file' do
it 'returns 404 status' do
- post :create, params.merge(file: jpg, format: :json)
-
+ post :create, params: params.merge(file: jpg), format: :json
expect(response.status).to eq(404)
end
end
@@ -22,7 +21,7 @@ shared_examples 'handle uploads' do
context "without params['file']" do
it "returns an error" do
- post :create, params.merge(format: :json)
+ post :create, params: params, format: :json
expect(response).to have_gitlab_http_status(422)
end
@@ -30,7 +29,7 @@ shared_examples 'handle uploads' do
context 'with valid image' do
before do
- post :create, params.merge(file: jpg, format: :json)
+ post :create, params: params.merge(file: jpg), format: :json
end
it 'returns a content with original filename, new link, and correct type.' do
@@ -54,7 +53,7 @@ shared_examples 'handle uploads' do
context 'with valid non-image file' do
before do
- post :create, params.merge(file: txt, format: :json)
+ post :create, params: params.merge(file: txt), format: :json
end
it 'returns a content with original filename, new link, and correct type.' do
@@ -67,7 +66,7 @@ shared_examples 'handle uploads' do
describe "GET #show" do
let(:show_upload) do
- get :show, params.merge(secret: secret, filename: "rails_sample.jpg")
+ get :show, params: params.merge(secret: secret, filename: "rails_sample.jpg")
end
before do
diff --git a/spec/support/shared_examples/milestone_tabs_examples.rb b/spec/support/shared_examples/milestone_tabs_examples.rb
index 70b499198bf..8b757586941 100644
--- a/spec/support/shared_examples/milestone_tabs_examples.rb
+++ b/spec/support/shared_examples/milestone_tabs_examples.rb
@@ -10,7 +10,7 @@ shared_examples 'milestone tabs' do
{ namespace_id: project.namespace.to_param, project_id: project, id: milestone.iid }
end
- get path, params.merge(extra_params)
+ get path, params: params.merge(extra_params)
end
describe '#merge_requests' do
diff --git a/spec/support/shared_examples/requests/api/diff_discussions.rb b/spec/support/shared_examples/requests/api/diff_discussions.rb
index 85a4bd8ca27..366c2955359 100644
--- a/spec/support/shared_examples/requests/api/diff_discussions.rb
+++ b/spec/support/shared_examples/requests/api/diff_discussions.rb
@@ -27,7 +27,8 @@ shared_examples 'diff discussions API' do |parent_type, noteable_type, id_name|
it "creates a new diff note" do
position = diff_note.position.to_h
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user), body: 'hi!', position: position
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user),
+ params: { body: 'hi!', position: position }
expect(response).to have_gitlab_http_status(201)
expect(json_response['notes'].first['body']).to eq('hi!')
@@ -38,7 +39,8 @@ shared_examples 'diff discussions API' do |parent_type, noteable_type, id_name|
it "returns a 400 bad request error when position is invalid" do
position = diff_note.position.to_h.merge(new_line: '100000')
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user), body: 'hi!', position: position
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user),
+ params: { body: 'hi!', position: position }
expect(response).to have_gitlab_http_status(400)
end
@@ -47,7 +49,7 @@ shared_examples 'diff discussions API' do |parent_type, noteable_type, id_name|
describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions/:discussion_id/notes" do
it 'adds a new note to the diff discussion' do
post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "discussions/#{diff_note.discussion_id}/notes", user), body: 'hi!'
+ "discussions/#{diff_note.discussion_id}/notes", user), params: { body: 'hi!' }
expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq('hi!')
diff --git a/spec/support/shared_examples/requests/api/discussions.rb b/spec/support/shared_examples/requests/api/discussions.rb
index b6aeb30d69c..e44da4faa5a 100644
--- a/spec/support/shared_examples/requests/api/discussions.rb
+++ b/spec/support/shared_examples/requests/api/discussions.rb
@@ -42,7 +42,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name|
describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions" do
it "creates a new note" do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user), body: 'hi!'
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user), params: { body: 'hi!' }
expect(response).to have_gitlab_http_status(201)
expect(json_response['notes'].first['body']).to eq('hi!')
@@ -56,7 +56,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name|
end
it "returns a 401 unauthorized error if user not authenticated" do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions"), body: 'hi!'
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions"), params: { body: 'hi!' }
expect(response).to have_gitlab_http_status(401)
end
@@ -65,7 +65,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name|
it 'accepts the creation date to be set' do
creation_time = 2.weeks.ago
post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", user),
- body: 'hi!', created_at: creation_time
+ params: { body: 'hi!', created_at: creation_time }
expect(response).to have_gitlab_http_status(201)
expect(json_response['notes'].first['body']).to eq('hi!')
@@ -81,7 +81,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name|
it 'responds with 404' do
post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/discussions", private_user),
- body: 'Foo'
+ params: { body: 'Foo' }
expect(response).to have_gitlab_http_status(404)
end
@@ -91,7 +91,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name|
describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions/:discussion_id/notes" do
it 'adds a new note to the discussion' do
post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "discussions/#{note.discussion_id}/notes", user), body: 'Hello!'
+ "discussions/#{note.discussion_id}/notes", user), params: { body: 'Hello!' }
expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq('Hello!')
@@ -109,7 +109,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name|
note.update_attribute(:type, nil)
post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "discussions/#{note.discussion_id}/notes", user), body: 'hi!'
+ "discussions/#{note.discussion_id}/notes", user), params: { body: 'hi!' }
expect(response).to have_gitlab_http_status(400)
end
@@ -118,7 +118,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name|
describe "PUT /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions/:discussion_id/notes/:note_id" do
it 'returns modified note' do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "discussions/#{note.discussion_id}/notes/#{note.id}", user), body: 'Hello!'
+ "discussions/#{note.discussion_id}/notes/#{note.id}", user), params: { body: 'Hello!' }
expect(response).to have_gitlab_http_status(200)
expect(json_response['body']).to eq('Hello!')
@@ -127,7 +127,7 @@ shared_examples 'discussions API' do |parent_type, noteable_type, id_name|
it 'returns a 404 error when note id not found' do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
"discussions/#{note.discussion_id}/notes/12345", user),
- body: 'Hello!'
+ params: { body: 'Hello!' }
expect(response).to have_gitlab_http_status(404)
end
diff --git a/spec/support/shared_examples/requests/api/merge_requests_list.rb b/spec/support/shared_examples/requests/api/merge_requests_list.rb
index 92d4dd598d5..453f42251c8 100644
--- a/spec/support/shared_examples/requests/api/merge_requests_list.rb
+++ b/spec/support/shared_examples/requests/api/merge_requests_list.rb
@@ -123,7 +123,7 @@ shared_examples 'merge requests list' do
end
it 'returns an empty array if no issue matches milestone' do
- get api(endpoint_path, user), milestone: '1.0.0'
+ get api(endpoint_path, user), params: { milestone: '1.0.0' }
expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
@@ -131,7 +131,7 @@ shared_examples 'merge requests list' do
end
it 'returns an empty array if milestone does not exist' do
- get api(endpoint_path, user), milestone: 'foo'
+ get api(endpoint_path, user), params: { milestone: 'foo' }
expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
@@ -139,7 +139,7 @@ shared_examples 'merge requests list' do
end
it 'returns an array of merge requests in given milestone' do
- get api(endpoint_path, user), milestone: '0.9'
+ get api(endpoint_path, user), params: { milestone: '0.9' }
closed_issues = json_response.select { |mr| mr['id'] == merge_request_closed.id }
expect(closed_issues.length).to eq(1)
@@ -147,7 +147,7 @@ shared_examples 'merge requests list' do
end
it 'returns an array of merge requests matching state in milestone' do
- get api(endpoint_path, user), milestone: '0.9', state: 'closed'
+ get api(endpoint_path, user), params: { milestone: '0.9', state: 'closed' }
expect(response).to have_gitlab_http_status(200)
expect(json_response).to be_an Array
@@ -187,7 +187,7 @@ shared_examples 'merge requests list' do
end
it 'returns an array of merge requests with any label when filtering by any label' do
- get api(endpoint_path, user), labels: IssuesFinder::FILTER_ANY
+ get api(endpoint_path, user), params: { labels: IssuesFinder::FILTER_ANY }
expect_paginated_array_response
expect(json_response.length).to eq(1)
@@ -195,7 +195,7 @@ shared_examples 'merge requests list' do
end
it 'returns an array of merge requests without a label when filtering by no label' do
- get api(endpoint_path, user), labels: IssuesFinder::FILTER_NONE
+ get api(endpoint_path, user), params: { labels: IssuesFinder::FILTER_NONE }
response_ids = json_response.map { |merge_request| merge_request['id'] }
@@ -286,7 +286,7 @@ shared_examples 'merge requests list' do
context 'source_branch param' do
it 'returns merge requests with the given source branch' do
- get api(endpoint_path, user), source_branch: merge_request_closed.source_branch, state: 'all'
+ get api(endpoint_path, user), params: { source_branch: merge_request_closed.source_branch, state: 'all' }
expect_response_contain_exactly(merge_request_closed, merge_request_merged, merge_request_locked)
end
@@ -294,7 +294,7 @@ shared_examples 'merge requests list' do
context 'target_branch param' do
it 'returns merge requests with the given target branch' do
- get api(endpoint_path, user), target_branch: merge_request_closed.target_branch, state: 'all'
+ get api(endpoint_path, user), params: { target_branch: merge_request_closed.target_branch, state: 'all' }
expect_response_contain_exactly(merge_request_closed, merge_request_merged, merge_request_locked)
end
diff --git a/spec/support/shared_examples/requests/api/notes.rb b/spec/support/shared_examples/requests/api/notes.rb
index 0e20dfe0725..71499e85654 100644
--- a/spec/support/shared_examples/requests/api/notes.rb
+++ b/spec/support/shared_examples/requests/api/notes.rb
@@ -86,7 +86,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
describe "POST /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes" do
it "creates a new note" do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), body: 'hi!'
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: { body: 'hi!' }
expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq('hi!')
@@ -100,7 +100,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
end
it "returns a 401 unauthorized error if user not authenticated" do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes"), body: 'hi!'
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes"), params: { body: 'hi!' }
expect(response).to have_gitlab_http_status(401)
end
@@ -108,7 +108,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
it "creates an activity event when a note is created" do
expect(Event).to receive(:create!)
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), body: 'hi!'
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: { body: 'hi!' }
end
context 'setting created_at' do
@@ -118,7 +118,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
context 'by an admin' do
it 'sets the creation time on the new note' do
admin = create(:admin)
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", admin), params
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", admin), params: params
expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq('hi!')
@@ -131,7 +131,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
if parent_type == 'projects'
context 'by a project owner' do
it 'sets the creation time on the new note' do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: params
expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq('hi!')
@@ -149,7 +149,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
parent.update!(namespace: group)
user2.refresh_authorized_projects
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user2), params
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user2), params: params
expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq('hi!')
@@ -161,7 +161,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
elsif parent_type == 'groups'
context 'by a group owner' do
it 'sets the creation time on the new note' do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: params
expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq('hi!')
@@ -176,7 +176,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
it 'ignores the given creation time' do
user2 = create(:user)
parent.add_developer(user2)
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user2), params
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user2), params: params
expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq('hi!')
@@ -190,7 +190,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
context 'when the user is posting an award emoji on a noteable created by someone else' do
it 'creates a new note' do
parent.add_developer(private_user)
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", private_user), body: ':+1:'
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", private_user), params: { body: ':+1:' }
expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq(':+1:')
@@ -199,7 +199,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
context 'when the user is posting an award emoji on his/her own noteable' do
it 'creates a new note' do
- post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), body: ':+1:'
+ post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", user), params: { body: ':+1:' }
expect(response).to have_gitlab_http_status(201)
expect(json_response['body']).to eq(':+1:')
@@ -213,7 +213,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
it 'responds with 404' do
post api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes", private_user),
- body: 'Foo'
+ params: { body: 'Foo' }
expect(response).to have_gitlab_http_status(404)
end
@@ -223,7 +223,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
describe "PUT /#{parent_type}/:id/#{noteable_type}/:noteable_id/notes/:note_id" do
it 'returns modified note' do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "notes/#{note.id}", user), body: 'Hello!'
+ "notes/#{note.id}", user), params: { body: 'Hello!' }
expect(response).to have_gitlab_http_status(200)
expect(json_response['body']).to eq('Hello!')
@@ -231,7 +231,7 @@ shared_examples 'noteable API' do |parent_type, noteable_type, id_name|
it 'returns a 404 error when note id not found' do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/notes/12345", user),
- body: 'Hello!'
+ params: { body: 'Hello!' }
expect(response).to have_gitlab_http_status(404)
end
diff --git a/spec/support/shared_examples/requests/api/resolvable_discussions.rb b/spec/support/shared_examples/requests/api/resolvable_discussions.rb
index 408ad08cc48..7e2416b23f3 100644
--- a/spec/support/shared_examples/requests/api/resolvable_discussions.rb
+++ b/spec/support/shared_examples/requests/api/resolvable_discussions.rb
@@ -2,7 +2,7 @@ shared_examples 'resolvable discussions API' do |parent_type, noteable_type, id_
describe "PUT /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions/:discussion_id" do
it "resolves discussion if resolved is true" do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "discussions/#{note.discussion_id}", user), resolved: true
+ "discussions/#{note.discussion_id}", user), params: { resolved: true }
expect(response).to have_gitlab_http_status(200)
expect(json_response['notes'].size).to eq(1)
@@ -11,7 +11,7 @@ shared_examples 'resolvable discussions API' do |parent_type, noteable_type, id_
it "unresolves discussion if resolved is false" do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "discussions/#{note.discussion_id}", user), resolved: false
+ "discussions/#{note.discussion_id}", user), params: { resolved: false }
expect(response).to have_gitlab_http_status(200)
expect(json_response['notes'].size).to eq(1)
@@ -27,14 +27,14 @@ shared_examples 'resolvable discussions API' do |parent_type, noteable_type, id_
it "returns a 401 unauthorized error if user is not authenticated" do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "discussions/#{note.discussion_id}"), resolved: true
+ "discussions/#{note.discussion_id}"), params: { resolved: true }
expect(response).to have_gitlab_http_status(401)
end
it "returns a 403 error if user resolves discussion of someone else" do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "discussions/#{note.discussion_id}", private_user), resolved: true
+ "discussions/#{note.discussion_id}", private_user), params: { resolved: true }
expect(response).to have_gitlab_http_status(403)
end
@@ -46,7 +46,7 @@ shared_examples 'resolvable discussions API' do |parent_type, noteable_type, id_
it 'responds with 404' do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "discussions/#{note.discussion_id}", private_user), resolved: true
+ "discussions/#{note.discussion_id}", private_user), params: { resolved: true }
expect(response).to have_gitlab_http_status(404)
end
@@ -56,7 +56,7 @@ shared_examples 'resolvable discussions API' do |parent_type, noteable_type, id_
describe "PUT /#{parent_type}/:id/#{noteable_type}/:noteable_id/discussions/:discussion_id/notes/:note_id" do
it 'returns resolved note when resolved parameter is true' do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "discussions/#{note.discussion_id}/notes/#{note.id}", user), resolved: true
+ "discussions/#{note.discussion_id}/notes/#{note.id}", user), params: { resolved: true }
expect(response).to have_gitlab_http_status(200)
expect(json_response['resolved']).to eq(true)
@@ -65,7 +65,7 @@ shared_examples 'resolvable discussions API' do |parent_type, noteable_type, id_
it 'returns a 404 error when note id not found' do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
"discussions/#{note.discussion_id}/notes/12345", user),
- body: 'Hello!'
+ params: { body: 'Hello!' }
expect(response).to have_gitlab_http_status(404)
end
@@ -79,7 +79,7 @@ shared_examples 'resolvable discussions API' do |parent_type, noteable_type, id_
it "returns a 403 error if user resolves note of someone else" do
put api("/#{parent_type}/#{parent.id}/#{noteable_type}/#{noteable[id_name]}/"\
- "discussions/#{note.discussion_id}/notes/#{note.id}", private_user), resolved: true
+ "discussions/#{note.discussion_id}/notes/#{note.id}", private_user), params: { resolved: true }
expect(response).to have_gitlab_http_status(403)
end
diff --git a/spec/views/notify/changed_milestone_email.html.haml_spec.rb b/spec/views/notify/changed_milestone_email.html.haml_spec.rb
new file mode 100644
index 00000000000..194b58840a3
--- /dev/null
+++ b/spec/views/notify/changed_milestone_email.html.haml_spec.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'notify/changed_milestone_email.html.haml' do
+ let(:milestone) { create(:milestone, title: 'some-milestone') }
+ let(:milestone_link) { milestone_url(milestone) }
+
+ before do
+ assign(:milestone, milestone)
+ assign(:milestone_url, milestone_link)
+ end
+
+ context 'milestone without start and due dates' do
+ it 'renders without date range' do
+ render
+
+ expect(rendered).to have_content('Milestone changed to some-milestone', exact: true)
+ expect(rendered).to have_link('some-milestone', href: milestone_link)
+ end
+ end
+
+ context 'milestone with start and due dates' do
+ before do
+ milestone.update(start_date: '2018-01-01', due_date: '2018-12-31')
+ end
+
+ it 'renders with date range' do
+ render
+
+ expect(rendered).to have_content('Milestone changed to some-milestone (Jan 1, 2018–Dec 31, 2018)', exact: true)
+ expect(rendered).to have_link('some-milestone', href: milestone_link)
+ end
+ end
+end
diff --git a/spec/views/projects/merge_requests/show.html.haml_spec.rb b/spec/views/projects/merge_requests/show.html.haml_spec.rb
index fa6c4ce4ac8..b0042be339c 100644
--- a/spec/views/projects/merge_requests/show.html.haml_spec.rb
+++ b/spec/views/projects/merge_requests/show.html.haml_spec.rb
@@ -32,6 +32,11 @@ describe 'projects/merge_requests/show.html.haml' do
assign(:noteable, closed_merge_request)
assign(:notes, [])
assign(:pipelines, Ci::Pipeline.none)
+ assign(
+ :issuable_sidebar,
+ MergeRequestSerializer.new(current_user: user, project: project)
+ .represent(closed_merge_request, serializer: 'sidebar')
+ )
preload_view_requirements
diff --git a/spec/workers/cluster_platform_configure_worker_spec.rb b/spec/workers/cluster_configure_worker_spec.rb
index 0eead0ab13d..6918ee3d7d8 100644
--- a/spec/workers/cluster_platform_configure_worker_spec.rb
+++ b/spec/workers/cluster_configure_worker_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe ClusterPlatformConfigureWorker, '#perform' do
+describe ClusterConfigureWorker, '#perform' do
let(:worker) { described_class.new }
context 'when group cluster' do
diff --git a/spec/workers/cluster_provision_worker_spec.rb b/spec/workers/cluster_provision_worker_spec.rb
index 0a2dfef36a4..da32f29fec0 100644
--- a/spec/workers/cluster_provision_worker_spec.rb
+++ b/spec/workers/cluster_provision_worker_spec.rb
@@ -23,7 +23,7 @@ describe ClusterProvisionWorker do
end
it 'configures kubernetes platform' do
- expect(ClusterPlatformConfigureWorker).to receive(:perform_async).with(cluster.id)
+ expect(ClusterConfigureWorker).to receive(:perform_async).with(cluster.id)
described_class.new.perform(cluster.id)
end
@@ -32,7 +32,7 @@ describe ClusterProvisionWorker do
context 'when cluster does not exist' do
it 'does not provision a cluster' do
expect_any_instance_of(Clusters::Gcp::ProvisionService).not_to receive(:execute)
- expect(ClusterPlatformConfigureWorker).not_to receive(:perform_async)
+ expect(ClusterConfigureWorker).not_to receive(:perform_async)
described_class.new.perform(123)
end