summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorPhil Hughes <me@iamphill.com>2018-04-18 12:59:37 +0100
committerPhil Hughes <me@iamphill.com>2018-04-18 12:59:37 +0100
commitfb3e23b06da10a90149aba0e2dbc3bca04286b0e (patch)
tree48b56085d0792225c41c6076556879bb863bc478 /spec
parent35d280450260bad53022b6022ece7d31b5f4bd1f (diff)
parent9c2f6e04cf5d2eb89d0ec68e8ace87b3804e9ae5 (diff)
downloadgitlab-ce-fb3e23b06da10a90149aba0e2dbc3bca04286b0e.tar.gz
Merge branch 'master' into ide-staged-changes
Diffstat (limited to 'spec')
-rw-r--r--spec/factories/ci/builds.rb1
-rw-r--r--spec/features/ide_spec.rb25
-rw-r--r--spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb17
-rw-r--r--spec/features/projects/clusters/gcp_spec.rb8
-rw-r--r--spec/features/projects/clusters_spec.rb2
-rw-r--r--spec/features/projects/files/user_uploads_files_spec.rb4
-rw-r--r--spec/features/projects/jobs/permissions_spec.rb130
-rw-r--r--spec/features/projects/pipelines/pipelines_spec.rb8
-rw-r--r--spec/fixtures/trace/sample_trace3480
-rw-r--r--spec/javascripts/branches/branches_delete_modal_spec.js40
-rw-r--r--spec/javascripts/ide/components/commit_sidebar/message_field_spec.js174
-rw-r--r--spec/javascripts/ide/components/commit_sidebar/radio_group_spec.js13
-rw-r--r--spec/javascripts/ide/stores/mutations/tree_spec.js10
-rw-r--r--spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js11
-rw-r--r--spec/javascripts/vue_shared/components/commit_spec.js86
-rw-r--r--spec/lib/banzai/object_renderer_spec.rb2
-rw-r--r--spec/lib/gitlab/ci/trace_spec.rb2
-rw-r--r--spec/lib/gitlab/diff/highlight_spec.rb9
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb11
-rw-r--r--spec/lib/gitlab/sentry_spec.rb44
-rw-r--r--spec/lib/gitlab/shell_spec.rb2
-rw-r--r--spec/models/ci/build_spec.rb4
-rw-r--r--spec/models/commit_spec.rb5
-rw-r--r--spec/models/commit_status_spec.rb32
-rw-r--r--spec/models/concerns/cache_markdown_field_spec.rb183
-rw-r--r--spec/models/repository_spec.rb6
-rw-r--r--spec/requests/api/repositories_spec.rb15
-rw-r--r--spec/rubocop/cop/avoid_break_from_strong_memoize_spec.rb74
-rw-r--r--spec/rubocop/cop/avoid_return_from_blocks_spec.rb127
-rw-r--r--spec/services/ci/register_job_service_spec.rb105
-rw-r--r--spec/services/notification_service_spec.rb40
-rw-r--r--spec/services/system_note_service_spec.rb8
-rw-r--r--spec/support/http_io/http_io_helpers.rb3
-rw-r--r--spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb2
-rw-r--r--spec/workers/issue_due_scheduler_worker_spec.rb22
-rw-r--r--spec/workers/mail_scheduler/issue_due_worker_spec.rb21
36 files changed, 3964 insertions, 762 deletions
diff --git a/spec/factories/ci/builds.rb b/spec/factories/ci/builds.rb
index e1fafa71d5c..33de637ff7d 100644
--- a/spec/factories/ci/builds.rb
+++ b/spec/factories/ci/builds.rb
@@ -62,6 +62,7 @@ FactoryBot.define do
end
trait :pending do
+ queued_at 'Di 29. Okt 09:50:59 CET 2013'
status 'pending'
end
diff --git a/spec/features/ide_spec.rb b/spec/features/ide_spec.rb
new file mode 100644
index 00000000000..b3f24c2966d
--- /dev/null
+++ b/spec/features/ide_spec.rb
@@ -0,0 +1,25 @@
+require 'spec_helper'
+
+describe 'IDE', :js do
+ describe 'sub-groups' do
+ let(:user) { create(:user) }
+ let(:group) { create(:group) }
+ let(:subgroup) { create(:group, parent: group) }
+ let(:subgroup_project) { create(:project, :repository, namespace: subgroup) }
+
+ before do
+ subgroup_project.add_master(user)
+ sign_in(user)
+
+ visit project_path(subgroup_project)
+
+ click_link('Web IDE')
+
+ wait_for_requests
+ end
+
+ it 'loads project in web IDE' do
+ expect(page).to have_selector('.context-header', text: subgroup_project.name)
+ end
+ end
+end
diff --git a/spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb b/spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb
index 565e375600b..3b6fffb7abd 100644
--- a/spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb
+++ b/spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb
@@ -27,6 +27,23 @@ describe 'Merge request > User scrolls to note on load', :js do
expect(fragment_position_top).to be < (page_scroll_y + page_height)
end
+ it 'renders un-collapsed notes with diff' do
+ page.current_window.resize_to(1000, 1000)
+
+ visit "#{project_merge_request_path(project, merge_request)}#{fragment_id}"
+
+ page.execute_script "window.scrollTo(0,0)"
+
+ note_element = find(fragment_id)
+ note_container = note_element.ancestor('.js-toggle-container')
+
+ expect(note_element.visible?).to eq true
+
+ page.within note_container do
+ expect(page).not_to have_selector('.js-error-lazy-load-diff')
+ end
+ end
+
it 'expands collapsed notes' do
visit "#{project_merge_request_path(project, merge_request)}#{collapsed_fragment_id}"
note_element = find(collapsed_fragment_id)
diff --git a/spec/features/projects/clusters/gcp_spec.rb b/spec/features/projects/clusters/gcp_spec.rb
index 4d47cdb500c..dfe8e02dce0 100644
--- a/spec/features/projects/clusters/gcp_spec.rb
+++ b/spec/features/projects/clusters/gcp_spec.rb
@@ -33,7 +33,7 @@ feature 'Gcp Cluster', :js do
visit project_clusters_path(project)
click_link 'Add Kubernetes cluster'
- click_link 'Create on GKE'
+ click_link 'Create on Google Kubernetes Engine'
end
context 'when user filled form with valid parameters' do
@@ -139,7 +139,7 @@ feature 'Gcp Cluster', :js do
visit project_clusters_path(project)
click_link 'Add Kubernetes cluster'
- click_link 'Create on GKE'
+ click_link 'Create on Google Kubernetes Engine'
fill_in 'cluster_provider_gcp_attributes_gcp_project_id', with: 'gcp-project-123'
fill_in 'cluster_name', with: 'dev-cluster'
@@ -159,7 +159,7 @@ feature 'Gcp Cluster', :js do
visit project_clusters_path(project)
click_link 'Add Kubernetes cluster'
- click_link 'Create on GKE'
+ click_link 'Create on Google Kubernetes Engine'
fill_in 'cluster_provider_gcp_attributes_gcp_project_id', with: 'gcp-project-123'
fill_in 'cluster_name', with: 'dev-cluster'
@@ -177,7 +177,7 @@ feature 'Gcp Cluster', :js do
visit project_clusters_path(project)
click_link 'Add Kubernetes cluster'
- click_link 'Create on GKE'
+ click_link 'Create on Google Kubernetes Engine'
end
it 'user sees a login page' do
diff --git a/spec/features/projects/clusters_spec.rb b/spec/features/projects/clusters_spec.rb
index bd9f7745cf8..a251a2f4e52 100644
--- a/spec/features/projects/clusters_spec.rb
+++ b/spec/features/projects/clusters_spec.rb
@@ -83,7 +83,7 @@ feature 'Clusters', :js do
visit project_clusters_path(project)
click_link 'Add Kubernetes cluster'
- click_link 'Create on GKE'
+ click_link 'Create on Google Kubernetes Engine'
end
it 'user sees a login page' do
diff --git a/spec/features/projects/files/user_uploads_files_spec.rb b/spec/features/projects/files/user_uploads_files_spec.rb
index 7a1e3a8bcce..8b212faa29d 100644
--- a/spec/features/projects/files/user_uploads_files_spec.rb
+++ b/spec/features/projects/files/user_uploads_files_spec.rb
@@ -7,11 +7,11 @@ describe 'Projects > Files > User uploads files' do
"You're not allowed to make changes to this project directly. "\
"A fork of this project has been created that you can make changes in, so you can submit a merge request."
end
- let(:project) { create(:project, :repository, name: 'Shop') }
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :repository, name: 'Shop', creator: user) }
let(:project2) { create(:project, :repository, name: 'Another Project', path: 'another-project') }
let(:project_tree_path_root_ref) { project_tree_path(project, project.repository.root_ref) }
let(:project2_tree_path_root_ref) { project_tree_path(project2, project2.repository.root_ref) }
- let(:user) { project.creator }
before do
project.add_master(user)
diff --git a/spec/features/projects/jobs/permissions_spec.rb b/spec/features/projects/jobs/permissions_spec.rb
new file mode 100644
index 00000000000..31abadf9bd6
--- /dev/null
+++ b/spec/features/projects/jobs/permissions_spec.rb
@@ -0,0 +1,130 @@
+require 'spec_helper'
+
+describe 'Project Jobs Permissions' do
+ let(:user) { create(:user) }
+ let(:group) { create(:group, name: 'some group') }
+ let(:project) { create(:project, :repository, namespace: group) }
+ let(:pipeline) { create(:ci_empty_pipeline, project: project, sha: project.commit.sha, ref: 'master') }
+ let!(:job) { create(:ci_build, :running, :coverage, :trace_artifact, pipeline: pipeline) }
+
+ before do
+ sign_in(user)
+
+ project.enable_ci
+ end
+
+ describe 'jobs pages' do
+ shared_examples 'recent job page details responds with status' do |status|
+ before do
+ visit project_job_path(project, job)
+ end
+
+ it { expect(status_code).to eq(status) }
+ end
+
+ shared_examples 'project jobs page responds with status' do |status|
+ before do
+ visit project_jobs_path(project)
+ end
+
+ it { expect(status_code).to eq(status) }
+ end
+
+ context 'when public access for jobs is disabled' do
+ before do
+ project.update(public_builds: false)
+ end
+
+ context 'when user is a guest' do
+ before do
+ project.add_guest(user)
+ end
+
+ it_behaves_like 'recent job page details responds with status', 404
+ it_behaves_like 'project jobs page responds with status', 404
+ end
+
+ context 'when project is internal' do
+ before do
+ project.update(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ end
+
+ it_behaves_like 'recent job page details responds with status', 404
+ it_behaves_like 'project jobs page responds with status', 404
+ end
+ end
+
+ context 'when public access for jobs is enabled' do
+ before do
+ project.update(public_builds: true)
+ end
+
+ context 'when project is internal' do
+ before do
+ project.update(visibility_level: Gitlab::VisibilityLevel::INTERNAL)
+ end
+
+ it_behaves_like 'recent job page details responds with status', 200 do
+ it 'renders job details', :js do
+ expect(page).to have_content "Job ##{job.id}"
+ expect(page).to have_css '#build-trace'
+ end
+ end
+
+ it_behaves_like 'project jobs page responds with status', 200 do
+ it 'renders job' do
+ page.within('.build') do
+ expect(page).to have_content("##{job.id}")
+ .and have_content(job.sha[0..7])
+ .and have_content(job.ref)
+ .and have_content(job.name)
+ end
+ end
+ end
+ end
+ end
+ end
+
+ describe 'artifacts page' do
+ context 'when recent job has artifacts available' do
+ before do
+ artifacts = Rails.root.join('spec/fixtures/ci_build_artifacts.zip')
+ archive = fixture_file_upload(artifacts, 'application/zip')
+
+ job.update_attributes(legacy_artifacts_file: archive)
+ end
+
+ context 'when public access for jobs is disabled' do
+ before do
+ project.update(public_builds: false)
+ end
+
+ context 'when user with guest role' do
+ before do
+ project.add_guest(user)
+ end
+
+ it 'responds with 404 status' do
+ visit download_project_job_artifacts_path(project, job)
+
+ expect(status_code).to eq(404)
+ end
+ end
+
+ context 'when user with reporter role' do
+ before do
+ project.add_reporter(user)
+ end
+
+ it 'starts download artifact' do
+ visit download_project_job_artifacts_path(project, job)
+
+ expect(status_code).to eq(200)
+ expect(page.response_headers['Content-Type']).to eq 'application/zip'
+ expect(page.response_headers['Content-Transfer-Encoding']).to eq 'binary'
+ end
+ end
+ end
+ end
+ end
+end
diff --git a/spec/features/projects/pipelines/pipelines_spec.rb b/spec/features/projects/pipelines/pipelines_spec.rb
index 6e63e0f0b49..705ba78a0b7 100644
--- a/spec/features/projects/pipelines/pipelines_spec.rb
+++ b/spec/features/projects/pipelines/pipelines_spec.rb
@@ -517,7 +517,7 @@ describe 'Pipelines', :js do
end
it 'creates a new pipeline' do
- expect { click_on 'Create pipeline' }
+ expect { click_on 'Run pipeline' }
.to change { Ci::Pipeline.count }.by(1)
expect(Ci::Pipeline.last).to be_web
@@ -526,7 +526,7 @@ describe 'Pipelines', :js do
context 'without gitlab-ci.yml' do
before do
- click_on 'Create pipeline'
+ click_on 'Run pipeline'
end
it { expect(page).to have_content('Missing .gitlab-ci.yml file') }
@@ -539,7 +539,7 @@ describe 'Pipelines', :js do
click_link 'master'
end
- expect { click_on 'Create pipeline' }
+ expect { click_on 'Run pipeline' }
.to change { Ci::Pipeline.count }.by(1)
end
end
@@ -557,7 +557,7 @@ describe 'Pipelines', :js do
it 'has field to add a new pipeline' do
expect(page).to have_selector('.js-branch-select')
expect(find('.js-branch-select')).to have_content project.default_branch
- expect(page).to have_content('Create for')
+ expect(page).to have_content('Run on')
end
end
diff --git a/spec/fixtures/trace/sample_trace b/spec/fixtures/trace/sample_trace
index 55fcb9d2756..c65cf05d5ca 100644
--- a/spec/fixtures/trace/sample_trace
+++ b/spec/fixtures/trace/sample_trace
@@ -1,24 +1,24 @@
-Running with gitlab-runner 10.4.0 (857480b6)
- on docker-auto-scale-com (9a6801bd)
-Using Docker executor with image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.6-golang-1.9-git-2.14-chrome-63.0-node-8.x-yarn-1.2-postgresql-9.6 ...
-Starting service postgres:9.2 ...
-Pulling docker image postgres:9.2 ...
-Using docker image postgres:9.2 ID=sha256:18cdbca56093c841d28e629eb8acd4224afe0aa4c57c839351fc181888b8a470 for postgres service...
+Running with gitlab-runner 10.6.0 (a3543a27)
+ on docker-auto-scale-com 30d62d59
+Using Docker executor with image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.6-golang-1.9-git-2.16-chrome-63.0-node-8.x-yarn-1.2-postgresql-9.6 ...
+Starting service mysql:latest ...
+Pulling docker image mysql:latest ...
+Using docker image sha256:5195076672a7e30525705a18f7d352c920bbd07a5ae72b30e374081fe660a011 for mysql:latest ...
Starting service redis:alpine ...
Pulling docker image redis:alpine ...
-Using docker image redis:alpine ID=sha256:cb1ec54b370d4a91dff57d00f91fd880dc710160a58440adaa133e0f84ae999d for redis service...
+Using docker image sha256:98bd7cfc43b8ef0ff130465e3d5427c0771002c2f35a6a9b62cb2d04602bed0a for redis:alpine ...
Waiting for services to be up and running...
-Using docker image sha256:3006a02a5a6f0a116358a13bbc46ee46fb2471175efd5b7f9b1c22345ec2a8e9 for predefined container...
-Pulling docker image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.6-golang-1.9-git-2.14-chrome-63.0-node-8.x-yarn-1.2-postgresql-9.6 ...
-Using docker image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.6-golang-1.9-git-2.14-chrome-63.0-node-8.x-yarn-1.2-postgresql-9.6 ID=sha256:1f59be408f12738509ffe4177d65e9de6391f32461de83d9d45f58517b30af99 for build container...
-section_start:1517486886:prepare_script
-Running on runner-9a6801bd-project-13083-concurrent-0 via runner-9a6801bd-gsrm-1517484168-a8449153...
-section_end:1517486887:prepare_script
-section_start:1517486887:get_sources
-Fetching changes for 42624-gitaly-bundle-isolation-not-working-in-ci with git depth set to 20...
+Pulling docker image dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.6-golang-1.9-git-2.16-chrome-63.0-node-8.x-yarn-1.2-postgresql-9.6 ...
+Using docker image sha256:1b06077bb03d9d42d801b53f45701bb6a7e862ca02e1e75f30ca7fcf1270eb02 for dev.gitlab.org:5005/gitlab/gitlab-build-images:ruby-2.3.6-golang-1.9-git-2.16-chrome-63.0-node-8.x-yarn-1.2-postgresql-9.6 ...
+section_start:1522927103:prepare_script
+Running on runner-30d62d59-project-13083-concurrent-0 via runner-30d62d59-prm-1522922015-ddc29478...
+section_end:1522927104:prepare_script
+section_start:1522927104:get_sources
+Fetching changes for master with git depth set to 20...
Removing .gitlab_shell_secret
Removing .gitlab_workhorse_secret
Removing .yarn-cache/
+Removing builds/2018_04/
Removing config/database.yml
Removing config/gitlab.yml
Removing config/redis.cache.yml
@@ -26,1160 +26,3420 @@ Removing config/redis.queues.yml
Removing config/redis.shared_state.yml
Removing config/resque.yml
Removing config/secrets.yml
-Removing coverage/
-Removing knapsack/
Removing log/api_json.log
Removing log/application.log
Removing log/gitaly-test.log
-Removing log/githost.log
Removing log/grpc.log
Removing log/test_json.log
-Removing node_modules/
-Removing public/assets/
-Removing rspec_flaky/
-Removing shared/tmp/
Removing tmp/tests/
Removing vendor/ruby/
-HEAD is now at 4cea24f Converted todos.js to axios
+HEAD is now at b7cbff3d Add `direct_upload` setting for artifacts
From https://gitlab.com/gitlab-org/gitlab-ce
- * [new branch] 42624-gitaly-bundle-isolation-not-working-in-ci -> origin/42624-gitaly-bundle-isolation-not-working-in-ci
-Checking out f42a5e24 as 42624-gitaly-bundle-isolation-not-working-in-ci...
+ 2dbcb9cb..641bb13b master -> origin/master
+Checking out 21488c74 as master...
Skipping Git submodules setup
-section_end:1517486896:get_sources
-section_start:1517486896:restore_cache
+section_end:1522927113:get_sources
+section_start:1522927113:restore_cache
Checking cache for ruby-2.3.6-with-yarn...
Downloading cache.zip from http://runners-cache-5-internal.gitlab.com:444/runner/project/13083/ruby-2.3.6-with-yarn
Successfully extracted cache
-section_end:1517486919:restore_cache
-section_start:1517486919:download_artifacts
-Downloading artifacts for retrieve-tests-metadata (50551658)...
-Downloading artifacts from coordinator... ok  id=50551658 responseStatus=200 OK token=HhF7y_1X
-Downloading artifacts for compile-assets (50551659)...
-Downloading artifacts from coordinator... ok  id=50551659 responseStatus=200 OK token=wTz6JrCP
-Downloading artifacts for setup-test-env (50551660)...
-Downloading artifacts from coordinator... ok  id=50551660 responseStatus=200 OK token=DTGgeVF5
+section_end:1522927128:restore_cache
+section_start:1522927128:download_artifacts
+Downloading artifacts for retrieve-tests-metadata (61303215)...
+Downloading artifacts from coordinator... ok  id=61303215 responseStatus=200 OK token=AdWPNg2R
+Downloading artifacts for compile-assets (61303216)...
+Downloading artifacts from coordinator... ok  id=61303216 responseStatus=200 OK token=iy2yYbq8
+Downloading artifacts for setup-test-env (61303217)...
+Downloading artifacts from coordinator... ok  id=61303217 responseStatus=200 OK token=ur1g79-4
WARNING: tmp/tests/gitlab-shell/.gitlab_shell_secret: chmod tmp/tests/gitlab-shell/.gitlab_shell_secret: no such file or directory (suppressing repeats)
-section_end:1517486934:download_artifacts
-section_start:1517486934:build_script
+section_end:1522927141:download_artifacts
+section_start:1522927141:build_script
$ bundle --version
Bundler version 1.16.1
+$ date
+Thu Apr 5 11:19:01 UTC 2018
$ source scripts/utils.sh
+$ date
+Thu Apr 5 11:19:01 UTC 2018
$ source scripts/prepare_build.sh
The Gemfile's dependencies are satisfied
-Successfully installed knapsack-1.15.0
+Successfully installed knapsack-1.16.0
1 gem installed
-NOTICE: database "gitlabhq_test" does not exist, skipping
-DROP DATABASE
-CREATE DATABASE
-CREATE ROLE
-GRANT
-- enable_extension("plpgsql")
- -> 0.0156s
+ -> 0.0010s
-- enable_extension("pg_trgm")
- -> 0.0156s
+ -> 0.0000s
-- create_table("abuse_reports", {:force=>:cascade})
- -> 0.0119s
+ -> 0.0401s
-- create_table("appearances", {:force=>:cascade})
- -> 0.0065s
+ -> 0.1035s
-- create_table("application_settings", {:force=>:cascade})
- -> 0.0382s
+ -> 0.0871s
-- create_table("audit_events", {:force=>:cascade})
- -> 0.0056s
+ -> 0.0539s
-- add_index("audit_events", ["entity_id", "entity_type"], {:name=>"index_audit_events_on_entity_id_and_entity_type", :using=>:btree})
- -> 0.0040s
+ -> 0.0647s
-- create_table("award_emoji", {:force=>:cascade})
- -> 0.0058s
+ -> 0.0134s
-- add_index("award_emoji", ["awardable_type", "awardable_id"], {:name=>"index_award_emoji_on_awardable_type_and_awardable_id", :using=>:btree})
- -> 0.0068s
+ -> 0.0074s
-- add_index("award_emoji", ["user_id", "name"], {:name=>"index_award_emoji_on_user_id_and_name", :using=>:btree})
- -> 0.0043s
+ -> 0.0072s
+-- create_table("badges", {:force=>:cascade})
+ -> 0.0122s
+-- add_index("badges", ["group_id"], {:name=>"index_badges_on_group_id", :using=>:btree})
+ -> 0.0086s
+-- add_index("badges", ["project_id"], {:name=>"index_badges_on_project_id", :using=>:btree})
+ -> 0.0069s
-- create_table("boards", {:force=>:cascade})
- -> 0.0049s
+ -> 0.0075s
+-- add_index("boards", ["group_id"], {:name=>"index_boards_on_group_id", :using=>:btree})
+ -> 0.0050s
-- add_index("boards", ["project_id"], {:name=>"index_boards_on_project_id", :using=>:btree})
- -> 0.0056s
+ -> 0.0051s
-- create_table("broadcast_messages", {:force=>:cascade})
- -> 0.0056s
+ -> 0.0082s
-- add_index("broadcast_messages", ["starts_at", "ends_at", "id"], {:name=>"index_broadcast_messages_on_starts_at_and_ends_at_and_id", :using=>:btree})
- -> 0.0041s
+ -> 0.0063s
-- create_table("chat_names", {:force=>:cascade})
- -> 0.0056s
+ -> 0.0084s
-- add_index("chat_names", ["service_id", "team_id", "chat_id"], {:name=>"index_chat_names_on_service_id_and_team_id_and_chat_id", :unique=>true, :using=>:btree})
- -> 0.0039s
+ -> 0.0088s
-- add_index("chat_names", ["user_id", "service_id"], {:name=>"index_chat_names_on_user_id_and_service_id", :unique=>true, :using=>:btree})
- -> 0.0036s
+ -> 0.0077s
-- create_table("chat_teams", {:force=>:cascade})
- -> 0.0068s
+ -> 0.0120s
-- add_index("chat_teams", ["namespace_id"], {:name=>"index_chat_teams_on_namespace_id", :unique=>true, :using=>:btree})
- -> 0.0098s
+ -> 0.0135s
-- create_table("ci_build_trace_section_names", {:force=>:cascade})
- -> 0.0048s
+ -> 0.0125s
-- add_index("ci_build_trace_section_names", ["project_id", "name"], {:name=>"index_ci_build_trace_section_names_on_project_id_and_name", :unique=>true, :using=>:btree})
- -> 0.0035s
+ -> 0.0087s
-- create_table("ci_build_trace_sections", {:force=>:cascade})
- -> 0.0040s
+ -> 0.0094s
-- add_index("ci_build_trace_sections", ["build_id", "section_name_id"], {:name=>"index_ci_build_trace_sections_on_build_id_and_section_name_id", :unique=>true, :using=>:btree})
- -> 0.0035s
+ -> 0.0916s
-- add_index("ci_build_trace_sections", ["project_id"], {:name=>"index_ci_build_trace_sections_on_project_id", :using=>:btree})
- -> 0.0033s
+ -> 0.0089s
+-- add_index("ci_build_trace_sections", ["section_name_id"], {:name=>"index_ci_build_trace_sections_on_section_name_id", :using=>:btree})
+ -> 0.0132s
-- create_table("ci_builds", {:force=>:cascade})
- -> 0.0062s
+ -> 0.0140s
+-- add_index("ci_builds", ["artifacts_expire_at"], {:name=>"index_ci_builds_on_artifacts_expire_at", :where=>"(artifacts_file <> ''::text)", :using=>:btree})
+ -> 0.0325s
-- add_index("ci_builds", ["auto_canceled_by_id"], {:name=>"index_ci_builds_on_auto_canceled_by_id", :using=>:btree})
- -> 0.0035s
+ -> 0.0081s
-- add_index("ci_builds", ["commit_id", "stage_idx", "created_at"], {:name=>"index_ci_builds_on_commit_id_and_stage_idx_and_created_at", :using=>:btree})
- -> 0.0032s
+ -> 0.0114s
-- add_index("ci_builds", ["commit_id", "status", "type"], {:name=>"index_ci_builds_on_commit_id_and_status_and_type", :using=>:btree})
- -> 0.0032s
+ -> 0.0119s
-- add_index("ci_builds", ["commit_id", "type", "name", "ref"], {:name=>"index_ci_builds_on_commit_id_and_type_and_name_and_ref", :using=>:btree})
- -> 0.0035s
+ -> 0.0116s
-- add_index("ci_builds", ["commit_id", "type", "ref"], {:name=>"index_ci_builds_on_commit_id_and_type_and_ref", :using=>:btree})
- -> 0.0042s
+ -> 0.0144s
-- add_index("ci_builds", ["project_id", "id"], {:name=>"index_ci_builds_on_project_id_and_id", :using=>:btree})
- -> 0.0031s
+ -> 0.0136s
-- add_index("ci_builds", ["protected"], {:name=>"index_ci_builds_on_protected", :using=>:btree})
- -> 0.0031s
+ -> 0.0113s
-- add_index("ci_builds", ["runner_id"], {:name=>"index_ci_builds_on_runner_id", :using=>:btree})
- -> 0.0033s
+ -> 0.0082s
-- add_index("ci_builds", ["stage_id"], {:name=>"index_ci_builds_on_stage_id", :using=>:btree})
- -> 0.0035s
+ -> 0.0086s
-- add_index("ci_builds", ["status", "type", "runner_id"], {:name=>"index_ci_builds_on_status_and_type_and_runner_id", :using=>:btree})
- -> 0.0031s
+ -> 0.0091s
-- add_index("ci_builds", ["status"], {:name=>"index_ci_builds_on_status", :using=>:btree})
- -> 0.0032s
+ -> 0.0081s
-- add_index("ci_builds", ["token"], {:name=>"index_ci_builds_on_token", :unique=>true, :using=>:btree})
- -> 0.0028s
+ -> 0.0103s
-- add_index("ci_builds", ["updated_at"], {:name=>"index_ci_builds_on_updated_at", :using=>:btree})
- -> 0.0047s
+ -> 0.0149s
-- add_index("ci_builds", ["user_id"], {:name=>"index_ci_builds_on_user_id", :using=>:btree})
- -> 0.0029s
+ -> 0.0156s
+-- create_table("ci_builds_metadata", {:force=>:cascade})
+ -> 0.0134s
+-- add_index("ci_builds_metadata", ["build_id"], {:name=>"index_ci_builds_metadata_on_build_id", :unique=>true, :using=>:btree})
+ -> 0.0067s
+-- add_index("ci_builds_metadata", ["project_id"], {:name=>"index_ci_builds_metadata_on_project_id", :using=>:btree})
+ -> 0.0061s
-- create_table("ci_group_variables", {:force=>:cascade})
- -> 0.0055s
+ -> 0.0088s
-- add_index("ci_group_variables", ["group_id", "key"], {:name=>"index_ci_group_variables_on_group_id_and_key", :unique=>true, :using=>:btree})
- -> 0.0028s
+ -> 0.0073s
-- create_table("ci_job_artifacts", {:force=>:cascade})
- -> 0.0048s
+ -> 0.0089s
+-- add_index("ci_job_artifacts", ["expire_at", "job_id"], {:name=>"index_ci_job_artifacts_on_expire_at_and_job_id", :using=>:btree})
+ -> 0.0061s
-- add_index("ci_job_artifacts", ["job_id", "file_type"], {:name=>"index_ci_job_artifacts_on_job_id_and_file_type", :unique=>true, :using=>:btree})
- -> 0.0027s
+ -> 0.0077s
-- add_index("ci_job_artifacts", ["project_id"], {:name=>"index_ci_job_artifacts_on_project_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0071s
-- create_table("ci_pipeline_schedule_variables", {:force=>:cascade})
- -> 0.0044s
+ -> 0.0512s
-- add_index("ci_pipeline_schedule_variables", ["pipeline_schedule_id", "key"], {:name=>"index_ci_pipeline_schedule_variables_on_schedule_id_and_key", :unique=>true, :using=>:btree})
- -> 0.0032s
+ -> 0.0144s
-- create_table("ci_pipeline_schedules", {:force=>:cascade})
- -> 0.0047s
+ -> 0.0603s
-- add_index("ci_pipeline_schedules", ["next_run_at", "active"], {:name=>"index_ci_pipeline_schedules_on_next_run_at_and_active", :using=>:btree})
- -> 0.0029s
+ -> 0.0247s
-- add_index("ci_pipeline_schedules", ["project_id"], {:name=>"index_ci_pipeline_schedules_on_project_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0082s
-- create_table("ci_pipeline_variables", {:force=>:cascade})
- -> 0.0045s
+ -> 0.0112s
-- add_index("ci_pipeline_variables", ["pipeline_id", "key"], {:name=>"index_ci_pipeline_variables_on_pipeline_id_and_key", :unique=>true, :using=>:btree})
- -> 0.0030s
+ -> 0.0075s
-- create_table("ci_pipelines", {:force=>:cascade})
- -> 0.0057s
+ -> 0.0111s
-- add_index("ci_pipelines", ["auto_canceled_by_id"], {:name=>"index_ci_pipelines_on_auto_canceled_by_id", :using=>:btree})
- -> 0.0030s
+ -> 0.0074s
-- add_index("ci_pipelines", ["pipeline_schedule_id"], {:name=>"index_ci_pipelines_on_pipeline_schedule_id", :using=>:btree})
- -> 0.0031s
+ -> 0.0086s
-- add_index("ci_pipelines", ["project_id", "ref", "status", "id"], {:name=>"index_ci_pipelines_on_project_id_and_ref_and_status_and_id", :using=>:btree})
- -> 0.0032s
+ -> 0.0104s
-- add_index("ci_pipelines", ["project_id", "sha"], {:name=>"index_ci_pipelines_on_project_id_and_sha", :using=>:btree})
- -> 0.0032s
+ -> 0.0107s
-- add_index("ci_pipelines", ["project_id"], {:name=>"index_ci_pipelines_on_project_id", :using=>:btree})
- -> 0.0035s
+ -> 0.0084s
-- add_index("ci_pipelines", ["status"], {:name=>"index_ci_pipelines_on_status", :using=>:btree})
- -> 0.0032s
+ -> 0.0065s
-- add_index("ci_pipelines", ["user_id"], {:name=>"index_ci_pipelines_on_user_id", :using=>:btree})
- -> 0.0029s
+ -> 0.0071s
-- create_table("ci_runner_projects", {:force=>:cascade})
- -> 0.0035s
+ -> 0.0077s
-- add_index("ci_runner_projects", ["project_id"], {:name=>"index_ci_runner_projects_on_project_id", :using=>:btree})
- -> 0.0029s
+ -> 0.0072s
-- add_index("ci_runner_projects", ["runner_id"], {:name=>"index_ci_runner_projects_on_runner_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0064s
-- create_table("ci_runners", {:force=>:cascade})
- -> 0.0059s
+ -> 0.0090s
-- add_index("ci_runners", ["contacted_at"], {:name=>"index_ci_runners_on_contacted_at", :using=>:btree})
- -> 0.0030s
+ -> 0.0078s
-- add_index("ci_runners", ["is_shared"], {:name=>"index_ci_runners_on_is_shared", :using=>:btree})
- -> 0.0030s
+ -> 0.0054s
-- add_index("ci_runners", ["locked"], {:name=>"index_ci_runners_on_locked", :using=>:btree})
- -> 0.0030s
+ -> 0.0052s
-- add_index("ci_runners", ["token"], {:name=>"index_ci_runners_on_token", :using=>:btree})
- -> 0.0029s
+ -> 0.0057s
-- create_table("ci_stages", {:force=>:cascade})
- -> 0.0046s
--- add_index("ci_stages", ["pipeline_id", "name"], {:name=>"index_ci_stages_on_pipeline_id_and_name", :using=>:btree})
- -> 0.0031s
+ -> 0.0059s
+-- add_index("ci_stages", ["pipeline_id", "name"], {:name=>"index_ci_stages_on_pipeline_id_and_name", :unique=>true, :using=>:btree})
+ -> 0.0054s
-- add_index("ci_stages", ["pipeline_id"], {:name=>"index_ci_stages_on_pipeline_id", :using=>:btree})
- -> 0.0030s
+ -> 0.0045s
-- add_index("ci_stages", ["project_id"], {:name=>"index_ci_stages_on_project_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0053s
-- create_table("ci_trigger_requests", {:force=>:cascade})
- -> 0.0058s
+ -> 0.0079s
-- add_index("ci_trigger_requests", ["commit_id"], {:name=>"index_ci_trigger_requests_on_commit_id", :using=>:btree})
- -> 0.0031s
+ -> 0.0059s
-- create_table("ci_triggers", {:force=>:cascade})
- -> 0.0043s
+ -> 0.0100s
-- add_index("ci_triggers", ["project_id"], {:name=>"index_ci_triggers_on_project_id", :using=>:btree})
- -> 0.0033s
--- create_table("ci_variables", {:force=>:cascade})
-> 0.0059s
+-- create_table("ci_variables", {:force=>:cascade})
+ -> 0.0110s
-- add_index("ci_variables", ["project_id", "key", "environment_scope"], {:name=>"index_ci_variables_on_project_id_and_key_and_environment_scope", :unique=>true, :using=>:btree})
- -> 0.0031s
+ -> 0.0066s
-- create_table("cluster_platforms_kubernetes", {:force=>:cascade})
- -> 0.0053s
+ -> 0.0082s
-- add_index("cluster_platforms_kubernetes", ["cluster_id"], {:name=>"index_cluster_platforms_kubernetes_on_cluster_id", :unique=>true, :using=>:btree})
- -> 0.0028s
+ -> 0.0047s
-- create_table("cluster_projects", {:force=>:cascade})
- -> 0.0032s
+ -> 0.0079s
-- add_index("cluster_projects", ["cluster_id"], {:name=>"index_cluster_projects_on_cluster_id", :using=>:btree})
- -> 0.0035s
+ -> 0.0045s
-- add_index("cluster_projects", ["project_id"], {:name=>"index_cluster_projects_on_project_id", :using=>:btree})
- -> 0.0030s
+ -> 0.0044s
-- create_table("cluster_providers_gcp", {:force=>:cascade})
- -> 0.0051s
+ -> 0.0247s
-- add_index("cluster_providers_gcp", ["cluster_id"], {:name=>"index_cluster_providers_gcp_on_cluster_id", :unique=>true, :using=>:btree})
- -> 0.0034s
+ -> 0.0088s
-- create_table("clusters", {:force=>:cascade})
- -> 0.0052s
+ -> 0.0767s
-- add_index("clusters", ["enabled"], {:name=>"index_clusters_on_enabled", :using=>:btree})
- -> 0.0031s
+ -> 0.0162s
-- add_index("clusters", ["user_id"], {:name=>"index_clusters_on_user_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0216s
-- create_table("clusters_applications_helm", {:force=>:cascade})
- -> 0.0045s
+ -> 0.0379s
-- create_table("clusters_applications_ingress", {:force=>:cascade})
- -> 0.0044s
+ -> 0.0409s
-- create_table("clusters_applications_prometheus", {:force=>:cascade})
- -> 0.0047s
+ -> 0.0178s
+-- create_table("clusters_applications_runners", {:force=>:cascade})
+ -> 0.0471s
+-- add_index("clusters_applications_runners", ["cluster_id"], {:name=>"index_clusters_applications_runners_on_cluster_id", :unique=>true, :using=>:btree})
+ -> 0.0487s
+-- add_index("clusters_applications_runners", ["runner_id"], {:name=>"index_clusters_applications_runners_on_runner_id", :using=>:btree})
+ -> 0.0094s
-- create_table("container_repositories", {:force=>:cascade})
- -> 0.0050s
+ -> 0.0142s
-- add_index("container_repositories", ["project_id", "name"], {:name=>"index_container_repositories_on_project_id_and_name", :unique=>true, :using=>:btree})
- -> 0.0032s
+ -> 0.0080s
-- add_index("container_repositories", ["project_id"], {:name=>"index_container_repositories_on_project_id", :using=>:btree})
- -> 0.0032s
+ -> 0.0070s
-- create_table("conversational_development_index_metrics", {:force=>:cascade})
- -> 0.0076s
+ -> 0.0204s
-- create_table("deploy_keys_projects", {:force=>:cascade})
- -> 0.0037s
+ -> 0.0154s
-- add_index("deploy_keys_projects", ["project_id"], {:name=>"index_deploy_keys_projects_on_project_id", :using=>:btree})
- -> 0.0032s
+ -> 0.0471s
-- create_table("deployments", {:force=>:cascade})
- -> 0.0049s
+ -> 0.0191s
-- add_index("deployments", ["created_at"], {:name=>"index_deployments_on_created_at", :using=>:btree})
- -> 0.0034s
+ -> 0.0552s
-- add_index("deployments", ["environment_id", "id"], {:name=>"index_deployments_on_environment_id_and_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0294s
-- add_index("deployments", ["environment_id", "iid", "project_id"], {:name=>"index_deployments_on_environment_id_and_iid_and_project_id", :using=>:btree})
- -> 0.0029s
+ -> 0.0408s
-- add_index("deployments", ["project_id", "iid"], {:name=>"index_deployments_on_project_id_and_iid", :unique=>true, :using=>:btree})
- -> 0.0032s
+ -> 0.0094s
-- create_table("emails", {:force=>:cascade})
- -> 0.0046s
+ -> 0.0127s
-- add_index("emails", ["confirmation_token"], {:name=>"index_emails_on_confirmation_token", :unique=>true, :using=>:btree})
- -> 0.0030s
+ -> 0.0082s
-- add_index("emails", ["email"], {:name=>"index_emails_on_email", :unique=>true, :using=>:btree})
- -> 0.0035s
+ -> 0.0110s
-- add_index("emails", ["user_id"], {:name=>"index_emails_on_user_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0079s
-- create_table("environments", {:force=>:cascade})
- -> 0.0052s
+ -> 0.0106s
-- add_index("environments", ["project_id", "name"], {:name=>"index_environments_on_project_id_and_name", :unique=>true, :using=>:btree})
- -> 0.0031s
+ -> 0.0086s
-- add_index("environments", ["project_id", "slug"], {:name=>"index_environments_on_project_id_and_slug", :unique=>true, :using=>:btree})
- -> 0.0028s
+ -> 0.0076s
-- create_table("events", {:force=>:cascade})
- -> 0.0046s
+ -> 0.0122s
-- add_index("events", ["action"], {:name=>"index_events_on_action", :using=>:btree})
- -> 0.0032s
--- add_index("events", ["author_id"], {:name=>"index_events_on_author_id", :using=>:btree})
- -> 0.0027s
+ -> 0.0068s
+-- add_index("events", ["author_id", "project_id"], {:name=>"index_events_on_author_id_and_project_id", :using=>:btree})
+ -> 0.0081s
-- add_index("events", ["project_id", "id"], {:name=>"index_events_on_project_id_and_id", :using=>:btree})
- -> 0.0027s
+ -> 0.0064s
-- add_index("events", ["target_type", "target_id"], {:name=>"index_events_on_target_type_and_target_id", :using=>:btree})
- -> 0.0027s
+ -> 0.0087s
-- create_table("feature_gates", {:force=>:cascade})
- -> 0.0046s
+ -> 0.0105s
-- add_index("feature_gates", ["feature_key", "key", "value"], {:name=>"index_feature_gates_on_feature_key_and_key_and_value", :unique=>true, :using=>:btree})
- -> 0.0031s
+ -> 0.0080s
-- create_table("features", {:force=>:cascade})
- -> 0.0041s
+ -> 0.0086s
-- add_index("features", ["key"], {:name=>"index_features_on_key", :unique=>true, :using=>:btree})
- -> 0.0030s
+ -> 0.0058s
-- create_table("fork_network_members", {:force=>:cascade})
- -> 0.0033s
+ -> 0.0081s
-- add_index("fork_network_members", ["fork_network_id"], {:name=>"index_fork_network_members_on_fork_network_id", :using=>:btree})
- -> 0.0033s
+ -> 0.0056s
-- add_index("fork_network_members", ["project_id"], {:name=>"index_fork_network_members_on_project_id", :unique=>true, :using=>:btree})
- -> 0.0029s
+ -> 0.0053s
-- create_table("fork_networks", {:force=>:cascade})
- -> 0.0049s
+ -> 0.0081s
-- add_index("fork_networks", ["root_project_id"], {:name=>"index_fork_networks_on_root_project_id", :unique=>true, :using=>:btree})
- -> 0.0029s
+ -> 0.0051s
-- create_table("forked_project_links", {:force=>:cascade})
- -> 0.0032s
+ -> 0.0070s
-- add_index("forked_project_links", ["forked_to_project_id"], {:name=>"index_forked_project_links_on_forked_to_project_id", :unique=>true, :using=>:btree})
- -> 0.0030s
+ -> 0.0061s
-- create_table("gcp_clusters", {:force=>:cascade})
- -> 0.0074s
+ -> 0.0090s
-- add_index("gcp_clusters", ["project_id"], {:name=>"index_gcp_clusters_on_project_id", :unique=>true, :using=>:btree})
- -> 0.0030s
+ -> 0.0073s
-- create_table("gpg_key_subkeys", {:force=>:cascade})
- -> 0.0042s
+ -> 0.0092s
-- add_index("gpg_key_subkeys", ["fingerprint"], {:name=>"index_gpg_key_subkeys_on_fingerprint", :unique=>true, :using=>:btree})
- -> 0.0029s
+ -> 0.0063s
-- add_index("gpg_key_subkeys", ["gpg_key_id"], {:name=>"index_gpg_key_subkeys_on_gpg_key_id", :using=>:btree})
- -> 0.0032s
+ -> 0.0603s
-- add_index("gpg_key_subkeys", ["keyid"], {:name=>"index_gpg_key_subkeys_on_keyid", :unique=>true, :using=>:btree})
- -> 0.0027s
+ -> 0.0705s
-- create_table("gpg_keys", {:force=>:cascade})
- -> 0.0042s
+ -> 0.0235s
-- add_index("gpg_keys", ["fingerprint"], {:name=>"index_gpg_keys_on_fingerprint", :unique=>true, :using=>:btree})
- -> 0.0032s
+ -> 0.0220s
-- add_index("gpg_keys", ["primary_keyid"], {:name=>"index_gpg_keys_on_primary_keyid", :unique=>true, :using=>:btree})
- -> 0.0026s
+ -> 0.0329s
-- add_index("gpg_keys", ["user_id"], {:name=>"index_gpg_keys_on_user_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0087s
-- create_table("gpg_signatures", {:force=>:cascade})
- -> 0.0054s
+ -> 0.0126s
-- add_index("gpg_signatures", ["commit_sha"], {:name=>"index_gpg_signatures_on_commit_sha", :unique=>true, :using=>:btree})
- -> 0.0029s
+ -> 0.0105s
-- add_index("gpg_signatures", ["gpg_key_id"], {:name=>"index_gpg_signatures_on_gpg_key_id", :using=>:btree})
- -> 0.0026s
+ -> 0.0094s
-- add_index("gpg_signatures", ["gpg_key_primary_keyid"], {:name=>"index_gpg_signatures_on_gpg_key_primary_keyid", :using=>:btree})
- -> 0.0029s
+ -> 0.0100s
-- add_index("gpg_signatures", ["gpg_key_subkey_id"], {:name=>"index_gpg_signatures_on_gpg_key_subkey_id", :using=>:btree})
- -> 0.0032s
+ -> 0.0079s
-- add_index("gpg_signatures", ["project_id"], {:name=>"index_gpg_signatures_on_project_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0081s
-- create_table("group_custom_attributes", {:force=>:cascade})
- -> 0.0044s
+ -> 0.0092s
-- add_index("group_custom_attributes", ["group_id", "key"], {:name=>"index_group_custom_attributes_on_group_id_and_key", :unique=>true, :using=>:btree})
- -> 0.0032s
+ -> 0.0086s
-- add_index("group_custom_attributes", ["key", "value"], {:name=>"index_group_custom_attributes_on_key_and_value", :using=>:btree})
- -> 0.0028s
+ -> 0.0071s
-- create_table("identities", {:force=>:cascade})
- -> 0.0043s
+ -> 0.0114s
-- add_index("identities", ["user_id"], {:name=>"index_identities_on_user_id", :using=>:btree})
- -> 0.0034s
+ -> 0.0064s
+-- create_table("internal_ids", {:id=>:bigserial, :force=>:cascade})
+ -> 0.0097s
+-- add_index("internal_ids", ["usage", "project_id"], {:name=>"index_internal_ids_on_usage_and_project_id", :unique=>true, :using=>:btree})
+ -> 0.0073s
-- create_table("issue_assignees", {:id=>false, :force=>:cascade})
- -> 0.0013s
+ -> 0.0127s
-- add_index("issue_assignees", ["issue_id", "user_id"], {:name=>"index_issue_assignees_on_issue_id_and_user_id", :unique=>true, :using=>:btree})
- -> 0.0028s
+ -> 0.0110s
-- add_index("issue_assignees", ["user_id"], {:name=>"index_issue_assignees_on_user_id", :using=>:btree})
- -> 0.0029s
+ -> 0.0079s
-- create_table("issue_metrics", {:force=>:cascade})
- -> 0.0032s
+ -> 0.0098s
-- add_index("issue_metrics", ["issue_id"], {:name=>"index_issue_metrics", :using=>:btree})
- -> 0.0029s
+ -> 0.0053s
-- create_table("issues", {:force=>:cascade})
- -> 0.0051s
+ -> 0.0090s
-- add_index("issues", ["author_id"], {:name=>"index_issues_on_author_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0056s
-- add_index("issues", ["confidential"], {:name=>"index_issues_on_confidential", :using=>:btree})
- -> 0.0029s
+ -> 0.0055s
-- add_index("issues", ["description"], {:name=>"index_issues_on_description_trigram", :using=>:gin, :opclasses=>{"description"=>"gin_trgm_ops"}})
- -> 0.0022s
+ -> 0.0006s
-- add_index("issues", ["milestone_id"], {:name=>"index_issues_on_milestone_id", :using=>:btree})
- -> 0.0027s
+ -> 0.0061s
-- add_index("issues", ["moved_to_id"], {:name=>"index_issues_on_moved_to_id", :where=>"(moved_to_id IS NOT NULL)", :using=>:btree})
- -> 0.0030s
+ -> 0.0051s
-- add_index("issues", ["project_id", "created_at", "id", "state"], {:name=>"index_issues_on_project_id_and_created_at_and_id_and_state", :using=>:btree})
- -> 0.0039s
+ -> 0.0069s
-- add_index("issues", ["project_id", "due_date", "id", "state"], {:name=>"idx_issues_on_project_id_and_due_date_and_id_and_state_partial", :where=>"(due_date IS NOT NULL)", :using=>:btree})
- -> 0.0031s
+ -> 0.0073s
-- add_index("issues", ["project_id", "iid"], {:name=>"index_issues_on_project_id_and_iid", :unique=>true, :using=>:btree})
- -> 0.0032s
+ -> 0.0060s
-- add_index("issues", ["project_id", "updated_at", "id", "state"], {:name=>"index_issues_on_project_id_and_updated_at_and_id_and_state", :using=>:btree})
- -> 0.0035s
+ -> 0.0094s
-- add_index("issues", ["relative_position"], {:name=>"index_issues_on_relative_position", :using=>:btree})
- -> 0.0030s
+ -> 0.0070s
-- add_index("issues", ["state"], {:name=>"index_issues_on_state", :using=>:btree})
- -> 0.0027s
+ -> 0.0078s
-- add_index("issues", ["title"], {:name=>"index_issues_on_title_trigram", :using=>:gin, :opclasses=>{"title"=>"gin_trgm_ops"}})
- -> 0.0021s
+ -> 0.0007s
-- add_index("issues", ["updated_at"], {:name=>"index_issues_on_updated_at", :using=>:btree})
- -> 0.0030s
+ -> 0.0068s
-- add_index("issues", ["updated_by_id"], {:name=>"index_issues_on_updated_by_id", :where=>"(updated_by_id IS NOT NULL)", :using=>:btree})
- -> 0.0028s
+ -> 0.0066s
-- create_table("keys", {:force=>:cascade})
- -> 0.0048s
+ -> 0.0087s
-- add_index("keys", ["fingerprint"], {:name=>"index_keys_on_fingerprint", :unique=>true, :using=>:btree})
- -> 0.0028s
+ -> 0.0066s
-- add_index("keys", ["user_id"], {:name=>"index_keys_on_user_id", :using=>:btree})
- -> 0.0029s
+ -> 0.0063s
-- create_table("label_links", {:force=>:cascade})
- -> 0.0041s
+ -> 0.0073s
-- add_index("label_links", ["label_id"], {:name=>"index_label_links_on_label_id", :using=>:btree})
- -> 0.0027s
+ -> 0.0050s
-- add_index("label_links", ["target_id", "target_type"], {:name=>"index_label_links_on_target_id_and_target_type", :using=>:btree})
- -> 0.0028s
+ -> 0.0062s
-- create_table("label_priorities", {:force=>:cascade})
- -> 0.0031s
+ -> 0.0073s
-- add_index("label_priorities", ["priority"], {:name=>"index_label_priorities_on_priority", :using=>:btree})
- -> 0.0028s
+ -> 0.0058s
-- add_index("label_priorities", ["project_id", "label_id"], {:name=>"index_label_priorities_on_project_id_and_label_id", :unique=>true, :using=>:btree})
- -> 0.0027s
+ -> 0.0056s
-- create_table("labels", {:force=>:cascade})
- -> 0.0046s
+ -> 0.0087s
-- add_index("labels", ["group_id", "project_id", "title"], {:name=>"index_labels_on_group_id_and_project_id_and_title", :unique=>true, :using=>:btree})
- -> 0.0028s
+ -> 0.0074s
-- add_index("labels", ["project_id"], {:name=>"index_labels_on_project_id", :using=>:btree})
- -> 0.0032s
+ -> 0.0061s
-- add_index("labels", ["template"], {:name=>"index_labels_on_template", :where=>"template", :using=>:btree})
- -> 0.0027s
+ -> 0.0060s
-- add_index("labels", ["title"], {:name=>"index_labels_on_title", :using=>:btree})
- -> 0.0030s
+ -> 0.0076s
-- add_index("labels", ["type", "project_id"], {:name=>"index_labels_on_type_and_project_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0061s
+-- create_table("lfs_file_locks", {:force=>:cascade})
+ -> 0.0078s
+-- add_index("lfs_file_locks", ["project_id", "path"], {:name=>"index_lfs_file_locks_on_project_id_and_path", :unique=>true, :using=>:btree})
+ -> 0.0067s
+-- add_index("lfs_file_locks", ["user_id"], {:name=>"index_lfs_file_locks_on_user_id", :using=>:btree})
+ -> 0.0060s
-- create_table("lfs_objects", {:force=>:cascade})
- -> 0.0040s
+ -> 0.0109s
-- add_index("lfs_objects", ["oid"], {:name=>"index_lfs_objects_on_oid", :unique=>true, :using=>:btree})
- -> 0.0032s
+ -> 0.0059s
-- create_table("lfs_objects_projects", {:force=>:cascade})
- -> 0.0035s
+ -> 0.0091s
-- add_index("lfs_objects_projects", ["project_id"], {:name=>"index_lfs_objects_projects_on_project_id", :using=>:btree})
- -> 0.0025s
+ -> 0.0060s
-- create_table("lists", {:force=>:cascade})
- -> 0.0033s
+ -> 0.0115s
-- add_index("lists", ["board_id", "label_id"], {:name=>"index_lists_on_board_id_and_label_id", :unique=>true, :using=>:btree})
- -> 0.0026s
+ -> 0.0055s
-- add_index("lists", ["label_id"], {:name=>"index_lists_on_label_id", :using=>:btree})
- -> 0.0026s
+ -> 0.0055s
-- create_table("members", {:force=>:cascade})
- -> 0.0046s
+ -> 0.0140s
-- add_index("members", ["access_level"], {:name=>"index_members_on_access_level", :using=>:btree})
- -> 0.0028s
+ -> 0.0067s
-- add_index("members", ["invite_token"], {:name=>"index_members_on_invite_token", :unique=>true, :using=>:btree})
- -> 0.0027s
+ -> 0.0069s
-- add_index("members", ["requested_at"], {:name=>"index_members_on_requested_at", :using=>:btree})
- -> 0.0025s
+ -> 0.0057s
-- add_index("members", ["source_id", "source_type"], {:name=>"index_members_on_source_id_and_source_type", :using=>:btree})
- -> 0.0027s
+ -> 0.0057s
-- add_index("members", ["user_id"], {:name=>"index_members_on_user_id", :using=>:btree})
- -> 0.0026s
+ -> 0.0073s
-- create_table("merge_request_diff_commits", {:id=>false, :force=>:cascade})
- -> 0.0027s
+ -> 0.0087s
-- add_index("merge_request_diff_commits", ["merge_request_diff_id", "relative_order"], {:name=>"index_merge_request_diff_commits_on_mr_diff_id_and_order", :unique=>true, :using=>:btree})
- -> 0.0032s
+ -> 0.0151s
-- add_index("merge_request_diff_commits", ["sha"], {:name=>"index_merge_request_diff_commits_on_sha", :using=>:btree})
- -> 0.0029s
+ -> 0.0057s
-- create_table("merge_request_diff_files", {:id=>false, :force=>:cascade})
- -> 0.0027s
+ -> 0.0094s
-- add_index("merge_request_diff_files", ["merge_request_diff_id", "relative_order"], {:name=>"index_merge_request_diff_files_on_mr_diff_id_and_order", :unique=>true, :using=>:btree})
- -> 0.0027s
+ -> 0.0138s
-- create_table("merge_request_diffs", {:force=>:cascade})
- -> 0.0042s
+ -> 0.0077s
-- add_index("merge_request_diffs", ["merge_request_id", "id"], {:name=>"index_merge_request_diffs_on_merge_request_id_and_id", :using=>:btree})
- -> 0.0030s
+ -> 0.0060s
-- create_table("merge_request_metrics", {:force=>:cascade})
- -> 0.0034s
+ -> 0.0098s
-- add_index("merge_request_metrics", ["first_deployed_to_production_at"], {:name=>"index_merge_request_metrics_on_first_deployed_to_production_at", :using=>:btree})
- -> 0.0028s
+ -> 0.0060s
-- add_index("merge_request_metrics", ["merge_request_id"], {:name=>"index_merge_request_metrics", :using=>:btree})
- -> 0.0025s
+ -> 0.0050s
-- add_index("merge_request_metrics", ["pipeline_id"], {:name=>"index_merge_request_metrics_on_pipeline_id", :using=>:btree})
- -> 0.0026s
+ -> 0.0045s
-- create_table("merge_requests", {:force=>:cascade})
-> 0.0066s
-- add_index("merge_requests", ["assignee_id"], {:name=>"index_merge_requests_on_assignee_id", :using=>:btree})
- -> 0.0029s
+ -> 0.0072s
-- add_index("merge_requests", ["author_id"], {:name=>"index_merge_requests_on_author_id", :using=>:btree})
- -> 0.0026s
+ -> 0.0050s
-- add_index("merge_requests", ["created_at"], {:name=>"index_merge_requests_on_created_at", :using=>:btree})
- -> 0.0026s
+ -> 0.0053s
-- add_index("merge_requests", ["description"], {:name=>"index_merge_requests_on_description_trigram", :using=>:gin, :opclasses=>{"description"=>"gin_trgm_ops"}})
- -> 0.0020s
+ -> 0.0008s
-- add_index("merge_requests", ["head_pipeline_id"], {:name=>"index_merge_requests_on_head_pipeline_id", :using=>:btree})
- -> 0.0027s
+ -> 0.0053s
-- add_index("merge_requests", ["latest_merge_request_diff_id"], {:name=>"index_merge_requests_on_latest_merge_request_diff_id", :using=>:btree})
- -> 0.0025s
+ -> 0.0048s
-- add_index("merge_requests", ["merge_user_id"], {:name=>"index_merge_requests_on_merge_user_id", :where=>"(merge_user_id IS NOT NULL)", :using=>:btree})
- -> 0.0029s
+ -> 0.0051s
-- add_index("merge_requests", ["milestone_id"], {:name=>"index_merge_requests_on_milestone_id", :using=>:btree})
- -> 0.0030s
+ -> 0.0055s
-- add_index("merge_requests", ["source_branch"], {:name=>"index_merge_requests_on_source_branch", :using=>:btree})
- -> 0.0026s
+ -> 0.0055s
-- add_index("merge_requests", ["source_project_id", "source_branch"], {:name=>"index_merge_requests_on_source_project_and_branch_state_opened", :where=>"((state)::text = 'opened'::text)", :using=>:btree})
- -> 0.0029s
+ -> 0.0061s
-- add_index("merge_requests", ["source_project_id", "source_branch"], {:name=>"index_merge_requests_on_source_project_id_and_source_branch", :using=>:btree})
- -> 0.0031s
+ -> 0.0068s
-- add_index("merge_requests", ["target_branch"], {:name=>"index_merge_requests_on_target_branch", :using=>:btree})
- -> 0.0028s
+ -> 0.0054s
-- add_index("merge_requests", ["target_project_id", "iid"], {:name=>"index_merge_requests_on_target_project_id_and_iid", :unique=>true, :using=>:btree})
- -> 0.0027s
+ -> 0.0061s
-- add_index("merge_requests", ["target_project_id", "merge_commit_sha", "id"], {:name=>"index_merge_requests_on_tp_id_and_merge_commit_sha_and_id", :using=>:btree})
- -> 0.0029s
+ -> 0.0077s
-- add_index("merge_requests", ["title"], {:name=>"index_merge_requests_on_title", :using=>:btree})
- -> 0.0026s
+ -> 0.0105s
-- add_index("merge_requests", ["title"], {:name=>"index_merge_requests_on_title_trigram", :using=>:gin, :opclasses=>{"title"=>"gin_trgm_ops"}})
- -> 0.0020s
+ -> 0.0008s
-- add_index("merge_requests", ["updated_by_id"], {:name=>"index_merge_requests_on_updated_by_id", :where=>"(updated_by_id IS NOT NULL)", :using=>:btree})
- -> 0.0029s
+ -> 0.0074s
-- create_table("merge_requests_closing_issues", {:force=>:cascade})
- -> 0.0031s
+ -> 0.0125s
-- add_index("merge_requests_closing_issues", ["issue_id"], {:name=>"index_merge_requests_closing_issues_on_issue_id", :using=>:btree})
- -> 0.0026s
+ -> 0.0064s
-- add_index("merge_requests_closing_issues", ["merge_request_id"], {:name=>"index_merge_requests_closing_issues_on_merge_request_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0061s
-- create_table("milestones", {:force=>:cascade})
- -> 0.0044s
+ -> 0.0064s
-- add_index("milestones", ["description"], {:name=>"index_milestones_on_description_trigram", :using=>:gin, :opclasses=>{"description"=>"gin_trgm_ops"}})
- -> 0.0022s
+ -> 0.0007s
-- add_index("milestones", ["due_date"], {:name=>"index_milestones_on_due_date", :using=>:btree})
- -> 0.0033s
+ -> 0.0053s
-- add_index("milestones", ["group_id"], {:name=>"index_milestones_on_group_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0068s
-- add_index("milestones", ["project_id", "iid"], {:name=>"index_milestones_on_project_id_and_iid", :unique=>true, :using=>:btree})
- -> 0.0028s
+ -> 0.0057s
-- add_index("milestones", ["title"], {:name=>"index_milestones_on_title", :using=>:btree})
- -> 0.0026s
+ -> 0.0051s
-- add_index("milestones", ["title"], {:name=>"index_milestones_on_title_trigram", :using=>:gin, :opclasses=>{"title"=>"gin_trgm_ops"}})
- -> 0.0021s
+ -> 0.0006s
-- create_table("namespaces", {:force=>:cascade})
- -> 0.0068s
+ -> 0.0083s
-- add_index("namespaces", ["created_at"], {:name=>"index_namespaces_on_created_at", :using=>:btree})
- -> 0.0030s
+ -> 0.0061s
-- add_index("namespaces", ["name", "parent_id"], {:name=>"index_namespaces_on_name_and_parent_id", :unique=>true, :using=>:btree})
- -> 0.0030s
+ -> 0.0062s
-- add_index("namespaces", ["name"], {:name=>"index_namespaces_on_name_trigram", :using=>:gin, :opclasses=>{"name"=>"gin_trgm_ops"}})
- -> 0.0020s
+ -> 0.0006s
-- add_index("namespaces", ["owner_id"], {:name=>"index_namespaces_on_owner_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0061s
-- add_index("namespaces", ["parent_id", "id"], {:name=>"index_namespaces_on_parent_id_and_id", :unique=>true, :using=>:btree})
- -> 0.0032s
+ -> 0.0072s
-- add_index("namespaces", ["path"], {:name=>"index_namespaces_on_path", :using=>:btree})
- -> 0.0031s
+ -> 0.0056s
-- add_index("namespaces", ["path"], {:name=>"index_namespaces_on_path_trigram", :using=>:gin, :opclasses=>{"path"=>"gin_trgm_ops"}})
- -> 0.0019s
+ -> 0.0006s
-- add_index("namespaces", ["require_two_factor_authentication"], {:name=>"index_namespaces_on_require_two_factor_authentication", :using=>:btree})
- -> 0.0029s
+ -> 0.0061s
-- add_index("namespaces", ["type"], {:name=>"index_namespaces_on_type", :using=>:btree})
- -> 0.0032s
--- create_table("notes", {:force=>:cascade})
-> 0.0055s
+-- create_table("notes", {:force=>:cascade})
+ -> 0.0092s
-- add_index("notes", ["author_id"], {:name=>"index_notes_on_author_id", :using=>:btree})
- -> 0.0029s
+ -> 0.0072s
-- add_index("notes", ["commit_id"], {:name=>"index_notes_on_commit_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0057s
-- add_index("notes", ["created_at"], {:name=>"index_notes_on_created_at", :using=>:btree})
- -> 0.0029s
+ -> 0.0065s
-- add_index("notes", ["discussion_id"], {:name=>"index_notes_on_discussion_id", :using=>:btree})
- -> 0.0029s
+ -> 0.0064s
-- add_index("notes", ["line_code"], {:name=>"index_notes_on_line_code", :using=>:btree})
- -> 0.0029s
+ -> 0.0078s
-- add_index("notes", ["note"], {:name=>"index_notes_on_note_trigram", :using=>:gin, :opclasses=>{"note"=>"gin_trgm_ops"}})
- -> 0.0024s
+ -> 0.0006s
-- add_index("notes", ["noteable_id", "noteable_type"], {:name=>"index_notes_on_noteable_id_and_noteable_type", :using=>:btree})
- -> 0.0029s
+ -> 0.0102s
-- add_index("notes", ["noteable_type"], {:name=>"index_notes_on_noteable_type", :using=>:btree})
- -> 0.0030s
+ -> 0.0092s
-- add_index("notes", ["project_id", "noteable_type"], {:name=>"index_notes_on_project_id_and_noteable_type", :using=>:btree})
- -> 0.0027s
+ -> 0.0082s
-- add_index("notes", ["updated_at"], {:name=>"index_notes_on_updated_at", :using=>:btree})
- -> 0.0026s
+ -> 0.0062s
-- create_table("notification_settings", {:force=>:cascade})
- -> 0.0053s
+ -> 0.0088s
-- add_index("notification_settings", ["source_id", "source_type"], {:name=>"index_notification_settings_on_source_id_and_source_type", :using=>:btree})
- -> 0.0028s
+ -> 0.0405s
-- add_index("notification_settings", ["user_id", "source_id", "source_type"], {:name=>"index_notifications_on_user_id_and_source_id_and_source_type", :unique=>true, :using=>:btree})
- -> 0.0030s
+ -> 0.0677s
-- add_index("notification_settings", ["user_id"], {:name=>"index_notification_settings_on_user_id", :using=>:btree})
- -> 0.0031s
+ -> 0.1199s
-- create_table("oauth_access_grants", {:force=>:cascade})
- -> 0.0042s
+ -> 0.0140s
-- add_index("oauth_access_grants", ["token"], {:name=>"index_oauth_access_grants_on_token", :unique=>true, :using=>:btree})
- -> 0.0031s
+ -> 0.0076s
-- create_table("oauth_access_tokens", {:force=>:cascade})
- -> 0.0051s
+ -> 0.0167s
-- add_index("oauth_access_tokens", ["refresh_token"], {:name=>"index_oauth_access_tokens_on_refresh_token", :unique=>true, :using=>:btree})
- -> 0.0030s
+ -> 0.0098s
-- add_index("oauth_access_tokens", ["resource_owner_id"], {:name=>"index_oauth_access_tokens_on_resource_owner_id", :using=>:btree})
- -> 0.0025s
+ -> 0.0074s
-- add_index("oauth_access_tokens", ["token"], {:name=>"index_oauth_access_tokens_on_token", :unique=>true, :using=>:btree})
- -> 0.0026s
+ -> 0.0078s
-- create_table("oauth_applications", {:force=>:cascade})
- -> 0.0049s
+ -> 0.0112s
-- add_index("oauth_applications", ["owner_id", "owner_type"], {:name=>"index_oauth_applications_on_owner_id_and_owner_type", :using=>:btree})
- -> 0.0030s
+ -> 0.0079s
-- add_index("oauth_applications", ["uid"], {:name=>"index_oauth_applications_on_uid", :unique=>true, :using=>:btree})
- -> 0.0032s
+ -> 0.0114s
-- create_table("oauth_openid_requests", {:force=>:cascade})
- -> 0.0048s
+ -> 0.0102s
-- create_table("pages_domains", {:force=>:cascade})
- -> 0.0052s
+ -> 0.0102s
-- add_index("pages_domains", ["domain"], {:name=>"index_pages_domains_on_domain", :unique=>true, :using=>:btree})
- -> 0.0027s
+ -> 0.0067s
+-- add_index("pages_domains", ["project_id", "enabled_until"], {:name=>"index_pages_domains_on_project_id_and_enabled_until", :using=>:btree})
+ -> 0.0114s
-- add_index("pages_domains", ["project_id"], {:name=>"index_pages_domains_on_project_id", :using=>:btree})
- -> 0.0030s
+ -> 0.0066s
+-- add_index("pages_domains", ["verified_at", "enabled_until"], {:name=>"index_pages_domains_on_verified_at_and_enabled_until", :using=>:btree})
+ -> 0.0073s
+-- add_index("pages_domains", ["verified_at"], {:name=>"index_pages_domains_on_verified_at", :using=>:btree})
+ -> 0.0063s
-- create_table("personal_access_tokens", {:force=>:cascade})
- -> 0.0056s
+ -> 0.0084s
-- add_index("personal_access_tokens", ["token"], {:name=>"index_personal_access_tokens_on_token", :unique=>true, :using=>:btree})
- -> 0.0032s
+ -> 0.0075s
-- add_index("personal_access_tokens", ["user_id"], {:name=>"index_personal_access_tokens_on_user_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0066s
-- create_table("project_authorizations", {:id=>false, :force=>:cascade})
- -> 0.0018s
+ -> 0.0087s
-- add_index("project_authorizations", ["project_id"], {:name=>"index_project_authorizations_on_project_id", :using=>:btree})
- -> 0.0033s
+ -> 0.0056s
-- add_index("project_authorizations", ["user_id", "project_id", "access_level"], {:name=>"index_project_authorizations_on_user_id_project_id_access_level", :unique=>true, :using=>:btree})
- -> 0.0029s
+ -> 0.0075s
-- create_table("project_auto_devops", {:force=>:cascade})
- -> 0.0043s
+ -> 0.0079s
-- add_index("project_auto_devops", ["project_id"], {:name=>"index_project_auto_devops_on_project_id", :unique=>true, :using=>:btree})
- -> 0.0029s
+ -> 0.0067s
-- create_table("project_custom_attributes", {:force=>:cascade})
- -> 0.0047s
+ -> 0.0071s
-- add_index("project_custom_attributes", ["key", "value"], {:name=>"index_project_custom_attributes_on_key_and_value", :using=>:btree})
- -> 0.0030s
+ -> 0.0060s
-- add_index("project_custom_attributes", ["project_id", "key"], {:name=>"index_project_custom_attributes_on_project_id_and_key", :unique=>true, :using=>:btree})
- -> 0.0028s
+ -> 0.0069s
-- create_table("project_features", {:force=>:cascade})
- -> 0.0038s
+ -> 0.0100s
-- add_index("project_features", ["project_id"], {:name=>"index_project_features_on_project_id", :using=>:btree})
- -> 0.0029s
+ -> 0.0069s
-- create_table("project_group_links", {:force=>:cascade})
- -> 0.0036s
+ -> 0.0117s
-- add_index("project_group_links", ["group_id"], {:name=>"index_project_group_links_on_group_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0121s
-- add_index("project_group_links", ["project_id"], {:name=>"index_project_group_links_on_project_id", :using=>:btree})
- -> 0.0030s
+ -> 0.0076s
-- create_table("project_import_data", {:force=>:cascade})
- -> 0.0049s
+ -> 0.0084s
-- add_index("project_import_data", ["project_id"], {:name=>"index_project_import_data_on_project_id", :using=>:btree})
- -> 0.0027s
+ -> 0.0058s
-- create_table("project_statistics", {:force=>:cascade})
- -> 0.0046s
+ -> 0.0075s
-- add_index("project_statistics", ["namespace_id"], {:name=>"index_project_statistics_on_namespace_id", :using=>:btree})
- -> 0.0027s
+ -> 0.0054s
-- add_index("project_statistics", ["project_id"], {:name=>"index_project_statistics_on_project_id", :unique=>true, :using=>:btree})
- -> 0.0029s
+ -> 0.0054s
-- create_table("projects", {:force=>:cascade})
- -> 0.0090s
+ -> 0.0077s
-- add_index("projects", ["ci_id"], {:name=>"index_projects_on_ci_id", :using=>:btree})
- -> 0.0033s
+ -> 0.0070s
-- add_index("projects", ["created_at"], {:name=>"index_projects_on_created_at", :using=>:btree})
- -> 0.0030s
+ -> 0.0060s
-- add_index("projects", ["creator_id"], {:name=>"index_projects_on_creator_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0071s
-- add_index("projects", ["description"], {:name=>"index_projects_on_description_trigram", :using=>:gin, :opclasses=>{"description"=>"gin_trgm_ops"}})
- -> 0.0022s
+ -> 0.0009s
+-- add_index("projects", ["id"], {:name=>"index_projects_on_id_partial_for_visibility", :unique=>true, :where=>"(visibility_level = ANY (ARRAY[10, 20]))", :using=>:btree})
+ -> 0.0062s
-- add_index("projects", ["last_activity_at"], {:name=>"index_projects_on_last_activity_at", :using=>:btree})
- -> 0.0032s
+ -> 0.0060s
-- add_index("projects", ["last_repository_check_failed"], {:name=>"index_projects_on_last_repository_check_failed", :using=>:btree})
- -> 0.0030s
+ -> 0.0063s
-- add_index("projects", ["last_repository_updated_at"], {:name=>"index_projects_on_last_repository_updated_at", :using=>:btree})
- -> 0.0031s
+ -> 0.0633s
-- add_index("projects", ["name"], {:name=>"index_projects_on_name_trigram", :using=>:gin, :opclasses=>{"name"=>"gin_trgm_ops"}})
- -> 0.0022s
+ -> 0.0012s
-- add_index("projects", ["namespace_id"], {:name=>"index_projects_on_namespace_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0167s
-- add_index("projects", ["path"], {:name=>"index_projects_on_path", :using=>:btree})
- -> 0.0028s
+ -> 0.0222s
-- add_index("projects", ["path"], {:name=>"index_projects_on_path_trigram", :using=>:gin, :opclasses=>{"path"=>"gin_trgm_ops"}})
- -> 0.0023s
+ -> 0.0010s
-- add_index("projects", ["pending_delete"], {:name=>"index_projects_on_pending_delete", :using=>:btree})
- -> 0.0029s
+ -> 0.0229s
-- add_index("projects", ["repository_storage"], {:name=>"index_projects_on_repository_storage", :using=>:btree})
- -> 0.0026s
+ -> 0.0173s
-- add_index("projects", ["runners_token"], {:name=>"index_projects_on_runners_token", :using=>:btree})
- -> 0.0034s
+ -> 0.0167s
-- add_index("projects", ["star_count"], {:name=>"index_projects_on_star_count", :using=>:btree})
- -> 0.0028s
+ -> 0.0491s
-- add_index("projects", ["visibility_level"], {:name=>"index_projects_on_visibility_level", :using=>:btree})
- -> 0.0027s
+ -> 0.0598s
-- create_table("protected_branch_merge_access_levels", {:force=>:cascade})
- -> 0.0042s
+ -> 0.1964s
-- add_index("protected_branch_merge_access_levels", ["protected_branch_id"], {:name=>"index_protected_branch_merge_access", :using=>:btree})
- -> 0.0029s
+ -> 0.1112s
-- create_table("protected_branch_push_access_levels", {:force=>:cascade})
- -> 0.0037s
+ -> 0.0195s
-- add_index("protected_branch_push_access_levels", ["protected_branch_id"], {:name=>"index_protected_branch_push_access", :using=>:btree})
- -> 0.0030s
+ -> 0.0069s
-- create_table("protected_branches", {:force=>:cascade})
- -> 0.0048s
+ -> 0.0113s
-- add_index("protected_branches", ["project_id"], {:name=>"index_protected_branches_on_project_id", :using=>:btree})
- -> 0.0030s
+ -> 0.0071s
-- create_table("protected_tag_create_access_levels", {:force=>:cascade})
- -> 0.0037s
+ -> 0.0180s
-- add_index("protected_tag_create_access_levels", ["protected_tag_id"], {:name=>"index_protected_tag_create_access", :using=>:btree})
- -> 0.0029s
+ -> 0.0068s
-- add_index("protected_tag_create_access_levels", ["user_id"], {:name=>"index_protected_tag_create_access_levels_on_user_id", :using=>:btree})
- -> 0.0029s
+ -> 0.0077s
-- create_table("protected_tags", {:force=>:cascade})
- -> 0.0051s
+ -> 0.0115s
-- add_index("protected_tags", ["project_id"], {:name=>"index_protected_tags_on_project_id", :using=>:btree})
- -> 0.0034s
+ -> 0.0081s
-- create_table("push_event_payloads", {:id=>false, :force=>:cascade})
- -> 0.0030s
+ -> 0.0108s
-- add_index("push_event_payloads", ["event_id"], {:name=>"index_push_event_payloads_on_event_id", :unique=>true, :using=>:btree})
- -> 0.0029s
+ -> 0.0189s
-- create_table("redirect_routes", {:force=>:cascade})
- -> 0.0049s
+ -> 0.0106s
-- add_index("redirect_routes", ["path"], {:name=>"index_redirect_routes_on_path", :unique=>true, :using=>:btree})
- -> 0.0031s
+ -> 0.0075s
-- add_index("redirect_routes", ["source_type", "source_id"], {:name=>"index_redirect_routes_on_source_type_and_source_id", :using=>:btree})
- -> 0.0034s
+ -> 0.0099s
-- create_table("releases", {:force=>:cascade})
- -> 0.0043s
+ -> 0.0126s
-- add_index("releases", ["project_id", "tag"], {:name=>"index_releases_on_project_id_and_tag", :using=>:btree})
- -> 0.0032s
+ -> 0.0066s
-- add_index("releases", ["project_id"], {:name=>"index_releases_on_project_id", :using=>:btree})
- -> 0.0030s
+ -> 0.0060s
-- create_table("routes", {:force=>:cascade})
- -> 0.0055s
+ -> 0.0091s
-- add_index("routes", ["path"], {:name=>"index_routes_on_path", :unique=>true, :using=>:btree})
- -> 0.0028s
+ -> 0.0073s
-- add_index("routes", ["path"], {:name=>"index_routes_on_path_text_pattern_ops", :using=>:btree, :opclasses=>{"path"=>"varchar_pattern_ops"}})
- -> 0.0026s
+ -> 0.0004s
-- add_index("routes", ["source_type", "source_id"], {:name=>"index_routes_on_source_type_and_source_id", :unique=>true, :using=>:btree})
- -> 0.0029s
+ -> 0.0111s
-- create_table("sent_notifications", {:force=>:cascade})
- -> 0.0048s
+ -> 0.0093s
-- add_index("sent_notifications", ["reply_key"], {:name=>"index_sent_notifications_on_reply_key", :unique=>true, :using=>:btree})
- -> 0.0029s
+ -> 0.0060s
-- create_table("services", {:force=>:cascade})
- -> 0.0091s
+ -> 0.0099s
-- add_index("services", ["project_id"], {:name=>"index_services_on_project_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0068s
-- add_index("services", ["template"], {:name=>"index_services_on_template", :using=>:btree})
- -> 0.0031s
+ -> 0.0076s
-- create_table("snippets", {:force=>:cascade})
- -> 0.0050s
+ -> 0.0073s
-- add_index("snippets", ["author_id"], {:name=>"index_snippets_on_author_id", :using=>:btree})
- -> 0.0030s
+ -> 0.0055s
-- add_index("snippets", ["file_name"], {:name=>"index_snippets_on_file_name_trigram", :using=>:gin, :opclasses=>{"file_name"=>"gin_trgm_ops"}})
- -> 0.0020s
+ -> 0.0006s
-- add_index("snippets", ["project_id"], {:name=>"index_snippets_on_project_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0058s
-- add_index("snippets", ["title"], {:name=>"index_snippets_on_title_trigram", :using=>:gin, :opclasses=>{"title"=>"gin_trgm_ops"}})
- -> 0.0020s
+ -> 0.0005s
-- add_index("snippets", ["updated_at"], {:name=>"index_snippets_on_updated_at", :using=>:btree})
- -> 0.0026s
+ -> 0.0100s
-- add_index("snippets", ["visibility_level"], {:name=>"index_snippets_on_visibility_level", :using=>:btree})
- -> 0.0026s
+ -> 0.0091s
-- create_table("spam_logs", {:force=>:cascade})
- -> 0.0048s
+ -> 0.0129s
-- create_table("subscriptions", {:force=>:cascade})
- -> 0.0041s
+ -> 0.0094s
-- add_index("subscriptions", ["subscribable_id", "subscribable_type", "user_id", "project_id"], {:name=>"index_subscriptions_on_subscribable_and_user_id_and_project_id", :unique=>true, :using=>:btree})
- -> 0.0030s
+ -> 0.0107s
-- create_table("system_note_metadata", {:force=>:cascade})
- -> 0.0040s
+ -> 0.0138s
-- add_index("system_note_metadata", ["note_id"], {:name=>"index_system_note_metadata_on_note_id", :unique=>true, :using=>:btree})
- -> 0.0029s
+ -> 0.0060s
-- create_table("taggings", {:force=>:cascade})
- -> 0.0047s
+ -> 0.0121s
-- add_index("taggings", ["tag_id", "taggable_id", "taggable_type", "context", "tagger_id", "tagger_type"], {:name=>"taggings_idx", :unique=>true, :using=>:btree})
- -> 0.0030s
+ -> 0.0078s
+-- add_index("taggings", ["tag_id"], {:name=>"index_taggings_on_tag_id", :using=>:btree})
+ -> 0.0058s
-- add_index("taggings", ["taggable_id", "taggable_type", "context"], {:name=>"index_taggings_on_taggable_id_and_taggable_type_and_context", :using=>:btree})
- -> 0.0025s
+ -> 0.0059s
+-- add_index("taggings", ["taggable_id", "taggable_type"], {:name=>"index_taggings_on_taggable_id_and_taggable_type", :using=>:btree})
+ -> 0.0056s
-- create_table("tags", {:force=>:cascade})
- -> 0.0044s
+ -> 0.0063s
-- add_index("tags", ["name"], {:name=>"index_tags_on_name", :unique=>true, :using=>:btree})
- -> 0.0026s
+ -> 0.0055s
-- create_table("timelogs", {:force=>:cascade})
- -> 0.0033s
+ -> 0.0061s
-- add_index("timelogs", ["issue_id"], {:name=>"index_timelogs_on_issue_id", :using=>:btree})
- -> 0.0027s
+ -> 0.0063s
-- add_index("timelogs", ["merge_request_id"], {:name=>"index_timelogs_on_merge_request_id", :using=>:btree})
- -> 0.0033s
+ -> 0.0052s
-- add_index("timelogs", ["user_id"], {:name=>"index_timelogs_on_user_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0055s
-- create_table("todos", {:force=>:cascade})
- -> 0.0043s
+ -> 0.0065s
-- add_index("todos", ["author_id"], {:name=>"index_todos_on_author_id", :using=>:btree})
- -> 0.0027s
+ -> 0.0081s
-- add_index("todos", ["commit_id"], {:name=>"index_todos_on_commit_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0085s
-- add_index("todos", ["note_id"], {:name=>"index_todos_on_note_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0083s
-- add_index("todos", ["project_id"], {:name=>"index_todos_on_project_id", :using=>:btree})
- -> 0.0027s
+ -> 0.0094s
-- add_index("todos", ["target_type", "target_id"], {:name=>"index_todos_on_target_type_and_target_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0070s
+-- add_index("todos", ["user_id", "id"], {:name=>"index_todos_on_user_id_and_id_done", :where=>"((state)::text = 'done'::text)", :using=>:btree})
+ -> 0.0099s
+-- add_index("todos", ["user_id", "id"], {:name=>"index_todos_on_user_id_and_id_pending", :where=>"((state)::text = 'pending'::text)", :using=>:btree})
+ -> 0.0080s
-- add_index("todos", ["user_id"], {:name=>"index_todos_on_user_id", :using=>:btree})
- -> 0.0026s
+ -> 0.0061s
-- create_table("trending_projects", {:force=>:cascade})
- -> 0.0030s
--- add_index("trending_projects", ["project_id"], {:name=>"index_trending_projects_on_project_id", :using=>:btree})
- -> 0.0027s
+ -> 0.0081s
+-- add_index("trending_projects", ["project_id"], {:name=>"index_trending_projects_on_project_id", :unique=>true, :using=>:btree})
+ -> 0.0046s
-- create_table("u2f_registrations", {:force=>:cascade})
- -> 0.0048s
+ -> 0.0063s
-- add_index("u2f_registrations", ["key_handle"], {:name=>"index_u2f_registrations_on_key_handle", :using=>:btree})
- -> 0.0029s
+ -> 0.0052s
-- add_index("u2f_registrations", ["user_id"], {:name=>"index_u2f_registrations_on_user_id", :using=>:btree})
- -> 0.0028s
+ -> 0.0072s
-- create_table("uploads", {:force=>:cascade})
- -> 0.0044s
+ -> 0.0067s
-- add_index("uploads", ["checksum"], {:name=>"index_uploads_on_checksum", :using=>:btree})
- -> 0.0028s
+ -> 0.0046s
-- add_index("uploads", ["model_id", "model_type"], {:name=>"index_uploads_on_model_id_and_model_type", :using=>:btree})
- -> 0.0027s
--- add_index("uploads", ["path"], {:name=>"index_uploads_on_path", :using=>:btree})
- -> 0.0028s
+ -> 0.0049s
+-- add_index("uploads", ["uploader", "path"], {:name=>"index_uploads_on_uploader_and_path", :using=>:btree})
+ -> 0.0052s
-- create_table("user_agent_details", {:force=>:cascade})
- -> 0.0051s
+ -> 0.0059s
-- add_index("user_agent_details", ["subject_id", "subject_type"], {:name=>"index_user_agent_details_on_subject_id_and_subject_type", :using=>:btree})
- -> 0.0028s
+ -> 0.0052s
+-- create_table("user_callouts", {:force=>:cascade})
+ -> 0.0059s
+-- add_index("user_callouts", ["user_id", "feature_name"], {:name=>"index_user_callouts_on_user_id_and_feature_name", :unique=>true, :using=>:btree})
+ -> 0.0094s
+-- add_index("user_callouts", ["user_id"], {:name=>"index_user_callouts_on_user_id", :using=>:btree})
+ -> 0.0064s
-- create_table("user_custom_attributes", {:force=>:cascade})
- -> 0.0044s
+ -> 0.0086s
-- add_index("user_custom_attributes", ["key", "value"], {:name=>"index_user_custom_attributes_on_key_and_value", :using=>:btree})
- -> 0.0027s
+ -> 0.0080s
-- add_index("user_custom_attributes", ["user_id", "key"], {:name=>"index_user_custom_attributes_on_user_id_and_key", :unique=>true, :using=>:btree})
- -> 0.0026s
--- create_table("user_synced_attributes_metadata", {:force=>:cascade})
+ -> 0.0066s
+-- create_table("user_interacted_projects", {:id=>false, :force=>:cascade})
+ -> 0.0108s
+-- add_index("user_interacted_projects", ["project_id", "user_id"], {:name=>"index_user_interacted_projects_on_project_id_and_user_id", :unique=>true, :using=>:btree})
+ -> 0.0114s
+-- add_index("user_interacted_projects", ["user_id"], {:name=>"index_user_interacted_projects_on_user_id", :using=>:btree})
-> 0.0056s
+-- create_table("user_synced_attributes_metadata", {:force=>:cascade})
+ -> 0.0115s
-- add_index("user_synced_attributes_metadata", ["user_id"], {:name=>"index_user_synced_attributes_metadata_on_user_id", :unique=>true, :using=>:btree})
- -> 0.0027s
+ -> 0.0054s
-- create_table("users", {:force=>:cascade})
- -> 0.0134s
+ -> 0.0111s
-- add_index("users", ["admin"], {:name=>"index_users_on_admin", :using=>:btree})
- -> 0.0030s
+ -> 0.0065s
-- add_index("users", ["confirmation_token"], {:name=>"index_users_on_confirmation_token", :unique=>true, :using=>:btree})
- -> 0.0029s
+ -> 0.0065s
-- add_index("users", ["created_at"], {:name=>"index_users_on_created_at", :using=>:btree})
- -> 0.0034s
+ -> 0.0068s
-- add_index("users", ["email"], {:name=>"index_users_on_email", :unique=>true, :using=>:btree})
- -> 0.0030s
+ -> 0.0066s
-- add_index("users", ["email"], {:name=>"index_users_on_email_trigram", :using=>:gin, :opclasses=>{"email"=>"gin_trgm_ops"}})
- -> 0.0431s
+ -> 0.0011s
-- add_index("users", ["ghost"], {:name=>"index_users_on_ghost", :using=>:btree})
- -> 0.0051s
+ -> 0.0063s
-- add_index("users", ["incoming_email_token"], {:name=>"index_users_on_incoming_email_token", :using=>:btree})
- -> 0.0044s
+ -> 0.0057s
-- add_index("users", ["name"], {:name=>"index_users_on_name", :using=>:btree})
- -> 0.0044s
+ -> 0.0056s
-- add_index("users", ["name"], {:name=>"index_users_on_name_trigram", :using=>:gin, :opclasses=>{"name"=>"gin_trgm_ops"}})
- -> 0.0034s
+ -> 0.0011s
-- add_index("users", ["reset_password_token"], {:name=>"index_users_on_reset_password_token", :unique=>true, :using=>:btree})
- -> 0.0044s
+ -> 0.0055s
-- add_index("users", ["rss_token"], {:name=>"index_users_on_rss_token", :using=>:btree})
- -> 0.0046s
+ -> 0.0068s
-- add_index("users", ["state"], {:name=>"index_users_on_state", :using=>:btree})
- -> 0.0040s
+ -> 0.0067s
-- add_index("users", ["username"], {:name=>"index_users_on_username", :using=>:btree})
- -> 0.0046s
+ -> 0.0072s
-- add_index("users", ["username"], {:name=>"index_users_on_username_trigram", :using=>:gin, :opclasses=>{"username"=>"gin_trgm_ops"}})
- -> 0.0044s
+ -> 0.0012s
-- create_table("users_star_projects", {:force=>:cascade})
- -> 0.0055s
+ -> 0.0100s
-- add_index("users_star_projects", ["project_id"], {:name=>"index_users_star_projects_on_project_id", :using=>:btree})
- -> 0.0037s
+ -> 0.0061s
-- add_index("users_star_projects", ["user_id", "project_id"], {:name=>"index_users_star_projects_on_user_id_and_project_id", :unique=>true, :using=>:btree})
- -> 0.0044s
+ -> 0.0068s
-- create_table("web_hook_logs", {:force=>:cascade})
- -> 0.0060s
+ -> 0.0097s
-- add_index("web_hook_logs", ["web_hook_id"], {:name=>"index_web_hook_logs_on_web_hook_id", :using=>:btree})
- -> 0.0034s
+ -> 0.0057s
-- create_table("web_hooks", {:force=>:cascade})
- -> 0.0120s
+ -> 0.0080s
-- add_index("web_hooks", ["project_id"], {:name=>"index_web_hooks_on_project_id", :using=>:btree})
- -> 0.0038s
+ -> 0.0062s
-- add_index("web_hooks", ["type"], {:name=>"index_web_hooks_on_type", :using=>:btree})
- -> 0.0036s
+ -> 0.0065s
+-- add_foreign_key("badges", "namespaces", {:column=>"group_id", :on_delete=>:cascade})
+ -> 0.0158s
+-- add_foreign_key("badges", "projects", {:on_delete=>:cascade})
+ -> 0.0140s
+-- add_foreign_key("boards", "namespaces", {:column=>"group_id", :on_delete=>:cascade})
+ -> 0.0138s
-- add_foreign_key("boards", "projects", {:name=>"fk_f15266b5f9", :on_delete=>:cascade})
- -> 0.0030s
+ -> 0.0118s
-- add_foreign_key("chat_teams", "namespaces", {:on_delete=>:cascade})
- -> 0.0021s
+ -> 0.0130s
-- add_foreign_key("ci_build_trace_section_names", "projects", {:on_delete=>:cascade})
- -> 0.0022s
+ -> 0.0131s
-- add_foreign_key("ci_build_trace_sections", "ci_build_trace_section_names", {:column=>"section_name_id", :name=>"fk_264e112c66", :on_delete=>:cascade})
- -> 0.0018s
+ -> 0.0210s
-- add_foreign_key("ci_build_trace_sections", "ci_builds", {:column=>"build_id", :name=>"fk_4ebe41f502", :on_delete=>:cascade})
- -> 0.0024s
+ -> 0.0823s
-- add_foreign_key("ci_build_trace_sections", "projects", {:on_delete=>:cascade})
- -> 0.0019s
+ -> 0.0942s
-- add_foreign_key("ci_builds", "ci_pipelines", {:column=>"auto_canceled_by_id", :name=>"fk_a2141b1522", :on_delete=>:nullify})
- -> 0.0023s
+ -> 0.1346s
-- add_foreign_key("ci_builds", "ci_stages", {:column=>"stage_id", :name=>"fk_3a9eaa254d", :on_delete=>:cascade})
- -> 0.0020s
+ -> 0.0506s
-- add_foreign_key("ci_builds", "projects", {:name=>"fk_befce0568a", :on_delete=>:cascade})
- -> 0.0024s
+ -> 0.0403s
+-- add_foreign_key("ci_builds_metadata", "ci_builds", {:column=>"build_id", :on_delete=>:cascade})
+ -> 0.0160s
+-- add_foreign_key("ci_builds_metadata", "projects", {:on_delete=>:cascade})
+ -> 0.0165s
-- add_foreign_key("ci_group_variables", "namespaces", {:column=>"group_id", :name=>"fk_33ae4d58d8", :on_delete=>:cascade})
- -> 0.0024s
+ -> 0.0153s
-- add_foreign_key("ci_job_artifacts", "ci_builds", {:column=>"job_id", :on_delete=>:cascade})
- -> 0.0019s
+ -> 0.0160s
-- add_foreign_key("ci_job_artifacts", "projects", {:on_delete=>:cascade})
- -> 0.0020s
+ -> 0.0278s
-- add_foreign_key("ci_pipeline_schedule_variables", "ci_pipeline_schedules", {:column=>"pipeline_schedule_id", :name=>"fk_41c35fda51", :on_delete=>:cascade})
- -> 0.0027s
+ -> 0.0193s
-- add_foreign_key("ci_pipeline_schedules", "projects", {:name=>"fk_8ead60fcc4", :on_delete=>:cascade})
- -> 0.0022s
+ -> 0.0184s
-- add_foreign_key("ci_pipeline_schedules", "users", {:column=>"owner_id", :name=>"fk_9ea99f58d2", :on_delete=>:nullify})
- -> 0.0025s
+ -> 0.0158s
-- add_foreign_key("ci_pipeline_variables", "ci_pipelines", {:column=>"pipeline_id", :name=>"fk_f29c5f4380", :on_delete=>:cascade})
- -> 0.0018s
+ -> 0.0097s
-- add_foreign_key("ci_pipelines", "ci_pipeline_schedules", {:column=>"pipeline_schedule_id", :name=>"fk_3d34ab2e06", :on_delete=>:nullify})
- -> 0.0019s
+ -> 0.0693s
-- add_foreign_key("ci_pipelines", "ci_pipelines", {:column=>"auto_canceled_by_id", :name=>"fk_262d4c2d19", :on_delete=>:nullify})
- -> 0.0029s
+ -> 0.1599s
-- add_foreign_key("ci_pipelines", "projects", {:name=>"fk_86635dbd80", :on_delete=>:cascade})
- -> 0.0023s
+ -> 0.1505s
-- add_foreign_key("ci_runner_projects", "projects", {:name=>"fk_4478a6f1e4", :on_delete=>:cascade})
- -> 0.0036s
+ -> 0.0984s
-- add_foreign_key("ci_stages", "ci_pipelines", {:column=>"pipeline_id", :name=>"fk_fb57e6cc56", :on_delete=>:cascade})
- -> 0.0017s
+ -> 0.1152s
-- add_foreign_key("ci_stages", "projects", {:name=>"fk_2360681d1d", :on_delete=>:cascade})
- -> 0.0020s
+ -> 0.1062s
-- add_foreign_key("ci_trigger_requests", "ci_triggers", {:column=>"trigger_id", :name=>"fk_b8ec8b7245", :on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0455s
-- add_foreign_key("ci_triggers", "projects", {:name=>"fk_e3e63f966e", :on_delete=>:cascade})
- -> 0.0021s
+ -> 0.0725s
-- add_foreign_key("ci_triggers", "users", {:column=>"owner_id", :name=>"fk_e8e10d1964", :on_delete=>:cascade})
- -> 0.0019s
+ -> 0.0774s
-- add_foreign_key("ci_variables", "projects", {:name=>"fk_ada5eb64b3", :on_delete=>:cascade})
- -> 0.0021s
+ -> 0.0626s
-- add_foreign_key("cluster_platforms_kubernetes", "clusters", {:on_delete=>:cascade})
- -> 0.0019s
+ -> 0.0529s
-- add_foreign_key("cluster_projects", "clusters", {:on_delete=>:cascade})
- -> 0.0018s
+ -> 0.0678s
-- add_foreign_key("cluster_projects", "projects", {:on_delete=>:cascade})
- -> 0.0020s
+ -> 0.0391s
-- add_foreign_key("cluster_providers_gcp", "clusters", {:on_delete=>:cascade})
- -> 0.0017s
+ -> 0.0328s
-- add_foreign_key("clusters", "users", {:on_delete=>:nullify})
- -> 0.0018s
+ -> 0.1266s
-- add_foreign_key("clusters_applications_helm", "clusters", {:on_delete=>:cascade})
- -> 0.0019s
+ -> 0.0489s
+-- add_foreign_key("clusters_applications_ingress", "clusters", {:name=>"fk_753a7b41c1", :on_delete=>:cascade})
+ -> 0.0565s
+-- add_foreign_key("clusters_applications_prometheus", "clusters", {:name=>"fk_557e773639", :on_delete=>:cascade})
+ -> 0.0174s
+-- add_foreign_key("clusters_applications_runners", "ci_runners", {:column=>"runner_id", :name=>"fk_02de2ded36", :on_delete=>:nullify})
+ -> 0.0182s
+-- add_foreign_key("clusters_applications_runners", "clusters", {:on_delete=>:cascade})
+ -> 0.0208s
-- add_foreign_key("container_repositories", "projects")
- -> 0.0020s
+ -> 0.0186s
-- add_foreign_key("deploy_keys_projects", "projects", {:name=>"fk_58a901ca7e", :on_delete=>:cascade})
- -> 0.0019s
+ -> 0.0140s
-- add_foreign_key("deployments", "projects", {:name=>"fk_b9a3851b82", :on_delete=>:cascade})
- -> 0.0021s
+ -> 0.0328s
-- add_foreign_key("environments", "projects", {:name=>"fk_d1c8c1da6a", :on_delete=>:cascade})
- -> 0.0019s
+ -> 0.0221s
-- add_foreign_key("events", "projects", {:on_delete=>:cascade})
- -> 0.0020s
+ -> 0.0212s
-- add_foreign_key("events", "users", {:column=>"author_id", :name=>"fk_edfd187b6f", :on_delete=>:cascade})
- -> 0.0020s
+ -> 0.0150s
-- add_foreign_key("fork_network_members", "fork_networks", {:on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0134s
-- add_foreign_key("fork_network_members", "projects", {:column=>"forked_from_project_id", :name=>"fk_b01280dae4", :on_delete=>:nullify})
- -> 0.0019s
+ -> 0.0200s
-- add_foreign_key("fork_network_members", "projects", {:on_delete=>:cascade})
- -> 0.0018s
+ -> 0.0162s
-- add_foreign_key("fork_networks", "projects", {:column=>"root_project_id", :name=>"fk_e7b436b2b5", :on_delete=>:nullify})
- -> 0.0018s
+ -> 0.0138s
-- add_foreign_key("forked_project_links", "projects", {:column=>"forked_to_project_id", :name=>"fk_434510edb0", :on_delete=>:cascade})
- -> 0.0018s
+ -> 0.0137s
-- add_foreign_key("gcp_clusters", "projects", {:on_delete=>:cascade})
- -> 0.0029s
+ -> 0.0148s
-- add_foreign_key("gcp_clusters", "services", {:on_delete=>:nullify})
- -> 0.0022s
+ -> 0.0216s
-- add_foreign_key("gcp_clusters", "users", {:on_delete=>:nullify})
- -> 0.0019s
+ -> 0.0156s
-- add_foreign_key("gpg_key_subkeys", "gpg_keys", {:on_delete=>:cascade})
- -> 0.0017s
+ -> 0.0139s
-- add_foreign_key("gpg_keys", "users", {:on_delete=>:cascade})
- -> 0.0019s
+ -> 0.0142s
-- add_foreign_key("gpg_signatures", "gpg_key_subkeys", {:on_delete=>:nullify})
- -> 0.0016s
+ -> 0.0216s
-- add_foreign_key("gpg_signatures", "gpg_keys", {:on_delete=>:nullify})
- -> 0.0016s
+ -> 0.0211s
-- add_foreign_key("gpg_signatures", "projects", {:on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0215s
-- add_foreign_key("group_custom_attributes", "namespaces", {:column=>"group_id", :on_delete=>:cascade})
- -> 0.0014s
+ -> 0.0174s
+-- add_foreign_key("internal_ids", "projects", {:on_delete=>:cascade})
+ -> 0.0143s
-- add_foreign_key("issue_assignees", "issues", {:name=>"fk_b7d881734a", :on_delete=>:cascade})
- -> 0.0019s
+ -> 0.0139s
-- add_foreign_key("issue_assignees", "users", {:name=>"fk_5e0c8d9154", :on_delete=>:cascade})
- -> 0.0015s
+ -> 0.0138s
-- add_foreign_key("issue_metrics", "issues", {:on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0106s
-- add_foreign_key("issues", "issues", {:column=>"moved_to_id", :name=>"fk_a194299be1", :on_delete=>:nullify})
- -> 0.0014s
+ -> 0.0366s
-- add_foreign_key("issues", "milestones", {:name=>"fk_96b1dd429c", :on_delete=>:nullify})
- -> 0.0016s
+ -> 0.0309s
-- add_foreign_key("issues", "projects", {:name=>"fk_899c8f3231", :on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0314s
-- add_foreign_key("issues", "users", {:column=>"author_id", :name=>"fk_05f1e72feb", :on_delete=>:nullify})
- -> 0.0015s
+ -> 0.0504s
+-- add_foreign_key("issues", "users", {:column=>"closed_by_id", :name=>"fk_c63cbf6c25", :on_delete=>:nullify})
+ -> 0.0428s
-- add_foreign_key("issues", "users", {:column=>"updated_by_id", :name=>"fk_ffed080f01", :on_delete=>:nullify})
- -> 0.0017s
+ -> 0.0333s
-- add_foreign_key("label_priorities", "labels", {:on_delete=>:cascade})
- -> 0.0015s
+ -> 0.0143s
-- add_foreign_key("label_priorities", "projects", {:on_delete=>:cascade})
- -> 0.0015s
+ -> 0.0160s
-- add_foreign_key("labels", "namespaces", {:column=>"group_id", :on_delete=>:cascade})
- -> 0.0015s
+ -> 0.0176s
-- add_foreign_key("labels", "projects", {:name=>"fk_7de4989a69", :on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0216s
+-- add_foreign_key("lfs_file_locks", "projects", {:on_delete=>:cascade})
+ -> 0.0144s
+-- add_foreign_key("lfs_file_locks", "users", {:on_delete=>:cascade})
+ -> 0.0178s
-- add_foreign_key("lists", "boards", {:name=>"fk_0d3f677137", :on_delete=>:cascade})
- -> 0.0015s
+ -> 0.0161s
-- add_foreign_key("lists", "labels", {:name=>"fk_7a5553d60f", :on_delete=>:cascade})
- -> 0.0014s
+ -> 0.0137s
-- add_foreign_key("members", "users", {:name=>"fk_2e88fb7ce9", :on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0171s
-- add_foreign_key("merge_request_diff_commits", "merge_request_diffs", {:on_delete=>:cascade})
- -> 0.0014s
+ -> 0.0143s
-- add_foreign_key("merge_request_diff_files", "merge_request_diffs", {:on_delete=>:cascade})
- -> 0.0014s
+ -> 0.0106s
-- add_foreign_key("merge_request_diffs", "merge_requests", {:name=>"fk_8483f3258f", :on_delete=>:cascade})
- -> 0.0019s
+ -> 0.0119s
-- add_foreign_key("merge_request_metrics", "ci_pipelines", {:column=>"pipeline_id", :on_delete=>:cascade})
- -> 0.0017s
+ -> 0.0163s
-- add_foreign_key("merge_request_metrics", "merge_requests", {:on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0204s
-- add_foreign_key("merge_request_metrics", "users", {:column=>"latest_closed_by_id", :name=>"fk_ae440388cc", :on_delete=>:nullify})
- -> 0.0015s
+ -> 0.0196s
-- add_foreign_key("merge_request_metrics", "users", {:column=>"merged_by_id", :name=>"fk_7f28d925f3", :on_delete=>:nullify})
- -> 0.0015s
+ -> 0.0202s
-- add_foreign_key("merge_requests", "ci_pipelines", {:column=>"head_pipeline_id", :name=>"fk_fd82eae0b9", :on_delete=>:nullify})
- -> 0.0014s
+ -> 0.0394s
-- add_foreign_key("merge_requests", "merge_request_diffs", {:column=>"latest_merge_request_diff_id", :name=>"fk_06067f5644", :on_delete=>:nullify})
- -> 0.0014s
+ -> 0.0532s
-- add_foreign_key("merge_requests", "milestones", {:name=>"fk_6a5165a692", :on_delete=>:nullify})
- -> 0.0015s
+ -> 0.0291s
-- add_foreign_key("merge_requests", "projects", {:column=>"source_project_id", :name=>"fk_3308fe130c", :on_delete=>:nullify})
- -> 0.0017s
+ -> 0.0278s
-- add_foreign_key("merge_requests", "projects", {:column=>"target_project_id", :name=>"fk_a6963e8447", :on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0367s
-- add_foreign_key("merge_requests", "users", {:column=>"assignee_id", :name=>"fk_6149611a04", :on_delete=>:nullify})
- -> 0.0016s
+ -> 0.0327s
-- add_foreign_key("merge_requests", "users", {:column=>"author_id", :name=>"fk_e719a85f8a", :on_delete=>:nullify})
- -> 0.0017s
+ -> 0.0337s
-- add_foreign_key("merge_requests", "users", {:column=>"merge_user_id", :name=>"fk_ad525e1f87", :on_delete=>:nullify})
- -> 0.0018s
+ -> 0.0517s
-- add_foreign_key("merge_requests", "users", {:column=>"updated_by_id", :name=>"fk_641731faff", :on_delete=>:nullify})
- -> 0.0017s
+ -> 0.0335s
-- add_foreign_key("merge_requests_closing_issues", "issues", {:on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0167s
-- add_foreign_key("merge_requests_closing_issues", "merge_requests", {:on_delete=>:cascade})
- -> 0.0014s
+ -> 0.0191s
-- add_foreign_key("milestones", "namespaces", {:column=>"group_id", :name=>"fk_95650a40d4", :on_delete=>:cascade})
- -> 0.0014s
+ -> 0.0206s
-- add_foreign_key("milestones", "projects", {:name=>"fk_9bd0a0c791", :on_delete=>:cascade})
- -> 0.0017s
+ -> 0.0221s
-- add_foreign_key("notes", "projects", {:name=>"fk_99e097b079", :on_delete=>:cascade})
- -> 0.0019s
+ -> 0.0332s
-- add_foreign_key("oauth_openid_requests", "oauth_access_grants", {:column=>"access_grant_id", :name=>"fk_oauth_openid_requests_oauth_access_grants_access_grant_id"})
- -> 0.0014s
+ -> 0.0128s
-- add_foreign_key("pages_domains", "projects", {:name=>"fk_ea2f6dfc6f", :on_delete=>:cascade})
- -> 0.0021s
+ -> 0.0220s
-- add_foreign_key("personal_access_tokens", "users")
- -> 0.0016s
+ -> 0.0187s
-- add_foreign_key("project_authorizations", "projects", {:on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0149s
-- add_foreign_key("project_authorizations", "users", {:on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0167s
-- add_foreign_key("project_auto_devops", "projects", {:on_delete=>:cascade})
- -> 0.0026s
+ -> 0.0142s
-- add_foreign_key("project_custom_attributes", "projects", {:on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0218s
-- add_foreign_key("project_features", "projects", {:name=>"fk_18513d9b92", :on_delete=>:cascade})
- -> 0.0020s
+ -> 0.0204s
-- add_foreign_key("project_group_links", "projects", {:name=>"fk_daa8cee94c", :on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0174s
-- add_foreign_key("project_import_data", "projects", {:name=>"fk_ffb9ee3a10", :on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0138s
-- add_foreign_key("project_statistics", "projects", {:on_delete=>:cascade})
- -> 0.0021s
+ -> 0.0125s
-- add_foreign_key("protected_branch_merge_access_levels", "protected_branches", {:name=>"fk_8a3072ccb3", :on_delete=>:cascade})
- -> 0.0014s
+ -> 0.0157s
-- add_foreign_key("protected_branch_push_access_levels", "protected_branches", {:name=>"fk_9ffc86a3d9", :on_delete=>:cascade})
- -> 0.0014s
+ -> 0.0112s
-- add_foreign_key("protected_branches", "projects", {:name=>"fk_7a9c6d93e7", :on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0122s
-- add_foreign_key("protected_tag_create_access_levels", "namespaces", {:column=>"group_id"})
- -> 0.0016s
+ -> 0.0131s
-- add_foreign_key("protected_tag_create_access_levels", "protected_tags", {:name=>"fk_f7dfda8c51", :on_delete=>:cascade})
- -> 0.0013s
+ -> 0.0168s
-- add_foreign_key("protected_tag_create_access_levels", "users")
- -> 0.0018s
+ -> 0.0221s
-- add_foreign_key("protected_tags", "projects", {:name=>"fk_8e4af87648", :on_delete=>:cascade})
- -> 0.0015s
+ -> 0.0135s
-- add_foreign_key("push_event_payloads", "events", {:name=>"fk_36c74129da", :on_delete=>:cascade})
- -> 0.0013s
+ -> 0.0107s
-- add_foreign_key("releases", "projects", {:name=>"fk_47fe2a0596", :on_delete=>:cascade})
- -> 0.0015s
+ -> 0.0131s
-- add_foreign_key("services", "projects", {:name=>"fk_71cce407f9", :on_delete=>:cascade})
- -> 0.0015s
+ -> 0.0142s
-- add_foreign_key("snippets", "projects", {:name=>"fk_be41fd4bb7", :on_delete=>:cascade})
- -> 0.0017s
+ -> 0.0178s
-- add_foreign_key("subscriptions", "projects", {:on_delete=>:cascade})
- -> 0.0018s
+ -> 0.0160s
-- add_foreign_key("system_note_metadata", "notes", {:name=>"fk_d83a918cb1", :on_delete=>:cascade})
- -> 0.0015s
+ -> 0.0156s
-- add_foreign_key("timelogs", "issues", {:name=>"fk_timelogs_issues_issue_id", :on_delete=>:cascade})
- -> 0.0015s
+ -> 0.0183s
-- add_foreign_key("timelogs", "merge_requests", {:name=>"fk_timelogs_merge_requests_merge_request_id", :on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0198s
+-- add_foreign_key("todos", "notes", {:name=>"fk_91d1f47b13", :on_delete=>:cascade})
+ -> 0.0276s
-- add_foreign_key("todos", "projects", {:name=>"fk_45054f9c45", :on_delete=>:cascade})
- -> 0.0018s
+ -> 0.0175s
+-- add_foreign_key("todos", "users", {:column=>"author_id", :name=>"fk_ccf0373936", :on_delete=>:cascade})
+ -> 0.0182s
+-- add_foreign_key("todos", "users", {:name=>"fk_d94154aa95", :on_delete=>:cascade})
+ -> 0.0184s
-- add_foreign_key("trending_projects", "projects", {:on_delete=>:cascade})
- -> 0.0015s
+ -> 0.0338s
-- add_foreign_key("u2f_registrations", "users")
- -> 0.0017s
+ -> 0.0176s
+-- add_foreign_key("user_callouts", "users", {:on_delete=>:cascade})
+ -> 0.0160s
-- add_foreign_key("user_custom_attributes", "users", {:on_delete=>:cascade})
- -> 0.0019s
+ -> 0.0191s
+-- add_foreign_key("user_interacted_projects", "projects", {:name=>"fk_722ceba4f7", :on_delete=>:cascade})
+ -> 0.0171s
+-- add_foreign_key("user_interacted_projects", "users", {:name=>"fk_0894651f08", :on_delete=>:cascade})
+ -> 0.0155s
-- add_foreign_key("user_synced_attributes_metadata", "users", {:on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0164s
-- add_foreign_key("users_star_projects", "projects", {:name=>"fk_22cd27ddfc", :on_delete=>:cascade})
- -> 0.0016s
+ -> 0.0180s
-- add_foreign_key("web_hook_logs", "web_hooks", {:on_delete=>:cascade})
- -> 0.0014s
+ -> 0.0164s
-- add_foreign_key("web_hooks", "projects", {:name=>"fk_0c8ca6d9d1", :on_delete=>:cascade})
- -> 0.0017s
+ -> 0.0172s
-- initialize_schema_migrations_table()
- -> 0.0112s
+ -> 0.0212s
+Adding limits to schema.rb for mysql
+-- column_exists?(:merge_request_diffs, :st_commits)
+ -> 0.0010s
+-- column_exists?(:merge_request_diffs, :st_diffs)
+ -> 0.0006s
+-- change_column(:snippets, :content, :text, {:limit=>2147483647})
+ -> 0.0308s
+-- change_column(:notes, :st_diff, :text, {:limit=>2147483647})
+ -> 0.0366s
+-- change_column(:snippets, :content_html, :text, {:limit=>2147483647})
+ -> 0.0272s
+-- change_column(:merge_request_diff_files, :diff, :text, {:limit=>2147483647})
+ -> 0.0170s
+$ date
+Thu Apr 5 11:19:41 UTC 2018
$ JOB_NAME=( $CI_JOB_NAME )
$ export CI_NODE_INDEX=${JOB_NAME[-2]}
$ export CI_NODE_TOTAL=${JOB_NAME[-1]}
$ export KNAPSACK_REPORT_PATH=knapsack/${CI_PROJECT_NAME}/${JOB_NAME[0]}_node_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
$ export KNAPSACK_GENERATE_REPORT=true
+$ export SUITE_FLAKY_RSPEC_REPORT_PATH=${FLAKY_RSPEC_SUITE_REPORT_PATH}
+$ export FLAKY_RSPEC_REPORT_PATH=rspec_flaky/all_${JOB_NAME[0]}_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
+$ export NEW_FLAKY_RSPEC_REPORT_PATH=rspec_flaky/new_${JOB_NAME[0]}_${CI_NODE_INDEX}_${CI_NODE_TOTAL}_report.json
+$ export FLAKY_RSPEC_GENERATE_REPORT=true
$ export CACHE_CLASSES=true
-$ cp ${KNAPSACK_SPINACH_SUITE_REPORT_PATH} ${KNAPSACK_REPORT_PATH}
+$ cp ${KNAPSACK_RSPEC_SUITE_REPORT_PATH} ${KNAPSACK_REPORT_PATH}
+$ [[ -f $FLAKY_RSPEC_REPORT_PATH ]] || echo "{}" > ${FLAKY_RSPEC_REPORT_PATH}
+$ [[ -f $NEW_FLAKY_RSPEC_REPORT_PATH ]] || echo "{}" > ${NEW_FLAKY_RSPEC_REPORT_PATH}
$ scripts/gitaly-test-spawn
-Gem.path: ["/root/.gem/ruby/2.3.0", "/usr/local/lib/ruby/gems/2.3.0", "/usr/local/bundle"]
-ENV['BUNDLE_GEMFILE']: nil
-ENV['RUBYOPT']: nil
-bundle config in /builds/gitlab-org/gitlab-ce
-scripts/gitaly-test-spawn:10:in `<main>': undefined local variable or method `gitaly_dir' for main:Object (NameError)
-Did you mean? gitaly_dir
-Settings are listed in order of priority. The top value will be used.
-retry
-Set for your local app (/usr/local/bundle/config): 3
+59
+$ knapsack rspec "--color --format documentation"
+
+Report specs:
+spec/services/todo_service_spec.rb
+spec/lib/gitlab/import_export/project_tree_saver_spec.rb
+spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb
+spec/controllers/projects/merge_requests_controller_spec.rb
+spec/controllers/groups_controller_spec.rb
+spec/features/projects/import_export/import_file_spec.rb
+spec/lib/gitlab/middleware/go_spec.rb
+spec/services/groups/transfer_service_spec.rb
+spec/features/projects/blobs/edit_spec.rb
+spec/services/boards/lists/move_service_spec.rb
+spec/services/create_deployment_service_spec.rb
+spec/controllers/groups/milestones_controller_spec.rb
+spec/helpers/groups_helper_spec.rb
+spec/requests/api/v3/todos_spec.rb
+spec/models/project_services/teamcity_service_spec.rb
+spec/lib/gitlab/conflict/file_spec.rb
+spec/lib/banzai/filter/snippet_reference_filter_spec.rb
+spec/finders/autocomplete_users_finder_spec.rb
+spec/models/service_spec.rb
+spec/services/test_hooks/project_service_spec.rb
+spec/features/projects/merge_requests/user_views_open_merge_request_spec.rb
+spec/finders/runner_jobs_finder_spec.rb
+spec/features/projects/snippets_spec.rb
+spec/requests/api/v3/environments_spec.rb
+spec/requests/api/namespaces_spec.rb
+spec/services/merge_requests/get_urls_service_spec.rb
+spec/models/lfs_file_lock_spec.rb
+spec/lib/gitlab/ci/config/entry/boolean_spec.rb
+
+Leftover specs:
+
+Knapsack report generator started!
+
+==> Setting up GitLab Shell...
+ GitLab Shell setup in 0.307428917 seconds...
+
+==> Setting up Gitaly...
+ Gitaly setup in 0.000135767 seconds...
+
+TodoService
+ updates cached counts when a todo is created
+ Issues
+ #new_issue
+ creates a todo if assigned
+ does not create a todo if unassigned
+ creates a todo if assignee is the current user
+ creates a todo for each valid mentioned user
+ creates a directly addressed todo for each valid addressed user
+ creates correct todos for each valid user based on the type of mention
+ does not create todo if user can not see the issue when issue is confidential
+ does not create directly addressed todo if user cannot see the issue when issue is confidential
+ when a private group is mentioned
+ creates a todo for group members
+ #update_issue
+ creates a todo for each valid mentioned user not included in skip_users
+ creates a todo for each valid user not included in skip_users based on the type of mention
+ creates a directly addressed todo for each valid addressed user not included in skip_users
+ does not create a todo if user was already mentioned and todo is pending
+ does not create a todo if user was already mentioned and todo is done
+ does not create a directly addressed todo if user was already mentioned or addressed and todo is pending
+ does not create a directly addressed todo if user was already mentioned or addressed and todo is done
+ does not create todo if user can not see the issue when issue is confidential
+ does not create a directly addressed todo if user can not see the issue when issue is confidential
+ issues with a task list
+ does not create todo when tasks are marked as completed
+ does not create directly addressed todo when tasks are marked as completed
+ does not raise an error when description not change
+ #close_issue
+ marks related pending todos to the target for the user as done
+ #destroy_target
+ refreshes the todos count cache for users with todos on the target
+ does not refresh the todos count cache for users with only done todos on the target
+ yields the target to the caller
+ #reassigned_issue
+ creates a pending todo for new assignee
+ does not create a todo if unassigned
+ creates a todo if new assignee is the current user
+ #mark_pending_todos_as_done
+ marks related pending todos to the target for the user as done
+ cached counts
+ updates when todos change
+ #mark_todos_as_done
+ behaves like updating todos state
+ updates related todos for the user with the new_state
+ returns the updated ids
+ cached counts
+ updates when todos change
+ #mark_todos_as_done_by_ids
+ behaves like updating todos state
+ updates related todos for the user with the new_state
+ returns the updated ids
+ cached counts
+ updates when todos change
+ #mark_todos_as_pending
+ behaves like updating todos state
+ updates related todos for the user with the new_state
+ returns the updated ids
+ cached counts
+ updates when todos change
+ #mark_todos_as_pending_by_ids
+ behaves like updating todos state
+ updates related todos for the user with the new_state
+ returns the updated ids
+ cached counts
+ updates when todos change
+ #new_note
+ mark related pending todos to the noteable for the note author as done
+ does not mark related pending todos it is a system note
+ creates a todo for each valid mentioned user
+ creates a todo for each valid user based on the type of mention
+ creates a directly addressed todo for each valid addressed user
+ does not create todo if user can not see the issue when leaving a note on a confidential issue
+ does not create a directly addressed todo if user can not see the issue when leaving a note on a confidential issue
+ does not create todo when leaving a note on snippet
+ on commit
+ creates a todo for each valid mentioned user when leaving a note on commit
+ creates a directly addressed todo for each valid mentioned user when leaving a note on commit
+ #mark_todo
+ creates a todo from a issue
+ #todo_exists?
+ returns false when no todo exist for the given issuable
+ returns true when a todo exist for the given issuable
+ Merge Requests
+ #new_merge_request
+ creates a pending todo if assigned
+ does not create a todo if unassigned
+ does not create a todo if assignee is the current user
+ creates a todo for each valid mentioned user
+ creates a todo for each valid user based on the type of mention
+ creates a directly addressed todo for each valid addressed user
+ #update_merge_request
+ creates a todo for each valid mentioned user not included in skip_users
+ creates a todo for each valid user not included in skip_users based on the type of mention
+ creates a directly addressed todo for each valid addressed user not included in skip_users
+ does not create a todo if user was already mentioned and todo is pending
+ does not create a todo if user was already mentioned and todo is done
+ does not create a directly addressed todo if user was already mentioned or addressed and todo is pending
+ does not create a directly addressed todo if user was already mentioned or addressed and todo is done
+ with a task list
+ does not create todo when tasks are marked as completed
+ does not create directly addressed todo when tasks are marked as completed
+ does not raise an error when description not change
+ #close_merge_request
+ marks related pending todos to the target for the user as done
+ #reassigned_merge_request
+ creates a pending todo for new assignee
+ does not create a todo if unassigned
+ creates a todo if new assignee is the current user
+ does not create a todo for guests
+ does not create a directly addressed todo for guests
+ #merge_merge_request
+ marks related pending todos to the target for the user as done
+ does not create todo for guests
+ does not create directly addressed todo for guests
+ #new_award_emoji
+ marks related pending todos to the target for the user as done
+ #merge_request_build_failed
+ creates a pending todo for the merge request author
+ creates a pending todo for merge_user
+ #merge_request_push
+ marks related pending todos to the target for the user as done
+ #merge_request_became_unmergeable
+ creates a pending todo for a merge_user
+ #mark_todo
+ creates a todo from a merge request
+ #new_note
+ creates a todo for mentioned user on new diff note
+ creates a directly addressed todo for addressed user on new diff note
+ creates a todo for mentioned user on legacy diff note
+ does not create todo for guests
+ #update_note
+ creates a todo for each valid mentioned user not included in skip_users
+ creates a todo for each valid user not included in skip_users based on the type of mention
+ creates a directly addressed todo for each valid addressed user not included in skip_users
+ does not create a todo if user was already mentioned and todo is pending
+ does not create a todo if user was already mentioned and todo is done
+ does not create a directly addressed todo if user was already mentioned or addressed and todo is pending
+ does not create a directly addressed todo if user was already mentioned or addressed and todo is done
+ #mark_todos_as_done
+ marks a relation of todos as done
+ marks an array of todos as done
+ returns the ids of updated todos
+ when some of the todos are done already
+ returns the ids of those still pending
+ returns an empty array if all are done
+ #mark_todos_as_done_by_ids
+ marks an array of todo ids as done
+ marks a single todo id as done
+ caches the number of todos of a user
+
+Gitlab::ImportExport::ProjectTreeSaver
+ saves the project tree into a json object
+ saves project successfully
+ JSON
+ saves the correct json
+ has milestones
+ has merge requests
+ has merge request's milestones
+ has merge request's source branch SHA
+ has merge request's target branch SHA
+ has events
+ has snippets
+ has snippet notes
+ has releases
+ has issues
+ has issue comments
+ has issue assignees
+ has author on issue comments
+ has project members
+ has merge requests diffs
+ has merge request diff files
+ has merge request diff commits
+ has merge requests comments
+ has author on merge requests comments
+ has pipeline stages
+ has pipeline statuses
+ has pipeline builds
+ has no when YML attributes but only the DB column
+ has pipeline commits
+ has ci pipeline notes
+ has labels with no associations
+ has labels associated to records
+ has project and group labels
+ has priorities associated to labels
+ saves the correct service type
+ saves the properties for a service
+ has project feature
+ has custom attributes
+ has badges
+ does not complain about non UTF-8 characters in MR diff files
+ with description override
+ overrides the project description
+ group members
+ does not export group members if it has no permission
+ does not export group members as master
+ exports group members as group owner
+ as admin
+ exports group members as admin
+ exports group members as project members
+ project attributes
+ contains the html description
+ does not contain the runners token
+
+Gitlab::BackgroundMigration::DeserializeMergeRequestDiffsAndCommits
+ #perform
+ when the diff IDs passed do not exist
+ does not raise
+ when the merge request diff has no serialised commits or diffs
+ does not raise
+ processing multiple merge request diffs
+ when BUFFER_ROWS is exceeded
+ inserts commit rows in chunks of BUFFER_ROWS
+ inserts diff rows in chunks of DIFF_FILE_BUFFER_ROWS
+ when BUFFER_ROWS is not exceeded
+ only updates once
+ when some rows were already inserted due to a previous failure
+ does not raise
+ logs a message
+ ends up with the correct rows
+ when the merge request diff update fails
+ raises an error
+ logs the error
+ still adds diff commits
+ still adds diff files
+ when the merge request diff has valid commits and diffs
+ creates correct entries in the merge_request_diff_commits table
+ creates correct entries in the merge_request_diff_files table
+ sets the st_commits and st_diffs columns to nil
+ when the merge request diff has diffs but no commits
+ creates correct entries in the merge_request_diff_commits table
+ creates correct entries in the merge_request_diff_files table
+ sets the st_commits and st_diffs columns to nil
+ when the merge request diffs do not have too_large set
+ creates correct entries in the merge_request_diff_commits table
+ creates correct entries in the merge_request_diff_files table
+ sets the st_commits and st_diffs columns to nil
+ when the merge request diffs do not have a_mode and b_mode set
+ creates correct entries in the merge_request_diff_commits table
+ creates correct entries in the merge_request_diff_files table
+ sets the st_commits and st_diffs columns to nil
+ when the merge request diffs have binary content
+ creates correct entries in the merge_request_diff_commits table
+ creates correct entries in the merge_request_diff_files table
+ sets the st_commits and st_diffs columns to nil
+ when the merge request diff has commits, but no diffs
+ creates correct entries in the merge_request_diff_commits table
+ creates correct entries in the merge_request_diff_files table
+ sets the st_commits and st_diffs columns to nil
+ when the merge request diffs have invalid content
+ creates correct entries in the merge_request_diff_commits table
+ creates correct entries in the merge_request_diff_files table
+ sets the st_commits and st_diffs columns to nil
+ when the merge request diffs are Rugged::Patch instances
+ creates correct entries in the merge_request_diff_commits table
+ creates correct entries in the merge_request_diff_files table
+ sets the st_commits and st_diffs columns to nil
+ when the merge request diffs are Rugged::Diff::Delta instances
+ creates correct entries in the merge_request_diff_commits table
+ creates correct entries in the merge_request_diff_files table
+ sets the st_commits and st_diffs columns to nil
+
+Projects::MergeRequestsController
+ GET commit_change_content
+ renders commit_change_content template
+ GET show
+ behaves like loads labels
+ loads labels into the @labels variable
+ as html
+ renders merge request page
+ loads notes
+ with special_role FIRST_TIME_CONTRIBUTOR
+ as json
+ with basic serializer param
+ renders basic MR entity as json
+ with widget serializer param
+ renders widget MR entity as json
+ when no serialiser was passed
+ renders widget MR entity as json
+ as diff
+ triggers workhorse to serve the request
+ as patch
+ triggers workhorse to serve the request
+ GET index
+ behaves like issuables list meta-data
+ creates indexed meta-data object for issuable notes and votes count
+ when given empty collection
+ doesn't execute any queries with false conditions
+ when page param
+ redirects to last_page if page number is larger than number of pages
+ redirects to specified page
+ does not redirect to external sites when provided a host field
+ when filtering by opened state
+ with opened merge requests
+ lists those merge requests
+ with reopened merge requests
+ lists those merge requests
+ PUT update
+ changing the assignee
+ limits the attributes exposed on the assignee
+ when user does not have access to update issue
+ responds with 404
+ there is no source project
+ closes MR without errors
+ allows editing of a closed merge request
+ does not allow to update target branch closed merge request
+ behaves like update invalid issuable
+ when updating causes conflicts
+ renders edit when format is html
+ renders json error message when format is json
+ when updating an invalid issuable
+ renders edit when merge request is invalid
+ POST merge
+ when user cannot access
+ returns 404
+ when the merge request is not mergeable
+ returns :failed
+ when the sha parameter does not match the source SHA
+ returns :sha_mismatch
+ when the sha parameter matches the source SHA
+ returns :success
+ starts the merge immediately
+ when the pipeline succeeds is passed
+ returns :merge_when_pipeline_succeeds
+ sets the MR to merge when the pipeline succeeds
+ when project.only_allow_merge_if_pipeline_succeeds? is true
+ returns :merge_when_pipeline_succeeds
+ and head pipeline is not the current one
+ returns :failed
+ only_allow_merge_if_all_discussions_are_resolved? setting
+ when enabled
+ with unresolved discussion
+ returns :failed
+ with all discussions resolved
+ returns :success
+ when disabled
+ with unresolved discussion
+ returns :success
+ with all discussions resolved
+ returns :success
+ DELETE destroy
+ denies access to users unless they're admin or project owner
+ when the user is owner
+ deletes the merge request
+ delegates the update of the todos count cache to TodoService
+ GET commits
+ renders the commits template to a string
+ GET pipelines
+ responds with serialized pipelines
+ POST remove_wip
+ removes the wip status
+ renders MergeRequest as JSON
+ POST cancel_merge_when_pipeline_succeeds
+ calls MergeRequests::MergeWhenPipelineSucceedsService
+ should respond with numeric status code success
+ renders MergeRequest as JSON
+ POST assign_related_issues
+ shows a flash message on success
+ correctly pluralizes flash message on success
+ calls MergeRequests::AssignIssuesService
+ is skipped when not signed in
+ GET ci_environments_status
+ the environment is from a forked project
+ links to the environment on that project
+ GET pipeline_status.json
+ when head_pipeline exists
+ return a detailed head_pipeline status in json
+ when head_pipeline does not exist
+ return empty
+ POST #rebase
+ successfully
+ enqeues a RebaseWorker
+ with a forked project
+ user cannot push to source branch
+ returns 404
+ user can push to source branch
+ returns 200
+
+GroupsController
+ GET #show
+ as html
+ assigns whether or not a group has children
+ as atom
+ assigns events for all the projects in the group
+ GET #new
+ when creating subgroups
+ and can_create_group is true
+ and logged in as Admin
+ behaves like member with ability to create subgroups
+ renders the new page (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ and logged in as Owner
+ behaves like member with ability to create subgroups
+ renders the new page (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ and logged in as Guest
+ behaves like member without ability to create subgroups
+ renders the 404 page (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ and logged in as Developer
+ behaves like member without ability to create subgroups
+ renders the 404 page (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ and logged in as Master
+ behaves like member without ability to create subgroups
+ renders the 404 page (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ and can_create_group is false
+ and logged in as Admin
+ behaves like member with ability to create subgroups
+ renders the new page (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ and logged in as Owner
+ behaves like member with ability to create subgroups
+ renders the new page (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ and logged in as Guest
+ behaves like member without ability to create subgroups
+ renders the 404 page (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ and logged in as Developer
+ behaves like member without ability to create subgroups
+ renders the 404 page (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ and logged in as Master
+ behaves like member without ability to create subgroups
+ renders the 404 page (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ GET #activity
+ as json
+ includes all projects in event feed
+ POST #create
+ when creating subgroups
+ and can_create_group is true
+ and logged in as Owner
+ creates the subgroup (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ and logged in as Developer
+ renders the new template (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ and can_create_group is false
+ and logged in as Owner
+ creates the subgroup (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ and logged in as Developer
+ renders the new template (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ when creating a top level group
+ and can_create_group is enabled
+ creates the Group
+ and can_create_group is disabled
+ does not create the Group
+ GET #index
+ as a user
+ redirects to Groups Dashboard
+ as a guest
+ redirects to Explore Groups
+ GET #issues
+ sorting by votes
+ sorts most popular issues
+ sorts least popular issues
+ GET #merge_requests
+ sorting by votes
+ sorts most popular merge requests
+ sorts least popular merge requests
+ DELETE #destroy
+ as another user
+ returns 404
+ as the group owner
+ schedules a group destroy
+ redirects to the root path
+ PUT update
+ updates the path successfully
+ does not update the path on error
+ #ensure_canonical_path
+ for a GET request
+ when requesting groups at the root path
+ when requesting the canonical path with different casing
+ redirects to the correct casing
+ when requesting a redirected path
+ redirects to the canonical path
+ when the old group path is a substring of the scheme or host
+ does not modify the requested host
+ when the old group path is substring of groups
+ does not modify the /groups part of the path
+ when requesting groups under the /groups path
+ when requesting the canonical path
+ non-show path
+ with exactly matching casing
+ does not redirect
+ with different casing
+ redirects to the correct casing
+ show path
+ with exactly matching casing
+ does not redirect
+ with different casing
+ redirects to the correct casing at the root path
+ when requesting a redirected path
+ redirects to the canonical path
+ when the old group path is a substring of the scheme or host
+ does not modify the requested host
+ when the old group path is substring of groups
+ does not modify the /groups part of the path
+ when the old group path is substring of groups plus the new path
+ does not modify the /groups part of the path
+ for a POST request
+ when requesting the canonical path with different casing
+ does not 404
+ does not redirect to the correct casing
+ when requesting a redirected path
+ returns not found
+ for a DELETE request
+ when requesting the canonical path with different casing
+ does not 404
+ does not redirect to the correct casing
+ when requesting a redirected path
+ returns not found
+ PUT transfer
+ when transfering to a subgroup goes right
+ should return a notice (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should redirect to the new path (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when converting to a root group goes right
+ should return a notice (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should redirect to the new path (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ When the transfer goes wrong
+ should return an alert (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should redirect to the current path (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the user is not allowed to transfer the group
+ should be denied (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+
+Import/Export - project import integration test
+Starting the Capybara driver server...
+ invalid project
+ when selecting the namespace
+ prefilled the path
+ user imports an exported project successfully
+ path is not prefilled
+ user imports an exported project successfully
+
+Gitlab::Middleware::Go
+ #call
+ when go-get=0
+ skips go-import generation
+ when go-get=1
+ with SSH disabled
+ with simple 2-segment project path
+ with subpackages
+ returns the full project path
+ without subpackages
+ returns the full project path
+ with a nested project path
+ with subpackages
+ behaves like a nested project
+ when the project is public
+ returns the full project path
+ when the project is private
+ when not authenticated
+ behaves like unauthorized
+ returns the 2-segment group path
+ when authenticated
+ using warden
+ when active
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ when blocked
+ behaves like unauthorized
+ returns the 2-segment group path
+ using a personal access token
+ with api scope
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ with read_user scope
+ behaves like unauthorized
+ returns the 2-segment group path
+ with a subpackage that is not a valid project path
+ behaves like a nested project
+ when the project is public
+ returns the full project path
+ when the project is private
+ when not authenticated
+ behaves like unauthorized
+ returns the 2-segment group path
+ when authenticated
+ using warden
+ when active
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ when blocked
+ behaves like unauthorized
+ returns the 2-segment group path
+ using a personal access token
+ with api scope
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ with read_user scope
+ behaves like unauthorized
+ returns the 2-segment group path
+ without subpackages
+ behaves like a nested project
+ when the project is public
+ returns the full project path
+ when the project is private
+ when not authenticated
+ behaves like unauthorized
+ returns the 2-segment group path
+ when authenticated
+ using warden
+ when active
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ when blocked
+ behaves like unauthorized
+ returns the 2-segment group path
+ using a personal access token
+ with api scope
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ with read_user scope
+ behaves like unauthorized
+ returns the 2-segment group path
+ with a bogus path
+ skips go-import generation
+ with HTTP disabled
+ with simple 2-segment project path
+ with subpackages
+ returns the full project path
+ without subpackages
+ returns the full project path
+ with a nested project path
+ with subpackages
+ behaves like a nested project
+ when the project is public
+ returns the full project path
+ when the project is private
+ when not authenticated
+ behaves like unauthorized
+ returns the 2-segment group path
+ when authenticated
+ using warden
+ when active
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ when blocked
+ behaves like unauthorized
+ returns the 2-segment group path
+ using a personal access token
+ with api scope
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ with read_user scope
+ behaves like unauthorized
+ returns the 2-segment group path
+ with a subpackage that is not a valid project path
+ behaves like a nested project
+ when the project is public
+ returns the full project path
+ when the project is private
+ when not authenticated
+ behaves like unauthorized
+ returns the 2-segment group path
+ when authenticated
+ using warden
+ when active
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ when blocked
+ behaves like unauthorized
+ returns the 2-segment group path
+ using a personal access token
+ with api scope
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ with read_user scope
+ behaves like unauthorized
+ returns the 2-segment group path
+ without subpackages
+ behaves like a nested project
+ when the project is public
+ returns the full project path
+ when the project is private
+ when not authenticated
+ behaves like unauthorized
+ returns the 2-segment group path
+ when authenticated
+ using warden
+ when active
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ when blocked
+ behaves like unauthorized
+ returns the 2-segment group path
+ using a personal access token
+ with api scope
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ with read_user scope
+ behaves like unauthorized
+ returns the 2-segment group path
+ with a bogus path
+ skips go-import generation
+ with nothing disabled
+ with simple 2-segment project path
+ with subpackages
+ returns the full project path
+ without subpackages
+ returns the full project path
+ with a nested project path
+ with subpackages
+ behaves like a nested project
+ when the project is public
+ returns the full project path
+ when the project is private
+ when not authenticated
+ behaves like unauthorized
+ returns the 2-segment group path
+ when authenticated
+ using warden
+ when active
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ when blocked
+ behaves like unauthorized
+ returns the 2-segment group path
+ using a personal access token
+ with api scope
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ with read_user scope
+ behaves like unauthorized
+ returns the 2-segment group path
+ with a subpackage that is not a valid project path
+ behaves like a nested project
+ when the project is public
+ returns the full project path
+ when the project is private
+ when not authenticated
+ behaves like unauthorized
+ returns the 2-segment group path
+ when authenticated
+ using warden
+ when active
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ when blocked
+ behaves like unauthorized
+ returns the 2-segment group path
+ using a personal access token
+ with api scope
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ with read_user scope
+ behaves like unauthorized
+ returns the 2-segment group path
+ without subpackages
+ behaves like a nested project
+ when the project is public
+ returns the full project path
+ when the project is private
+ when not authenticated
+ behaves like unauthorized
+ returns the 2-segment group path
+ when authenticated
+ using warden
+ when active
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ when blocked
+ behaves like unauthorized
+ returns the 2-segment group path
+ using a personal access token
+ with api scope
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ with read_user scope
+ behaves like unauthorized
+ returns the 2-segment group path
+ with a bogus path
+ skips go-import generation
+ with nothing disabled (blank string)
+ with simple 2-segment project path
+ with subpackages
+ returns the full project path
+ without subpackages
+ returns the full project path
+ with a nested project path
+ with subpackages
+ behaves like a nested project
+ when the project is public
+ returns the full project path
+ when the project is private
+ when not authenticated
+ behaves like unauthorized
+ returns the 2-segment group path
+ when authenticated
+ using warden
+ when active
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ when blocked
+ behaves like unauthorized
+ returns the 2-segment group path
+ using a personal access token
+ with api scope
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ with read_user scope
+ behaves like unauthorized
+ returns the 2-segment group path
+ with a subpackage that is not a valid project path
+ behaves like a nested project
+ when the project is public
+ returns the full project path
+ when the project is private
+ when not authenticated
+ behaves like unauthorized
+ returns the 2-segment group path
+ when authenticated
+ using warden
+ when active
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ when blocked
+ behaves like unauthorized
+ returns the 2-segment group path
+ using a personal access token
+ with api scope
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ with read_user scope
+ behaves like unauthorized
+ returns the 2-segment group path
+ without subpackages
+ behaves like a nested project
+ when the project is public
+ returns the full project path
+ when the project is private
+ when not authenticated
+ behaves like unauthorized
+ returns the 2-segment group path
+ when authenticated
+ using warden
+ when active
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ when blocked
+ behaves like unauthorized
+ returns the 2-segment group path
+ using a personal access token
+ with api scope
+ behaves like authenticated
+ with access to the project
+ returns the full project path
+ without access to the project
+ behaves like unauthorized
+ returns the 2-segment group path
+ with read_user scope
+ behaves like unauthorized
+ returns the 2-segment group path
+ with a bogus path
+ skips go-import generation
+
+Groups::TransferService
+ #execute
+ when transforming a group into a root group
+ behaves like ensuring allowed transfer for a group
+ with other database than PostgreSQL
+ should return false (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should add an error on group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when there's an exception on Gitlab shell directories
+ should return false (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should add an error on group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the group is already a root group
+ should add an error on group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the user does not have the right policies
+ should return false (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should add an error on group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when there is a group with the same path
+ should return false (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should add an error on group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the group is a subgroup and the transfer is valid
+ should update group attributes (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should update group children path (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should update group projects path (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when transferring a subgroup into another group
+ behaves like ensuring allowed transfer for a group
+ with other database than PostgreSQL
+ should return false (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should add an error on group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when there's an exception on Gitlab shell directories
+ should return false (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should add an error on group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the new parent group is the same as the previous parent group
+ should return false (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should add an error on group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the user does not have the right policies
+ should return false (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should add an error on group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the parent has a group with the same path
+ should return false (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should add an error on group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the parent group has a project with the same path
+ should return false (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should add an error on group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the group is allowed to be transferred
+ should update visibility for the group based on the parent group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should update parent group to the new parent (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should return the group as children of the new parent (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should create a redirect for the group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the group has a lower visibility than the parent group
+ should not update the visibility for the group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the group has a higher visibility than the parent group
+ should update visibility level based on the parent group (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when transferring a group with group descendants
+ should update subgroups path (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should create redirects for the subgroups (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the new parent has a higher visibility than the children
+ should not update the children visibility (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the new parent has a lower visibility than the children
+ should update children visibility to match the new parent (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when transferring a group with project descendants
+ should update projects path (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should create permanent redirects for the projects (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the new parent has a higher visibility than the projects
+ should not update projects visibility (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when the new parent has a lower visibility than the projects
+ should update projects visibility to match the new parent (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when transferring a group with subgroups & projects descendants
+ should update subgroups path (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should update projects path (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should create redirect for the subgroups and projects (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when transfering a group with nested groups and projects
+ should update subgroups path (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should update projects path (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ should create redirect for the subgroups and projects (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+ when updating the group goes wrong
+ should restore group and projects visibility (PENDING: around hook at ./spec/spec_helper.rb:190 did not execute the example)
+
+Editing file blob
+ as a developer
+ from MR diff
+ returns me to the mr
+ from blob file path
+ updates content
+ previews content
+ visit blob edit
+ redirects to sign in and returns
+ as developer
+ redirects to sign in and returns
+ as guest
+ redirects to sign in and returns
+ as developer
+ on some branch
+ shows blob editor with same branch
+ with protected branch
+ shows blob editor with patch branch
+ as master
+ shows blob editor with same branch
+
+Boards::Lists::MoveService
+ #execute
+ when board parent is a project
+ behaves like lists move service
+ keeps position of lists when list type is closed
+ when list type is set to label
+ keeps position of lists when new position is nil
+ keeps position of lists when new positon is equal to old position
+ keeps position of lists when new positon is negative
+ keeps position of lists when new positon is equal to number of labels lists
+ keeps position of lists when new positon is greater than number of labels lists
+ increments position of intermediate lists when new positon is equal to first position
+ decrements position of intermediate lists when new positon is equal to last position
+ decrements position of intermediate lists when new position is greater than old position
+ increments position of intermediate lists when new position is lower than old position
+ when board parent is a group
+ behaves like lists move service
+ keeps position of lists when list type is closed
+ when list type is set to label
+ keeps position of lists when new position is nil
+ keeps position of lists when new positon is equal to old position
+ keeps position of lists when new positon is negative
+ keeps position of lists when new positon is equal to number of labels lists
+ keeps position of lists when new positon is greater than number of labels lists
+ increments position of intermediate lists when new positon is equal to first position
+ decrements position of intermediate lists when new positon is equal to last position
+ decrements position of intermediate lists when new position is greater than old position
+ increments position of intermediate lists when new position is lower than old position
+
+CreateDeploymentService
+ #execute
+ when environment exists
+ creates a deployment
+ when environment does not exist
+ does not create a deployment
+ when start action is defined
+ and environment is stopped
+ makes environment available
+ creates a deployment
+ when stop action is defined
+ and environment is available
+ makes environment stopped
+ does not create a deployment
+ when variables are used
+ creates a new deployment
+ does not create a new environment
+ updates external url
+ when project was removed
+ does not create deployment or environment
+ #expanded_environment_url
+ when yaml environment uses $CI_COMMIT_REF_NAME
+ should eq "http://review/master"
+ when yaml environment uses $CI_ENVIRONMENT_SLUG
+ should eq "http://review/prod-slug"
+ when yaml environment uses yaml_variables containing symbol keys
+ should eq "http://review/host"
+ when yaml environment does not have url
+ returns the external_url from persisted environment
+ processing of builds
+ without environment specified
+ behaves like does not create deployment
+ does not create a new deployment
+ does not call a service
+ when environment is specified
+ when job succeeds
+ behaves like creates deployment
+ creates a new deployment
+ calls a service
+ is set as deployable
+ updates environment URL
+ when job fails
+ behaves like does not create deployment
+ does not create a new deployment
+ does not call a service
+ when job is retried
+ behaves like creates deployment
+ creates a new deployment
+ calls a service
+ is set as deployable
+ updates environment URL
+ merge request metrics
+ while updating the 'first_deployed_to_production_at' time
+ for merge requests merged before the current deploy
+ sets the time if the deploy's environment is 'production'
+ doesn't set the time if the deploy's environment is not 'production'
+ does not raise errors if the merge request does not have a metrics record
+ for merge requests merged before the previous deploy
+ if the 'first_deployed_to_production_at' time is already set
+ does not overwrite the older 'first_deployed_to_production_at' time
+ if the 'first_deployed_to_production_at' time is not already set
+ does not overwrite the older 'first_deployed_to_production_at' time
+
+Groups::MilestonesController
+ #index
+ shows group milestones page
+ as JSON
+ lists legacy group milestones and group milestones
+ #show
+ when there is a title parameter
+ searchs for a legacy group milestone
+ when there is not a title parameter
+ searchs for a group milestone
+ behaves like milestone tabs
+ #merge_requests
+ as html
+ redirects to milestone#show
+ as json
+ renders the merge requests tab template to a string
+ #participants
+ as html
+ redirects to milestone#show
+ as json
+ renders the participants tab template to a string
+ #labels
+ as html
+ redirects to milestone#show
+ as json
+ renders the labels tab template to a string
+ #create
+ creates group milestone with Chinese title
+ #update
+ updates group milestone
+ legacy group milestones
+ updates only group milestones state
+ #ensure_canonical_path
+ for a GET request
+ when requesting the canonical path
+ non-show path
+ with exactly matching casing
+ does not redirect
+ with different casing
+ redirects to the correct casing
+ show path
+ with exactly matching casing
+ does not redirect
+ with different casing
+ redirects to the correct casing
+ when requesting a redirected path
+ redirects to the canonical path
+ when the old group path is a substring of the scheme or host
+ does not modify the requested host
+ when the old group path is substring of groups
+ does not modify the /groups part of the path
+ when the old group path is substring of groups plus the new path
+ does not modify the /groups part of the path
+ for a non-GET request
+ when requesting the canonical path with different casing
+ does not 404
+ does not redirect to the correct casing
+ when requesting a redirected path
+ returns not found
+
+GroupsHelper
+ group_icon
+ returns an url for the avatar
+ group_icon_url
+ returns an url for the avatar
+ gives default avatar_icon when no avatar is present
+ group_lfs_status
+ only one project in group
+ returns all projects as enabled
+ returns all projects as disabled
+ more than one project in group
+ LFS enabled in group
+ returns both projects as enabled
+ returns only one as enabled
+ LFS disabled in group
+ returns both projects as disabled
+ returns only one as disabled
+ group_title
+ outputs the groups in the correct order (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ #share_with_group_lock_help_text
+ root_share_with_group_locked: false, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: false, current_user: :root_owner, help_text: :default_help, linked_ancestor: nil
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: false, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: false, current_user: :sub_owner, help_text: :default_help, linked_ancestor: nil
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: false, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: false, current_user: :sub_sub_owner, help_text: :default_help, linked_ancestor: nil
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: false, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: true, current_user: :root_owner, help_text: :default_help, linked_ancestor: nil
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: false, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: true, current_user: :sub_owner, help_text: :default_help, linked_ancestor: nil
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: false, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: true, current_user: :sub_sub_owner, help_text: :default_help, linked_ancestor: nil
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: false, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: false, current_user: :root_owner, help_text: :ancestor_locked_and_has_been_overridden, linked_ancestor: :subgroup
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: false, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: false, current_user: :sub_owner, help_text: :ancestor_locked_and_has_been_overridden, linked_ancestor: :subgroup
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: false, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: false, current_user: :sub_sub_owner, help_text: :ancestor_locked_and_has_been_overridden, linked_ancestor: :subgroup
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: false, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: true, current_user: :root_owner, help_text: :ancestor_locked_but_you_can_override, linked_ancestor: :subgroup
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: false, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: true, current_user: :sub_owner, help_text: :ancestor_locked_but_you_can_override, linked_ancestor: :subgroup
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: false, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: true, current_user: :sub_sub_owner, help_text: :ancestor_locked_so_ask_the_owner, linked_ancestor: :subgroup
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: true, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: false, current_user: :root_owner, help_text: :default_help, linked_ancestor: nil
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: true, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: false, current_user: :sub_owner, help_text: :default_help, linked_ancestor: nil
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: true, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: false, current_user: :sub_sub_owner, help_text: :default_help, linked_ancestor: nil
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: true, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: true, current_user: :root_owner, help_text: :default_help, linked_ancestor: nil
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: true, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: true, current_user: :sub_owner, help_text: :default_help, linked_ancestor: nil
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: true, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: true, current_user: :sub_sub_owner, help_text: :default_help, linked_ancestor: nil
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: true, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: false, current_user: :root_owner, help_text: :ancestor_locked_and_has_been_overridden, linked_ancestor: :root_group
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: true, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: false, current_user: :sub_owner, help_text: :ancestor_locked_and_has_been_overridden, linked_ancestor: :root_group
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: true, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: false, current_user: :sub_sub_owner, help_text: :ancestor_locked_and_has_been_overridden, linked_ancestor: :root_group
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: true, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: true, current_user: :root_owner, help_text: :ancestor_locked_but_you_can_override, linked_ancestor: :root_group
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: true, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: true, current_user: :sub_owner, help_text: :ancestor_locked_so_ask_the_owner, linked_ancestor: :root_group
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ root_share_with_group_locked: true, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: true, current_user: :sub_sub_owner, help_text: :ancestor_locked_so_ask_the_owner, linked_ancestor: :root_group
+ has the correct help text with correct ancestor links (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ #group_sidebar_links
+ returns all the expected links
+ includes settings when the user can admin the group
+ excludes cross project features when the user cannot read cross project
+
+API::V3::Todos
+ DELETE /todos/:id
+ when unauthenticated
+ returns authentication error
+ when authenticated
+ marks a todo as done
+ updates todos cache
+ returns 404 if the todo does not belong to the current user
+ DELETE /todos
+ when unauthenticated
+ returns authentication error
+ when authenticated
+ marks all todos as done
+ updates todos cache
+
+TeamcityService
+ Associations
+ should belong to project
+ should have one service_hook
+ Validations
+ when service is active
+ should validate that :build_type cannot be empty/falsy
+ should validate that :teamcity_url cannot be empty/falsy
+ behaves like issue tracker service URL attribute
+ should allow :teamcity_url to be ‹"https://example.com"›
+ should not allow :teamcity_url to be ‹"example.com"›
+ should not allow :teamcity_url to be ‹"ftp://example.com"›
+ should not allow :teamcity_url to be ‹"herp-and-derp"›
+ #username
+ does not validate the presence of username if password is nil
+ validates the presence of username if password is present
+ #password
+ does not validate the presence of password if username is nil
+ validates the presence of password if username is present
+ when service is inactive
+ should not validate that :build_type cannot be empty/falsy
+ should not validate that :teamcity_url cannot be empty/falsy
+ should not validate that :username cannot be empty/falsy
+ should not validate that :password cannot be empty/falsy
+ Callbacks
+ before_update :reset_password
+ saves password if new url is set together with password when no password was previously set
+ when a password was previously set
+ resets password if url changed
+ does not reset password if username changed
+ does not reset password if new url is set together with password, even if it's the same password
+ #build_page
+ returns the contents of the reactive cache
+ #commit_status
+ returns the contents of the reactive cache
+ #calculate_reactive_cache
+ build_page
+ returns a specific URL when status is 500
+ returns a build URL when teamcity_url has no trailing slash
+ teamcity_url has trailing slash
+ returns a build URL
+ commit_status
+ sets commit status to :error when status is 500
+ sets commit status to "pending" when status is 404
+ sets commit status to "success" when build status contains SUCCESS
+ sets commit status to "failed" when build status contains FAILURE
+ sets commit status to "pending" when build status contains Pending
+ sets commit status to :error when build status is unknown
+
+Gitlab::Conflict::File
+ #resolve_lines
+ raises ResolutionError when passed a hash without resolutions for all sections
+ when resolving everything to the same side
+ has the correct number of lines
+ has content matching the chosen lines
+ with mixed resolutions
+ has the correct number of lines
+ returns a file containing only the chosen parts of the resolved sections
+ #highlight_lines!
+ modifies the existing lines
+ is called implicitly when rich_text is accessed on a line
+ sets the rich_text of the lines matching the text content
+ highlights the lines correctly
+ #sections
+ only inserts match lines when there is a gap between sections
+ sets conflict to false for sections with only unchanged lines
+ only includes a maximum of CONTEXT_LINES (plus an optional match line) in context sections
+ sets conflict to true for sections with only changed lines
+ adds unique IDs to conflict sections, and not to other sections
+ with an example file
+ sets the correct match line headers
+ does not add match lines where they are not needed
+ creates context sections of the correct length
+ #as_json
+ includes the blob path for the file
+ includes the blob icon for the file
+ with the full_content option passed
+ includes the full content of the conflict
+ includes the detected language of the conflict file
+
+Banzai::Filter::SnippetReferenceFilter
+ requires project context
+ ignores valid references contained inside 'pre' element
+ ignores valid references contained inside 'code' element
+ ignores valid references contained inside 'a' element
+ ignores valid references contained inside 'style' element
+ internal reference
+ links to a valid reference
+ links with adjacent text
+ ignores invalid snippet IDs
+ includes a title attribute
+ escapes the title attribute
+ includes default classes
+ includes a data-project attribute
+ includes a data-snippet attribute
+ supports an :only_path context
+ cross-project / cross-namespace complete reference
+ links to a valid reference
+ link has valid text
+ has valid text
+ ignores invalid snippet IDs on the referenced project
+ cross-project / same-namespace complete reference
+ links to a valid reference
+ link has valid text
+ has valid text
+ ignores invalid snippet IDs on the referenced project
+ cross-project shorthand reference
+ links to a valid reference
+ link has valid text
+ has valid text
+ ignores invalid snippet IDs on the referenced project
+ cross-project URL reference
+ links to a valid reference
+ links with adjacent text
+ ignores invalid snippet IDs on the referenced project
+ group context
+ links to a valid reference
+
+AutocompleteUsersFinder
+ #execute
+ should contain exactly #<User id:2126 @johndoe>, #<User id:2128 @user2119>, #<User id:2129 @user2120>, and #<User id:2130 @user2121>
+ when current_user not passed or nil
+ should contain exactly
+ when project passed
+ should contain exactly #<User id:2140 @user2127>
+ when author_id passed
+ should contain exactly #<User id:2146 @user2131> and #<User id:2142 @notsorandom>
+ when group passed and project not passed
+ should contain exactly #<User id:2147 @johndoe>
+ when passed a subgroup
+ includes users from parent groups as well (PENDING: around hook at ./spec/spec_helper.rb:186 did not execute the example)
+ when filtered by search
+ should contain exactly #<User id:2152 @johndoe>
+ when filtered by skip_users
+ should contain exactly #<User id:2157 @johndoe> and #<User id:2159 @user2138>
+ when todos exist
+ when filtered by todo_filter without todo_state_filter
+ should contain exactly
+ when filtered by todo_filter with pending todo_state_filter
+ should contain exactly #<User id:2175 @johndoe>
+ when filtered by todo_filter with done todo_state_filter
+ should contain exactly #<User id:2190 @user2163>
+ when filtered by current_user
+ should contain exactly #<User id:2202 @notsorandom>, #<User id:2201 @johndoe>, #<User id:2203 @user2174>, and #<User id:2204 @user2175>
+ when filtered by author_id
+ should contain exactly #<User id:2206 @notsorandom>, #<User id:2205 @johndoe>, #<User id:2207 @user2176>, #<User id:2208 @user2177>, and #<User id:2209 @user2178>
+
+Service
+ Associations
+ should belong to project
+ should have one service_hook
+ Validations
+ should validate that :type cannot be empty/falsy
+ Scopes
+ .confidential_note_hooks
+ includes services where confidential_note_events is true
+ excludes services where confidential_note_events is false
+ Test Button
+ #can_test?
+ when repository is not empty
+ returns true
+ when repository is empty
+ returns true
+ #test
+ when repository is not empty
+ test runs execute
+ when repository is empty
+ test runs execute
+ Template
+ .build_from_template
+ when template is invalid
+ sets service template to inactive when template is invalid
+ for pushover service
+ is prefilled for projects pushover service
+ has all fields prefilled
+ {property}_changed?
+ returns false when the property has not been assigned a new value
+ returns true when the property has been assigned a different value
+ returns true when the property has been assigned a different value twice
+ returns false when the property has been re-assigned the same value
+ returns false when the property has been assigned a new value then saved
+ {property}_touched?
+ returns false when the property has not been assigned a new value
+ returns true when the property has been assigned a different value
+ returns true when the property has been assigned a different value twice
+ returns true when the property has been re-assigned the same value
+ returns false when the property has been assigned a new value then saved
+ {property}_was
+ returns nil when the property has not been assigned a new value
+ returns the previous value when the property has been assigned a different value
+ returns initial value when the property has been re-assigned the same value
+ returns initial value when the property has been assigned multiple values
+ returns nil when the property has been assigned a new value then saved
+ initialize service with no properties
+ does not raise error
+ creates the properties
+ callbacks
+ on create
+ updates the has_external_issue_tracker boolean
+ on update
+ updates the has_external_issue_tracker boolean
+ #deprecated?
+ should return false by default
+ #deprecation_message
+ should be empty by default
+ .find_by_template
+ returns service template
+ #api_field_names
+ filters out sensitive fields
+
+TestHooks::ProjectService
+ #execute
+ hook with not implemented test
+ returns error message
+ push_events
+ returns error message if not enough data
+ executes hook
+ tag_push_events
+ returns error message if not enough data
+ executes hook
+ note_events
+ returns error message if not enough data
+ executes hook
+ issues_events
+ returns error message if not enough data
+ executes hook
+ confidential_issues_events
+ returns error message if not enough data
+ executes hook
+ merge_requests_events
+ returns error message if not enough data
+ executes hook
+ job_events
+ returns error message if not enough data
+ executes hook
+ pipeline_events
+ returns error message if not enough data
+ executes hook
+ wiki_page_events
+ returns error message if wiki disabled
+ returns error message if not enough data
+ executes hook
+
+User views an open merge request
+ when a merge request does not have repository
+ renders both the title and the description
+ when a merge request has repository
+ when rendering description preview
+ renders empty description preview
+ renders description preview
+ when the branch is rebased on the target
+ does not show diverged commits count
+ when the branch is diverged on the target
+ shows diverged commits count
+
+RunnerJobsFinder
+ #execute
+ when params is empty
+ returns all jobs assigned to Runner
+ when params contains status
+ when status is created
+ returns matched job
+ when status is pending
+ returns matched job
+ when status is running
+ returns matched job
+ when status is success
+ returns matched job
+ when status is failed
+ returns matched job
+ when status is canceled
+ returns matched job
+ when status is skipped
+ returns matched job
+ when status is manual
+ returns matched job
+
+Project snippets
+ when the project has snippets
+ pagination
+ behaves like paginated snippets
+ is limited to 20 items per page
+ clicking on the link to the second page
+ shows the remaining snippets
+ list content
+ contains all project snippets
+ when submitting a note
+ should have autocomplete
+ should have zen mode
+
+API::V3::Environments
+ GET /projects/:id/environments
+ as member of the project
+ returns project environments
+ behaves like a paginated resources
+ has pagination headers
+ as non member
+ returns a 404 status code
+ POST /projects/:id/environments
+ as a member
+ creates a environment with valid params
+ requires name to be passed
+ returns a 400 if environment already exists
+ returns a 400 if slug is specified
+ a non member
+ rejects the request
+ returns a 400 when the required params are missing
+ PUT /projects/:id/environments/:environment_id
+ returns a 200 if name and external_url are changed
+ won't allow slug to be changed
+ won't update the external_url if only the name is passed
+ returns a 404 if the environment does not exist
+ DELETE /projects/:id/environments/:environment_id
+ as a master
+ returns a 200 for an existing environment
+ returns a 404 for non existing id
+ a non member
+ rejects the request
+
+API::Namespaces
+ GET /namespaces
+ when unauthenticated
+ returns authentication error
+ when authenticated as admin
+ returns correct attributes
+ admin: returns an array of all namespaces
+ admin: returns an array of matched namespaces
+ when authenticated as a regular user
+ returns correct attributes when user can admin group
+ returns correct attributes when user cannot admin group
+ user: returns an array of namespaces
+ admin: returns an array of matched namespaces
+ GET /namespaces/:id
+ when unauthenticated
+ returns authentication error
+ when authenticated as regular user
+ when requested namespace is not owned by user
+ when requesting group
+ returns not-found
+ when requesting personal namespace
+ returns not-found
+ when requested namespace is owned by user
+ behaves like namespace reader
+ when namespace exists
+ when requested by ID
+ when requesting group
+ behaves like can access namespace
+ returns namespace details
+ when requesting personal namespace
+ behaves like can access namespace
+ returns namespace details
+ when requested by path
+ when requesting group
+ behaves like can access namespace
+ returns namespace details
+ when requesting personal namespace
+ behaves like can access namespace
+ returns namespace details
+ when namespace doesn't exist
+ returns not-found
+ when authenticated as admin
+ when requested namespace is not owned by user
+ when requesting group
+ behaves like can access namespace
+ returns namespace details
+ when requesting personal namespace
+ behaves like can access namespace
+ returns namespace details
+ when requested namespace is owned by user
+ behaves like namespace reader
+ when namespace exists
+ when requested by ID
+ when requesting group
+ behaves like can access namespace
+ returns namespace details
+ when requesting personal namespace
+ behaves like can access namespace
+ returns namespace details
+ when requested by path
+ when requesting group
+ behaves like can access namespace
+ returns namespace details
+ when requesting personal namespace
+ behaves like can access namespace
+ returns namespace details
+ when namespace doesn't exist
+ returns not-found
+
+MergeRequests::GetUrlsService
+ #execute
+ pushing to default branch
+ behaves like no_merge_request_url
+ returns no URL
+ pushing to project with MRs disabled
+ behaves like no_merge_request_url
+ returns no URL
+ pushing one completely new branch
+ behaves like new_merge_request_link
+ returns url to create new merge request
+ pushing to existing branch but no merge request
+ behaves like new_merge_request_link
+ returns url to create new merge request
+ pushing to deleted branch
+ behaves like no_merge_request_url
+ returns no URL
+ pushing to existing branch and merge request opened
+ behaves like show_merge_request_url
+ returns url to view merge request
+ pushing to existing branch and merge request is reopened
+ behaves like show_merge_request_url
+ returns url to view merge request
+ pushing to existing branch from forked project
+ behaves like show_merge_request_url
+ returns url to view merge request
+ pushing to existing branch and merge request is closed
+ behaves like new_merge_request_link
+ returns url to create new merge request
+ pushing to existing branch and merge request is merged
+ behaves like new_merge_request_link
+ returns url to create new merge request
+ pushing new branch and existing branch (with merge request created) at once
+ returns 2 urls for both creating new and showing merge request
+ when printing_merge_request_link_enabled is false
+ returns empty array
+
+LfsFileLock
+ should belong to project
+ should belong to user
+ should validate that :project_id cannot be empty/falsy
+ should validate that :user_id cannot be empty/falsy
+ should validate that :path cannot be empty/falsy
+ #can_be_unlocked_by?
+ when it's forced
+ can be unlocked by the author
+ can be unlocked by a master
+ can't be unlocked by other user
+ when it isn't forced
+ can be unlocked by the author
+ can't be unlocked by a master
+ can't be unlocked by other user
+
+Gitlab::Ci::Config::Entry::Boolean
+ validations
+ when entry config value is valid
+ #value
+ returns key value
+ #valid?
+ is valid
+ when entry value is not valid
+ #errors
+ saves errors
+Knapsack report was generated. Preview:
+{
+ "spec/services/todo_service_spec.rb": 53.71851348876953,
+ "spec/lib/gitlab/import_export/project_tree_saver_spec.rb": 48.39624857902527,
+ "spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb": 35.17360734939575,
+ "spec/controllers/projects/merge_requests_controller_spec.rb": 25.50887441635132,
+ "spec/controllers/groups_controller_spec.rb": 13.007296323776245,
+ "spec/features/projects/import_export/import_file_spec.rb": 16.827879428863525,
+ "spec/lib/gitlab/middleware/go_spec.rb": 12.497276306152344,
+ "spec/features/projects/blobs/edit_spec.rb": 11.511932134628296,
+ "spec/services/boards/lists/move_service_spec.rb": 8.695446491241455,
+ "spec/services/create_deployment_service_spec.rb": 6.754847526550293,
+ "spec/controllers/groups/milestones_controller_spec.rb": 6.8740551471710205,
+ "spec/helpers/groups_helper_spec.rb": 0.9002459049224854,
+ "spec/requests/api/v3/todos_spec.rb": 6.5924904346466064,
+ "spec/models/project_services/teamcity_service_spec.rb": 2.9881808757781982,
+ "spec/lib/gitlab/conflict/file_spec.rb": 5.294132709503174,
+ "spec/lib/banzai/filter/snippet_reference_filter_spec.rb": 4.118850469589233,
+ "spec/finders/autocomplete_users_finder_spec.rb": 3.864232063293457,
+ "spec/models/service_spec.rb": 3.1697962284088135,
+ "spec/services/test_hooks/project_service_spec.rb": 4.167759656906128,
+ "spec/features/projects/merge_requests/user_views_open_merge_request_spec.rb": 4.707003355026245,
+ "spec/finders/runner_jobs_finder_spec.rb": 3.2137575149536133,
+ "spec/features/projects/snippets_spec.rb": 3.631467580795288,
+ "spec/requests/api/v3/environments_spec.rb": 2.314746856689453,
+ "spec/requests/api/namespaces_spec.rb": 2.352935314178467,
+ "spec/services/merge_requests/get_urls_service_spec.rb": 2.8039824962615967,
+ "spec/models/lfs_file_lock_spec.rb": 0.7295050621032715,
+ "spec/lib/gitlab/ci/config/entry/boolean_spec.rb": 0.007024049758911133
+}
+
+Knapsack global time execution for tests: 04m 49s
+
+Pending: (Failures listed here are expected and do not affect your suite's status)
+
+ 1) GroupsController GET #new when creating subgroups and can_create_group is true and logged in as Admin behaves like member with ability to create subgroups renders the new page
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:15
+
+ 2) GroupsController GET #new when creating subgroups and can_create_group is true and logged in as Owner behaves like member with ability to create subgroups renders the new page
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:15
+
+ 3) GroupsController GET #new when creating subgroups and can_create_group is true and logged in as Guest behaves like member without ability to create subgroups renders the 404 page
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:25
+
+ 4) GroupsController GET #new when creating subgroups and can_create_group is true and logged in as Developer behaves like member without ability to create subgroups renders the 404 page
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:25
+
+ 5) GroupsController GET #new when creating subgroups and can_create_group is true and logged in as Master behaves like member without ability to create subgroups renders the 404 page
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:25
+
+ 6) GroupsController GET #new when creating subgroups and can_create_group is false and logged in as Admin behaves like member with ability to create subgroups renders the new page
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:15
+
+ 7) GroupsController GET #new when creating subgroups and can_create_group is false and logged in as Owner behaves like member with ability to create subgroups renders the new page
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:15
+
+ 8) GroupsController GET #new when creating subgroups and can_create_group is false and logged in as Guest behaves like member without ability to create subgroups renders the 404 page
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:25
+
+ 9) GroupsController GET #new when creating subgroups and can_create_group is false and logged in as Developer behaves like member without ability to create subgroups renders the 404 page
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:25
+
+ 10) GroupsController GET #new when creating subgroups and can_create_group is false and logged in as Master behaves like member without ability to create subgroups renders the 404 page
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:25
+
+ 11) GroupsController POST #create when creating subgroups and can_create_group is true and logged in as Owner creates the subgroup
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:117
+
+ 12) GroupsController POST #create when creating subgroups and can_create_group is true and logged in as Developer renders the new template
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:129
+
+ 13) GroupsController POST #create when creating subgroups and can_create_group is false and logged in as Owner creates the subgroup
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:117
+
+ 14) GroupsController POST #create when creating subgroups and can_create_group is false and logged in as Developer renders the new template
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:129
+
+ 15) GroupsController PUT transfer when transfering to a subgroup goes right should return a notice
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:516
+
+ 16) GroupsController PUT transfer when transfering to a subgroup goes right should redirect to the new path
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:520
+
+ 17) GroupsController PUT transfer when converting to a root group goes right should return a notice
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:535
+
+ 18) GroupsController PUT transfer when converting to a root group goes right should redirect to the new path
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:539
+
+ 19) GroupsController PUT transfer When the transfer goes wrong should return an alert
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:557
+
+ 20) GroupsController PUT transfer When the transfer goes wrong should redirect to the current path
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:561
+
+ 21) GroupsController PUT transfer when the user is not allowed to transfer the group should be denied
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/controllers/groups_controller_spec.rb:577
+
+ 22) Groups::TransferService#execute when transforming a group into a root group behaves like ensuring allowed transfer for a group with other database than PostgreSQL should return false
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:15
+
+ 23) Groups::TransferService#execute when transforming a group into a root group behaves like ensuring allowed transfer for a group with other database than PostgreSQL should add an error on group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:19
+
+ 24) Groups::TransferService#execute when transforming a group into a root group behaves like ensuring allowed transfer for a group when there's an exception on Gitlab shell directories should return false
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:33
+
+ 25) Groups::TransferService#execute when transforming a group into a root group behaves like ensuring allowed transfer for a group when there's an exception on Gitlab shell directories should add an error on group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:37
+
+ 26) Groups::TransferService#execute when transforming a group into a root group when the group is already a root group should add an error on group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:53
+
+ 27) Groups::TransferService#execute when transforming a group into a root group when the user does not have the right policies should return false
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:62
+
+ 28) Groups::TransferService#execute when transforming a group into a root group when the user does not have the right policies should add an error on group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:66
+
+ 29) Groups::TransferService#execute when transforming a group into a root group when there is a group with the same path should return false
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:79
+
+ 30) Groups::TransferService#execute when transforming a group into a root group when there is a group with the same path should add an error on group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:83
+
+ 31) Groups::TransferService#execute when transforming a group into a root group when the group is a subgroup and the transfer is valid should update group attributes
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:99
+
+ 32) Groups::TransferService#execute when transforming a group into a root group when the group is a subgroup and the transfer is valid should update group children path
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:103
+
+ 33) Groups::TransferService#execute when transforming a group into a root group when the group is a subgroup and the transfer is valid should update group projects path
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:109
+
+ 34) Groups::TransferService#execute when transferring a subgroup into another group behaves like ensuring allowed transfer for a group with other database than PostgreSQL should return false
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:15
+
+ 35) Groups::TransferService#execute when transferring a subgroup into another group behaves like ensuring allowed transfer for a group with other database than PostgreSQL should add an error on group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:19
+
+ 36) Groups::TransferService#execute when transferring a subgroup into another group behaves like ensuring allowed transfer for a group when there's an exception on Gitlab shell directories should return false
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:33
+
+ 37) Groups::TransferService#execute when transferring a subgroup into another group behaves like ensuring allowed transfer for a group when there's an exception on Gitlab shell directories should add an error on group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:37
+
+ 38) Groups::TransferService#execute when transferring a subgroup into another group when the new parent group is the same as the previous parent group should return false
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:125
+
+ 39) Groups::TransferService#execute when transferring a subgroup into another group when the new parent group is the same as the previous parent group should add an error on group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:129
+
+ 40) Groups::TransferService#execute when transferring a subgroup into another group when the user does not have the right policies should return false
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:138
+
+ 41) Groups::TransferService#execute when transferring a subgroup into another group when the user does not have the right policies should add an error on group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:142
+
+ 42) Groups::TransferService#execute when transferring a subgroup into another group when the parent has a group with the same path should return false
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:155
+
+ 43) Groups::TransferService#execute when transferring a subgroup into another group when the parent has a group with the same path should add an error on group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:159
+
+ 44) Groups::TransferService#execute when transferring a subgroup into another group when the parent group has a project with the same path should return false
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:174
+
+ 45) Groups::TransferService#execute when transferring a subgroup into another group when the parent group has a project with the same path should add an error on group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:178
+
+ 46) Groups::TransferService#execute when transferring a subgroup into another group when the group is allowed to be transferred should update visibility for the group based on the parent group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:212
+
+ 47) Groups::TransferService#execute when transferring a subgroup into another group when the group is allowed to be transferred should update parent group to the new parent
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:216
+
+ 48) Groups::TransferService#execute when transferring a subgroup into another group when the group is allowed to be transferred should return the group as children of the new parent
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:220
+
+ 49) Groups::TransferService#execute when transferring a subgroup into another group when the group is allowed to be transferred should create a redirect for the group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:225
+
+ 50) Groups::TransferService#execute when transferring a subgroup into another group when the group is allowed to be transferred when the group has a lower visibility than the parent group should not update the visibility for the group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:194
+
+ 51) Groups::TransferService#execute when transferring a subgroup into another group when the group is allowed to be transferred when the group has a higher visibility than the parent group should update visibility level based on the parent group
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:205
+
+ 52) Groups::TransferService#execute when transferring a subgroup into another group when transferring a group with group descendants should update subgroups path
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:239
+
+ 53) Groups::TransferService#execute when transferring a subgroup into another group when transferring a group with group descendants should create redirects for the subgroups
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:246
+
+ 54) Groups::TransferService#execute when transferring a subgroup into another group when transferring a group with group descendants when the new parent has a higher visibility than the children should not update the children visibility
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:253
+
+ 55) Groups::TransferService#execute when transferring a subgroup into another group when transferring a group with group descendants when the new parent has a lower visibility than the children should update children visibility to match the new parent
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:264
+
+ 56) Groups::TransferService#execute when transferring a subgroup into another group when transferring a group with project descendants should update projects path
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:282
+
+ 57) Groups::TransferService#execute when transferring a subgroup into another group when transferring a group with project descendants should create permanent redirects for the projects
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:289
+
+ 58) Groups::TransferService#execute when transferring a subgroup into another group when transferring a group with project descendants when the new parent has a higher visibility than the projects should not update projects visibility
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:296
+
+ 59) Groups::TransferService#execute when transferring a subgroup into another group when transferring a group with project descendants when the new parent has a lower visibility than the projects should update projects visibility to match the new parent
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:307
+
+ 60) Groups::TransferService#execute when transferring a subgroup into another group when transferring a group with subgroups & projects descendants should update subgroups path
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:327
+
+ 61) Groups::TransferService#execute when transferring a subgroup into another group when transferring a group with subgroups & projects descendants should update projects path
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:334
+
+ 62) Groups::TransferService#execute when transferring a subgroup into another group when transferring a group with subgroups & projects descendants should create redirect for the subgroups and projects
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:341
+
+ 63) Groups::TransferService#execute when transferring a subgroup into another group when transfering a group with nested groups and projects should update subgroups path
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:363
+
+ 64) Groups::TransferService#execute when transferring a subgroup into another group when transfering a group with nested groups and projects should update projects path
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:375
+
+ 65) Groups::TransferService#execute when transferring a subgroup into another group when transfering a group with nested groups and projects should create redirect for the subgroups and projects
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:383
+
+ 66) Groups::TransferService#execute when transferring a subgroup into another group when updating the group goes wrong should restore group and projects visibility
+ # around hook at ./spec/spec_helper.rb:190 did not execute the example
+ # ./spec/services/groups/transfer_service_spec.rb:405
+
+ 67) GroupsHelper group_title outputs the groups in the correct order
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:106
+
+ 68) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: false, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: false, current_user: :root_owner, help_text: :default_help, linked_ancestor: nil has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 69) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: false, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: false, current_user: :sub_owner, help_text: :default_help, linked_ancestor: nil has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 70) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: false, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: false, current_user: :sub_sub_owner, help_text: :default_help, linked_ancestor: nil has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 71) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: false, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: true, current_user: :root_owner, help_text: :default_help, linked_ancestor: nil has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 72) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: false, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: true, current_user: :sub_owner, help_text: :default_help, linked_ancestor: nil has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 73) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: false, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: true, current_user: :sub_sub_owner, help_text: :default_help, linked_ancestor: nil has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 74) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: false, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: false, current_user: :root_owner, help_text: :ancestor_locked_and_has_been_overridden, linked_ancestor: :subgroup has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 75) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: false, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: false, current_user: :sub_owner, help_text: :ancestor_locked_and_has_been_overridden, linked_ancestor: :subgroup has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 76) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: false, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: false, current_user: :sub_sub_owner, help_text: :ancestor_locked_and_has_been_overridden, linked_ancestor: :subgroup has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 77) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: false, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: true, current_user: :root_owner, help_text: :ancestor_locked_but_you_can_override, linked_ancestor: :subgroup has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 78) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: false, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: true, current_user: :sub_owner, help_text: :ancestor_locked_but_you_can_override, linked_ancestor: :subgroup has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 79) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: false, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: true, current_user: :sub_sub_owner, help_text: :ancestor_locked_so_ask_the_owner, linked_ancestor: :subgroup has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 80) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: true, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: false, current_user: :root_owner, help_text: :default_help, linked_ancestor: nil has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 81) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: true, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: false, current_user: :sub_owner, help_text: :default_help, linked_ancestor: nil has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 82) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: true, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: false, current_user: :sub_sub_owner, help_text: :default_help, linked_ancestor: nil has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 83) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: true, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: true, current_user: :root_owner, help_text: :default_help, linked_ancestor: nil has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
+
+ 84) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: true, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: true, current_user: :sub_owner, help_text: :default_help, linked_ancestor: nil has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
-path
-Set for your local app (/usr/local/bundle/config): "vendor"
-Set via BUNDLE_PATH: "/usr/local/bundle"
+ 85) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: true, subgroup_share_with_group_locked: false, sub_subgroup_share_with_group_locked: true, current_user: :sub_sub_owner, help_text: :default_help, linked_ancestor: nil has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
-jobs
-Set for your local app (/usr/local/bundle/config): "2"
+ 86) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: true, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: false, current_user: :root_owner, help_text: :ancestor_locked_and_has_been_overridden, linked_ancestor: :root_group has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
-clean
-Set for your local app (/usr/local/bundle/config): "true"
+ 87) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: true, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: false, current_user: :sub_owner, help_text: :ancestor_locked_and_has_been_overridden, linked_ancestor: :root_group has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
-without
-Set for your local app (/usr/local/bundle/config): [:production]
+ 88) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: true, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: false, current_user: :sub_sub_owner, help_text: :ancestor_locked_and_has_been_overridden, linked_ancestor: :root_group has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
-silence_root_warning
-Set via BUNDLE_SILENCE_ROOT_WARNING: true
+ 89) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: true, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: true, current_user: :root_owner, help_text: :ancestor_locked_but_you_can_override, linked_ancestor: :root_group has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
-app_config
-Set via BUNDLE_APP_CONFIG: "/usr/local/bundle"
+ 90) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: true, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: true, current_user: :sub_owner, help_text: :ancestor_locked_so_ask_the_owner, linked_ancestor: :root_group has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
-install_flags
-Set via BUNDLE_INSTALL_FLAGS: "--without=production --jobs=2 --path=vendor --retry=3 --quiet"
+ 91) GroupsHelper#share_with_group_lock_help_text root_share_with_group_locked: true, subgroup_share_with_group_locked: true, sub_subgroup_share_with_group_locked: true, current_user: :sub_sub_owner, help_text: :ancestor_locked_so_ask_the_owner, linked_ancestor: :root_group has the correct help text with correct ancestor links
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/helpers/groups_helper_spec.rb:198
-bin
-Set via BUNDLE_BIN: "/usr/local/bundle/bin"
+ 92) AutocompleteUsersFinder#execute when passed a subgroup includes users from parent groups as well
+ # around hook at ./spec/spec_helper.rb:186 did not execute the example
+ # ./spec/finders/autocomplete_users_finder_spec.rb:55
-gemfile
-Set via BUNDLE_GEMFILE: "/builds/gitlab-org/gitlab-ce/Gemfile"
+Finished in 5 minutes 7 seconds (files took 16.6 seconds to load)
+819 examples, 0 failures, 92 pending
-section_end:1517486961:build_script
-section_start:1517486961:after_script
-section_end:1517486962:after_script
-section_start:1517486962:upload_artifacts
+section_end:1522927514:build_script
+section_start:1522927514:after_script
+Running after script...
+$ date
+Thu Apr 5 11:25:14 UTC 2018
+section_end:1522927515:after_script
+section_start:1522927515:archive_cache
+Not uploading cache ruby-2.3.6-with-yarn due to policy
+section_end:1522927516:archive_cache
+section_start:1522927516:upload_artifacts
Uploading artifacts...
-WARNING: coverage/: no matching files 
+coverage/: found 5 matching files 
knapsack/: found 5 matching files 
+rspec_flaky/: found 4 matching files 
WARNING: tmp/capybara/: no matching files 
-Uploading artifacts to coordinator... ok  id=50551722 responseStatus=201 Created token=XkN753rp
-section_end:1517486963:upload_artifacts
-ERROR: Job failed: exit code 1
- \ No newline at end of file
+Uploading artifacts to coordinator... ok  id=61303283 responseStatus=201 Created token=rusBKvxM
+section_end:1522927520:upload_artifacts
+Job succeeded
+
diff --git a/spec/javascripts/branches/branches_delete_modal_spec.js b/spec/javascripts/branches/branches_delete_modal_spec.js
new file mode 100644
index 00000000000..b223b8e2c0a
--- /dev/null
+++ b/spec/javascripts/branches/branches_delete_modal_spec.js
@@ -0,0 +1,40 @@
+import $ from 'jquery';
+import DeleteModal from '~/branches/branches_delete_modal';
+
+describe('branches delete modal', () => {
+ describe('setDisableDeleteButton', () => {
+ let submitSpy;
+ let $deleteButton;
+
+ beforeEach(() => {
+ setFixtures(`
+ <div id="modal-delete-branch">
+ <form>
+ <button type="submit" class="js-delete-branch">Delete</button>
+ </form>
+ </div>
+ `);
+ $deleteButton = $('.js-delete-branch');
+ submitSpy = jasmine.createSpy('submit').and.callFake(event => event.preventDefault());
+ $('#modal-delete-branch form').on('submit', submitSpy);
+ // eslint-disable-next-line no-new
+ new DeleteModal();
+ });
+
+ it('does not submit if button is disabled', () => {
+ $deleteButton.attr('disabled', true);
+
+ $deleteButton.click();
+
+ expect(submitSpy).not.toHaveBeenCalled();
+ });
+
+ it('submits if button is not disabled', () => {
+ $deleteButton.attr('disabled', false);
+
+ $deleteButton.click();
+
+ expect(submitSpy).toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/javascripts/ide/components/commit_sidebar/message_field_spec.js b/spec/javascripts/ide/components/commit_sidebar/message_field_spec.js
new file mode 100644
index 00000000000..d62d58101d6
--- /dev/null
+++ b/spec/javascripts/ide/components/commit_sidebar/message_field_spec.js
@@ -0,0 +1,174 @@
+import Vue from 'vue';
+import CommitMessageField from '~/ide/components/commit_sidebar/message_field.vue';
+import createComponent from 'spec/helpers/vue_mount_component_helper';
+
+describe('IDE commit message field', () => {
+ const Component = Vue.extend(CommitMessageField);
+ let vm;
+
+ beforeEach(() => {
+ setFixtures('<div id="app"></div>');
+
+ vm = createComponent(
+ Component,
+ {
+ text: '',
+ },
+ '#app',
+ );
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('adds is-focused class on focus', done => {
+ vm.$el.querySelector('textarea').focus();
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelector('.is-focused')).not.toBeNull();
+
+ done();
+ });
+ });
+
+ it('removed is-focused class on blur', done => {
+ vm.$el.querySelector('textarea').focus();
+
+ vm
+ .$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelector('.is-focused')).not.toBeNull();
+
+ vm.$el.querySelector('textarea').blur();
+
+ return vm.$nextTick();
+ })
+ .then(() => {
+ expect(vm.$el.querySelector('.is-focused')).toBeNull();
+
+ done();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('emits input event on input', () => {
+ spyOn(vm, '$emit');
+
+ const textarea = vm.$el.querySelector('textarea');
+ textarea.value = 'testing';
+
+ textarea.dispatchEvent(new Event('input'));
+
+ expect(vm.$emit).toHaveBeenCalledWith('input', 'testing');
+ });
+
+ describe('highlights', () => {
+ describe('subject line', () => {
+ it('does not highlight less than 50 characters', done => {
+ vm.text = 'text less than 50 chars';
+
+ vm
+ .$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelector('.highlights span').textContent).toContain(
+ 'text less than 50 chars',
+ );
+ expect(vm.$el.querySelector('mark').style.display).toBe('none');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('highlights characters over 50 length', done => {
+ vm.text =
+ 'text less than 50 chars that should not highlighted. text more than 50 should be highlighted';
+
+ vm
+ .$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelector('.highlights span').textContent).toContain(
+ 'text less than 50 chars that should not highlighte',
+ );
+ expect(vm.$el.querySelector('mark').style.display).not.toBe('none');
+ expect(vm.$el.querySelector('mark').textContent).toBe(
+ 'd. text more than 50 should be highlighted',
+ );
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ describe('body text', () => {
+ it('does not highlight body text less tan 72 characters', done => {
+ vm.text = 'subject line\nbody content';
+
+ vm
+ .$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2);
+ expect(vm.$el.querySelectorAll('mark')[1].style.display).toBe('none');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('highlights body text more than 72 characters', done => {
+ vm.text =
+ 'subject line\nbody content that will be highlighted when it is more than 72 characters in length';
+
+ vm
+ .$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2);
+ expect(vm.$el.querySelectorAll('mark')[1].style.display).not.toBe('none');
+ expect(vm.$el.querySelectorAll('mark')[1].textContent).toBe(' in length');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('highlights body text & subject line', done => {
+ vm.text =
+ 'text less than 50 chars that should not highlighted\nbody content that will be highlighted when it is more than 72 characters in length';
+
+ vm
+ .$nextTick()
+ .then(() => {
+ expect(vm.$el.querySelectorAll('.highlights span').length).toBe(2);
+ expect(vm.$el.querySelectorAll('mark').length).toBe(2);
+
+ expect(vm.$el.querySelectorAll('mark')[0].textContent).toContain('d');
+ expect(vm.$el.querySelectorAll('mark')[1].textContent).toBe(' in length');
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+ });
+
+ describe('scrolling textarea', () => {
+ it('updates transform of highlights', done => {
+ vm.text = 'subject line\n\n\n\n\n\n\n\n\n\n\nbody content';
+
+ vm
+ .$nextTick()
+ .then(() => {
+ vm.$el.querySelector('textarea').scrollTo(0, 50);
+
+ vm.handleScroll();
+ })
+ .then(vm.$nextTick)
+ .then(() => {
+ expect(vm.scrollTop).toBe(50);
+ expect(vm.$el.querySelector('.highlights').style.transform).toBe(
+ 'translate3d(0px, -50px, 0px)',
+ );
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+});
diff --git a/spec/javascripts/ide/components/commit_sidebar/radio_group_spec.js b/spec/javascripts/ide/components/commit_sidebar/radio_group_spec.js
index 4e8243439f3..21bfe4be52f 100644
--- a/spec/javascripts/ide/components/commit_sidebar/radio_group_spec.js
+++ b/spec/javascripts/ide/components/commit_sidebar/radio_group_spec.js
@@ -69,19 +69,6 @@ describe('IDE commit sidebar radio group', () => {
});
});
- it('renders helpText tooltip', done => {
- vm.helpText = 'help text';
-
- Vue.nextTick(() => {
- const help = vm.$el.querySelector('.help-block');
-
- expect(help).not.toBeNull();
- expect(help.getAttribute('data-original-title')).toBe('help text');
-
- done();
- });
- });
-
describe('with input', () => {
beforeEach(done => {
vm.$destroy();
diff --git a/spec/javascripts/ide/stores/mutations/tree_spec.js b/spec/javascripts/ide/stores/mutations/tree_spec.js
index e6c085eaff6..67e9f7509da 100644
--- a/spec/javascripts/ide/stores/mutations/tree_spec.js
+++ b/spec/javascripts/ide/stores/mutations/tree_spec.js
@@ -55,6 +55,16 @@ describe('Multi-file store tree mutations', () => {
expect(tree.tree[1].name).toBe('submodule');
expect(tree.tree[2].name).toBe('blob');
});
+
+ it('keeps loading state', () => {
+ mutations.CREATE_TREE(localState, { treePath: 'project/master' });
+ mutations.SET_DIRECTORY_DATA(localState, {
+ data,
+ treePath: 'project/master',
+ });
+
+ expect(localState.trees['project/master'].loading).toBe(true);
+ });
});
describe('REMOVE_ALL_CHANGES_FILES', () => {
diff --git a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
index 78bac1c61a5..5573d7c5c93 100644
--- a/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
+++ b/spec/javascripts/vue_mr_widget/components/states/mr_widget_pipeline_failed_spec.js
@@ -1,16 +1,19 @@
import Vue from 'vue';
-import pipelineFailedComponent from '~/vue_merge_request_widget/components/states/mr_widget_pipeline_failed';
+import PipelineFailed from '~/vue_merge_request_widget/components/states/pipeline_failed.vue';
+import { removeBreakLine } from 'spec/helpers/vue_component_helper';
-describe('MRWidgetPipelineFailed', () => {
+describe('PipelineFailed', () => {
describe('template', () => {
- const Component = Vue.extend(pipelineFailedComponent);
+ const Component = Vue.extend(PipelineFailed);
const vm = new Component({
el: document.createElement('div'),
});
it('should have correct elements', () => {
expect(vm.$el.classList.contains('mr-widget-body')).toBeTruthy();
expect(vm.$el.querySelector('button').getAttribute('disabled')).toBeTruthy();
- expect(vm.$el.innerText).toContain('The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure');
+ expect(
+ removeBreakLine(vm.$el.innerText).trim(),
+ ).toContain('The pipeline for this merge request failed. Please retry the job or push a new commit to fix the failure');
});
});
});
diff --git a/spec/javascripts/vue_shared/components/commit_spec.js b/spec/javascripts/vue_shared/components/commit_spec.js
index fdead874209..ed66361bfc3 100644
--- a/spec/javascripts/vue_shared/components/commit_spec.js
+++ b/spec/javascripts/vue_shared/components/commit_spec.js
@@ -1,5 +1,6 @@
import Vue from 'vue';
import commitComp from '~/vue_shared/components/commit.vue';
+import mountComponent from '../../helpers/vue_mount_component_helper';
describe('Commit component', () => {
let props;
@@ -10,25 +11,28 @@ describe('Commit component', () => {
CommitComponent = Vue.extend(commitComp);
});
+ afterEach(() => {
+ component.$destroy();
+ });
+
it('should render a fork icon if it does not represent a tag', () => {
- component = new CommitComponent({
- propsData: {
- tag: false,
- commitRef: {
- name: 'master',
- ref_url: 'http://localhost/namespace2/gitlabhq/tree/master',
- },
- commitUrl: 'https://gitlab.com/gitlab-org/gitlab-ce/commit/b7836eddf62d663c665769e1b0960197fd215067',
- shortSha: 'b7836edd',
- title: 'Commit message',
- author: {
- avatar_url: 'https://gitlab.com/uploads/-/system/user/avatar/300478/avatar.png',
- web_url: 'https://gitlab.com/jschatz1',
- path: '/jschatz1',
- username: 'jschatz1',
- },
+ component = mountComponent(CommitComponent, {
+ tag: false,
+ commitRef: {
+ name: 'master',
+ ref_url: 'http://localhost/namespace2/gitlabhq/tree/master',
},
- }).$mount();
+ commitUrl:
+ 'https://gitlab.com/gitlab-org/gitlab-ce/commit/b7836eddf62d663c665769e1b0960197fd215067',
+ shortSha: 'b7836edd',
+ title: 'Commit message',
+ author: {
+ avatar_url: 'https://gitlab.com/uploads/-/system/user/avatar/300478/avatar.png',
+ web_url: 'https://gitlab.com/jschatz1',
+ path: '/jschatz1',
+ username: 'jschatz1',
+ },
+ });
expect(component.$el.querySelector('.icon-container').children).toContain('svg');
});
@@ -41,7 +45,8 @@ describe('Commit component', () => {
name: 'master',
ref_url: 'http://localhost/namespace2/gitlabhq/tree/master',
},
- commitUrl: 'https://gitlab.com/gitlab-org/gitlab-ce/commit/b7836eddf62d663c665769e1b0960197fd215067',
+ commitUrl:
+ 'https://gitlab.com/gitlab-org/gitlab-ce/commit/b7836eddf62d663c665769e1b0960197fd215067',
shortSha: 'b7836edd',
title: 'Commit message',
author: {
@@ -53,9 +58,7 @@ describe('Commit component', () => {
commitIconSvg: '<svg></svg>',
};
- component = new CommitComponent({
- propsData: props,
- }).$mount();
+ component = mountComponent(CommitComponent, props);
});
it('should render a tag icon if it represents a tag', () => {
@@ -63,7 +66,9 @@ describe('Commit component', () => {
});
it('should render a link to the ref url', () => {
- expect(component.$el.querySelector('.ref-name').getAttribute('href')).toEqual(props.commitRef.ref_url);
+ expect(component.$el.querySelector('.ref-name').getAttribute('href')).toEqual(
+ props.commitRef.ref_url,
+ );
});
it('should render the ref name', () => {
@@ -71,7 +76,9 @@ describe('Commit component', () => {
});
it('should render the commit short sha with a link to the commit url', () => {
- expect(component.$el.querySelector('.commit-sha').getAttribute('href')).toEqual(props.commitUrl);
+ expect(component.$el.querySelector('.commit-sha').getAttribute('href')).toEqual(
+ props.commitUrl,
+ );
expect(component.$el.querySelector('.commit-sha').textContent).toContain(props.shortSha);
});
@@ -88,21 +95,25 @@ describe('Commit component', () => {
it('Should render the author avatar with title and alt attributes', () => {
expect(
- component.$el.querySelector('.commit-title .avatar-image-container img').getAttribute('data-original-title'),
+ component.$el
+ .querySelector('.commit-title .avatar-image-container img')
+ .getAttribute('data-original-title'),
).toContain(props.author.username);
expect(
- component.$el.querySelector('.commit-title .avatar-image-container img').getAttribute('alt'),
+ component.$el
+ .querySelector('.commit-title .avatar-image-container img')
+ .getAttribute('alt'),
).toContain(`${props.author.username}'s avatar`);
});
});
it('should render the commit title', () => {
- expect(
- component.$el.querySelector('a.commit-row-message').getAttribute('href'),
- ).toEqual(props.commitUrl);
- expect(
- component.$el.querySelector('a.commit-row-message').textContent,
- ).toContain(props.title);
+ expect(component.$el.querySelector('a.commit-row-message').getAttribute('href')).toEqual(
+ props.commitUrl,
+ );
+ expect(component.$el.querySelector('a.commit-row-message').textContent).toContain(
+ props.title,
+ );
});
});
@@ -114,19 +125,18 @@ describe('Commit component', () => {
name: 'master',
ref_url: 'http://localhost/namespace2/gitlabhq/tree/master',
},
- commitUrl: 'https://gitlab.com/gitlab-org/gitlab-ce/commit/b7836eddf62d663c665769e1b0960197fd215067',
+ commitUrl:
+ 'https://gitlab.com/gitlab-org/gitlab-ce/commit/b7836eddf62d663c665769e1b0960197fd215067',
shortSha: 'b7836edd',
title: null,
author: {},
};
- component = new CommitComponent({
- propsData: props,
- }).$mount();
+ component = mountComponent(CommitComponent, props);
- expect(
- component.$el.querySelector('.commit-title span').textContent,
- ).toContain('Cant find HEAD commit for this branch');
+ expect(component.$el.querySelector('.commit-title span').textContent).toContain(
+ "Can't find HEAD commit for this branch",
+ );
});
});
});
diff --git a/spec/lib/banzai/object_renderer_spec.rb b/spec/lib/banzai/object_renderer_spec.rb
index 1fe034ae9a2..209a547c3b3 100644
--- a/spec/lib/banzai/object_renderer_spec.rb
+++ b/spec/lib/banzai/object_renderer_spec.rb
@@ -11,7 +11,7 @@ describe Banzai::ObjectRenderer do
)
end
- let(:object) { Note.new(note: 'hello', note_html: '<p dir="auto">hello</p>', cached_markdown_version: CacheMarkdownField::CACHE_VERSION) }
+ let(:object) { Note.new(note: 'hello', note_html: '<p dir="auto">hello</p>', cached_markdown_version: CacheMarkdownField::CACHE_COMMONMARK_VERSION) }
describe '#render' do
context 'with cache' do
diff --git a/spec/lib/gitlab/ci/trace_spec.rb b/spec/lib/gitlab/ci/trace_spec.rb
index 3a9371ed2e8..6a9c6442282 100644
--- a/spec/lib/gitlab/ci/trace_spec.rb
+++ b/spec/lib/gitlab/ci/trace_spec.rb
@@ -458,7 +458,7 @@ describe Gitlab::Ci::Trace do
context 'when job does not have trace artifact' do
context 'when trace file stored in default path' do
let!(:build) { create(:ci_build, :success, :trace_live) }
- let!(:src_path) { trace.read { |s| return s.path } }
+ let!(:src_path) { trace.read { |s| s.path } }
let!(:src_checksum) { Digest::SHA256.file(src_path).hexdigest }
it_behaves_like 'archive trace file'
diff --git a/spec/lib/gitlab/diff/highlight_spec.rb b/spec/lib/gitlab/diff/highlight_spec.rb
index 73d60c021c8..7c9e8c8d04e 100644
--- a/spec/lib/gitlab/diff/highlight_spec.rb
+++ b/spec/lib/gitlab/diff/highlight_spec.rb
@@ -79,6 +79,8 @@ describe Gitlab::Diff::Highlight do
end
it 'keeps the original rich line' do
+ allow(Gitlab::Sentry).to receive(:track_exception)
+
code = %q{+ raise RuntimeError, "System commands must be given as an array of strings"}
expect(subject[5].text).to eq(code)
@@ -86,12 +88,9 @@ describe Gitlab::Diff::Highlight do
end
it 'reports to Sentry if configured' do
- allow(Gitlab::Sentry).to receive(:enabled?).and_return(true)
-
- expect(Gitlab::Sentry).to receive(:context)
- expect(Raven).to receive(:capture_exception)
+ expect(Gitlab::Sentry).to receive(:track_exception).and_call_original
- subject
+ expect { subject }. to raise_exception(RangeError)
end
end
end
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 1e00e8d2739..5acf40ea5ce 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -470,9 +470,20 @@ describe Gitlab::Git::Repository, seed_helper: true do
FileUtils.rm_rf(heads_dir)
FileUtils.mkdir_p(heads_dir)
+ repository.expire_has_local_branches_cache
expect(repository.has_local_branches?).to eq(false)
end
end
+
+ context 'memoizes the value' do
+ it 'returns true' do
+ expect(repository).to receive(:uncached_has_local_branches?).once.and_call_original
+
+ 2.times do
+ expect(repository.has_local_branches?).to eq(true)
+ end
+ end
+ end
end
context 'with gitaly' do
diff --git a/spec/lib/gitlab/sentry_spec.rb b/spec/lib/gitlab/sentry_spec.rb
index 8c211d1c63f..499757da061 100644
--- a/spec/lib/gitlab/sentry_spec.rb
+++ b/spec/lib/gitlab/sentry_spec.rb
@@ -7,7 +7,49 @@ describe Gitlab::Sentry do
described_class.context(nil)
- expect(Raven.tags_context[:locale]).to eq(I18n.locale.to_s)
+ expect(Raven.tags_context[:locale].to_s).to eq(I18n.locale.to_s)
+ end
+ end
+
+ describe '.track_exception' do
+ let(:exception) { RuntimeError.new('boom') }
+
+ before do
+ allow(described_class).to receive(:enabled?).and_return(true)
+ end
+
+ it 'raises the exception if it should' do
+ expect(described_class).to receive(:should_raise?).and_return(true)
+ expect { described_class.track_exception(exception) }
+ .to raise_error(RuntimeError)
+ end
+
+ context 'when exceptions should not be raised' do
+ before do
+ allow(described_class).to receive(:should_raise?).and_return(false)
+ end
+
+ it 'logs the exception with all attributes passed' do
+ expected_extras = {
+ some_other_info: 'info',
+ issue_url: 'http://gitlab.com/gitlab-org/gitlab-ce/issues/1'
+ }
+
+ expect(Raven).to receive(:capture_exception)
+ .with(exception, extra: a_hash_including(expected_extras))
+
+ described_class.track_exception(
+ exception,
+ issue_url: 'http://gitlab.com/gitlab-org/gitlab-ce/issues/1',
+ extra: { some_other_info: 'info' }
+ )
+ end
+
+ it 'sets the context' do
+ expect(described_class).to receive(:context)
+
+ described_class.track_exception(exception)
+ end
end
end
end
diff --git a/spec/lib/gitlab/shell_spec.rb b/spec/lib/gitlab/shell_spec.rb
index 7ff2c0639ec..7f579df1c36 100644
--- a/spec/lib/gitlab/shell_spec.rb
+++ b/spec/lib/gitlab/shell_spec.rb
@@ -727,7 +727,7 @@ describe Gitlab::Shell do
def find_in_authorized_keys_file(key_id)
gitlab_shell.batch_read_key_ids do |ids|
- return true if ids.include?(key_id)
+ return true if ids.include?(key_id) # rubocop:disable Cop/AvoidReturnFromBlocks
end
false
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index a12717835b0..d7075d4a6b4 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -2140,10 +2140,6 @@ describe Ci::Build do
it "doesn't save timeout_source" do
expect { run_job_without_exception }.not_to change { job.reload.ensure_metadata.timeout_source }
end
-
- it 'raises an exception' do
- expect { job.run! }.to raise_error(StateMachines::InvalidTransition)
- end
end
end
diff --git a/spec/models/commit_spec.rb b/spec/models/commit_spec.rb
index 959383ff0b7..4e6b037a720 100644
--- a/spec/models/commit_spec.rb
+++ b/spec/models/commit_spec.rb
@@ -450,6 +450,11 @@ eos
it "returns nil if the path doesn't exists" do
expect(commit.uri_type('this/path/doesnt/exist')).to be_nil
end
+
+ it 'is nil if the path is nil or empty' do
+ expect(commit.uri_type(nil)).to be_nil
+ expect(commit.uri_type("")).to be_nil
+ end
end
context 'when Gitaly commit_tree_entry feature is enabled' do
diff --git a/spec/models/commit_status_spec.rb b/spec/models/commit_status_spec.rb
index c536dab2681..2ed29052dc1 100644
--- a/spec/models/commit_status_spec.rb
+++ b/spec/models/commit_status_spec.rb
@@ -533,4 +533,36 @@ describe CommitStatus do
end
end
end
+
+ describe '#enqueue' do
+ let!(:current_time) { Time.new(2018, 4, 5, 14, 0, 0) }
+
+ before do
+ allow(Time).to receive(:now).and_return(current_time)
+ end
+
+ shared_examples 'commit status enqueued' do
+ it 'sets queued_at value when enqueued' do
+ expect { commit_status.enqueue }.to change { commit_status.reload.queued_at }.from(nil).to(current_time)
+ end
+ end
+
+ context 'when initial state is :created' do
+ let(:commit_status) { create(:commit_status, :created) }
+
+ it_behaves_like 'commit status enqueued'
+ end
+
+ context 'when initial state is :skipped' do
+ let(:commit_status) { create(:commit_status, :skipped) }
+
+ it_behaves_like 'commit status enqueued'
+ end
+
+ context 'when initial state is :manual' do
+ let(:commit_status) { create(:commit_status, :manual) }
+
+ it_behaves_like 'commit status enqueued'
+ end
+ end
end
diff --git a/spec/models/concerns/cache_markdown_field_spec.rb b/spec/models/concerns/cache_markdown_field_spec.rb
index 3c7f578975b..b3797c1fb46 100644
--- a/spec/models/concerns/cache_markdown_field_spec.rb
+++ b/spec/models/concerns/cache_markdown_field_spec.rb
@@ -72,7 +72,7 @@ describe CacheMarkdownField do
let(:updated_markdown) { '`Bar`' }
let(:updated_html) { '<p dir="auto"><code>Bar</code></p>' }
- let(:thing) { ThingWithMarkdownFields.new(foo: markdown, foo_html: html, cached_markdown_version: CacheMarkdownField::CACHE_VERSION) }
+ let(:thing) { ThingWithMarkdownFields.new(foo: markdown, foo_html: html, cached_markdown_version: CacheMarkdownField::CACHE_COMMONMARK_VERSION) }
describe '.attributes' do
it 'excludes cache attributes' do
@@ -89,17 +89,24 @@ describe CacheMarkdownField do
it { expect(thing.foo).to eq(markdown) }
it { expect(thing.foo_html).to eq(html) }
it { expect(thing.foo_html_changed?).not_to be_truthy }
- it { expect(thing.cached_markdown_version).to eq(CacheMarkdownField::CACHE_VERSION) }
+ it { expect(thing.cached_markdown_version).to eq(CacheMarkdownField::CACHE_COMMONMARK_VERSION) }
end
context 'a changed markdown field' do
- before do
- thing.foo = updated_markdown
- thing.save
+ shared_examples 'with cache version' do |cache_version|
+ let(:thing) { ThingWithMarkdownFields.new(foo: markdown, foo_html: html, cached_markdown_version: cache_version) }
+
+ before do
+ thing.foo = updated_markdown
+ thing.save
+ end
+
+ it { expect(thing.foo_html).to eq(updated_html) }
+ it { expect(thing.cached_markdown_version).to eq(cache_version) }
end
- it { expect(thing.foo_html).to eq(updated_html) }
- it { expect(thing.cached_markdown_version).to eq(CacheMarkdownField::CACHE_VERSION) }
+ it_behaves_like 'with cache version', CacheMarkdownField::CACHE_REDCARPET_VERSION
+ it_behaves_like 'with cache version', CacheMarkdownField::CACHE_COMMONMARK_VERSION
end
context 'when a markdown field is set repeatedly to an empty string' do
@@ -123,15 +130,22 @@ describe CacheMarkdownField do
end
context 'a non-markdown field changed' do
- before do
- thing.bar = 'OK'
- thing.save
+ shared_examples 'with cache version' do |cache_version|
+ let(:thing) { ThingWithMarkdownFields.new(foo: markdown, foo_html: html, cached_markdown_version: cache_version) }
+
+ before do
+ thing.bar = 'OK'
+ thing.save
+ end
+
+ it { expect(thing.bar).to eq('OK') }
+ it { expect(thing.foo).to eq(markdown) }
+ it { expect(thing.foo_html).to eq(html) }
+ it { expect(thing.cached_markdown_version).to eq(cache_version) }
end
- it { expect(thing.bar).to eq('OK') }
- it { expect(thing.foo).to eq(markdown) }
- it { expect(thing.foo_html).to eq(html) }
- it { expect(thing.cached_markdown_version).to eq(CacheMarkdownField::CACHE_VERSION) }
+ it_behaves_like 'with cache version', CacheMarkdownField::CACHE_REDCARPET_VERSION
+ it_behaves_like 'with cache version', CacheMarkdownField::CACHE_COMMONMARK_VERSION
end
context 'version is out of date' do
@@ -142,59 +156,85 @@ describe CacheMarkdownField do
end
it { expect(thing.foo_html).to eq(updated_html) }
- it { expect(thing.cached_markdown_version).to eq(CacheMarkdownField::CACHE_VERSION) }
+ it { expect(thing.cached_markdown_version).to eq(CacheMarkdownField::CACHE_REDCARPET_VERSION) }
end
describe '#cached_html_up_to_date?' do
- subject { thing.cached_html_up_to_date?(:foo) }
+ shared_examples 'with cache version' do |cache_version|
+ let(:thing) { ThingWithMarkdownFields.new(foo: markdown, foo_html: html, cached_markdown_version: cache_version) }
- it 'returns false when the version is absent' do
- thing.cached_markdown_version = nil
+ subject { thing.cached_html_up_to_date?(:foo) }
- is_expected.to be_falsy
- end
+ it 'returns false when the version is absent' do
+ thing.cached_markdown_version = nil
- it 'returns false when the version is too early' do
- thing.cached_markdown_version -= 1
+ is_expected.to be_falsy
+ end
- is_expected.to be_falsy
- end
+ it 'returns false when the version is too early' do
+ thing.cached_markdown_version -= 1
- it 'returns false when the version is too late' do
- thing.cached_markdown_version += 1
+ is_expected.to be_falsy
+ end
- is_expected.to be_falsy
- end
+ it 'returns false when the version is too late' do
+ thing.cached_markdown_version += 1
- it 'returns true when the version is just right' do
- thing.cached_markdown_version = CacheMarkdownField::CACHE_VERSION
+ is_expected.to be_falsy
+ end
- is_expected.to be_truthy
- end
+ it 'returns true when the version is just right' do
+ thing.cached_markdown_version = cache_version
- it 'returns false if markdown has been changed but html has not' do
- thing.foo = updated_html
+ is_expected.to be_truthy
+ end
- is_expected.to be_falsy
- end
+ it 'returns false if markdown has been changed but html has not' do
+ thing.foo = updated_html
- it 'returns true if markdown has not been changed but html has' do
- thing.foo_html = updated_html
+ is_expected.to be_falsy
+ end
+
+ it 'returns true if markdown has not been changed but html has' do
+ thing.foo_html = updated_html
- is_expected.to be_truthy
+ is_expected.to be_truthy
+ end
+
+ it 'returns true if markdown and html have both been changed' do
+ thing.foo = updated_markdown
+ thing.foo_html = updated_html
+
+ is_expected.to be_truthy
+ end
+
+ it 'returns false if the markdown field is set but the html is not' do
+ thing.foo_html = nil
+
+ is_expected.to be_falsy
+ end
end
- it 'returns true if markdown and html have both been changed' do
- thing.foo = updated_markdown
- thing.foo_html = updated_html
+ it_behaves_like 'with cache version', CacheMarkdownField::CACHE_REDCARPET_VERSION
+ it_behaves_like 'with cache version', CacheMarkdownField::CACHE_COMMONMARK_VERSION
+ end
+
+ describe '#latest_cached_markdown_version' do
+ subject { thing.latest_cached_markdown_version }
- is_expected.to be_truthy
+ it 'returns redcarpet version' do
+ thing.cached_markdown_version = CacheMarkdownField::CACHE_COMMONMARK_VERSION_START - 1
+ is_expected.to eq(CacheMarkdownField::CACHE_REDCARPET_VERSION)
end
- it 'returns false if the markdown field is set but the html is not' do
- thing.foo_html = nil
+ it 'returns commonmark version' do
+ thing.cached_markdown_version = CacheMarkdownField::CACHE_COMMONMARK_VERSION_START + 1
+ is_expected.to eq(CacheMarkdownField::CACHE_COMMONMARK_VERSION)
+ end
- is_expected.to be_falsy
+ it 'returns default version when version is nil' do
+ thing.cached_markdown_version = nil
+ is_expected.to eq(CacheMarkdownField::CACHE_REDCARPET_VERSION)
end
end
@@ -221,37 +261,44 @@ describe CacheMarkdownField do
thing.cached_markdown_version = nil
thing.refresh_markdown_cache
- expect(thing.cached_markdown_version).to eq(CacheMarkdownField::CACHE_VERSION)
+ expect(thing.cached_markdown_version).to eq(CacheMarkdownField::CACHE_REDCARPET_VERSION)
end
end
describe '#refresh_markdown_cache!' do
- before do
- thing.foo = updated_markdown
- end
+ shared_examples 'with cache version' do |cache_version|
+ let(:thing) { ThingWithMarkdownFields.new(foo: markdown, foo_html: html, cached_markdown_version: cache_version) }
- it 'fills all html fields' do
- thing.refresh_markdown_cache!
+ before do
+ thing.foo = updated_markdown
+ end
- expect(thing.foo_html).to eq(updated_html)
- expect(thing.foo_html_changed?).to be_truthy
- expect(thing.baz_html_changed?).to be_truthy
- end
+ it 'fills all html fields' do
+ thing.refresh_markdown_cache!
- it 'skips saving if not persisted' do
- expect(thing).to receive(:persisted?).and_return(false)
- expect(thing).not_to receive(:update_columns)
+ expect(thing.foo_html).to eq(updated_html)
+ expect(thing.foo_html_changed?).to be_truthy
+ expect(thing.baz_html_changed?).to be_truthy
+ end
- thing.refresh_markdown_cache!
- end
+ it 'skips saving if not persisted' do
+ expect(thing).to receive(:persisted?).and_return(false)
+ expect(thing).not_to receive(:update_columns)
- it 'saves the changes using #update_columns' do
- expect(thing).to receive(:persisted?).and_return(true)
- expect(thing).to receive(:update_columns)
- .with("foo_html" => updated_html, "baz_html" => "", "cached_markdown_version" => CacheMarkdownField::CACHE_VERSION)
+ thing.refresh_markdown_cache!
+ end
- thing.refresh_markdown_cache!
+ it 'saves the changes using #update_columns' do
+ expect(thing).to receive(:persisted?).and_return(true)
+ expect(thing).to receive(:update_columns)
+ .with("foo_html" => updated_html, "baz_html" => "", "cached_markdown_version" => cache_version)
+
+ thing.refresh_markdown_cache!
+ end
end
+
+ it_behaves_like 'with cache version', CacheMarkdownField::CACHE_REDCARPET_VERSION
+ it_behaves_like 'with cache version', CacheMarkdownField::CACHE_COMMONMARK_VERSION
end
describe '#banzai_render_context' do
@@ -299,7 +346,7 @@ describe CacheMarkdownField do
expect(thing.foo_html).to eq(updated_html)
expect(thing.baz_html).to eq(updated_html)
- expect(thing.cached_markdown_version).to eq(CacheMarkdownField::CACHE_VERSION)
+ expect(thing.cached_markdown_version).to eq(CacheMarkdownField::CACHE_REDCARPET_VERSION)
end
end
@@ -319,7 +366,7 @@ describe CacheMarkdownField do
expect(thing.foo_html).to eq(updated_html)
expect(thing.baz_html).to eq(updated_html)
- expect(thing.cached_markdown_version).to eq(CacheMarkdownField::CACHE_VERSION)
+ expect(thing.cached_markdown_version).to eq(CacheMarkdownField::CACHE_REDCARPET_VERSION)
end
end
end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 60ab52565cb..e45fe7db1e7 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -1437,6 +1437,12 @@ describe Repository do
repository.expire_emptiness_caches
end
+
+ it 'expires the memoized repository cache' do
+ allow(repository.raw_repository).to receive(:expire_has_local_branches_cache).and_call_original
+
+ repository.expire_emptiness_caches
+ end
end
describe 'skip_merges option' do
diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb
index 741800ff61d..9e6d69e3874 100644
--- a/spec/requests/api/repositories_spec.rb
+++ b/spec/requests/api/repositories_spec.rb
@@ -427,5 +427,20 @@ describe API::Repositories do
let(:request) { get api(route, guest) }
end
end
+
+ # Regression: https://gitlab.com/gitlab-org/gitlab-ce/issues/45363
+ describe 'Links header contains working URLs when no `order_by` nor `sort` is given' do
+ let(:project) { create(:project, :public, :repository) }
+ let(:current_user) { nil }
+
+ it 'returns `Link` header that includes URLs with default value for `order_by` & `sort`' do
+ get api(route, current_user)
+
+ first_link_url = response.headers['Link'].split(';').first
+
+ expect(first_link_url).to include('order_by=commits')
+ expect(first_link_url).to include('sort=asc')
+ end
+ end
end
end
diff --git a/spec/rubocop/cop/avoid_break_from_strong_memoize_spec.rb b/spec/rubocop/cop/avoid_break_from_strong_memoize_spec.rb
new file mode 100644
index 00000000000..ac7b1575ec0
--- /dev/null
+++ b/spec/rubocop/cop/avoid_break_from_strong_memoize_spec.rb
@@ -0,0 +1,74 @@
+require 'spec_helper'
+require 'rubocop'
+require 'rubocop/rspec/support'
+require_relative '../../../rubocop/cop/avoid_break_from_strong_memoize'
+
+describe RuboCop::Cop::AvoidBreakFromStrongMemoize do
+ include CopHelper
+
+ subject(:cop) { described_class.new }
+
+ it 'flags violation for break inside strong_memoize' do
+ expect_offense(<<~RUBY)
+ strong_memoize(:result) do
+ break if something
+ ^^^^^ Do not use break inside strong_memoize, use next instead.
+
+ do_an_heavy_calculation
+ end
+ RUBY
+ end
+
+ it 'flags violation for break inside strong_memoize nested blocks' do
+ expect_offense(<<~RUBY)
+ strong_memoize do
+ items.each do |item|
+ break item
+ ^^^^^^^^^^ Do not use break inside strong_memoize, use next instead.
+ end
+ end
+ RUBY
+ end
+
+ it "doesn't flag violation for next inside strong_memoize" do
+ expect_no_offenses(<<~RUBY)
+ strong_memoize(:result) do
+ next if something
+
+ do_an_heavy_calculation
+ end
+ RUBY
+ end
+
+ it "doesn't flag violation for break inside blocks" do
+ expect_no_offenses(<<~RUBY)
+ call do
+ break if something
+
+ do_an_heavy_calculation
+ end
+ RUBY
+ end
+
+ it "doesn't call add_offense twice for nested blocks" do
+ source = <<~RUBY
+ call do
+ strong_memoize(:result) do
+ break if something
+
+ do_an_heavy_calculation
+ end
+ end
+ RUBY
+ expect_any_instance_of(described_class).to receive(:add_offense).once
+
+ inspect_source(source)
+ end
+
+ it "doesn't check when block is empty" do
+ expect_no_offenses(<<~RUBY)
+ strong_memoize(:result) do
+ end
+ RUBY
+ end
+end
diff --git a/spec/rubocop/cop/avoid_return_from_blocks_spec.rb b/spec/rubocop/cop/avoid_return_from_blocks_spec.rb
new file mode 100644
index 00000000000..a5c280a7adc
--- /dev/null
+++ b/spec/rubocop/cop/avoid_return_from_blocks_spec.rb
@@ -0,0 +1,127 @@
+require 'spec_helper'
+require 'rubocop'
+require 'rubocop/rspec/support'
+require_relative '../../../rubocop/cop/avoid_return_from_blocks'
+
+describe RuboCop::Cop::AvoidReturnFromBlocks do
+ include CopHelper
+
+ subject(:cop) { described_class.new }
+
+ it 'flags violation for return inside a block' do
+ expect_offense(<<~RUBY)
+ call do
+ do_something
+ return if something_else
+ ^^^^^^ Do not return from a block, use next or break instead.
+ end
+ RUBY
+ end
+
+ it "doesn't call add_offense twice for nested blocks" do
+ source = <<~RUBY
+ call do
+ call do
+ something
+ return if something_else
+ end
+ end
+ RUBY
+ expect_any_instance_of(described_class).to receive(:add_offense).once
+
+ inspect_source(source)
+ end
+
+ it 'flags violation for return inside included > def > block' do
+ expect_offense(<<~RUBY)
+ included do
+ def a_method
+ return if something
+
+ call do
+ return if something_else
+ ^^^^^^ Do not return from a block, use next or break instead.
+ end
+ end
+ end
+ RUBY
+ end
+
+ shared_examples 'examples with whitelisted method' do |whitelisted_method|
+ it "doesn't flag violation for return inside #{whitelisted_method}" do
+ expect_no_offenses(<<~RUBY)
+ items.#{whitelisted_method} do |item|
+ do_something
+ return if something_else
+ end
+ RUBY
+ end
+ end
+
+ %i[each each_filename times loop].each do |whitelisted_method|
+ it_behaves_like 'examples with whitelisted method', whitelisted_method
+ end
+
+ shared_examples 'examples with def methods' do |def_method|
+ it "doesn't flag violation for return inside #{def_method}" do
+ expect_no_offenses(<<~RUBY)
+ helpers do
+ #{def_method} do
+ return if something
+
+ do_something_more
+ end
+ end
+ RUBY
+ end
+ end
+
+ %i[define_method lambda].each do |def_method|
+ it_behaves_like 'examples with def methods', def_method
+ end
+
+ it "doesn't flag violation for return inside a lambda" do
+ expect_no_offenses(<<~RUBY)
+ lambda do
+ do_something
+ return if something_else
+ end
+ RUBY
+ end
+
+ it "doesn't flag violation for return used inside a method definition" do
+ expect_no_offenses(<<~RUBY)
+ describe Klass do
+ def a_method
+ do_something
+ return if something_else
+ end
+ end
+ RUBY
+ end
+
+ it "doesn't flag violation for next inside a block" do
+ expect_no_offenses(<<~RUBY)
+ call do
+ do_something
+ next if something_else
+ end
+ RUBY
+ end
+
+ it "doesn't flag violation for break inside a block" do
+ expect_no_offenses(<<~RUBY)
+ call do
+ do_something
+ break if something_else
+ end
+ RUBY
+ end
+
+ it "doesn't check when block is empty" do
+ expect_no_offenses(<<~RUBY)
+ call do
+ end
+ RUBY
+ end
+end
diff --git a/spec/services/ci/register_job_service_spec.rb b/spec/services/ci/register_job_service_spec.rb
index 97a563c1ce1..8a537e83d5f 100644
--- a/spec/services/ci/register_job_service_spec.rb
+++ b/spec/services/ci/register_job_service_spec.rb
@@ -370,10 +370,111 @@ module Ci
it_behaves_like 'validation is not active'
end
end
+ end
+
+ describe '#register_success' do
+ let!(:current_time) { Time.new(2018, 4, 5, 14, 0, 0) }
+ let!(:attempt_counter) { double('Gitlab::Metrics::NullMetric') }
+ let!(:job_queue_duration_seconds) { double('Gitlab::Metrics::NullMetric') }
+
+ before do
+ allow(Time).to receive(:now).and_return(current_time)
+
+ # Stub defaults for any metrics other than the ones we're testing
+ allow(Gitlab::Metrics).to receive(:counter)
+ .with(any_args)
+ .and_return(Gitlab::Metrics::NullMetric.instance)
+ allow(Gitlab::Metrics).to receive(:histogram)
+ .with(any_args)
+ .and_return(Gitlab::Metrics::NullMetric.instance)
+
+ # Stub tested metrics
+ allow(Gitlab::Metrics).to receive(:counter)
+ .with(:job_register_attempts_total, anything)
+ .and_return(attempt_counter)
+ allow(Gitlab::Metrics).to receive(:histogram)
+ .with(:job_queue_duration_seconds, anything, anything, anything)
+ .and_return(job_queue_duration_seconds)
+
+ project.update(shared_runners_enabled: true)
+ pending_job.update(created_at: current_time - 3600, queued_at: current_time - 1800)
+ end
+
+ shared_examples 'attempt counter collector' do
+ it 'increments attempt counter' do
+ allow(job_queue_duration_seconds).to receive(:observe)
+ expect(attempt_counter).to receive(:increment)
+
+ execute(runner)
+ end
+ end
+
+ shared_examples 'jobs queueing time histogram collector' do
+ it 'counts job queuing time histogram with expected labels' do
+ allow(attempt_counter).to receive(:increment)
+ expect(job_queue_duration_seconds).to receive(:observe)
+ .with({ shared_runner: expected_shared_runner,
+ jobs_running_for_project: expected_jobs_running_for_project_first_job }, 1800)
+
+ execute(runner)
+ end
+
+ context 'when project already has running jobs' do
+ let!(:build2) { create( :ci_build, :running, pipeline: pipeline, runner: shared_runner) }
+ let!(:build3) { create( :ci_build, :running, pipeline: pipeline, runner: shared_runner) }
+
+ it 'counts job queuing time histogram with expected labels' do
+ allow(attempt_counter).to receive(:increment)
+ expect(job_queue_duration_seconds).to receive(:observe)
+ .with({ shared_runner: expected_shared_runner,
+ jobs_running_for_project: expected_jobs_running_for_project_third_job }, 1800)
+
+ execute(runner)
+ end
+ end
+ end
- def execute(runner)
- described_class.new(runner).execute.build
+ shared_examples 'metrics collector' do
+ it_behaves_like 'attempt counter collector'
+ it_behaves_like 'jobs queueing time histogram collector'
end
+
+ context 'when shared runner is used' do
+ let(:runner) { shared_runner }
+ let(:expected_shared_runner) { true }
+ let(:expected_jobs_running_for_project_first_job) { 0 }
+ let(:expected_jobs_running_for_project_third_job) { 2 }
+
+ it_behaves_like 'metrics collector'
+
+ context 'when pending job with queued_at=nil is used' do
+ before do
+ pending_job.update(queued_at: nil)
+ end
+
+ it_behaves_like 'attempt counter collector'
+
+ it "doesn't count job queuing time histogram" do
+ allow(attempt_counter).to receive(:increment)
+ expect(job_queue_duration_seconds).not_to receive(:observe)
+
+ execute(runner)
+ end
+ end
+ end
+
+ context 'when specific runner is used' do
+ let(:runner) { specific_runner }
+ let(:expected_shared_runner) { false }
+ let(:expected_jobs_running_for_project_first_job) { '+Inf' }
+ let(:expected_jobs_running_for_project_third_job) { '+Inf' }
+
+ it_behaves_like 'metrics collector'
+ end
+ end
+
+ def execute(runner)
+ described_class.new(runner).execute.build
end
end
end
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index f8fa2540804..55bbe954491 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -933,6 +933,46 @@ describe NotificationService, :mailer do
let(:notification_trigger) { notification.issue_moved(issue, new_issue, @u_disabled) }
end
end
+
+ describe '#issue_due' do
+ before do
+ issue.update!(due_date: Date.today)
+
+ update_custom_notification(:issue_due, @u_guest_custom, resource: project)
+ update_custom_notification(:issue_due, @u_custom_global)
+ end
+
+ it 'sends email to issue notification recipients, excluding watchers' do
+ notification.issue_due(issue)
+
+ should_email(issue.assignees.first)
+ should_email(issue.author)
+ should_email(@u_guest_custom)
+ should_email(@u_custom_global)
+ should_email(@u_participant_mentioned)
+ should_email(@subscriber)
+ should_email(@watcher_and_subscriber)
+ should_not_email(@u_watcher)
+ should_not_email(@u_guest_watcher)
+ should_not_email(@unsubscriber)
+ should_not_email(@u_participating)
+ should_not_email(@u_disabled)
+ should_not_email(@u_lazy_participant)
+ end
+
+ it 'sends the email from the author' do
+ notification.issue_due(issue)
+ email = find_email_for(@subscriber)
+
+ expect(email.header[:from].display_names).to eq([issue.author.name])
+ end
+
+ it_behaves_like 'participating notifications' do
+ let(:participant) { create(:user, username: 'user-participant') }
+ let(:issuable) { issue }
+ let(:notification_trigger) { notification.issue_due(issue) }
+ end
+ end
end
describe 'Merge Requests' do
diff --git a/spec/services/system_note_service_spec.rb b/spec/services/system_note_service_spec.rb
index e28b0ea5cf2..893804f1470 100644
--- a/spec/services/system_note_service_spec.rb
+++ b/spec/services/system_note_service_spec.rb
@@ -909,7 +909,13 @@ describe SystemNoteService do
it 'sets the note text' do
noteable.update_attribute(:time_estimate, 277200)
- expect(subject.note).to eq "changed time estimate to 1w 4d 5h"
+ expect(subject.note).to eq "changed time estimate to 1w 4d 5h,"
+ end
+
+ it 'appends a comma to separate the note from the update_at time' do
+ noteable.update_attribute(:time_estimate, 277200)
+
+ expect(subject.note).to end_with(',')
end
end
diff --git a/spec/support/http_io/http_io_helpers.rb b/spec/support/http_io/http_io_helpers.rb
index 31e07e720cd..2c68c2cd9a6 100644
--- a/spec/support/http_io/http_io_helpers.rb
+++ b/spec/support/http_io/http_io_helpers.rb
@@ -44,10 +44,11 @@ module HttpIOHelpers
def remote_trace_body
@remote_trace_body ||= File.read(expand_fixture_path('trace/sample_trace'))
+ .force_encoding(Encoding::BINARY)
end
def remote_trace_size
- remote_trace_body.length
+ remote_trace_body.bytesize
end
def set_smaller_buffer_size_than(file_size)
diff --git a/spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb b/spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb
index 934d53e7bba..93c21a99e59 100644
--- a/spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb
+++ b/spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb
@@ -4,7 +4,7 @@ shared_examples "matches the method pattern" do |method|
let(:pattern) { patterns[method] }
it do
- return skip "No pattern provided, skipping." unless pattern
+ skip "No pattern provided, skipping." unless pattern
expect(target.method(method).call(*args)).to match(pattern)
end
diff --git a/spec/workers/issue_due_scheduler_worker_spec.rb b/spec/workers/issue_due_scheduler_worker_spec.rb
new file mode 100644
index 00000000000..7b60835fd26
--- /dev/null
+++ b/spec/workers/issue_due_scheduler_worker_spec.rb
@@ -0,0 +1,22 @@
+require 'spec_helper'
+
+describe IssueDueSchedulerWorker do
+ describe '#perform' do
+ it 'schedules one MailScheduler::IssueDueWorker per project with open issues due tomorrow' do
+ project1 = create(:project)
+ project2 = create(:project)
+ project_closed_issue = create(:project)
+ project_issue_due_another_day = create(:project)
+
+ create(:issue, :opened, project: project1, due_date: Date.tomorrow)
+ create(:issue, :opened, project: project1, due_date: Date.tomorrow)
+ create(:issue, :opened, project: project2, due_date: Date.tomorrow)
+ create(:issue, :closed, project: project_closed_issue, due_date: Date.tomorrow)
+ create(:issue, :opened, project: project_issue_due_another_day, due_date: Date.today)
+
+ expect(MailScheduler::IssueDueWorker).to receive(:bulk_perform_async).with([[project1.id], [project2.id]])
+
+ described_class.new.perform
+ end
+ end
+end
diff --git a/spec/workers/mail_scheduler/issue_due_worker_spec.rb b/spec/workers/mail_scheduler/issue_due_worker_spec.rb
new file mode 100644
index 00000000000..48ac1b8a1a4
--- /dev/null
+++ b/spec/workers/mail_scheduler/issue_due_worker_spec.rb
@@ -0,0 +1,21 @@
+require 'spec_helper'
+
+describe MailScheduler::IssueDueWorker do
+ describe '#perform' do
+ let(:worker) { described_class.new }
+ let(:project) { create(:project) }
+
+ it 'sends emails for open issues due tomorrow in the project specified' do
+ issue1 = create(:issue, :opened, project: project, due_date: Date.tomorrow)
+ issue2 = create(:issue, :opened, project: project, due_date: Date.tomorrow)
+ create(:issue, :closed, project: project, due_date: Date.tomorrow) # closed
+ create(:issue, :opened, project: project, due_date: 2.days.from_now) # due on another day
+ create(:issue, :opened, due_date: Date.tomorrow) # different project
+
+ expect_any_instance_of(NotificationService).to receive(:issue_due).with(issue1)
+ expect_any_instance_of(NotificationService).to receive(:issue_due).with(issue2)
+
+ worker.perform(project.id)
+ end
+ end
+end