summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorShinya Maeda <shinya@gitlab.com>2018-10-04 09:44:14 +0900
committerShinya Maeda <shinya@gitlab.com>2018-10-04 09:44:14 +0900
commit5381985bd012562696637122b1dcd067480a94d3 (patch)
tree7e05baefc2df32f6ef324cae755de6294c89c92f /spec
parent9c13a512f4a836d2d0d61dc4fbbc6fd8f76aa474 (diff)
parentdfb9ac3a5f97a4c556bacea78174836fe7d39145 (diff)
downloadgitlab-ce-5381985bd012562696637122b1dcd067480a94d3.tar.gz
Merge branch 'master-ce' into scheduled-manual-jobs
Diffstat (limited to 'spec')
-rw-r--r--spec/features/admin/admin_manage_applications_spec.rb4
-rw-r--r--spec/features/issues/filtered_search/dropdown_hint_spec.rb18
-rw-r--r--spec/features/markdown/markdown_spec.rb6
-rw-r--r--spec/features/merge_request/user_comments_on_diff_spec.rb18
-rw-r--r--spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb2
-rw-r--r--spec/features/merge_request/user_sees_versions_spec.rb10
-rw-r--r--spec/features/merge_request/user_views_diffs_spec.rb2
-rw-r--r--spec/features/profiles/user_manages_applications_spec.rb4
-rw-r--r--spec/features/projects/environments/environment_spec.rb12
-rw-r--r--spec/features/projects/import_export/export_file_spec.rb2
-rw-r--r--spec/features/projects/jobs/user_browses_job_spec.rb14
-rw-r--r--spec/features/projects/jobs_spec.rb166
-rw-r--r--spec/features/projects/wiki/user_views_wiki_page_spec.rb13
-rw-r--r--spec/finders/merge_requests_finder_spec.rb56
-rw-r--r--spec/javascripts/boards/board_new_issue_spec.js1
-rw-r--r--spec/javascripts/diffs/components/app_spec.js18
-rw-r--r--spec/javascripts/diffs/components/changed_files_spec.js105
-rw-r--r--spec/javascripts/diffs/components/file_row_stats_spec.js33
-rw-r--r--spec/javascripts/diffs/components/tree_list_spec.js120
-rw-r--r--spec/javascripts/diffs/mock_data/diff_file.js2
-rw-r--r--spec/javascripts/diffs/store/actions_spec.js87
-rw-r--r--spec/javascripts/diffs/store/getters_spec.js27
-rw-r--r--spec/javascripts/diffs/store/mutations_spec.js41
-rw-r--r--spec/javascripts/diffs/store/utils_spec.js109
-rw-r--r--spec/javascripts/filtered_search/dropdown_utils_spec.js5
-rw-r--r--spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js8
-rw-r--r--spec/javascripts/ide/components/file_row_extra_spec.js8
-rw-r--r--spec/javascripts/ide/components/repo_tab_spec.js4
-rw-r--r--spec/javascripts/job_spec.js19
-rw-r--r--spec/javascripts/jobs/components/environments_block_spec.js59
-rw-r--r--spec/javascripts/jobs/components/header_spec.js98
-rw-r--r--spec/javascripts/jobs/components/job_app_spec.js185
-rw-r--r--spec/javascripts/jobs/components/jobs_container_spec.js23
-rw-r--r--spec/javascripts/jobs/components/sidebar_details_block_spec.js139
-rw-r--r--spec/javascripts/jobs/components/sidebar_spec.js196
-rw-r--r--spec/javascripts/jobs/components/stages_dropdown_spec.js32
-rw-r--r--spec/javascripts/jobs/mock_data.js1047
-rw-r--r--spec/javascripts/jobs/store/actions_spec.js54
-rw-r--r--spec/javascripts/jobs/store/getters_spec.js121
-rw-r--r--spec/javascripts/notes/components/noteable_discussion_spec.js25
-rw-r--r--spec/javascripts/sidebar/components/time_tracking/time_tracker_spec.js33
-rw-r--r--spec/javascripts/vue_shared/components/changed_file_icon_spec.js (renamed from spec/javascripts/ide/components/changed_file_icon_spec.js)12
-rw-r--r--spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb8
-rw-r--r--spec/lib/gitlab/conflict/file_spec.rb4
-rw-r--r--spec/lib/gitlab/git/blob_spec.rb17
-rw-r--r--spec/lib/gitlab/git/branch_spec.rb8
-rw-r--r--spec/lib/gitlab/git/commit_spec.rb31
-rw-r--r--spec/lib/gitlab/git/diff_spec.rb61
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb214
-rw-r--r--spec/lib/gitlab/git_access_spec.rb29
-rw-r--r--spec/lib/gitlab/gitaly_client/wiki_service_spec.rb4
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb1
-rw-r--r--spec/lib/gitlab/web_ide_commits_counter_spec.rb19
-rw-r--r--spec/models/merge_request_spec.rb2
-rw-r--r--spec/models/namespace_spec.rb5
-rw-r--r--spec/models/project_spec.rb5
-rw-r--r--spec/models/remote_mirror_spec.rb6
-rw-r--r--spec/models/repository_spec.rb24
-rw-r--r--spec/models/wiki_page_spec.rb2
-rw-r--r--spec/requests/api/commits_spec.rb6
-rw-r--r--spec/requests/api/merge_requests_spec.rb38
-rw-r--r--spec/services/git_tag_push_service_spec.rb5
-rw-r--r--spec/services/merge_requests/squash_service_spec.rb6
-rw-r--r--spec/services/projects/after_import_service_spec.rb4
-rw-r--r--spec/services/projects/create_service_spec.rb6
-rw-r--r--spec/services/projects/hashed_storage/migrate_repository_service_spec.rb6
-rw-r--r--spec/services/projects/transfer_service_spec.rb6
-rw-r--r--spec/support/helpers/cycle_analytics_helpers.rb13
-rw-r--r--spec/support/helpers/git_helpers.rb6
-rw-r--r--spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb8
-rw-r--r--spec/views/projects/jobs/show.html.haml_spec.rb155
-rw-r--r--spec/workers/git_garbage_collect_worker_spec.rb6
-rw-r--r--spec/workers/repository_remove_remote_worker_spec.rb5
73 files changed, 2634 insertions, 1014 deletions
diff --git a/spec/features/admin/admin_manage_applications_spec.rb b/spec/features/admin/admin_manage_applications_spec.rb
index f979d2f6090..a4904272706 100644
--- a/spec/features/admin/admin_manage_applications_spec.rb
+++ b/spec/features/admin/admin_manage_applications_spec.rb
@@ -16,7 +16,7 @@ RSpec.describe 'admin manage applications' do
check :doorkeeper_application_trusted
click_on 'Submit'
expect(page).to have_content('Application: test')
- expect(page).to have_content('Application Id')
+ expect(page).to have_content('Application ID')
expect(page).to have_content('Secret')
expect(page).to have_content('Trusted Y')
@@ -28,7 +28,7 @@ RSpec.describe 'admin manage applications' do
click_on 'Submit'
expect(page).to have_content('test_changed')
- expect(page).to have_content('Application Id')
+ expect(page).to have_content('Application ID')
expect(page).to have_content('Secret')
expect(page).to have_content('Trusted N')
diff --git a/spec/features/issues/filtered_search/dropdown_hint_spec.rb b/spec/features/issues/filtered_search/dropdown_hint_spec.rb
index b99c5a7f4e3..0e296ab2109 100644
--- a/spec/features/issues/filtered_search/dropdown_hint_spec.rb
+++ b/spec/features/issues/filtered_search/dropdown_hint_spec.rb
@@ -15,6 +15,7 @@ describe 'Dropdown hint', :js do
before do
project.add_maintainer(user)
create(:issue, project: project)
+ create(:merge_request, source_project: project, target_project: project)
end
context 'when user not logged in' do
@@ -224,4 +225,21 @@ describe 'Dropdown hint', :js do
end
end
end
+
+ context 'merge request page' do
+ before do
+ sign_in(user)
+ visit project_merge_requests_path(project)
+ filtered_search.click
+ end
+
+ it 'shows the WIP menu item and opens the WIP options dropdown' do
+ click_hint('wip')
+
+ expect(page).to have_css(js_dropdown_hint, visible: false)
+ expect(page).to have_css('#js-dropdown-wip', visible: true)
+ expect_tokens([{ name: 'wip' }])
+ expect_filtered_search_input_empty
+ end
+ end
end
diff --git a/spec/features/markdown/markdown_spec.rb b/spec/features/markdown/markdown_spec.rb
index cac8a5068ec..3b37ede8579 100644
--- a/spec/features/markdown/markdown_spec.rb
+++ b/spec/features/markdown/markdown_spec.rb
@@ -264,9 +264,9 @@ describe 'GitLab Markdown', :aggregate_failures do
@project_wiki = @feat.project_wiki
@project_wiki_page = @feat.project_wiki_page
- file = Gollum::File.new(@project_wiki.wiki)
- expect(file).to receive(:path).and_return('images/example.jpg')
- expect(@project_wiki).to receive(:find_file).with('images/example.jpg').and_return(file)
+ path = 'images/example.jpg'
+ gitaly_wiki_file = Gitlab::GitalyClient::WikiFile.new(path: path)
+ expect(@project_wiki).to receive(:find_file).with(path).and_return(Gitlab::Git::WikiFile.new(gitaly_wiki_file))
allow(@project_wiki).to receive(:wiki_base_path) { '/namespace1/gitlabhq/wikis' }
@html = markdown(@feat.raw_markdown, { pipeline: :wiki, project_wiki: @project_wiki, page_slug: @project_wiki_page.slug })
diff --git a/spec/features/merge_request/user_comments_on_diff_spec.rb b/spec/features/merge_request/user_comments_on_diff_spec.rb
index 441b080bee5..00cf368e8c9 100644
--- a/spec/features/merge_request/user_comments_on_diff_spec.rb
+++ b/spec/features/merge_request/user_comments_on_diff_spec.rb
@@ -28,7 +28,7 @@ describe 'User comments on a diff', :js do
click_button('Comment')
end
- page.within('.files > div:nth-child(3)') do
+ page.within('.diff-files-holder > div:nth-child(3)') do
expect(page).to have_content('Line is wrong')
find('.js-btn-vue-toggle-comments').click
@@ -49,7 +49,7 @@ describe 'User comments on a diff', :js do
wait_for_requests
- page.within('.files > div:nth-child(2) .note-body > .note-text') do
+ page.within('.diff-files-holder > div:nth-child(2) .note-body > .note-text') do
expect(page).to have_content('Line is correct')
end
@@ -63,7 +63,7 @@ describe 'User comments on a diff', :js do
wait_for_requests
# Hide the comment.
- page.within('.files > div:nth-child(3)') do
+ page.within('.diff-files-holder > div:nth-child(3)') do
find('.js-btn-vue-toggle-comments').click
expect(page).not_to have_content('Line is wrong')
@@ -71,21 +71,21 @@ describe 'User comments on a diff', :js do
# At this moment a user should see only one comment.
# The other one should be hidden.
- page.within('.files > div:nth-child(2) .note-body > .note-text') do
+ page.within('.diff-files-holder > div:nth-child(2) .note-body > .note-text') do
expect(page).to have_content('Line is correct')
end
# Show the comment.
- page.within('.files > div:nth-child(3)') do
+ page.within('.diff-files-holder > div:nth-child(3)') do
find('.js-btn-vue-toggle-comments').click
end
# Now both the comments should be shown.
- page.within('.files > div:nth-child(3) .note-body > .note-text') do
+ page.within('.diff-files-holder > div:nth-child(3) .note-body > .note-text') do
expect(page).to have_content('Line is wrong')
end
- page.within('.files > div:nth-child(2) .note-body > .note-text') do
+ page.within('.diff-files-holder > div:nth-child(2) .note-body > .note-text') do
expect(page).to have_content('Line is correct')
end
@@ -95,11 +95,11 @@ describe 'User comments on a diff', :js do
wait_for_requests
- page.within('.files > div:nth-child(3) .parallel .note-body > .note-text') do
+ page.within('.diff-files-holder > div:nth-child(3) .parallel .note-body > .note-text') do
expect(page).to have_content('Line is wrong')
end
- page.within('.files > div:nth-child(2) .parallel .note-body > .note-text') do
+ page.within('.diff-files-holder > div:nth-child(2) .parallel .note-body > .note-text') do
expect(page).to have_content('Line is correct')
end
end
diff --git a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb
index 428eb414274..d3da8cc6752 100644
--- a/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb
+++ b/spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb
@@ -81,6 +81,8 @@ describe 'Merge request > User sees avatars on diff notes', :js do
visit diffs_project_merge_request_path(project, merge_request, view: view)
wait_for_requests
+
+ find('.js-toggle-tree-list').click
end
it 'shows note avatar' do
diff --git a/spec/features/merge_request/user_sees_versions_spec.rb b/spec/features/merge_request/user_sees_versions_spec.rb
index f42b4dcbb47..92db4f44098 100644
--- a/spec/features/merge_request/user_sees_versions_spec.rb
+++ b/spec/features/merge_request/user_sees_versions_spec.rb
@@ -110,7 +110,8 @@ describe 'Merge request > User sees versions', :js do
diff_id: merge_request_diff3.id,
start_sha: '6f6d7e7ed97bb5f0054f2b1df789b39ca89b6ff9'
)
- expect(page).to have_content '4 changed files with 15 additions and 6 deletions'
+ expect(page).to have_content '4 changed files'
+ expect(page).to have_content '15 additions 6 deletions'
expect(page).to have_content 'Not all comments are displayed'
position = Gitlab::Diff::Position.new(
@@ -131,7 +132,8 @@ describe 'Merge request > User sees versions', :js do
end
it 'show diff between new and old version' do
- expect(page).to have_content '4 changed files with 15 additions and 6 deletions'
+ expect(page).to have_content '4 changed files'
+ expect(page).to have_content '15 additions 6 deletions'
end
it 'returns to latest version when "Show latest version" button is clicked' do
@@ -158,7 +160,7 @@ describe 'Merge request > User sees versions', :js do
it 'has 0 chages between versions' do
page.within '.mr-version-compare-dropdown' do
- expect(find('.dropdown-toggle')).to have_content 'version 1'
+ expect(find('.dropdown-menu-toggle')).to have_content 'version 1'
end
page.within '.mr-version-dropdown' do
@@ -179,7 +181,7 @@ describe 'Merge request > User sees versions', :js do
it 'sets the compared versions to be the same' do
page.within '.mr-version-compare-dropdown' do
- expect(find('.dropdown-toggle')).to have_content 'version 2'
+ expect(find('.dropdown-menu-toggle')).to have_content 'version 2'
end
page.within '.mr-version-dropdown' do
diff --git a/spec/features/merge_request/user_views_diffs_spec.rb b/spec/features/merge_request/user_views_diffs_spec.rb
index b1bfe9e5de3..7f95a1282f9 100644
--- a/spec/features/merge_request/user_views_diffs_spec.rb
+++ b/spec/features/merge_request/user_views_diffs_spec.rb
@@ -10,6 +10,8 @@ describe 'User views diffs', :js do
visit(diffs_project_merge_request_path(project, merge_request))
wait_for_requests
+
+ find('.js-toggle-tree-list').click
end
shared_examples 'unfold diffs' do
diff --git a/spec/features/profiles/user_manages_applications_spec.rb b/spec/features/profiles/user_manages_applications_spec.rb
index 387584fef62..34aaab240cc 100644
--- a/spec/features/profiles/user_manages_applications_spec.rb
+++ b/spec/features/profiles/user_manages_applications_spec.rb
@@ -16,7 +16,7 @@ describe 'User manages applications' do
click_on 'Save application'
expect(page).to have_content 'Application: test'
- expect(page).to have_content 'Application Id'
+ expect(page).to have_content 'Application ID'
expect(page).to have_content 'Secret'
click_on 'Edit'
@@ -26,7 +26,7 @@ describe 'User manages applications' do
click_on 'Save application'
expect(page).to have_content 'test_changed'
- expect(page).to have_content 'Application Id'
+ expect(page).to have_content 'Application ID'
expect(page).to have_content 'Secret'
visit applications_profile_path
diff --git a/spec/features/projects/environments/environment_spec.rb b/spec/features/projects/environments/environment_spec.rb
index 4c5dda29fee..70e0879dd81 100644
--- a/spec/features/projects/environments/environment_spec.rb
+++ b/spec/features/projects/environments/environment_spec.rb
@@ -60,7 +60,7 @@ describe 'Environment' do
context 'with manual action' do
let(:action) do
create(:ci_build, :manual, pipeline: pipeline,
- name: 'deploy to production')
+ name: 'deploy to production', environment: environment.name)
end
context 'when user has ability to trigger deployment' do
@@ -73,12 +73,16 @@ describe 'Environment' do
expect(page).to have_link(action.name.humanize)
end
- it 'does allow to play manual action' do
+ it 'does allow to play manual action', :js do
expect(action).to be_manual
+ find('button.dropdown').click
+
expect { click_link(action.name.humanize) }
.not_to change { Ci::Pipeline.count }
+ wait_for_all_requests
+
expect(page).to have_content(action.name)
expect(action.reload).to be_pending
end
@@ -165,10 +169,10 @@ describe 'Environment' do
name: action.ref, project: project)
end
- it 'allows to stop environment' do
+ it 'allows to stop environment', :js do
click_button('Stop')
click_button('Stop environment') # confirm modal
-
+ wait_for_all_requests
expect(page).to have_content('close_app')
end
end
diff --git a/spec/features/projects/import_export/export_file_spec.rb b/spec/features/projects/import_export/export_file_spec.rb
index a2b96514d64..f76f9ba7577 100644
--- a/spec/features/projects/import_export/export_file_spec.rb
+++ b/spec/features/projects/import_export/export_file_spec.rb
@@ -12,7 +12,7 @@ describe 'Import/Export - project export integration test', :js do
let(:export_path) { "#{Dir.tmpdir}/import_file_spec" }
let(:config_hash) { YAML.load_file(Gitlab::ImportExport.config_file).deep_stringify_keys }
- let(:sensitive_words) { %w[pass secret token key] }
+ let(:sensitive_words) { %w[pass secret token key encrypted] }
let(:safe_list) do
{
token: [ProjectHook, Ci::Trigger, CommitStatus],
diff --git a/spec/features/projects/jobs/user_browses_job_spec.rb b/spec/features/projects/jobs/user_browses_job_spec.rb
index 2d791947ee9..fc7b78ac21f 100644
--- a/spec/features/projects/jobs/user_browses_job_spec.rb
+++ b/spec/features/projects/jobs/user_browses_job_spec.rb
@@ -16,7 +16,9 @@ describe 'User browses a job', :js do
visit(project_job_path(project, build))
end
- it 'erases the job log' do
+ it 'erases the job log', :js do
+ wait_for_requests
+
expect(page).to have_content("Job ##{build.id}")
expect(page).to have_css('#build-trace')
@@ -29,18 +31,17 @@ describe 'User browses a job', :js do
expect(build.artifacts_file.exists?).to be_falsy
expect(build.artifacts_metadata.exists?).to be_falsy
- page.within('.erased') do
- expect(page).to have_content('Job has been erased')
- end
+ expect(page).to have_content('Job has been erased')
end
context 'with a failed job' do
let!(:build) { create(:ci_build, :failed, :trace_artifact, pipeline: pipeline) }
it 'displays the failure reason' do
+ wait_for_all_requests
within('.builds-container') do
build_link = first('.build-job > a')
- expect(build_link['data-title']).to eq('test - failed - (unknown failure)')
+ expect(build_link['data-original-title']).to eq('test - failed - (unknown failure)')
end
end
end
@@ -49,9 +50,10 @@ describe 'User browses a job', :js do
let!(:build) { create(:ci_build, :failed, :retried, :trace_artifact, pipeline: pipeline) }
it 'displays the failure reason and retried label' do
+ wait_for_all_requests
within('.builds-container') do
build_link = first('.build-job > a')
- expect(build_link['data-title']).to eq('test - failed - (unknown failure) (retried)')
+ expect(build_link['data-original-title']).to eq('test - failed - (unknown failure) (retried)')
end
end
end
diff --git a/spec/features/projects/jobs_spec.rb b/spec/features/projects/jobs_spec.rb
index 5b767c96910..45fc492f23f 100644
--- a/spec/features/projects/jobs_spec.rb
+++ b/spec/features/projects/jobs_spec.rb
@@ -134,23 +134,25 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
expect(page).to have_content pipeline.commit.title
end
- it 'shows active job' do
+ it 'shows active job', :js do
visit project_job_path(project, job)
+ wait_for_requests
expect(page).to have_selector('.build-job.active')
end
end
- context 'sidebar' do
+ context 'sidebar', :js do
let(:job) { create(:ci_build, :success, :trace_live, pipeline: pipeline, name: '<img src=x onerror=alert(document.domain)>') }
before do
visit project_job_path(project, job)
+ wait_for_requests
end
it 'renders escaped tooltip name' do
page.within('aside.right-sidebar') do
- expect(find('.active.build-job a')['data-title']).to eq('<img src="x"> - passed')
+ expect(find('.active.build-job a')['data-original-title']).to eq('&lt;img src=x onerror=alert(document.domain)&gt; - passed')
end
end
end
@@ -367,39 +369,167 @@ describe 'Jobs', :clean_gitlab_redis_shared_state do
end
end
- context 'when job starts environment' do
- let(:environment) { create(:environment, project: project) }
- let(:pipeline) { create(:ci_pipeline, project: project) }
+ context 'when job starts environment', :js do
+ let(:environment) { create(:environment, name: 'production', project: project) }
- context 'job is successfull and has deployment' do
- let(:deployment) { create(:deployment) }
- let(:job) { create(:ci_build, :success, :trace_artifact, environment: environment.name, deployments: [deployment], pipeline: pipeline) }
+ context 'job is successful and has deployment' do
+ let(:build) { create(:ci_build, :success, :trace_live, environment: environment.name, pipeline: pipeline) }
+ let!(:deployment) { create(:deployment, environment: environment, project: environment.project, deployable: build) }
- it 'shows a link for the job' do
- visit project_job_path(project, job)
+ before do
+ visit project_job_path(project, build)
+ wait_for_requests
+ # scroll to the top of the page first
+ execute_script "window.scrollTo(0,0)"
+ end
+ it 'shows a link for the job' do
expect(page).to have_link environment.name
end
+
+ it 'shows deployment message' do
+ expect(page).to have_content 'This job is the most recent deployment'
+ expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}")
+ end
end
context 'job is complete and not successful' do
- let(:job) { create(:ci_build, :failed, :trace_artifact, environment: environment.name, pipeline: pipeline) }
+ let(:build) { create(:ci_build, :failed, :trace_artifact, environment: environment.name, pipeline: pipeline) }
it 'shows a link for the job' do
- visit project_job_path(project, job)
+ visit project_job_path(project, build)
+ wait_for_requests
+ # scroll to the top of the page first
+ execute_script "window.scrollTo(0,0)"
expect(page).to have_link environment.name
+ expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}")
end
end
- context 'job creates a new deployment' do
- let!(:deployment) { create(:deployment, environment: environment, sha: project.commit.id) }
- let(:job) { create(:ci_build, :success, :trace_artifact, environment: environment.name, pipeline: pipeline) }
+ context 'deployment still not finished' do
+ let(:build) { create(:ci_build, :success, environment: environment.name, pipeline: pipeline) }
it 'shows a link to latest deployment' do
- visit project_job_path(project, job)
+ visit project_job_path(project, build)
+ wait_for_all_requests
+ # scroll to the top of the page first
+ execute_script "window.scrollTo(0,0)"
+
+ expect(page).to have_link environment.name
+ expect(page).to have_content 'This job is creating a deployment'
+ expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}")
+ end
+ end
+ end
+
+ describe 'environment info in job view', :js do
+ before do
+ visit project_job_path(project, job)
+ wait_for_requests
+ # scroll to the top of the page first
+ execute_script "window.scrollTo(0,0)"
+ end
+
+ context 'job with outdated deployment' do
+ let(:job) { create(:ci_build, :success, :trace_artifact, environment: 'staging', pipeline: pipeline) }
+ let(:second_build) { create(:ci_build, :success, :trace_artifact, environment: 'staging', pipeline: pipeline) }
+ let(:environment) { create(:environment, name: 'staging', project: project) }
+ let!(:first_deployment) { create(:deployment, environment: environment, deployable: job) }
+ let!(:second_deployment) { create(:deployment, environment: environment, deployable: second_build) }
+
+ it 'shows deployment message' do
+ expected_text = 'This job is an out-of-date deployment ' \
+ "to staging. View the most recent deployment ##{second_deployment.iid}."
+
+ expect(page).to have_css('.environment-information', text: expected_text)
+ end
+
+ it 'renders a link to the most recent deployment' do
+ expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}")
+ expect(find('.js-job-deployment-link')['href']).to include(second_deployment.deployable.project.path, second_deployment.deployable_id.to_s)
+ end
+ end
+
+ context 'job failed to deploy' do
+ let(:job) { create(:ci_build, :failed, :trace_artifact, environment: 'staging', pipeline: pipeline) }
+ let!(:environment) { create(:environment, name: 'staging', project: project) }
+
+ it 'shows deployment message' do
+ expected_text = 'The deployment of this job to staging did not succeed.'
+
+ expect(page).to have_css(
+ '.environment-information', text: expected_text)
+ end
+ end
+
+ context 'job will deploy' do
+ let(:job) { create(:ci_build, :running, :trace_live, environment: 'staging', pipeline: pipeline) }
+
+ context 'when environment exists' do
+ let!(:environment) { create(:environment, name: 'staging', project: project) }
+
+ it 'shows deployment message' do
+ expected_text = 'This job is creating a deployment to staging'
+
+ expect(page).to have_css(
+ '.environment-information', text: expected_text)
+ expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}")
+ end
+
+ context 'when it has deployment' do
+ let!(:deployment) { create(:deployment, environment: environment) }
+
+ it 'shows that deployment will be overwritten' do
+ expected_text = 'This job is creating a deployment to staging'
+
+ expect(page).to have_css(
+ '.environment-information', text: expected_text)
+ expect(page).to have_css(
+ '.environment-information', text: 'latest deployment')
+ expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}")
+ end
+ end
+ end
+
+ context 'when environment does not exist' do
+ let!(:environment) { create(:environment, name: 'staging', project: project) }
+
+ it 'shows deployment message' do
+ expected_text = 'This job is creating a deployment to staging'
+
+ expect(page).to have_css(
+ '.environment-information', text: expected_text)
+ expect(page).not_to have_css(
+ '.environment-information', text: 'latest deployment')
+ expect(find('.js-environment-link')['href']).to match("environments/#{environment.id}")
+ end
+ end
+ end
+
+ context 'job that failed to deploy and environment has not been created' do
+ let(:job) { create(:ci_build, :failed, :trace_artifact, environment: 'staging', pipeline: pipeline) }
+ let!(:environment) { create(:environment, name: 'staging', project: project) }
+
+ it 'shows deployment message' do
+ expected_text = 'The deployment of this job to staging did not succeed'
+
+ expect(page).to have_css(
+ '.environment-information', text: expected_text)
+ end
+ end
+
+ context 'job that will deploy and environment has not been created' do
+ let(:job) { create(:ci_build, :running, :trace_live, environment: 'staging', pipeline: pipeline) }
+ let!(:environment) { create(:environment, name: 'staging', project: project) }
+
+ it 'shows deployment message' do
+ expected_text = 'This job is creating a deployment to staging'
- expect(page).to have_link('latest deployment')
+ expect(page).to have_css(
+ '.environment-information', text: expected_text)
+ expect(page).not_to have_css(
+ '.environment-information', text: 'latest deployment')
end
end
end
diff --git a/spec/features/projects/wiki/user_views_wiki_page_spec.rb b/spec/features/projects/wiki/user_views_wiki_page_spec.rb
index 747406efc8b..9a4ce426e69 100644
--- a/spec/features/projects/wiki/user_views_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_views_wiki_page_spec.rb
@@ -83,12 +83,13 @@ describe 'User views a wiki page' do
end
it 'shows a file stored in a page' do
- gollum_file_double = double('Gollum::File',
- mime_type: 'image/jpeg',
- name: 'images/image.jpg',
- path: 'images/image.jpg',
- raw_data: '')
- wiki_file = Gitlab::Git::WikiFile.new(gollum_file_double)
+ raw_file = Gitlab::GitalyClient::WikiFile.new(
+ mime_type: 'image/jpeg',
+ name: 'images/image.jpg',
+ path: 'images/image.jpg',
+ raw_data: ''
+ )
+ wiki_file = Gitlab::Git::WikiFile.new(raw_file)
allow(wiki_file).to receive(:mime_type).and_return('image/jpeg')
allow_any_instance_of(ProjectWiki).to receive(:find_file).with('image.jpg', nil).and_return(wiki_file)
diff --git a/spec/finders/merge_requests_finder_spec.rb b/spec/finders/merge_requests_finder_spec.rb
index 35d0eeda8f6..33d01697c75 100644
--- a/spec/finders/merge_requests_finder_spec.rb
+++ b/spec/finders/merge_requests_finder_spec.rb
@@ -16,12 +16,18 @@ describe MergeRequestsFinder do
p
end
let(:project4) { create(:project, :public, group: subgroup) }
+ let(:project5) { create(:project, :public, group: subgroup) }
+ let(:project6) { create(:project, :public, group: subgroup) }
let!(:merge_request1) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project1) }
let!(:merge_request2) { create(:merge_request, :conflict, author: user, source_project: project2, target_project: project1, state: 'closed') }
- let!(:merge_request3) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project2, state: 'locked') }
- let!(:merge_request4) { create(:merge_request, :simple, author: user, source_project: project3, target_project: project3) }
- let!(:merge_request5) { create(:merge_request, :simple, author: user, source_project: project4, target_project: project4) }
+ let!(:merge_request3) { create(:merge_request, :simple, author: user, source_project: project2, target_project: project2, state: 'locked', title: 'thing WIP thing') }
+ let!(:merge_request4) { create(:merge_request, :simple, author: user, source_project: project3, target_project: project3, title: 'WIP thing') }
+ let!(:merge_request5) { create(:merge_request, :simple, author: user, source_project: project4, target_project: project4, title: '[WIP]') }
+ let!(:merge_request6) { create(:merge_request, :simple, author: user, source_project: project5, target_project: project5, title: 'WIP: thing') }
+ let!(:merge_request7) { create(:merge_request, :simple, author: user, source_project: project6, target_project: project6, title: 'wip thing') }
+ let!(:merge_request8) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project1, title: '[wip] thing') }
+ let!(:merge_request9) { create(:merge_request, :simple, author: user, source_project: project1, target_project: project2, title: 'wip: thing') }
before do
project1.add_maintainer(user)
@@ -29,19 +35,21 @@ describe MergeRequestsFinder do
project3.add_developer(user)
project2.add_developer(user2)
project4.add_developer(user)
+ project5.add_developer(user)
+ project6.add_developer(user)
end
describe "#execute" do
it 'filters by scope' do
params = { scope: 'authored', state: 'opened' }
merge_requests = described_class.new(user, params).execute
- expect(merge_requests.size).to eq(3)
+ expect(merge_requests.size).to eq(7)
end
it 'filters by project' do
params = { project_id: project1.id, scope: 'authored', state: 'opened' }
merge_requests = described_class.new(user, params).execute
- expect(merge_requests.size).to eq(1)
+ expect(merge_requests.size).to eq(2)
end
it 'filters by group' do
@@ -49,7 +57,7 @@ describe MergeRequestsFinder do
merge_requests = described_class.new(user, params).execute
- expect(merge_requests.size).to eq(2)
+ expect(merge_requests.size).to eq(3)
end
it 'filters by group including subgroups', :nested_groups do
@@ -57,13 +65,13 @@ describe MergeRequestsFinder do
merge_requests = described_class.new(user, params).execute
- expect(merge_requests.size).to eq(3)
+ expect(merge_requests.size).to eq(6)
end
it 'filters by non_archived' do
params = { non_archived: true }
merge_requests = described_class.new(user, params).execute
- expect(merge_requests.size).to eq(4)
+ expect(merge_requests.size).to eq(8)
end
it 'filters by iid' do
@@ -98,6 +106,36 @@ describe MergeRequestsFinder do
expect(merge_requests).to contain_exactly(merge_request3)
end
+ it 'filters by wip' do
+ params = { wip: 'yes' }
+
+ merge_requests = described_class.new(user, params).execute
+
+ expect(merge_requests).to contain_exactly(merge_request4, merge_request5, merge_request6, merge_request7, merge_request8, merge_request9)
+ end
+
+ it 'filters by not wip' do
+ params = { wip: 'no' }
+
+ merge_requests = described_class.new(user, params).execute
+
+ expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3)
+ end
+
+ it 'returns all items if no valid wip param exists' do
+ params = { wip: '' }
+
+ merge_requests = described_class.new(user, params).execute
+
+ expect(merge_requests).to contain_exactly(merge_request1, merge_request2, merge_request3, merge_request4, merge_request5, merge_request6, merge_request7, merge_request8, merge_request9)
+ end
+
+ it 'adds wip to scalar params' do
+ scalar_params = described_class.scalar_params
+
+ expect(scalar_params).to include(:wip, :assignee_id)
+ end
+
context 'filtering by group milestone' do
let!(:group) { create(:group, :public) }
let(:group_milestone) { create(:milestone, group: group) }
@@ -207,7 +245,7 @@ describe MergeRequestsFinder do
it 'returns the number of rows for the default state' do
finder = described_class.new(user)
- expect(finder.row_count).to eq(3)
+ expect(finder.row_count).to eq(7)
end
it 'returns the number of rows for a given state' do
diff --git a/spec/javascripts/boards/board_new_issue_spec.js b/spec/javascripts/boards/board_new_issue_spec.js
index ee37821ad08..1245e3e099a 100644
--- a/spec/javascripts/boards/board_new_issue_spec.js
+++ b/spec/javascripts/boards/board_new_issue_spec.js
@@ -69,7 +69,6 @@ describe('Issue boards new issue form', () => {
vm.$el.querySelector('.btn-success').click();
expect(vm.submit.calls.count()).toBe(1);
- expect(vm.$refs['submit-button']).toBe(vm.$el.querySelector('.btn-success'));
})
.then(done)
.catch(done.fail);
diff --git a/spec/javascripts/diffs/components/app_spec.js b/spec/javascripts/diffs/components/app_spec.js
index cf7d8df5405..a3a714678af 100644
--- a/spec/javascripts/diffs/components/app_spec.js
+++ b/spec/javascripts/diffs/components/app_spec.js
@@ -44,7 +44,8 @@ describe('diffs/components/app', () => {
it('shows comments message, with commit', done => {
vm.$store.state.diffs.commit = getDiffWithCommit().commit;
- vm.$nextTick()
+ vm
+ .$nextTick()
.then(() => {
expect(vm.$el).toContainText('Only comments from the following commit are shown below');
expect(vm.$el).toContainElement('.blob-commit-info');
@@ -55,10 +56,14 @@ describe('diffs/components/app', () => {
it('shows comments message, with old mergeRequestDiff', done => {
vm.$store.state.diffs.mergeRequestDiff = { latest: false };
+ vm.$store.state.diffs.targetBranch = 'master';
- vm.$nextTick()
+ vm
+ .$nextTick()
.then(() => {
- expect(vm.$el).toContainText("Not all comments are displayed because you're viewing an old version of the diff.");
+ expect(vm.$el).toContainText(
+ "Not all comments are displayed because you're viewing an old version of the diff.",
+ );
})
.then(done)
.catch(done.fail);
@@ -67,9 +72,12 @@ describe('diffs/components/app', () => {
it('shows comments message, with startVersion', done => {
vm.$store.state.diffs.startVersion = 'test';
- vm.$nextTick()
+ vm
+ .$nextTick()
.then(() => {
- expect(vm.$el).toContainText("Not all comments are displayed because you're comparing two versions of the diff.");
+ expect(vm.$el).toContainText(
+ "Not all comments are displayed because you're comparing two versions of the diff.",
+ );
})
.then(done)
.catch(done.fail);
diff --git a/spec/javascripts/diffs/components/changed_files_spec.js b/spec/javascripts/diffs/components/changed_files_spec.js
deleted file mode 100644
index 7f21273a991..00000000000
--- a/spec/javascripts/diffs/components/changed_files_spec.js
+++ /dev/null
@@ -1,105 +0,0 @@
-import Vue from 'vue';
-import Vuex from 'vuex';
-import { mountComponentWithStore } from 'spec/helpers';
-import diffsModule from '~/diffs/store/modules';
-import changedFiles from '~/diffs/components/changed_files.vue';
-
-describe('ChangedFiles', () => {
- const Component = Vue.extend(changedFiles);
- const store = new Vuex.Store({
- modules: {
- diffs: diffsModule(),
- },
- });
-
- let vm;
-
- beforeEach(() => {
- setFixtures(`
- <div id="dummy-element"></div>
- <div class="js-tabs-affix"></div>
- `);
-
- const props = {
- diffFiles: [
- {
- addedLines: 10,
- removedLines: 20,
- blob: {
- path: 'some/code.txt',
- },
- filePath: 'some/code.txt',
- },
- ],
- };
-
- vm = mountComponentWithStore(Component, { props, store });
- });
-
- describe('with single file added', () => {
- it('shows files changes', () => {
- expect(vm.$el).toContainText('1 changed file');
- });
-
- it('shows file additions and deletions', () => {
- expect(vm.$el).toContainText('10 additions');
- expect(vm.$el).toContainText('20 deletions');
- });
- });
-
- describe('diff view mode buttons', () => {
- let inlineButton;
- let parallelButton;
-
- beforeEach(() => {
- inlineButton = vm.$el.querySelector('.js-inline-diff-button');
- parallelButton = vm.$el.querySelector('.js-parallel-diff-button');
- });
-
- it('should have Inline and Side-by-side buttons', () => {
- expect(inlineButton).toBeDefined();
- expect(parallelButton).toBeDefined();
- });
-
- it('should add active class to Inline button', done => {
- vm.$store.state.diffs.diffViewType = 'inline';
-
- vm.$nextTick(() => {
- expect(inlineButton.classList.contains('active')).toEqual(true);
- expect(parallelButton.classList.contains('active')).toEqual(false);
-
- done();
- });
- });
-
- it('should toggle active state of buttons when diff view type changed', done => {
- vm.$store.state.diffs.diffViewType = 'parallel';
-
- vm.$nextTick(() => {
- expect(inlineButton.classList.contains('active')).toEqual(false);
- expect(parallelButton.classList.contains('active')).toEqual(true);
-
- done();
- });
- });
-
- describe('clicking them', () => {
- it('should toggle the diff view type', done => {
- parallelButton.click();
-
- vm.$nextTick(() => {
- expect(inlineButton.classList.contains('active')).toEqual(false);
- expect(parallelButton.classList.contains('active')).toEqual(true);
-
- inlineButton.click();
-
- vm.$nextTick(() => {
- expect(inlineButton.classList.contains('active')).toEqual(true);
- expect(parallelButton.classList.contains('active')).toEqual(false);
- done();
- });
- });
- });
- });
- });
-});
diff --git a/spec/javascripts/diffs/components/file_row_stats_spec.js b/spec/javascripts/diffs/components/file_row_stats_spec.js
new file mode 100644
index 00000000000..a8a7f3f1d82
--- /dev/null
+++ b/spec/javascripts/diffs/components/file_row_stats_spec.js
@@ -0,0 +1,33 @@
+import Vue from 'vue';
+import FileRowStats from '~/diffs/components/file_row_stats.vue';
+import mountComponent from 'spec/helpers/vue_mount_component_helper';
+
+describe('Diff file row stats', () => {
+ let Component;
+ let vm;
+
+ beforeAll(() => {
+ Component = Vue.extend(FileRowStats);
+ });
+
+ beforeEach(() => {
+ vm = mountComponent(Component, {
+ file: {
+ addedLines: 20,
+ removedLines: 10,
+ },
+ });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders added lines count', () => {
+ expect(vm.$el.querySelector('.cgreen').textContent).toContain('+20');
+ });
+
+ it('renders removed lines count', () => {
+ expect(vm.$el.querySelector('.cred').textContent).toContain('-10');
+ });
+});
diff --git a/spec/javascripts/diffs/components/tree_list_spec.js b/spec/javascripts/diffs/components/tree_list_spec.js
new file mode 100644
index 00000000000..08e25d2004e
--- /dev/null
+++ b/spec/javascripts/diffs/components/tree_list_spec.js
@@ -0,0 +1,120 @@
+import Vue from 'vue';
+import Vuex from 'vuex';
+import TreeList from '~/diffs/components/tree_list.vue';
+import createStore from '~/diffs/store/modules';
+import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+
+describe('Diffs tree list component', () => {
+ let Component;
+ let vm;
+
+ beforeAll(() => {
+ Component = Vue.extend(TreeList);
+ });
+
+ beforeEach(() => {
+ Vue.use(Vuex);
+
+ const store = new Vuex.Store({
+ modules: {
+ diffs: createStore(),
+ },
+ });
+
+ // Setup initial state
+ store.state.diffs.addedLines = 10;
+ store.state.diffs.removedLines = 20;
+ store.state.diffs.diffFiles.push('test');
+
+ vm = mountComponentWithStore(Component, { store });
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ it('renders diff stats', () => {
+ expect(vm.$el.textContent).toContain('1 changed file');
+ expect(vm.$el.textContent).toContain('10 additions');
+ expect(vm.$el.textContent).toContain('20 deletions');
+ });
+
+ it('renders empty text', () => {
+ expect(vm.$el.textContent).toContain('No files found');
+ });
+
+ describe('with files', () => {
+ beforeEach(done => {
+ Object.assign(vm.$store.state.diffs.treeEntries, {
+ 'index.js': {
+ addedLines: 0,
+ changed: true,
+ deleted: false,
+ fileHash: 'test',
+ key: 'index.js',
+ name: 'index.js',
+ path: 'index.js',
+ removedLines: 0,
+ tempFile: true,
+ type: 'blob',
+ },
+ app: {
+ key: 'app',
+ path: 'app',
+ name: 'app',
+ type: 'tree',
+ tree: [],
+ },
+ });
+ vm.$store.state.diffs.tree = [
+ vm.$store.state.diffs.treeEntries['index.js'],
+ vm.$store.state.diffs.treeEntries.app,
+ ];
+
+ vm.$nextTick(done);
+ });
+
+ it('renders tree', () => {
+ expect(vm.$el.querySelectorAll('.file-row').length).toBe(2);
+ expect(vm.$el.querySelectorAll('.file-row')[0].textContent).toContain('index.js');
+ expect(vm.$el.querySelectorAll('.file-row')[1].textContent).toContain('app');
+ });
+
+ it('filters tree list to blobs matching search', done => {
+ vm.search = 'index';
+
+ vm.$nextTick(() => {
+ expect(vm.$el.querySelectorAll('.file-row').length).toBe(1);
+ expect(vm.$el.querySelectorAll('.file-row')[0].textContent).toContain('index.js');
+
+ done();
+ });
+ });
+
+ it('calls toggleTreeOpen when clicking folder', () => {
+ spyOn(vm.$store, 'dispatch').and.stub();
+
+ vm.$el.querySelectorAll('.file-row')[1].click();
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith('diffs/toggleTreeOpen', 'app');
+ });
+
+ it('calls scrollToFile when clicking blob', () => {
+ spyOn(vm.$store, 'dispatch').and.stub();
+
+ vm.$el.querySelector('.file-row').click();
+
+ expect(vm.$store.dispatch).toHaveBeenCalledWith('diffs/scrollToFile', 'index.js');
+ });
+ });
+
+ describe('clearSearch', () => {
+ it('resets search', () => {
+ vm.search = 'test';
+
+ vm.$el.querySelector('.tree-list-clear-icon').click();
+
+ expect(vm.search).toBe('');
+ });
+ });
+});
diff --git a/spec/javascripts/diffs/mock_data/diff_file.js b/spec/javascripts/diffs/mock_data/diff_file.js
index 372b8f066cf..2aa2f8f3528 100644
--- a/spec/javascripts/diffs/mock_data/diff_file.js
+++ b/spec/javascripts/diffs/mock_data/diff_file.js
@@ -33,7 +33,7 @@ export default {
contentSha: 'c48ee0d1bf3b30453f5b32250ce03134beaa6d13',
storedExternally: null,
externalStorage: null,
- oldPathHtml: ['CHANGELOG', 'CHANGELOG'],
+ oldPathHtml: 'CHANGELOG',
newPathHtml: 'CHANGELOG',
editPath: '/gitlab-org/gitlab-test/edit/spooky-stuff/CHANGELOG',
viewPath: '/gitlab-org/gitlab-test/blob/spooky-stuff/CHANGELOG',
diff --git a/spec/javascripts/diffs/store/actions_spec.js b/spec/javascripts/diffs/store/actions_spec.js
index 05b39bad6ea..aacad7a479b 100644
--- a/spec/javascripts/diffs/store/actions_spec.js
+++ b/spec/javascripts/diffs/store/actions_spec.js
@@ -22,6 +22,9 @@ import actions, {
expandAllFiles,
toggleFileDiscussions,
saveDiffDiscussion,
+ toggleTreeOpen,
+ scrollToFile,
+ toggleShowTreeList,
} from '~/diffs/store/actions';
import * as types from '~/diffs/store/mutation_types';
import { reduceDiscussionsToLineCodes } from '~/notes/stores/utils';
@@ -608,4 +611,88 @@ describe('DiffsStoreActions', () => {
.catch(done.fail);
});
});
+
+ describe('toggleTreeOpen', () => {
+ it('commits TOGGLE_FOLDER_OPEN', done => {
+ testAction(
+ toggleTreeOpen,
+ 'path',
+ {},
+ [{ type: types.TOGGLE_FOLDER_OPEN, payload: 'path' }],
+ [],
+ done,
+ );
+ });
+ });
+
+ describe('scrollToFile', () => {
+ let commit;
+
+ beforeEach(() => {
+ commit = jasmine.createSpy();
+ jasmine.clock().install();
+ });
+
+ afterEach(() => {
+ jasmine.clock().uninstall();
+ });
+
+ it('updates location hash', () => {
+ const state = {
+ treeEntries: {
+ path: {
+ fileHash: 'test',
+ },
+ },
+ };
+
+ scrollToFile({ state, commit }, 'path');
+
+ expect(document.location.hash).toBe('#test');
+ });
+
+ it('commits UPDATE_CURRENT_DIFF_FILE_ID', () => {
+ const state = {
+ treeEntries: {
+ path: {
+ fileHash: 'test',
+ },
+ },
+ };
+
+ scrollToFile({ state, commit }, 'path');
+
+ expect(commit).toHaveBeenCalledWith(types.UPDATE_CURRENT_DIFF_FILE_ID, 'test');
+ });
+
+ it('resets currentDiffId after timeout', () => {
+ const state = {
+ treeEntries: {
+ path: {
+ fileHash: 'test',
+ },
+ },
+ };
+
+ scrollToFile({ state, commit }, 'path');
+
+ jasmine.clock().tick(1000);
+
+ expect(commit.calls.argsFor(1)).toEqual([types.UPDATE_CURRENT_DIFF_FILE_ID, '']);
+ });
+ });
+
+ describe('toggleShowTreeList', () => {
+ it('commits toggle', done => {
+ testAction(toggleShowTreeList, null, {}, [{ type: types.TOGGLE_SHOW_TREE_LIST }], [], done);
+ });
+
+ it('updates localStorage', () => {
+ spyOn(localStorage, 'setItem');
+
+ toggleShowTreeList({ commit() {}, state: { showTreeList: true } });
+
+ expect(localStorage.setItem).toHaveBeenCalledWith('mr_tree_show', true);
+ });
+ });
});
diff --git a/spec/javascripts/diffs/store/getters_spec.js b/spec/javascripts/diffs/store/getters_spec.js
index 4747e437c4e..cfeaaec6980 100644
--- a/spec/javascripts/diffs/store/getters_spec.js
+++ b/spec/javascripts/diffs/store/getters_spec.js
@@ -291,4 +291,31 @@ describe('Diffs Module Getters', () => {
expect(getters.getDiffFileByHash(localState)('123')).toBeUndefined();
});
});
+
+ describe('allBlobs', () => {
+ it('returns an array of blobs', () => {
+ localState.treeEntries = {
+ file: {
+ type: 'blob',
+ },
+ tree: {
+ type: 'tree',
+ },
+ };
+
+ expect(getters.allBlobs(localState)).toEqual([
+ {
+ type: 'blob',
+ },
+ ]);
+ });
+ });
+
+ describe('diffFilesLength', () => {
+ it('returns length of diff files', () => {
+ localState.diffFiles.push('test', 'test 2');
+
+ expect(getters.diffFilesLength(localState)).toBe(2);
+ });
+ });
});
diff --git a/spec/javascripts/diffs/store/mutations_spec.js b/spec/javascripts/diffs/store/mutations_spec.js
index 9a5d8dfbd15..cc8d5dc4bac 100644
--- a/spec/javascripts/diffs/store/mutations_spec.js
+++ b/spec/javascripts/diffs/store/mutations_spec.js
@@ -1,3 +1,4 @@
+import createState from '~/diffs/store/modules/diff_state';
import mutations from '~/diffs/store/mutations';
import * as types from '~/diffs/store/mutation_types';
import { INLINE_DIFF_VIEW_TYPE } from '~/diffs/constants';
@@ -356,4 +357,44 @@ describe('DiffsStoreMutations', () => {
expect(state.diffFiles[0].highlightedDiffLines[0].discussions.length).toEqual(0);
});
});
+
+ describe('TOGGLE_FOLDER_OPEN', () => {
+ it('toggles entry opened prop', () => {
+ const state = {
+ treeEntries: {
+ path: {
+ opened: false,
+ },
+ },
+ };
+
+ mutations[types.TOGGLE_FOLDER_OPEN](state, 'path');
+
+ expect(state.treeEntries.path.opened).toBe(true);
+ });
+ });
+
+ describe('TOGGLE_SHOW_TREE_LIST', () => {
+ it('toggles showTreeList', () => {
+ const state = createState();
+
+ mutations[types.TOGGLE_SHOW_TREE_LIST](state);
+
+ expect(state.showTreeList).toBe(false, 'Failed to toggle showTreeList to false');
+
+ mutations[types.TOGGLE_SHOW_TREE_LIST](state);
+
+ expect(state.showTreeList).toBe(true, 'Failed to toggle showTreeList to true');
+ });
+ });
+
+ describe('UPDATE_CURRENT_DIFF_FILE_ID', () => {
+ it('updates currentDiffFileId', () => {
+ const state = createState();
+
+ mutations[types.UPDATE_CURRENT_DIFF_FILE_ID](state, 'somefileid');
+
+ expect(state.currentDiffFileId).toBe('somefileid');
+ });
+ });
});
diff --git a/spec/javascripts/diffs/store/utils_spec.js b/spec/javascripts/diffs/store/utils_spec.js
index 897cd1483aa..e660f94c72e 100644
--- a/spec/javascripts/diffs/store/utils_spec.js
+++ b/spec/javascripts/diffs/store/utils_spec.js
@@ -421,4 +421,113 @@ describe('DiffsStoreUtils', () => {
).toBe(false);
});
});
+
+ describe('generateTreeList', () => {
+ let files;
+
+ beforeAll(() => {
+ files = [
+ {
+ newPath: 'app/index.js',
+ deletedFile: false,
+ newFile: false,
+ removedLines: 10,
+ addedLines: 0,
+ fileHash: 'test',
+ },
+ {
+ newPath: 'app/test/index.js',
+ deletedFile: false,
+ newFile: true,
+ removedLines: 0,
+ addedLines: 0,
+ fileHash: 'test',
+ },
+ {
+ newPath: 'package.json',
+ deletedFile: true,
+ newFile: false,
+ removedLines: 0,
+ addedLines: 0,
+ fileHash: 'test',
+ },
+ ];
+ });
+
+ it('creates a tree of files', () => {
+ const { tree } = utils.generateTreeList(files);
+
+ expect(tree).toEqual([
+ {
+ key: 'app',
+ path: 'app',
+ name: 'app',
+ type: 'tree',
+ tree: [
+ {
+ addedLines: 0,
+ changed: true,
+ deleted: false,
+ fileHash: 'test',
+ key: 'app/index.js',
+ name: 'index.js',
+ path: 'app/index.js',
+ removedLines: 10,
+ tempFile: false,
+ type: 'blob',
+ tree: [],
+ },
+ {
+ key: 'app/test',
+ path: 'app/test',
+ name: 'test',
+ type: 'tree',
+ opened: true,
+ tree: [
+ {
+ addedLines: 0,
+ changed: true,
+ deleted: false,
+ fileHash: 'test',
+ key: 'app/test/index.js',
+ name: 'index.js',
+ path: 'app/test/index.js',
+ removedLines: 0,
+ tempFile: true,
+ type: 'blob',
+ tree: [],
+ },
+ ],
+ },
+ ],
+ opened: true,
+ },
+ {
+ key: 'package.json',
+ path: 'package.json',
+ name: 'package.json',
+ type: 'blob',
+ changed: true,
+ tempFile: false,
+ deleted: true,
+ fileHash: 'test',
+ addedLines: 0,
+ removedLines: 0,
+ tree: [],
+ },
+ ]);
+ });
+
+ it('creates flat list of blobs & folders', () => {
+ const { treeEntries } = utils.generateTreeList(files);
+
+ expect(Object.keys(treeEntries)).toEqual([
+ 'app',
+ 'app/index.js',
+ 'app/test',
+ 'app/test/index.js',
+ 'package.json',
+ ]);
+ });
+ });
});
diff --git a/spec/javascripts/filtered_search/dropdown_utils_spec.js b/spec/javascripts/filtered_search/dropdown_utils_spec.js
index 8792e99d461..68bbbf838da 100644
--- a/spec/javascripts/filtered_search/dropdown_utils_spec.js
+++ b/spec/javascripts/filtered_search/dropdown_utils_spec.js
@@ -288,13 +288,13 @@ describe('Dropdown Utils', () => {
describe('setDataValueIfSelected', () => {
beforeEach(() => {
- spyOn(FilteredSearchDropdownManager, 'addWordToInput')
- .and.callFake(() => {});
+ spyOn(FilteredSearchDropdownManager, 'addWordToInput').and.callFake(() => {});
});
it('calls addWordToInput when dataValue exists', () => {
const selected = {
getAttribute: () => 'value',
+ hasAttribute: () => false,
};
DropdownUtils.setDataValueIfSelected(null, selected);
@@ -304,6 +304,7 @@ describe('Dropdown Utils', () => {
it('returns true when dataValue exists', () => {
const selected = {
getAttribute: () => 'value',
+ hasAttribute: () => false,
};
const result = DropdownUtils.setDataValueIfSelected(null, selected);
diff --git a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
index 756a654765b..53a6d1d62b0 100644
--- a/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
+++ b/spec/javascripts/filtered_search/filtered_search_visual_tokens_spec.js
@@ -240,13 +240,17 @@ describe('Filtered Search Visual Tokens', () => {
beforeEach(() => {
setFixtures(`
<div class="test-area">
- ${subject.createVisualTokenElementHTML()}
+ ${subject.createVisualTokenElementHTML('custom-token')}
</div>
`);
tokenElement = document.querySelector('.test-area').firstElementChild;
});
+ it('should add class name to token element', () => {
+ expect(document.querySelector('.test-area .custom-token')).toBeDefined();
+ });
+
it('contains name div', () => {
expect(tokenElement.querySelector('.name')).toEqual(jasmine.anything());
});
@@ -280,7 +284,7 @@ describe('Filtered Search Visual Tokens', () => {
describe('addVisualTokenElement', () => {
it('renders search visual tokens', () => {
- subject.addVisualTokenElement('search term', null, true);
+ subject.addVisualTokenElement('search term', null, { isSearchTerm: true });
const token = tokensContainer.querySelector('.js-visual-token');
expect(token.classList.contains('filtered-search-term')).toEqual(true);
diff --git a/spec/javascripts/ide/components/file_row_extra_spec.js b/spec/javascripts/ide/components/file_row_extra_spec.js
index 60dabe28045..c93a939ad71 100644
--- a/spec/javascripts/ide/components/file_row_extra_spec.js
+++ b/spec/javascripts/ide/components/file_row_extra_spec.js
@@ -107,14 +107,14 @@ describe('IDE extra file row component', () => {
describe('changes file icon', () => {
it('hides when file is not changed', () => {
- expect(vm.$el.querySelector('.ide-file-changed-icon')).toBe(null);
+ expect(vm.$el.querySelector('.file-changed-icon')).toBe(null);
});
it('shows when file is changed', done => {
vm.file.changed = true;
vm.$nextTick(() => {
- expect(vm.$el.querySelector('.ide-file-changed-icon')).not.toBe(null);
+ expect(vm.$el.querySelector('.file-changed-icon')).not.toBe(null);
done();
});
@@ -124,7 +124,7 @@ describe('IDE extra file row component', () => {
vm.file.staged = true;
vm.$nextTick(() => {
- expect(vm.$el.querySelector('.ide-file-changed-icon')).not.toBe(null);
+ expect(vm.$el.querySelector('.file-changed-icon')).not.toBe(null);
done();
});
@@ -134,7 +134,7 @@ describe('IDE extra file row component', () => {
vm.file.tempFile = true;
vm.$nextTick(() => {
- expect(vm.$el.querySelector('.ide-file-changed-icon')).not.toBe(null);
+ expect(vm.$el.querySelector('.file-changed-icon')).not.toBe(null);
done();
});
diff --git a/spec/javascripts/ide/components/repo_tab_spec.js b/spec/javascripts/ide/components/repo_tab_spec.js
index 278a0753322..3b52f279bf2 100644
--- a/spec/javascripts/ide/components/repo_tab_spec.js
+++ b/spec/javascripts/ide/components/repo_tab_spec.js
@@ -93,13 +93,13 @@ describe('RepoTab', () => {
Vue.nextTick()
.then(() => {
- expect(vm.$el.querySelector('.ide-file-modified')).toBeNull();
+ expect(vm.$el.querySelector('.file-modified')).toBeNull();
vm.$el.dispatchEvent(new Event('mouseout'));
})
.then(Vue.nextTick)
.then(() => {
- expect(vm.$el.querySelector('.ide-file-modified')).not.toBeNull();
+ expect(vm.$el.querySelector('.file-modified')).not.toBeNull();
done();
})
diff --git a/spec/javascripts/job_spec.js b/spec/javascripts/job_spec.js
index 2fcb5566ebc..d6b5dec9e47 100644
--- a/spec/javascripts/job_spec.js
+++ b/spec/javascripts/job_spec.js
@@ -57,25 +57,6 @@ describe('Job', () => {
expect(job.buildStage).toBe('test');
expect(job.state).toBe('');
});
-
- it('only shows the jobs matching the current stage', () => {
- expect($('.build-job[data-stage="build"]').is(':visible')).toBe(false);
- expect($('.build-job[data-stage="test"]').is(':visible')).toBe(true);
- expect($('.build-job[data-stage="deploy"]').is(':visible')).toBe(false);
- });
-
- it('selects the current stage in the build dropdown menu', () => {
- expect($('.stage-selection').text()).toBe('test');
- });
-
- it('updates the jobs when the build dropdown changes', () => {
- $('.stage-item:contains("build")').click();
-
- expect($('.stage-selection').text()).toBe('build');
- expect($('.build-job[data-stage="build"]').is(':visible')).toBe(true);
- expect($('.build-job[data-stage="test"]').is(':visible')).toBe(false);
- expect($('.build-job[data-stage="deploy"]').is(':visible')).toBe(false);
- });
});
describe('running build', () => {
diff --git a/spec/javascripts/jobs/components/environments_block_spec.js b/spec/javascripts/jobs/components/environments_block_spec.js
index 015c26be9fc..7d836129b13 100644
--- a/spec/javascripts/jobs/components/environments_block_spec.js
+++ b/spec/javascripts/jobs/components/environments_block_spec.js
@@ -5,19 +5,16 @@ import mountComponent from '../../helpers/vue_mount_component_helper';
describe('Environments block', () => {
const Component = Vue.extend(component);
let vm;
- const icon = {
+ const status = {
group: 'success',
icon: 'status_success',
label: 'passed',
text: 'passed',
tooltip: 'passed',
};
- const deployment = {
- path: 'deployment',
- name: 'deployment name',
- };
+
const environment = {
- path: '/environment',
+ environment_path: '/environment',
name: 'environment',
};
@@ -25,15 +22,14 @@ describe('Environments block', () => {
vm.$destroy();
});
- describe('with latest deployment', () => {
+ describe('with last deployment', () => {
it('renders info for most recent deployment', () => {
vm = mountComponent(Component, {
deploymentStatus: {
- status: 'latest',
- icon,
- deployment,
+ status: 'last',
environment,
},
+ iconStatus: status,
});
expect(vm.$el.textContent.trim()).toEqual(
@@ -48,17 +44,17 @@ describe('Environments block', () => {
vm = mountComponent(Component, {
deploymentStatus: {
status: 'out_of_date',
- icon,
- deployment,
environment: Object.assign({}, environment, {
- last_deployment: { name: 'deployment', path: 'last_deployment' },
+ last_deployment: { iid: 'deployment', deployable: { build_path: 'bar' } },
}),
},
+ iconStatus: status,
});
expect(vm.$el.textContent.trim()).toEqual(
- 'This job is an out-of-date deployment to environment. View the most recent deployment deployment.',
+ 'This job is an out-of-date deployment to environment. View the most recent deployment #deployment.',
);
+ expect(vm.$el.querySelector('.js-job-deployment-link').getAttribute('href')).toEqual('bar');
});
});
@@ -67,10 +63,9 @@ describe('Environments block', () => {
vm = mountComponent(Component, {
deploymentStatus: {
status: 'out_of_date',
- icon,
- deployment: null,
environment,
},
+ iconStatus: status,
});
expect(vm.$el.textContent.trim()).toEqual(
@@ -85,10 +80,9 @@ describe('Environments block', () => {
vm = mountComponent(Component, {
deploymentStatus: {
status: 'failed',
- icon,
- deployment: null,
environment,
},
+ iconStatus: status,
});
expect(vm.$el.textContent.trim()).toEqual(
@@ -99,21 +93,24 @@ describe('Environments block', () => {
describe('creating deployment', () => {
describe('with last deployment', () => {
- it('renders info about creating deployment and overriding lastest deployment', () => {
+ it('renders info about creating deployment and overriding latest deployment', () => {
vm = mountComponent(Component, {
deploymentStatus: {
status: 'creating',
- icon,
- deployment,
environment: Object.assign({}, environment, {
- last_deployment: { name: 'deployment', path: 'last_deployment' },
+ last_deployment: {
+ iid: 'deployment',
+ deployable: { build_path: 'foo' },
+ },
}),
},
+ iconStatus: status,
});
expect(vm.$el.textContent.trim()).toEqual(
- 'This job is creating a deployment to environment and will overwrite the last deployment.',
+ 'This job is creating a deployment to environment and will overwrite the latest deployment.',
);
+ expect(vm.$el.querySelector('.js-job-deployment-link').getAttribute('href')).toEqual('foo');
});
});
@@ -122,10 +119,9 @@ describe('Environments block', () => {
vm = mountComponent(Component, {
deploymentStatus: {
status: 'creating',
- icon,
- deployment: null,
environment,
},
+ iconStatus: status,
});
expect(vm.$el.textContent.trim()).toEqual(
@@ -133,5 +129,18 @@ describe('Environments block', () => {
);
});
});
+
+ describe('without environment', () => {
+ it('does not render environment link', () => {
+ vm = mountComponent(Component, {
+ deploymentStatus: {
+ status: 'creating',
+ environment: null,
+ },
+ iconStatus: status,
+ });
+ expect(vm.$el.querySelector('.js-environment-link')).toBeNull();
+ });
+ });
});
});
diff --git a/spec/javascripts/jobs/components/header_spec.js b/spec/javascripts/jobs/components/header_spec.js
deleted file mode 100644
index e21e2c6d6e3..00000000000
--- a/spec/javascripts/jobs/components/header_spec.js
+++ /dev/null
@@ -1,98 +0,0 @@
-import Vue from 'vue';
-import headerComponent from '~/jobs/components/header.vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-
-describe('Job details header', () => {
- let HeaderComponent;
- let vm;
- let props;
-
- beforeEach(() => {
- HeaderComponent = Vue.extend(headerComponent);
-
- const threeWeeksAgo = new Date();
- threeWeeksAgo.setDate(threeWeeksAgo.getDate() - 21);
-
- const twoDaysAgo = new Date();
- twoDaysAgo.setDate(twoDaysAgo.getDate() - 2);
-
- props = {
- job: {
- status: {
- group: 'failed',
- icon: 'status_failed',
- label: 'failed',
- text: 'failed',
- details_path: 'path',
- },
- id: 123,
- created_at: threeWeeksAgo.toISOString(),
- user: {
- web_url: 'path',
- name: 'Foo',
- username: 'foobar',
- email: 'foo@bar.com',
- avatar_url: 'link',
- },
- started: twoDaysAgo.toISOString(),
- new_issue_path: 'path',
- },
- isLoading: false,
- };
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('job reason', () => {
- it('should not render the reason when reason is absent', () => {
- vm = mountComponent(HeaderComponent, props);
-
- expect(vm.shouldRenderReason).toBe(false);
- });
-
- it('should render the reason when reason is present', () => {
- props.job.callout_message = 'There is an unknown failure, please try again';
-
- vm = mountComponent(HeaderComponent, props);
-
- expect(vm.shouldRenderReason).toBe(true);
- });
- });
-
- describe('triggered job', () => {
- beforeEach(() => {
- vm = mountComponent(HeaderComponent, props);
- });
-
- it('should render provided job information', () => {
- expect(
- vm.$el
- .querySelector('.header-main-content')
- .textContent.replace(/\s+/g, ' ')
- .trim(),
- ).toEqual('failed Job #123 triggered 2 days ago by Foo');
- });
-
- it('should render new issue link', () => {
- expect(vm.$el.querySelector('.js-new-issue').getAttribute('href')).toEqual(
- props.job.new_issue_path,
- );
- });
- });
-
- describe('created job', () => {
- it('should render created key', () => {
- props.job.started = false;
- vm = mountComponent(HeaderComponent, props);
-
- expect(
- vm.$el
- .querySelector('.header-main-content')
- .textContent.replace(/\s+/g, ' ')
- .trim(),
- ).toEqual('failed Job #123 created 3 weeks ago by Foo');
- });
- });
-});
diff --git a/spec/javascripts/jobs/components/job_app_spec.js b/spec/javascripts/jobs/components/job_app_spec.js
new file mode 100644
index 00000000000..c31fa6f9887
--- /dev/null
+++ b/spec/javascripts/jobs/components/job_app_spec.js
@@ -0,0 +1,185 @@
+import Vue from 'vue';
+import jobApp from '~/jobs/components/job_app.vue';
+import createStore from '~/jobs/store';
+import { mountComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
+
+describe('Job App ', () => {
+ const Component = Vue.extend(jobApp);
+ let store;
+ let vm;
+
+ const threeWeeksAgo = new Date();
+ threeWeeksAgo.setDate(threeWeeksAgo.getDate() - 21);
+
+ const twoDaysAgo = new Date();
+ twoDaysAgo.setDate(twoDaysAgo.getDate() - 2);
+
+ const job = {
+ status: {
+ group: 'failed',
+ icon: 'status_failed',
+ label: 'failed',
+ text: 'failed',
+ details_path: 'path',
+ },
+ id: 123,
+ created_at: threeWeeksAgo.toISOString(),
+ user: {
+ web_url: 'path',
+ name: 'Foo',
+ username: 'foobar',
+ email: 'foo@bar.com',
+ avatar_url: 'link',
+ },
+ started: twoDaysAgo.toISOString(),
+ new_issue_path: 'path',
+ runners: {
+ available: false,
+ },
+ tags: ['docker'],
+ };
+
+ const props = {
+ runnerHelpUrl: 'help/runners',
+ };
+
+ beforeEach(() => {
+ store = createStore();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('Header section', () => {
+ describe('job callout message', () => {
+ it('should not render the reason when reason is absent', () => {
+ store.dispatch('receiveJobSuccess', job);
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
+
+ expect(vm.shouldRenderCalloutMessage).toBe(false);
+ });
+
+ it('should render the reason when reason is present', () => {
+ store.dispatch(
+ 'receiveJobSuccess',
+ Object.assign({}, job, {
+ callout_message: 'There is an unknown failure, please try again',
+ }),
+ );
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
+
+ expect(vm.shouldRenderCalloutMessage).toBe(true);
+ });
+ });
+
+ describe('triggered job', () => {
+ beforeEach(() => {
+ store.dispatch('receiveJobSuccess', job);
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
+ });
+
+ it('should render provided job information', () => {
+ expect(
+ vm.$el
+ .querySelector('.header-main-content')
+ .textContent.replace(/\s+/g, ' ')
+ .trim(),
+ ).toEqual('failed Job #123 triggered 2 days ago by Foo');
+ });
+
+ it('should render new issue link', () => {
+ expect(vm.$el.querySelector('.js-new-issue').getAttribute('href')).toEqual(
+ job.new_issue_path,
+ );
+ });
+ });
+
+ describe('created job', () => {
+ it('should render created key', () => {
+ store.dispatch('receiveJobSuccess', Object.assign({}, job, { started: false }));
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
+
+ expect(
+ vm.$el
+ .querySelector('.header-main-content')
+ .textContent.replace(/\s+/g, ' ')
+ .trim(),
+ ).toEqual('failed Job #123 created 3 weeks ago by Foo');
+ });
+ });
+ });
+
+ describe('stuck block', () => {
+ it('renders stuck block when there are no runners', () => {
+ store.dispatch(
+ 'receiveJobSuccess',
+ Object.assign({}, job, {
+ status: {
+ group: 'pending',
+ icon: 'status_pending',
+ label: 'pending',
+ text: 'pending',
+ details_path: 'path',
+ },
+ }),
+ );
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
+
+ expect(vm.$el.querySelector('.js-job-stuck')).not.toBeNull();
+ });
+
+ it('renders tags in stuck block when there are no runners', () => {
+ store.dispatch(
+ 'receiveJobSuccess',
+ Object.assign({}, job, {
+ status: {
+ group: 'pending',
+ icon: 'status_pending',
+ label: 'pending',
+ text: 'pending',
+ details_path: 'path',
+ },
+ }),
+ );
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
+
+ expect(vm.$el.querySelector('.js-job-stuck').textContent).toContain(job.tags[0]);
+ });
+
+ it(' does not renders stuck block when there are no runners', () => {
+ store.dispatch('receiveJobSuccess', Object.assign({}, job, { runners: { available: true } }));
+
+ vm = mountComponentWithStore(Component, {
+ props,
+ store,
+ });
+
+ expect(vm.$el.querySelector('.js-job-stuck')).toBeNull();
+ });
+ });
+});
diff --git a/spec/javascripts/jobs/components/jobs_container_spec.js b/spec/javascripts/jobs/components/jobs_container_spec.js
index f3f8ff0d031..fa3a2c4c266 100644
--- a/spec/javascripts/jobs/components/jobs_container_spec.js
+++ b/spec/javascripts/jobs/components/jobs_container_spec.js
@@ -2,7 +2,7 @@ import Vue from 'vue';
import component from '~/jobs/components/jobs_container.vue';
import mountComponent from '../../helpers/vue_mount_component_helper';
-describe('Artifacts block', () => {
+describe('Jobs List block', () => {
const Component = Vue.extend(component);
let vm;
@@ -16,8 +16,7 @@ describe('Artifacts block', () => {
text: 'passed',
tooltip: 'passed',
},
- path: 'job/233432756',
- id: '233432756',
+ id: 233432756,
tooltip: 'build - passed',
retried: true,
};
@@ -33,8 +32,7 @@ describe('Artifacts block', () => {
text: 'passed',
tooltip: 'passed',
},
- path: 'job/2322756',
- id: '2322756',
+ id: 2322756,
tooltip: 'build - passed',
active: true,
};
@@ -50,8 +48,7 @@ describe('Artifacts block', () => {
text: 'passed',
tooltip: 'passed',
},
- path: 'job/232153',
- id: '232153',
+ id: 232153,
tooltip: 'build - passed',
};
@@ -62,14 +59,16 @@ describe('Artifacts block', () => {
it('renders list of jobs', () => {
vm = mountComponent(Component, {
jobs: [job, retried, active],
+ jobId: 12313,
});
expect(vm.$el.querySelectorAll('a').length).toEqual(3);
});
- it('renders arrow right when job is active', () => {
+ it('renders arrow right when job id matches `jobId`', () => {
vm = mountComponent(Component, {
jobs: [active],
+ jobId: active.id,
});
expect(vm.$el.querySelector('a .js-arrow-right')).not.toBeNull();
@@ -78,6 +77,7 @@ describe('Artifacts block', () => {
it('does not render arrow right when job is not active', () => {
vm = mountComponent(Component, {
jobs: [job],
+ jobId: active.id,
});
expect(vm.$el.querySelector('a .js-arrow-right')).toBeNull();
@@ -86,6 +86,7 @@ describe('Artifacts block', () => {
it('renders job name when present', () => {
vm = mountComponent(Component, {
jobs: [job],
+ jobId: active.id,
});
expect(vm.$el.querySelector('a').textContent.trim()).toContain(job.name);
@@ -95,6 +96,7 @@ describe('Artifacts block', () => {
it('renders job id when job name is not available', () => {
vm = mountComponent(Component, {
jobs: [retried],
+ jobId: active.id,
});
expect(vm.$el.querySelector('a').textContent.trim()).toContain(retried.id);
@@ -103,14 +105,16 @@ describe('Artifacts block', () => {
it('links to the job page', () => {
vm = mountComponent(Component, {
jobs: [job],
+ jobId: active.id,
});
- expect(vm.$el.querySelector('a').getAttribute('href')).toEqual(job.path);
+ expect(vm.$el.querySelector('a').getAttribute('href')).toEqual(job.status.details_path);
});
it('renders retry icon when job was retried', () => {
vm = mountComponent(Component, {
jobs: [retried],
+ jobId: active.id,
});
expect(vm.$el.querySelector('.js-retry-icon')).not.toBeNull();
@@ -119,6 +123,7 @@ describe('Artifacts block', () => {
it('does not render retry icon when job was not retried', () => {
vm = mountComponent(Component, {
jobs: [job],
+ jobId: active.id,
});
expect(vm.$el.querySelector('.js-retry-icon')).toBeNull();
diff --git a/spec/javascripts/jobs/components/sidebar_details_block_spec.js b/spec/javascripts/jobs/components/sidebar_details_block_spec.js
deleted file mode 100644
index ba19534dac2..00000000000
--- a/spec/javascripts/jobs/components/sidebar_details_block_spec.js
+++ /dev/null
@@ -1,139 +0,0 @@
-import Vue from 'vue';
-import sidebarDetailsBlock from '~/jobs/components/sidebar_details_block.vue';
-import job from '../mock_data';
-import mountComponent from '../../helpers/vue_mount_component_helper';
-
-describe('Sidebar details block', () => {
- let SidebarComponent;
- let vm;
-
- function trimWhitespace(element) {
- return element.textContent.replace(/\s+/g, ' ').trim();
- }
-
- beforeEach(() => {
- SidebarComponent = Vue.extend(sidebarDetailsBlock);
- });
-
- afterEach(() => {
- vm.$destroy();
- });
-
- describe('when it is loading', () => {
- it('should render a loading spinner', () => {
- vm = mountComponent(SidebarComponent, {
- job: {},
- isLoading: true,
- });
- expect(vm.$el.querySelector('.fa-spinner')).toBeDefined();
- });
- });
-
- describe('when there is no retry path retry', () => {
- it('should not render a retry button', () => {
- vm = mountComponent(SidebarComponent, {
- job: {},
- isLoading: false,
- });
-
- expect(vm.$el.querySelector('.js-retry-job')).toBeNull();
- });
- });
-
- describe('without terminal path', () => {
- it('does not render terminal link', () => {
- vm = mountComponent(SidebarComponent, {
- job,
- isLoading: false,
- });
-
- expect(vm.$el.querySelector('.js-terminal-link')).toBeNull();
- });
- });
-
- describe('with terminal path', () => {
- it('renders terminal link', () => {
- vm = mountComponent(SidebarComponent, {
- job,
- isLoading: false,
- terminalPath: 'job/43123/terminal',
- });
-
- expect(vm.$el.querySelector('.js-terminal-link')).not.toBeNull();
- });
- });
-
- beforeEach(() => {
- vm = mountComponent(SidebarComponent, {
- job,
- isLoading: false,
- });
- });
-
- describe('actions', () => {
- it('should render link to new issue', () => {
- expect(vm.$el.querySelector('.js-new-issue').getAttribute('href')).toEqual(
- job.new_issue_path,
- );
- expect(vm.$el.querySelector('.js-new-issue').textContent.trim()).toEqual('New issue');
- });
-
- it('should render link to retry job', () => {
- expect(vm.$el.querySelector('.js-retry-job').getAttribute('href')).toEqual(job.retry_path);
- });
-
- it('should render link to cancel job', () => {
- expect(vm.$el.querySelector('.js-cancel-job').getAttribute('href')).toEqual(job.cancel_path);
- });
- });
-
- describe('information', () => {
- it('should render merge request link', () => {
- expect(trimWhitespace(vm.$el.querySelector('.js-job-mr'))).toEqual('Merge Request: !2');
-
- expect(vm.$el.querySelector('.js-job-mr a').getAttribute('href')).toEqual(
- job.merge_request.path,
- );
- });
-
- it('should render job duration', () => {
- expect(trimWhitespace(vm.$el.querySelector('.js-job-duration'))).toEqual(
- 'Duration: 6 seconds',
- );
- });
-
- it('should render erased date', () => {
- expect(trimWhitespace(vm.$el.querySelector('.js-job-erased'))).toEqual('Erased: 3 weeks ago');
- });
-
- it('should render finished date', () => {
- expect(trimWhitespace(vm.$el.querySelector('.js-job-finished'))).toEqual(
- 'Finished: 3 weeks ago',
- );
- });
-
- it('should render queued date', () => {
- expect(trimWhitespace(vm.$el.querySelector('.js-job-queued'))).toEqual('Queued: 9 seconds');
- });
-
- it('should render runner ID', () => {
- expect(trimWhitespace(vm.$el.querySelector('.js-job-runner'))).toEqual(
- 'Runner: local ci runner (#1)',
- );
- });
-
- it('should render timeout information', () => {
- expect(trimWhitespace(vm.$el.querySelector('.js-job-timeout'))).toEqual(
- 'Timeout: 1m 40s (from runner)',
- );
- });
-
- it('should render coverage', () => {
- expect(trimWhitespace(vm.$el.querySelector('.js-job-coverage'))).toEqual('Coverage: 20%');
- });
-
- it('should render tags', () => {
- expect(trimWhitespace(vm.$el.querySelector('.js-job-tags'))).toEqual('Tags: tag');
- });
- });
-});
diff --git a/spec/javascripts/jobs/components/sidebar_spec.js b/spec/javascripts/jobs/components/sidebar_spec.js
new file mode 100644
index 00000000000..2f5c4245ced
--- /dev/null
+++ b/spec/javascripts/jobs/components/sidebar_spec.js
@@ -0,0 +1,196 @@
+import Vue from 'vue';
+import sidebarDetailsBlock from '~/jobs/components/sidebar.vue';
+import createStore from '~/jobs/store';
+import job, { stages, jobsInStage } from '../mock_data';
+import { mountComponentWithStore } from '../../helpers/vue_mount_component_helper';
+import { trimText } from '../../helpers/vue_component_helper';
+
+describe('Sidebar details block', () => {
+ const SidebarComponent = Vue.extend(sidebarDetailsBlock);
+ let vm;
+ let store;
+
+ beforeEach(() => {
+ store = createStore();
+ });
+
+ afterEach(() => {
+ vm.$destroy();
+ });
+
+ describe('when it is loading', () => {
+ it('should render a loading spinner', () => {
+ store.dispatch('requestJob');
+ vm = mountComponentWithStore(SidebarComponent, { store });
+
+ expect(vm.$el.querySelector('.fa-spinner')).toBeDefined();
+ });
+ });
+
+ describe('when there is no retry path retry', () => {
+ it('should not render a retry button', () => {
+ const copy = Object.assign({}, job);
+ delete copy.retry_path;
+
+ store.dispatch('receiveJobSuccess', copy);
+ vm = mountComponentWithStore(SidebarComponent, {
+ store,
+ });
+
+ expect(vm.$el.querySelector('.js-retry-job')).toBeNull();
+ });
+ });
+
+ describe('without terminal path', () => {
+ it('does not render terminal link', () => {
+ store.dispatch('receiveJobSuccess', job);
+ vm = mountComponentWithStore(SidebarComponent, { store });
+
+ expect(vm.$el.querySelector('.js-terminal-link')).toBeNull();
+ });
+ });
+
+ describe('with terminal path', () => {
+ it('renders terminal link', () => {
+ store.dispatch('receiveJobSuccess', job);
+ vm = mountComponentWithStore(SidebarComponent, {
+ store,
+ props: {
+ terminalPath: 'job/43123/terminal',
+ },
+ });
+
+ expect(vm.$el.querySelector('.js-terminal-link')).not.toBeNull();
+ });
+ });
+
+ beforeEach(() => {
+ store.dispatch('receiveJobSuccess', job);
+ vm = mountComponentWithStore(SidebarComponent, { store });
+ });
+
+ describe('actions', () => {
+ it('should render link to new issue', () => {
+ expect(vm.$el.querySelector('.js-new-issue').getAttribute('href')).toEqual(
+ job.new_issue_path,
+ );
+ expect(vm.$el.querySelector('.js-new-issue').textContent.trim()).toEqual('New issue');
+ });
+
+ it('should render link to retry job', () => {
+ expect(vm.$el.querySelector('.js-retry-job').getAttribute('href')).toEqual(job.retry_path);
+ });
+
+ it('should render link to cancel job', () => {
+ expect(vm.$el.querySelector('.js-cancel-job').getAttribute('href')).toEqual(job.cancel_path);
+ });
+ });
+
+ describe('information', () => {
+ it('should render merge request link', () => {
+ expect(trimText(vm.$el.querySelector('.js-job-mr').textContent)).toEqual('Merge Request: !2');
+
+ expect(vm.$el.querySelector('.js-job-mr a').getAttribute('href')).toEqual(
+ job.merge_request.path,
+ );
+ });
+
+ it('should render job duration', () => {
+ expect(trimText(vm.$el.querySelector('.js-job-duration').textContent)).toEqual(
+ 'Duration: 6 seconds',
+ );
+ });
+
+ it('should render erased date', () => {
+ expect(trimText(vm.$el.querySelector('.js-job-erased').textContent)).toEqual(
+ 'Erased: 3 weeks ago',
+ );
+ });
+
+ it('should render finished date', () => {
+ expect(trimText(vm.$el.querySelector('.js-job-finished').textContent)).toEqual(
+ 'Finished: 3 weeks ago',
+ );
+ });
+
+ it('should render queued date', () => {
+ expect(trimText(vm.$el.querySelector('.js-job-queued').textContent)).toEqual(
+ 'Queued: 9 seconds',
+ );
+ });
+
+ it('should render runner ID', () => {
+ expect(trimText(vm.$el.querySelector('.js-job-runner').textContent)).toEqual(
+ 'Runner: local ci runner (#1)',
+ );
+ });
+
+ it('should render timeout information', () => {
+ expect(trimText(vm.$el.querySelector('.js-job-timeout').textContent)).toEqual(
+ 'Timeout: 1m 40s (from runner)',
+ );
+ });
+
+ it('should render coverage', () => {
+ expect(trimText(vm.$el.querySelector('.js-job-coverage').textContent)).toEqual(
+ 'Coverage: 20%',
+ );
+ });
+
+ it('should render tags', () => {
+ expect(trimText(vm.$el.querySelector('.js-job-tags').textContent)).toEqual('Tags: tag');
+ });
+ });
+
+ describe('stages dropdown', () => {
+ beforeEach(() => {
+ store.dispatch('receiveJobSuccess', job);
+ });
+
+ describe('while fetching stages', () => {
+ it('renders dropdown with More label', () => {
+ vm = mountComponentWithStore(SidebarComponent, { store });
+
+ expect(vm.$el.querySelector('.js-selected-stage').textContent.trim()).toEqual('More');
+ });
+ });
+
+ describe('with stages', () => {
+ beforeEach(() => {
+ store.dispatch('receiveStagesSuccess', stages);
+ vm = mountComponentWithStore(SidebarComponent, { store });
+ });
+
+ it('renders first stage as selected', () => {
+ expect(vm.$el.querySelector('.js-selected-stage').textContent.trim()).toEqual(
+ stages[0].name,
+ );
+ });
+ });
+
+ describe('without jobs for stages', () => {
+ beforeEach(() => {
+ store.dispatch('receiveJobSuccess', job);
+ store.dispatch('receiveStagesSuccess', stages);
+ vm = mountComponentWithStore(SidebarComponent, { store });
+ });
+
+ it('does not render job container', () => {
+ expect(vm.$el.querySelector('.js-jobs-container')).toBeNull();
+ });
+ });
+
+ describe('with jobs for stages', () => {
+ beforeEach(() => {
+ store.dispatch('receiveJobSuccess', job);
+ store.dispatch('receiveStagesSuccess', stages);
+ store.dispatch('receiveJobsForStageSuccess', jobsInStage.latest_statuses);
+ vm = mountComponentWithStore(SidebarComponent, { store });
+ });
+
+ it('renders list of jobs', () => {
+ expect(vm.$el.querySelector('.js-jobs-container')).not.toBeNull();
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/jobs/components/stages_dropdown_spec.js b/spec/javascripts/jobs/components/stages_dropdown_spec.js
index 402289345aa..aa6cc0f1b1a 100644
--- a/spec/javascripts/jobs/components/stages_dropdown_spec.js
+++ b/spec/javascripts/jobs/components/stages_dropdown_spec.js
@@ -8,10 +8,25 @@ describe('Artifacts block', () => {
beforeEach(() => {
vm = mountComponent(Component, {
- pipelineId: 28029444,
- pipelinePath: 'pipeline/28029444',
- pipelineRef: '50101-truncated-job-information',
- pipelineRefPath: 'commits/50101-truncated-job-information',
+ pipeline: {
+ id: 28029444,
+ details: {
+ status: {
+ details_path: '/gitlab-org/gitlab-ce/pipelines/28029444',
+ group: 'success',
+ has_details: true,
+ icon: 'status_success',
+ label: 'passed',
+ text: 'passed',
+ tooltip: 'passed',
+ },
+ },
+ path: 'pipeline/28029444',
+ },
+ ref: {
+ path: 'commits/50101-truncated-job-information',
+ name: '50101-truncated-job-information',
+ },
stages: [
{
name: 'build',
@@ -20,15 +35,6 @@ describe('Artifacts block', () => {
name: 'test',
},
],
- pipelineStatus: {
- details_path: '/gitlab-org/gitlab-ce/pipelines/28029444',
- group: 'success',
- has_details: true,
- icon: 'status_success',
- label: 'passed',
- text: 'passed',
- tooltip: 'passed',
- },
});
});
diff --git a/spec/javascripts/jobs/mock_data.js b/spec/javascripts/jobs/mock_data.js
index 8fdd9b309b7..4269b42e8b6 100644
--- a/spec/javascripts/jobs/mock_data.js
+++ b/spec/javascripts/jobs/mock_data.js
@@ -20,7 +20,8 @@ export default {
group: 'success',
has_details: true,
details_path: '/root/ci-mock/-/jobs/4757',
- favicon: '/assets/ci_favicons/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.png',
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.png',
action: {
icon: 'retry',
title: 'Retry',
@@ -37,7 +38,8 @@ export default {
username: 'root',
id: 1,
state: 'active',
- avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon',
+ avatar_url:
+ 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon',
web_url: 'http://localhost:3000/root',
},
erase_path: '/root/ci-mock/-/jobs/4757/erase',
@@ -54,7 +56,8 @@ export default {
username: 'root',
id: 1,
state: 'active',
- avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon',
+ avatar_url:
+ 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon',
web_url: 'http://localhost:3000/root',
},
active: false,
@@ -78,7 +81,8 @@ export default {
group: 'success',
has_details: true,
details_path: '/root/ci-mock/pipelines/140',
- favicon: '/assets/ci_favicons/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.png',
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-308b4fc054cdd1b68d0865e6cfb7b02e92e3472f201507418f8eddb74ac11a59.png',
},
duration: 6,
finished_at: '2017-06-01T17:32:00.042Z',
@@ -107,11 +111,14 @@ export default {
username: 'root',
id: 1,
state: 'active',
- avatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon',
+ avatar_url:
+ 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon',
web_url: 'http://localhost:3000/root',
},
- author_gravatar_url: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon',
- commit_url: 'http://localhost:3000/root/ci-mock/commit/c58647773a6b5faf066d4ad6ff2c9fbba5f180f6',
+ author_gravatar_url:
+ 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon',
+ commit_url:
+ 'http://localhost:3000/root/ci-mock/commit/c58647773a6b5faf066d4ad6ff2c9fbba5f180f6',
commit_path: '/root/ci-mock/commit/c58647773a6b5faf066d4ad6ff2c9fbba5f180f6',
},
},
@@ -125,3 +132,1029 @@ export default {
},
raw_path: '/root/ci-mock/builds/4757/raw',
};
+
+export const stages = [
+ {
+ name: 'build',
+ title: 'build: running',
+ groups: [
+ {
+ name: 'build:linux',
+ size: 1,
+ status: {
+ icon: 'status_pending',
+ text: 'pending',
+ label: 'pending',
+ group: 'pending',
+ tooltip: 'pending',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/1180',
+ illustration: {
+ image: 'illustrations/pending_job_empty.svg',
+ size: 'svg-430',
+ title: 'This job has not started yet',
+ content: 'This job is in pending state and is waiting to be picked by a runner',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_pending-5bdf338420e5221ca24353b6bff1c9367189588750632e9a871b7af09ff6a2ae.png',
+ action: {
+ icon: 'cancel',
+ title: 'Cancel',
+ path: '/gitlab-org/gitlab-shell/-/jobs/1180/cancel',
+ method: 'post',
+ },
+ },
+ jobs: [
+ {
+ id: 1180,
+ name: 'build:linux',
+ started: false,
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/1180',
+ cancel_path: '/gitlab-org/gitlab-shell/-/jobs/1180/cancel',
+ playable: false,
+ created_at: '2018-09-28T11:09:57.229Z',
+ updated_at: '2018-09-28T11:09:57.503Z',
+ status: {
+ icon: 'status_pending',
+ text: 'pending',
+ label: 'pending',
+ group: 'pending',
+ tooltip: 'pending',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/1180',
+ illustration: {
+ image: 'illustrations/pending_job_empty.svg',
+ size: 'svg-430',
+ title: 'This job has not started yet',
+ content: 'This job is in pending state and is waiting to be picked by a runner',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_pending-5bdf338420e5221ca24353b6bff1c9367189588750632e9a871b7af09ff6a2ae.png',
+ action: {
+ icon: 'cancel',
+ title: 'Cancel',
+ path: '/gitlab-org/gitlab-shell/-/jobs/1180/cancel',
+ method: 'post',
+ },
+ },
+ },
+ ],
+ },
+ {
+ name: 'build:osx',
+ size: 1,
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/444',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/444/retry',
+ method: 'post',
+ },
+ },
+ jobs: [
+ {
+ id: 444,
+ name: 'build:osx',
+ started: '2018-05-18T05:32:20.655Z',
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/444',
+ retry_path: '/gitlab-org/gitlab-shell/-/jobs/444/retry',
+ playable: false,
+ created_at: '2018-05-18T15:32:54.364Z',
+ updated_at: '2018-05-18T15:32:54.364Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/444',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/444/retry',
+ method: 'post',
+ },
+ },
+ },
+ ],
+ },
+ ],
+ status: {
+ icon: 'status_running',
+ text: 'running',
+ label: 'running',
+ group: 'running',
+ tooltip: 'running',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/pipelines/27#build',
+ illustration: null,
+ favicon:
+ '/assets/ci_favicons/favicon_status_running-9c635b2419a8e1ec991c993061b89cc5aefc0743bb238ecd0c381e7741a70e8c.png',
+ },
+ path: '/gitlab-org/gitlab-shell/pipelines/27#build',
+ dropdown_path: '/gitlab-org/gitlab-shell/pipelines/27/stage.json?stage=build',
+ },
+ {
+ name: 'test',
+ title: 'test: passed with warnings',
+ groups: [
+ {
+ name: 'jenkins',
+ size: 1,
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: null,
+ group: 'success',
+ tooltip: null,
+ has_details: false,
+ details_path: null,
+ illustration: null,
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ },
+ jobs: [
+ {
+ id: 459,
+ name: 'jenkins',
+ started: '2018-05-18T09:32:20.658Z',
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/459',
+ playable: false,
+ created_at: '2018-05-18T15:32:55.330Z',
+ updated_at: '2018-05-18T15:32:55.330Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: null,
+ group: 'success',
+ tooltip: null,
+ has_details: false,
+ details_path: null,
+ illustration: null,
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ },
+ },
+ ],
+ },
+ {
+ name: 'rspec:linux',
+ size: 3,
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: false,
+ details_path: null,
+ illustration: null,
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ },
+ jobs: [
+ {
+ id: 445,
+ name: 'rspec:linux 0 3',
+ started: '2018-05-18T07:32:20.655Z',
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/445',
+ retry_path: '/gitlab-org/gitlab-shell/-/jobs/445/retry',
+ playable: false,
+ created_at: '2018-05-18T15:32:54.425Z',
+ updated_at: '2018-05-18T15:32:54.425Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/445',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/445/retry',
+ method: 'post',
+ },
+ },
+ },
+ {
+ id: 446,
+ name: 'rspec:linux 1 3',
+ started: '2018-05-18T07:32:20.655Z',
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/446',
+ retry_path: '/gitlab-org/gitlab-shell/-/jobs/446/retry',
+ playable: false,
+ created_at: '2018-05-18T15:32:54.506Z',
+ updated_at: '2018-05-18T15:32:54.506Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/446',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/446/retry',
+ method: 'post',
+ },
+ },
+ },
+ {
+ id: 447,
+ name: 'rspec:linux 2 3',
+ started: '2018-05-18T07:32:20.656Z',
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/447',
+ retry_path: '/gitlab-org/gitlab-shell/-/jobs/447/retry',
+ playable: false,
+ created_at: '2018-05-18T15:32:54.572Z',
+ updated_at: '2018-05-18T15:32:54.572Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/447',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/447/retry',
+ method: 'post',
+ },
+ },
+ },
+ ],
+ },
+ {
+ name: 'rspec:osx',
+ size: 1,
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/452',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/452/retry',
+ method: 'post',
+ },
+ },
+ jobs: [
+ {
+ id: 452,
+ name: 'rspec:osx',
+ started: '2018-05-18T07:32:20.657Z',
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/452',
+ retry_path: '/gitlab-org/gitlab-shell/-/jobs/452/retry',
+ playable: false,
+ created_at: '2018-05-18T15:32:54.920Z',
+ updated_at: '2018-05-18T15:32:54.920Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/452',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/452/retry',
+ method: 'post',
+ },
+ },
+ },
+ ],
+ },
+ {
+ name: 'rspec:windows',
+ size: 3,
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: false,
+ details_path: null,
+ illustration: null,
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ },
+ jobs: [
+ {
+ id: 448,
+ name: 'rspec:windows 0 3',
+ started: '2018-05-18T07:32:20.656Z',
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/448',
+ retry_path: '/gitlab-org/gitlab-shell/-/jobs/448/retry',
+ playable: false,
+ created_at: '2018-05-18T15:32:54.639Z',
+ updated_at: '2018-05-18T15:32:54.639Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/448',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/448/retry',
+ method: 'post',
+ },
+ },
+ },
+ {
+ id: 449,
+ name: 'rspec:windows 1 3',
+ started: '2018-05-18T07:32:20.656Z',
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/449',
+ retry_path: '/gitlab-org/gitlab-shell/-/jobs/449/retry',
+ playable: false,
+ created_at: '2018-05-18T15:32:54.703Z',
+ updated_at: '2018-05-18T15:32:54.703Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/449',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/449/retry',
+ method: 'post',
+ },
+ },
+ },
+ {
+ id: 451,
+ name: 'rspec:windows 2 3',
+ started: '2018-05-18T07:32:20.657Z',
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/451',
+ retry_path: '/gitlab-org/gitlab-shell/-/jobs/451/retry',
+ playable: false,
+ created_at: '2018-05-18T15:32:54.853Z',
+ updated_at: '2018-05-18T15:32:54.853Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/451',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/451/retry',
+ method: 'post',
+ },
+ },
+ },
+ ],
+ },
+ {
+ name: 'spinach:linux',
+ size: 1,
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/453',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/453/retry',
+ method: 'post',
+ },
+ },
+ jobs: [
+ {
+ id: 453,
+ name: 'spinach:linux',
+ started: '2018-05-18T07:32:20.657Z',
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/453',
+ retry_path: '/gitlab-org/gitlab-shell/-/jobs/453/retry',
+ playable: false,
+ created_at: '2018-05-18T15:32:54.993Z',
+ updated_at: '2018-05-18T15:32:54.993Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/453',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/453/retry',
+ method: 'post',
+ },
+ },
+ },
+ ],
+ },
+ {
+ name: 'spinach:osx',
+ size: 1,
+ status: {
+ icon: 'status_warning',
+ text: 'failed',
+ label: 'failed (allowed to fail)',
+ group: 'failed_with_warnings',
+ tooltip: 'failed - (unknown failure) (allowed to fail)',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/454',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/454/retry',
+ method: 'post',
+ },
+ },
+ jobs: [
+ {
+ id: 454,
+ name: 'spinach:osx',
+ started: '2018-05-18T07:32:20.657Z',
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/454',
+ retry_path: '/gitlab-org/gitlab-shell/-/jobs/454/retry',
+ playable: false,
+ created_at: '2018-05-18T15:32:55.053Z',
+ updated_at: '2018-05-18T15:32:55.053Z',
+ status: {
+ icon: 'status_warning',
+ text: 'failed',
+ label: 'failed (allowed to fail)',
+ group: 'failed_with_warnings',
+ tooltip: 'failed - (unknown failure) (allowed to fail)',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/454',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_failed-41304d7f7e3828808b0c26771f0309e55296819a9beea3ea9fbf6689d9857c12.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/454/retry',
+ method: 'post',
+ },
+ },
+ callout_message: 'There is an unknown failure, please try again',
+ recoverable: true,
+ },
+ ],
+ },
+ ],
+ status: {
+ icon: 'status_warning',
+ text: 'passed',
+ label: 'passed with warnings',
+ group: 'success_with_warnings',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/pipelines/27#test',
+ illustration: null,
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ },
+ path: '/gitlab-org/gitlab-shell/pipelines/27#test',
+ dropdown_path: '/gitlab-org/gitlab-shell/pipelines/27/stage.json?stage=test',
+ },
+ {
+ name: 'deploy',
+ title: 'deploy: running',
+ groups: [
+ {
+ name: 'production',
+ size: 1,
+ status: {
+ icon: 'status_created',
+ text: 'created',
+ label: 'created',
+ group: 'created',
+ tooltip: 'created',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/457',
+ illustration: {
+ image: 'illustrations/job_not_triggered.svg',
+ size: 'svg-306',
+ title: 'This job has not been triggered yet',
+ content:
+ 'This job depends on upstream jobs that need to succeed in order for this job to be triggered',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_created-4b975aa976d24e5a3ea7cd9a5713e6ce2cd9afd08b910415e96675de35f64955.png',
+ action: {
+ icon: 'cancel',
+ title: 'Cancel',
+ path: '/gitlab-org/gitlab-shell/-/jobs/457/cancel',
+ method: 'post',
+ },
+ },
+ jobs: [
+ {
+ id: 457,
+ name: 'production',
+ started: false,
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/457',
+ cancel_path: '/gitlab-org/gitlab-shell/-/jobs/457/cancel',
+ playable: false,
+ created_at: '2018-05-18T15:32:55.259Z',
+ updated_at: '2018-09-28T11:09:57.454Z',
+ status: {
+ icon: 'status_created',
+ text: 'created',
+ label: 'created',
+ group: 'created',
+ tooltip: 'created',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/457',
+ illustration: {
+ image: 'illustrations/job_not_triggered.svg',
+ size: 'svg-306',
+ title: 'This job has not been triggered yet',
+ content:
+ 'This job depends on upstream jobs that need to succeed in order for this job to be triggered',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_created-4b975aa976d24e5a3ea7cd9a5713e6ce2cd9afd08b910415e96675de35f64955.png',
+ action: {
+ icon: 'cancel',
+ title: 'Cancel',
+ path: '/gitlab-org/gitlab-shell/-/jobs/457/cancel',
+ method: 'post',
+ },
+ },
+ },
+ ],
+ },
+ {
+ name: 'staging',
+ size: 1,
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/455',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/455/retry',
+ method: 'post',
+ },
+ },
+ jobs: [
+ {
+ id: 455,
+ name: 'staging',
+ started: '2018-05-18T09:32:20.658Z',
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/455',
+ retry_path: '/gitlab-org/gitlab-shell/-/jobs/455/retry',
+ playable: false,
+ created_at: '2018-05-18T15:32:55.119Z',
+ updated_at: '2018-05-18T15:32:55.119Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/455',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/455/retry',
+ method: 'post',
+ },
+ },
+ },
+ ],
+ },
+ {
+ name: 'stop staging',
+ size: 1,
+ status: {
+ icon: 'status_created',
+ text: 'created',
+ label: 'created',
+ group: 'created',
+ tooltip: 'created',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/456',
+ illustration: {
+ image: 'illustrations/job_not_triggered.svg',
+ size: 'svg-306',
+ title: 'This job has not been triggered yet',
+ content:
+ 'This job depends on upstream jobs that need to succeed in order for this job to be triggered',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_created-4b975aa976d24e5a3ea7cd9a5713e6ce2cd9afd08b910415e96675de35f64955.png',
+ action: {
+ icon: 'cancel',
+ title: 'Cancel',
+ path: '/gitlab-org/gitlab-shell/-/jobs/456/cancel',
+ method: 'post',
+ },
+ },
+ jobs: [
+ {
+ id: 456,
+ name: 'stop staging',
+ started: false,
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/456',
+ cancel_path: '/gitlab-org/gitlab-shell/-/jobs/456/cancel',
+ playable: false,
+ created_at: '2018-05-18T15:32:55.205Z',
+ updated_at: '2018-09-28T11:09:57.396Z',
+ status: {
+ icon: 'status_created',
+ text: 'created',
+ label: 'created',
+ group: 'created',
+ tooltip: 'created',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/456',
+ illustration: {
+ image: 'illustrations/job_not_triggered.svg',
+ size: 'svg-306',
+ title: 'This job has not been triggered yet',
+ content:
+ 'This job depends on upstream jobs that need to succeed in order for this job to be triggered',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_created-4b975aa976d24e5a3ea7cd9a5713e6ce2cd9afd08b910415e96675de35f64955.png',
+ action: {
+ icon: 'cancel',
+ title: 'Cancel',
+ path: '/gitlab-org/gitlab-shell/-/jobs/456/cancel',
+ method: 'post',
+ },
+ },
+ },
+ ],
+ },
+ ],
+ status: {
+ icon: 'status_running',
+ text: 'running',
+ label: 'running',
+ group: 'running',
+ tooltip: 'running',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/pipelines/27#deploy',
+ illustration: null,
+ favicon:
+ '/assets/ci_favicons/favicon_status_running-9c635b2419a8e1ec991c993061b89cc5aefc0743bb238ecd0c381e7741a70e8c.png',
+ },
+ path: '/gitlab-org/gitlab-shell/pipelines/27#deploy',
+ dropdown_path: '/gitlab-org/gitlab-shell/pipelines/27/stage.json?stage=deploy',
+ },
+ {
+ name: 'notify',
+ title: 'notify: manual action',
+ groups: [
+ {
+ name: 'slack',
+ size: 1,
+ status: {
+ icon: 'status_manual',
+ text: 'manual',
+ label: 'manual play action',
+ group: 'manual',
+ tooltip: 'manual action',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/458',
+ illustration: {
+ image: 'illustrations/manual_action.svg',
+ size: 'svg-394',
+ title: 'This job requires a manual action',
+ content:
+ 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
+ action: {
+ icon: 'play',
+ title: 'Play',
+ path: '/gitlab-org/gitlab-shell/-/jobs/458/play',
+ method: 'post',
+ },
+ },
+ jobs: [
+ {
+ id: 458,
+ name: 'slack',
+ started: null,
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/458',
+ play_path: '/gitlab-org/gitlab-shell/-/jobs/458/play',
+ playable: true,
+ created_at: '2018-05-18T15:32:55.303Z',
+ updated_at: '2018-05-18T15:34:08.535Z',
+ status: {
+ icon: 'status_manual',
+ text: 'manual',
+ label: 'manual play action',
+ group: 'manual',
+ tooltip: 'manual action',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/458',
+ illustration: {
+ image: 'illustrations/manual_action.svg',
+ size: 'svg-394',
+ title: 'This job requires a manual action',
+ content:
+ 'This job depends on a user to trigger its process. Often they are used to deploy code to production environments',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
+ action: {
+ icon: 'play',
+ title: 'Play',
+ path: '/gitlab-org/gitlab-shell/-/jobs/458/play',
+ method: 'post',
+ },
+ },
+ },
+ ],
+ },
+ ],
+ status: {
+ icon: 'status_manual',
+ text: 'manual',
+ label: 'manual action',
+ group: 'manual',
+ tooltip: 'manual action',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/pipelines/27#notify',
+ illustration: null,
+ favicon:
+ '/assets/ci_favicons/favicon_status_manual-829a0804612cef47d9efc1618dba38325483657c847dba0546c3b9f0295bb36c.png',
+ },
+ path: '/gitlab-org/gitlab-shell/pipelines/27#notify',
+ dropdown_path: '/gitlab-org/gitlab-shell/pipelines/27/stage.json?stage=notify',
+ },
+];
+
+export const jobsInStage = {
+ name: 'build',
+ title: 'build: running',
+ latest_statuses: [
+ {
+ id: 1180,
+ name: 'build:linux',
+ started: false,
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/1180',
+ cancel_path: '/gitlab-org/gitlab-shell/-/jobs/1180/cancel',
+ playable: false,
+ created_at: '2018-09-28T11:09:57.229Z',
+ updated_at: '2018-09-28T11:09:57.503Z',
+ status: {
+ icon: 'status_pending',
+ text: 'pending',
+ label: 'pending',
+ group: 'pending',
+ tooltip: 'pending',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/1180',
+ illustration: {
+ image: 'illustrations/pending_job_empty.svg',
+ size: 'svg-430',
+ title: 'This job has not started yet',
+ content: 'This job is in pending state and is waiting to be picked by a runner',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_pending-5bdf338420e5221ca24353b6bff1c9367189588750632e9a871b7af09ff6a2ae.png',
+ action: {
+ icon: 'cancel',
+ title: 'Cancel',
+ path: '/gitlab-org/gitlab-shell/-/jobs/1180/cancel',
+ method: 'post',
+ },
+ },
+ },
+ {
+ id: 444,
+ name: 'build:osx',
+ started: '2018-05-18T05:32:20.655Z',
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/444',
+ retry_path: '/gitlab-org/gitlab-shell/-/jobs/444/retry',
+ playable: false,
+ created_at: '2018-05-18T15:32:54.364Z',
+ updated_at: '2018-05-18T15:32:54.364Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/444',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/444/retry',
+ method: 'post',
+ },
+ },
+ },
+ ],
+ retried: [
+ {
+ id: 443,
+ name: 'build:linux',
+ started: '2018-05-18T06:32:20.655Z',
+ build_path: '/gitlab-org/gitlab-shell/-/jobs/443',
+ retry_path: '/gitlab-org/gitlab-shell/-/jobs/443/retry',
+ playable: false,
+ created_at: '2018-05-18T15:32:54.296Z',
+ updated_at: '2018-05-18T15:32:54.296Z',
+ status: {
+ icon: 'status_success',
+ text: 'passed',
+ label: 'passed',
+ group: 'success',
+ tooltip: 'passed (retried)',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/-/jobs/443',
+ illustration: {
+ image: 'illustrations/skipped-job_empty.svg',
+ size: 'svg-430',
+ title: 'This job does not have a trace.',
+ },
+ favicon:
+ '/assets/ci_favicons/favicon_status_success-8451333011eee8ce9f2ab25dc487fe24a8758c694827a582f17f42b0a90446a2.png',
+ action: {
+ icon: 'retry',
+ title: 'Retry',
+ path: '/gitlab-org/gitlab-shell/-/jobs/443/retry',
+ method: 'post',
+ },
+ },
+ },
+ ],
+ status: {
+ icon: 'status_running',
+ text: 'running',
+ label: 'running',
+ group: 'running',
+ tooltip: 'running',
+ has_details: true,
+ details_path: '/gitlab-org/gitlab-shell/pipelines/27#build',
+ illustration: null,
+ favicon:
+ '/assets/ci_favicons/favicon_status_running-9c635b2419a8e1ec991c993061b89cc5aefc0743bb238ecd0c381e7741a70e8c.png',
+ },
+ path: '/gitlab-org/gitlab-shell/pipelines/27#build',
+ dropdown_path: '/gitlab-org/gitlab-shell/pipelines/27/stage.json?stage=build',
+};
diff --git a/spec/javascripts/jobs/store/actions_spec.js b/spec/javascripts/jobs/store/actions_spec.js
index 5042718dfa0..5ab1f75d0d6 100644
--- a/spec/javascripts/jobs/store/actions_spec.js
+++ b/spec/javascripts/jobs/store/actions_spec.js
@@ -27,7 +27,6 @@ import {
receiveStagesSuccess,
receiveStagesError,
requestJobsForStage,
- setSelectedStage,
fetchJobsForStage,
receiveJobsForStageSuccess,
receiveJobsForStageError,
@@ -236,7 +235,8 @@ describe('Job State actions', () => {
},
{
payload: {
- html: 'I, [2018-08-17T22:57:45.707325 #1841] INFO -- :', complete: true,
+ html: 'I, [2018-08-17T22:57:45.707325 #1841] INFO -- :',
+ complete: true,
},
type: 'receiveTraceSuccess',
},
@@ -421,7 +421,9 @@ describe('Job State actions', () => {
let mock;
beforeEach(() => {
- mockedState.stagesEndpoint = `${TEST_HOST}/endpoint.json`;
+ mockedState.job.pipeline = {
+ path: `${TEST_HOST}/endpoint.json/stages`,
+ };
mock = new MockAdapter(axios);
});
@@ -430,8 +432,10 @@ describe('Job State actions', () => {
});
describe('success', () => {
- it('dispatches requestStages and receiveStagesSuccess ', done => {
- mock.onGet(`${TEST_HOST}/endpoint.json`).replyOnce(200, [{ id: 121212, name: 'build' }]);
+ it('dispatches requestStages and receiveStagesSuccess, fetchJobsForStage ', done => {
+ mock
+ .onGet(`${TEST_HOST}/endpoint.json/stages`)
+ .replyOnce(200, { details: { stages: [{ id: 121212, name: 'build' }] } });
testAction(
fetchStages,
@@ -446,6 +450,10 @@ describe('Job State actions', () => {
payload: [{ id: 121212, name: 'build' }],
type: 'receiveStagesSuccess',
},
+ {
+ payload: { id: 121212, name: 'build' },
+ type: 'fetchJobsForStage',
+ },
],
done,
);
@@ -516,24 +524,10 @@ describe('Job State actions', () => {
});
});
- describe('setSelectedStage', () => {
- it('should commit SET_SELECTED_STAGE mutation ', done => {
- testAction(
- setSelectedStage,
- { name: 'build' },
- mockedState,
- [{ type: types.SET_SELECTED_STAGE, payload: { name: 'build' } }],
- [],
- done,
- );
- });
- });
-
describe('fetchJobsForStage', () => {
let mock;
beforeEach(() => {
- mockedState.stageJobsEndpoint = `${TEST_HOST}/endpoint.json`;
mock = new MockAdapter(axios);
});
@@ -542,20 +536,18 @@ describe('Job State actions', () => {
});
describe('success', () => {
- it('dispatches setSelectedStage, requestJobsForStage and receiveJobsForStageSuccess ', done => {
- mock.onGet(`${TEST_HOST}/endpoint.json`).replyOnce(200, [{ id: 121212, name: 'build' }]);
+ it('dispatches requestJobsForStage and receiveJobsForStageSuccess ', done => {
+ mock
+ .onGet(`${TEST_HOST}/jobs.json`)
+ .replyOnce(200, { latest_statuses: [{ id: 121212, name: 'build' }], retried: [] });
testAction(
fetchJobsForStage,
- null,
+ { dropdown_path: `${TEST_HOST}/jobs.json` },
mockedState,
[],
[
{
- type: 'setSelectedStage',
- payload: null,
- },
- {
type: 'requestJobsForStage',
},
{
@@ -570,21 +562,17 @@ describe('Job State actions', () => {
describe('error', () => {
beforeEach(() => {
- mock.onGet(`${TEST_HOST}/endpoint.json`).reply(500);
+ mock.onGet(`${TEST_HOST}/jobs.json`).reply(500);
});
- it('dispatches setSelectedStage, requestJobsForStage and receiveJobsForStageError', done => {
+ it('dispatches requestJobsForStage and receiveJobsForStageError', done => {
testAction(
fetchJobsForStage,
- null,
+ { dropdown_path: `${TEST_HOST}/jobs.json` },
mockedState,
[],
[
{
- payload: null,
- type: 'setSelectedStage',
- },
- {
type: 'requestJobsForStage',
},
{
diff --git a/spec/javascripts/jobs/store/getters_spec.js b/spec/javascripts/jobs/store/getters_spec.js
new file mode 100644
index 00000000000..63ef4135d83
--- /dev/null
+++ b/spec/javascripts/jobs/store/getters_spec.js
@@ -0,0 +1,121 @@
+import * as getters from '~/jobs/store/getters';
+import state from '~/jobs/store/state';
+
+describe('Job Store Getters', () => {
+ let localState;
+
+ beforeEach(() => {
+ localState = state();
+ });
+
+ describe('headerActions', () => {
+ describe('with new issue path', () => {
+ it('returns an array with action to create a new issue', () => {
+ localState.job.new_issue_path = 'issues/new';
+
+ expect(getters.headerActions(localState)).toEqual([
+ {
+ label: 'New issue',
+ path: localState.job.new_issue_path,
+ cssClass:
+ 'js-new-issue btn btn-success btn-inverted d-none d-md-block d-lg-block d-xl-block',
+ type: 'link',
+ },
+ ]);
+ });
+ });
+
+ describe('without new issue path', () => {
+ it('returns an empty array', () => {
+ expect(getters.headerActions(localState)).toEqual([]);
+ });
+ });
+ });
+
+ describe('headerTime', () => {
+ describe('when the job has started key', () => {
+ it('returns started key', () => {
+ const started = '2018-08-31T16:20:49.023Z';
+ localState.job.started = started;
+
+ expect(getters.headerTime(localState)).toEqual(started);
+ });
+ });
+
+ describe('when the job does not have started key', () => {
+ it('returns created_at key', () => {
+ const created = '2018-08-31T16:20:49.023Z';
+ localState.job.created_at = created;
+ expect(getters.headerTime(localState)).toEqual(created);
+ });
+ });
+ });
+
+ describe('shouldRenderCalloutMessage', () => {
+ describe('with status and callout message', () => {
+ it('returns true', () => {
+ localState.job.callout_message = 'Callout message';
+ localState.job.status = { icon: 'passed' };
+
+ expect(getters.shouldRenderCalloutMessage(localState)).toEqual(true);
+ });
+ });
+
+ describe('without status & with callout message', () => {
+ it('returns false', () => {
+ localState.job.callout_message = 'Callout message';
+ expect(getters.shouldRenderCalloutMessage(localState)).toEqual(false);
+ });
+ });
+
+ describe('with status & without callout message', () => {
+ it('returns false', () => {
+ localState.job.status = { icon: 'passed' };
+
+ expect(getters.shouldRenderCalloutMessage(localState)).toEqual(false);
+ });
+ });
+ });
+
+ describe('jobHasStarted', () => {
+ describe('when started equals false', () => {
+ it('returns false', () => {
+ localState.job.started = false;
+ expect(getters.jobHasStarted(localState)).toEqual(false);
+ });
+ });
+
+ describe('when started equals string', () => {
+ it('returns true', () => {
+ localState.job.started = '2018-08-31T16:20:49.023Z';
+ expect(getters.jobHasStarted(localState)).toEqual(true);
+ });
+ });
+ });
+
+ describe('hasEnvironment', () => {
+ describe('without `deployment_status`', () => {
+ it('returns false', () => {
+ expect(getters.hasEnvironment(localState)).toEqual(false);
+ });
+ });
+ describe('with an empty object for `deployment_status`', () => {
+ it('returns false', () => {
+ localState.job.deployment_status = {};
+ expect(getters.hasEnvironment(localState)).toEqual(false);
+ });
+ });
+ describe('when `deployment_status` is defined and not empty', () => {
+ it('returns true', () => {
+ localState.job.deployment_status = {
+ status: 'creating',
+ environment: {
+ last_deployment: {},
+ },
+ };
+
+ expect(getters.hasEnvironment(localState)).toEqual(true);
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/notes/components/noteable_discussion_spec.js b/spec/javascripts/notes/components/noteable_discussion_spec.js
index 2a01bd85520..40b5f009ceb 100644
--- a/spec/javascripts/notes/components/noteable_discussion_spec.js
+++ b/spec/javascripts/notes/components/noteable_discussion_spec.js
@@ -133,4 +133,29 @@ describe('noteable_discussion component', () => {
});
});
});
+
+ describe('componentData', () => {
+ it('should return first note object for placeholder note', () => {
+ const data = {
+ isPlaceholderNote: true,
+ notes: [
+ { body: 'hello world!' },
+ ],
+ };
+
+ const note = vm.componentData(data);
+ expect(note).toEqual(data.notes[0]);
+ });
+
+ it('should return given note for nonplaceholder notes', () => {
+ const data = {
+ notes: [
+ { id: 12 },
+ ],
+ };
+
+ const note = vm.componentData(data);
+ expect(note).toEqual(data);
+ });
+ });
});
diff --git a/spec/javascripts/sidebar/components/time_tracking/time_tracker_spec.js b/spec/javascripts/sidebar/components/time_tracking/time_tracker_spec.js
index 9dff52a9d49..0e30759c41d 100644
--- a/spec/javascripts/sidebar/components/time_tracking/time_tracker_spec.js
+++ b/spec/javascripts/sidebar/components/time_tracking/time_tracker_spec.js
@@ -8,7 +8,10 @@ describe('Issuable Time Tracker', () => {
let initialData;
let vm;
- const initTimeTrackingComponent = opts => {
+ const initTimeTrackingComponent = ({ timeEstimate,
+ timeSpent,
+ timeEstimateHumanReadable,
+ timeSpentHumanReadable }) => {
setFixtures(`
<div>
<div id="mock-container"></div>
@@ -16,10 +19,10 @@ describe('Issuable Time Tracker', () => {
`);
initialData = {
- time_estimate: opts.timeEstimate,
- time_spent: opts.timeSpent,
- human_time_estimate: opts.timeEstimateHumanReadable,
- human_time_spent: opts.timeSpentHumanReadable,
+ timeEstimate,
+ timeSpent,
+ humanTimeEstimate: timeEstimateHumanReadable,
+ humanTimeSpent: timeSpentHumanReadable,
rootPath: '/',
};
@@ -43,8 +46,8 @@ describe('Issuable Time Tracker', () => {
describe('Initialization', () => {
beforeEach(() => {
initTimeTrackingComponent({
- timeEstimate: 100000,
- timeSpent: 5000,
+ timeEstimate: 10000, // 2h 46m
+ timeSpent: 5000, // 1h 23m
timeEstimateHumanReadable: '2h 46m',
timeSpentHumanReadable: '1h 23m',
});
@@ -56,14 +59,14 @@ describe('Issuable Time Tracker', () => {
it('should correctly set timeEstimate', done => {
Vue.nextTick(() => {
- expect(vm.timeEstimate).toBe(initialData.time_estimate);
+ expect(vm.timeEstimate).toBe(initialData.timeEstimate);
done();
});
});
it('should correctly set time_spent', done => {
Vue.nextTick(() => {
- expect(vm.timeSpent).toBe(initialData.time_spent);
+ expect(vm.timeSpent).toBe(initialData.timeSpent);
done();
});
});
@@ -74,8 +77,8 @@ describe('Issuable Time Tracker', () => {
describe('Comparison pane', () => {
beforeEach(() => {
initTimeTrackingComponent({
- timeEstimate: 100000,
- timeSpent: 5000,
+ timeEstimate: 100000, // 1d 3h
+ timeSpent: 5000, // 1h 23m
timeEstimateHumanReadable: '',
timeSpentHumanReadable: '',
});
@@ -106,8 +109,8 @@ describe('Issuable Time Tracker', () => {
});
it('should display the remaining meter with the correct background color when over estimate', done => {
- vm.time_estimate = 100000;
- vm.time_spent = 20000000;
+ vm.timeEstimate = 10000; // 2h 46m
+ vm.timeSpent = 20000000; // 231 days
Vue.nextTick(() => {
expect(vm.$el.querySelector('.time-tracking-comparison-pane .progress[variant="danger"]')).not.toBeNull();
done();
@@ -119,7 +122,7 @@ describe('Issuable Time Tracker', () => {
describe('Estimate only pane', () => {
beforeEach(() => {
initTimeTrackingComponent({
- timeEstimate: 100000,
+ timeEstimate: 10000, // 2h 46m
timeSpent: 0,
timeEstimateHumanReadable: '2h 46m',
timeSpentHumanReadable: '',
@@ -142,7 +145,7 @@ describe('Issuable Time Tracker', () => {
beforeEach(() => {
initTimeTrackingComponent({
timeEstimate: 0,
- timeSpent: 5000,
+ timeSpent: 5000, // 1h 23m
timeEstimateHumanReadable: '2h 46m',
timeSpentHumanReadable: '1h 23m',
});
diff --git a/spec/javascripts/ide/components/changed_file_icon_spec.js b/spec/javascripts/vue_shared/components/changed_file_icon_spec.js
index 7308219f705..5b1038840c7 100644
--- a/spec/javascripts/ide/components/changed_file_icon_spec.js
+++ b/spec/javascripts/vue_shared/components/changed_file_icon_spec.js
@@ -1,8 +1,8 @@
import Vue from 'vue';
-import changedFileIcon from '~/ide/components/changed_file_icon.vue';
+import changedFileIcon from '~/vue_shared/components/changed_file_icon.vue';
import createComponent from 'spec/helpers/vue_mount_component_helper';
-describe('IDE changed file icon', () => {
+describe('Changed file icon', () => {
let vm;
beforeEach(() => {
@@ -33,14 +33,14 @@ describe('IDE changed file icon', () => {
});
describe('changedIconClass', () => {
- it('includes ide-file-modified when not a temp file', () => {
- expect(vm.changedIconClass).toContain('ide-file-modified');
+ it('includes file-modified when not a temp file', () => {
+ expect(vm.changedIconClass).toContain('file-modified');
});
- it('includes ide-file-addition when a temp file', () => {
+ it('includes file-addition when a temp file', () => {
vm.file.tempFile = true;
- expect(vm.changedIconClass).toContain('ide-file-addition');
+ expect(vm.changedIconClass).toContain('file-addition');
});
});
});
diff --git a/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb b/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb
index 0735ebd6dcb..5dce3fcbcb6 100644
--- a/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb
+++ b/spec/lib/gitlab/background_migration/deserialize_merge_request_diffs_and_commits_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe Gitlab::BackgroundMigration::DeserializeMergeRequestDiffsAndCommits, :migration, schema: 20171114162227 do
+ include GitHelpers
+
let(:merge_request_diffs) { table(:merge_request_diffs) }
let(:merge_requests) { table(:merge_requests) }
@@ -9,11 +11,7 @@ describe Gitlab::BackgroundMigration::DeserializeMergeRequestDiffsAndCommits, :m
let(:merge_request) { merge_requests.create!(iid: 1, target_project_id: project.id, source_project_id: project.id, target_branch: 'feature', source_branch: 'master').becomes(MergeRequest) }
let(:merge_request_diff) { MergeRequest.find(merge_request.id).create_merge_request_diff }
let(:updated_merge_request_diff) { MergeRequestDiff.find(merge_request_diff.id) }
- let(:rugged) do
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- project.repository.rugged
- end
- end
+ let(:rugged) { rugged_repo(project.repository) }
before do
allow_any_instance_of(MergeRequestDiff)
diff --git a/spec/lib/gitlab/conflict/file_spec.rb b/spec/lib/gitlab/conflict/file_spec.rb
index 9095ffbfd52..1bd077ddbdf 100644
--- a/spec/lib/gitlab/conflict/file_spec.rb
+++ b/spec/lib/gitlab/conflict/file_spec.rb
@@ -1,9 +1,11 @@
require 'spec_helper'
describe Gitlab::Conflict::File do
+ include GitHelpers
+
let(:project) { create(:project, :repository) }
let(:repository) { project.repository }
- let(:rugged) { Gitlab::GitalyClient::StorageSettings.allow_disk_access { repository.rugged } }
+ let(:rugged) { rugged_repo(repository) }
let(:their_commit) { rugged.branches['conflict-start'].target }
let(:our_commit) { rugged.branches['conflict-resolvable'].target }
let(:merge_request) { create(:merge_request, source_branch: 'conflict-resolvable', target_branch: 'conflict-start', source_project: project) }
diff --git a/spec/lib/gitlab/git/blob_spec.rb b/spec/lib/gitlab/git/blob_spec.rb
index ea49502ae2e..b243f0dacae 100644
--- a/spec/lib/gitlab/git/blob_spec.rb
+++ b/spec/lib/gitlab/git/blob_spec.rb
@@ -4,6 +4,9 @@ require "spec_helper"
describe Gitlab::Git::Blob, :seed_helper do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
+ let(:rugged) do
+ Rugged::Repository.new(File.join(TestEnv.repos_path, TEST_REPO_PATH))
+ end
describe 'initialize' do
let(:blob) { Gitlab::Git::Blob.new(name: 'test') }
@@ -139,9 +142,7 @@ describe Gitlab::Git::Blob, :seed_helper do
it 'limits the size of a large file' do
blob_size = Gitlab::Git::Blob::MAX_DATA_DISPLAY_SIZE + 1
buffer = Array.new(blob_size, 0)
- rugged_blob = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- Rugged::Blob.from_buffer(repository.rugged, buffer.join(''))
- end
+ rugged_blob = Rugged::Blob.from_buffer(rugged, buffer.join(''))
blob = Gitlab::Git::Blob.raw(repository, rugged_blob)
expect(blob.size).to eq(blob_size)
@@ -156,9 +157,7 @@ describe Gitlab::Git::Blob, :seed_helper do
context 'when sha references a tree' do
it 'returns nil' do
- tree = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repository.rugged.rev_parse('master^{tree}')
- end
+ tree = rugged.rev_parse('master^{tree}')
blob = Gitlab::Git::Blob.raw(repository, tree.oid)
@@ -262,11 +261,7 @@ describe Gitlab::Git::Blob, :seed_helper do
end
describe '.batch_lfs_pointers' do
- let(:tree_object) do
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repository.rugged.rev_parse('master^{tree}')
- end
- end
+ let(:tree_object) { rugged.rev_parse('master^{tree}') }
let(:non_lfs_blob) do
Gitlab::Git::Blob.find(
diff --git a/spec/lib/gitlab/git/branch_spec.rb b/spec/lib/gitlab/git/branch_spec.rb
index 79ccbb79966..0df282d0ae3 100644
--- a/spec/lib/gitlab/git/branch_spec.rb
+++ b/spec/lib/gitlab/git/branch_spec.rb
@@ -3,9 +3,7 @@ require "spec_helper"
describe Gitlab::Git::Branch, :seed_helper do
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
let(:rugged) do
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repository.rugged
- end
+ Rugged::Repository.new(File.join(TestEnv.repos_path, repository.relative_path))
end
subject { repository.branches }
@@ -74,9 +72,7 @@ describe Gitlab::Git::Branch, :seed_helper do
Gitlab::Git.committer_hash(email: user.email, name: user.name)
end
let(:params) do
- parents = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- [repository.rugged.head.target]
- end
+ parents = [rugged.head.target]
tree = parents.first.tree
{
diff --git a/spec/lib/gitlab/git/commit_spec.rb b/spec/lib/gitlab/git/commit_spec.rb
index 2718a3c5e49..9ef27081f98 100644
--- a/spec/lib/gitlab/git/commit_spec.rb
+++ b/spec/lib/gitlab/git/commit_spec.rb
@@ -1,19 +1,17 @@
require "spec_helper"
describe Gitlab::Git::Commit, :seed_helper do
+ include GitHelpers
+
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
- let(:commit) { described_class.find(repository, SeedRepo::Commit::ID) }
- let(:rugged_commit) do
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repository.rugged.lookup(SeedRepo::Commit::ID)
- end
+ let(:rugged_repo) do
+ Rugged::Repository.new(File.join(TestEnv.repos_path, TEST_REPO_PATH))
end
+ let(:commit) { described_class.find(repository, SeedRepo::Commit::ID) }
+ let(:rugged_commit) { rugged_repo.lookup(SeedRepo::Commit::ID) }
+
describe "Commit info" do
before do
- repo = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged
- end
-
@committer = {
email: 'mike@smith.com',
name: "Mike Smith",
@@ -26,12 +24,12 @@ describe Gitlab::Git::Commit, :seed_helper do
time: Time.now
}
- @parents = [repo.head.target]
+ @parents = [rugged_repo.head.target]
@gitlab_parents = @parents.map { |c| described_class.find(repository, c.oid) }
@tree = @parents.first.tree
sha = Rugged::Commit.create(
- repo,
+ rugged_repo,
author: @author,
committer: @committer,
tree: @tree,
@@ -40,7 +38,7 @@ describe Gitlab::Git::Commit, :seed_helper do
update_ref: "HEAD"
)
- @raw_commit = repo.lookup(sha)
+ @raw_commit = rugged_repo.lookup(sha)
@commit = described_class.find(repository, sha)
end
@@ -61,10 +59,7 @@ describe Gitlab::Git::Commit, :seed_helper do
after do
# Erase the new commit so other tests get the original repo
- repo = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged
- end
- repo.references.update("refs/heads/master", SeedRepo::LastCommit::ID)
+ rugged_repo.references.update("refs/heads/master", SeedRepo::LastCommit::ID)
end
end
@@ -120,9 +115,7 @@ describe Gitlab::Git::Commit, :seed_helper do
describe '.find' do
it "should return first head commit if without params" do
expect(described_class.last(repository).id).to eq(
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repository.rugged.head.target.oid
- end
+ rugged_repo.head.target.oid
)
end
diff --git a/spec/lib/gitlab/git/diff_spec.rb b/spec/lib/gitlab/git/diff_spec.rb
index 27d803e0117..8a4415506c4 100644
--- a/spec/lib/gitlab/git/diff_spec.rb
+++ b/spec/lib/gitlab/git/diff_spec.rb
@@ -64,9 +64,22 @@ EOT
end
end
- context 'using a Rugged::Patch' do
+ context 'using a GitalyClient::Diff' do
+ let(:gitaly_diff) do
+ Gitlab::GitalyClient::Diff.new(
+ to_path: ".gitmodules",
+ from_path: ".gitmodules",
+ old_mode: 0100644,
+ new_mode: 0100644,
+ from_id: '357406f3075a57708d0163752905cc1576fceacc',
+ to_id: '8e5177d718c561d36efde08bad36b43687ee6bf0',
+ patch: raw_patch
+ )
+ end
+ let(:diff) { described_class.new(gitaly_diff) }
+
context 'with a small diff' do
- let(:diff) { described_class.new(gitaly_diff) }
+ let(:raw_patch) { @raw_diff_hash[:diff] }
it 'initializes the diff' do
expect(diff.to_hash).to eq(@raw_diff_hash)
@@ -78,16 +91,17 @@ EOT
end
context 'using a diff that is too large' do
- it 'prunes the diff' do
- gitaly_diff.too_large = true
- diff = described_class.new(gitaly_diff)
+ let(:raw_patch) { 'a' * 204800 }
+ it 'prunes the diff' do
expect(diff.diff).to be_empty
expect(diff).to be_too_large
end
end
context 'using a collapsable diff that is too large' do
+ let(:raw_patch) { 'a' * 204800 }
+
it 'prunes the diff as a large diff instead of as a collapsed diff' do
gitaly_diff.too_large = true
diff = described_class.new(gitaly_diff, expanded: false)
@@ -97,43 +111,6 @@ EOT
expect(diff).not_to be_collapsed
end
end
- end
-
- context 'using a GitalyClient::Diff' do
- let(:diff) do
- described_class.new(
- Gitlab::GitalyClient::Diff.new(
- to_path: ".gitmodules",
- from_path: ".gitmodules",
- old_mode: 0100644,
- new_mode: 0100644,
- from_id: '357406f3075a57708d0163752905cc1576fceacc',
- to_id: '8e5177d718c561d36efde08bad36b43687ee6bf0',
- patch: raw_patch
- )
- )
- end
-
- context 'with a small diff' do
- let(:raw_patch) { @raw_diff_hash[:diff] }
-
- it 'initializes the diff' do
- expect(diff.to_hash).to eq(@raw_diff_hash)
- end
-
- it 'does not prune the diff' do
- expect(diff).not_to be_too_large
- end
- end
-
- context 'using a diff that is too large' do
- let(:raw_patch) { 'a' * 204800 }
-
- it 'prunes the diff' do
- expect(diff.diff).to be_empty
- expect(diff).to be_too_large
- end
- end
context 'when the patch passed is not UTF-8-encoded' do
let(:raw_patch) { @raw_diff_hash[:diff].encode(Encoding::ASCII_8BIT) }
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index d02536a2fb4..51eb997a325 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -19,7 +19,10 @@ describe Gitlab::Git::Repository, :seed_helper do
end
end
+ let(:mutable_repository) { Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') }
let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
+ let(:repository_path) { File.join(TestEnv.repos_path, repository.relative_path) }
+ let(:repository_rugged) { Rugged::Repository.new(repository_path) }
let(:storage_path) { TestEnv.repos_path }
let(:user) { build(:user) }
@@ -71,7 +74,6 @@ describe Gitlab::Git::Repository, :seed_helper do
describe "Respond to" do
subject { repository }
- it { is_expected.to respond_to(:rugged) }
it { is_expected.to respond_to(:root_ref) }
it { is_expected.to respond_to(:tags) }
end
@@ -91,57 +93,6 @@ describe Gitlab::Git::Repository, :seed_helper do
end
end
- describe "#rugged" do
- describe 'when storage is broken', :broken_storage do
- it 'raises a storage exception when storage is not available' do
- broken_repo = described_class.new('broken', 'a/path.git', '')
-
- expect { broken_repo.rugged }.to raise_error(Gitlab::Git::Storage::Inaccessible)
- end
- end
-
- it 'raises a no repository exception when there is no repo' do
- broken_repo = described_class.new('default', 'a/path.git', '')
-
- expect do
- Gitlab::GitalyClient::StorageSettings.allow_disk_access { broken_repo.rugged }
- end.to raise_error(Gitlab::Git::Repository::NoRepository)
- end
-
- describe 'alternates keyword argument' do
- context 'with no Git env stored' do
- before do
- allow(Gitlab::Git::HookEnv).to receive(:all).and_return({})
- end
-
- it "is passed an empty array" do
- expect(Rugged::Repository).to receive(:new).with(repository_path, alternates: [])
-
- repository_rugged
- end
- end
-
- context 'with absolute and relative Git object dir envvars stored' do
- before do
- allow(Gitlab::Git::HookEnv).to receive(:all).and_return({
- 'GIT_OBJECT_DIRECTORY_RELATIVE' => './objects/foo',
- 'GIT_ALTERNATE_OBJECT_DIRECTORIES_RELATIVE' => ['./objects/bar', './objects/baz'],
- 'GIT_OBJECT_DIRECTORY' => 'ignored',
- 'GIT_ALTERNATE_OBJECT_DIRECTORIES' => %w[ignored ignored],
- 'GIT_OTHER' => 'another_env'
- })
- end
-
- it "is passed the relative object dir envvars after being converted to absolute ones" do
- alternates = %w[foo bar baz].map { |d| File.join(repository_path, './objects', d) }
- expect(Rugged::Repository).to receive(:new).with(repository_path, alternates: alternates)
-
- repository_rugged
- end
- end
- end
- end
-
describe '#branch_names' do
subject { repository.branch_names }
@@ -284,7 +235,6 @@ describe Gitlab::Git::Repository, :seed_helper do
end
describe '#submodule_url_for' do
- let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
let(:ref) { 'master' }
def submodule_url(path)
@@ -336,7 +286,7 @@ describe Gitlab::Git::Repository, :seed_helper do
it { expect(repository.has_local_branches?).to eq(true) }
context 'mutable' do
- let(:repository) { Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') }
+ let(:repository) { mutable_repository }
after do
ensure_seeds
@@ -369,7 +319,7 @@ describe Gitlab::Git::Repository, :seed_helper do
end
describe "#delete_branch" do
- let(:repository) { Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') }
+ let(:repository) { mutable_repository }
after do
ensure_seeds
@@ -393,7 +343,7 @@ describe Gitlab::Git::Repository, :seed_helper do
end
describe "#create_branch" do
- let(:repository) { Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') }
+ let(:repository) { mutable_repository }
after do
ensure_seeds
@@ -418,39 +368,33 @@ describe Gitlab::Git::Repository, :seed_helper do
end
describe '#delete_refs' do
- let(:repo) { Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') }
-
- def repo_rugged
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repo.rugged
- end
- end
+ let(:repository) { mutable_repository }
after do
ensure_seeds
end
it 'deletes the ref' do
- repo.delete_refs('refs/heads/feature')
+ repository.delete_refs('refs/heads/feature')
- expect(repo_rugged.references['refs/heads/feature']).to be_nil
+ expect(repository_rugged.references['refs/heads/feature']).to be_nil
end
it 'deletes all refs' do
refs = %w[refs/heads/wip refs/tags/v1.1.0]
- repo.delete_refs(*refs)
+ repository.delete_refs(*refs)
refs.each do |ref|
- expect(repo_rugged.references[ref]).to be_nil
+ expect(repository_rugged.references[ref]).to be_nil
end
end
it 'does not fail when deleting an empty list of refs' do
- expect { repo.delete_refs(*[]) }.not_to raise_error
+ expect { repository.delete_refs(*[]) }.not_to raise_error
end
it 'raises an error if it failed' do
- expect { repo.delete_refs('refs\heads\fix') }.to raise_error(Gitlab::Git::Repository::GitError)
+ expect { repository.delete_refs('refs\heads\fix') }.to raise_error(Gitlab::Git::Repository::GitError)
end
end
@@ -528,9 +472,7 @@ describe Gitlab::Git::Repository, :seed_helper do
end
def new_repository_path
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- new_repository.path
- end
+ File.join(TestEnv.repos_path, new_repository.relative_path)
end
end
@@ -577,18 +519,16 @@ describe Gitlab::Git::Repository, :seed_helper do
Gitlab::Git::Commit.find(repository, @rename_commit_id)
end
- before(:context) do
+ before do
# Add new commits so that there's a renamed file in the commit history
- repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged
- @commit_with_old_name_id = new_commit_edit_old_file(repo).oid
- @rename_commit_id = new_commit_move_file(repo).oid
- @commit_with_new_name_id = new_commit_edit_new_file(repo).oid
+ @commit_with_old_name_id = new_commit_edit_old_file(repository_rugged).oid
+ @rename_commit_id = new_commit_move_file(repository_rugged).oid
+ @commit_with_new_name_id = new_commit_edit_new_file(repository_rugged).oid
end
- after(:context) do
+ after do
# Erase our commits so other tests get the original repo
- repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged
- repo.references.update("refs/heads/master", SeedRepo::LastCommit::ID)
+ repository_rugged.references.update("refs/heads/master", SeedRepo::LastCommit::ID)
end
context "where 'follow' == true" do
@@ -1010,12 +950,10 @@ describe Gitlab::Git::Repository, :seed_helper do
subject { repository.branches }
context 'with local and remote branches' do
- let(:repository) do
- Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
- end
+ let(:repository) { mutable_repository }
before do
- create_remote_branch(repository, 'joe', 'remote_branch', 'master')
+ create_remote_branch('joe', 'remote_branch', 'master')
repository.create_branch('local_branch', 'master')
end
@@ -1038,12 +976,10 @@ describe Gitlab::Git::Repository, :seed_helper do
end
context 'with local and remote branches' do
- let(:repository) do
- Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
- end
+ let(:repository) { mutable_repository }
before do
- create_remote_branch(repository, 'joe', 'remote_branch', 'master')
+ create_remote_branch('joe', 'remote_branch', 'master')
repository.create_branch('local_branch', 'master')
end
@@ -1303,24 +1239,24 @@ describe Gitlab::Git::Repository, :seed_helper do
end
describe '#local_branches' do
- before(:all) do
- @repo = Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
+ let(:repository) { mutable_repository }
+
+ before do
+ create_remote_branch('joe', 'remote_branch', 'master')
+ repository.create_branch('local_branch', 'master')
end
- after(:all) do
+ after do
ensure_seeds
end
it 'returns the local branches' do
- create_remote_branch(@repo, 'joe', 'remote_branch', 'master')
- @repo.create_branch('local_branch', 'master')
-
- expect(@repo.local_branches.any? { |branch| branch.name == 'remote_branch' }).to eq(false)
- expect(@repo.local_branches.any? { |branch| branch.name == 'local_branch' }).to eq(true)
+ expect(repository.local_branches.any? { |branch| branch.name == 'remote_branch' }).to eq(false)
+ expect(repository.local_branches.any? { |branch| branch.name == 'local_branch' }).to eq(true)
end
it 'returns a Branch with UTF-8 fields' do
- branches = @repo.local_branches.to_a
+ branches = repository.local_branches.to_a
expect(branches.size).to be > 0
branches.each do |branch|
expect(branch.name).to be_utf8
@@ -1331,11 +1267,11 @@ describe Gitlab::Git::Repository, :seed_helper do
it 'gets the branches from GitalyClient' do
expect_any_instance_of(Gitlab::GitalyClient::RefService).to receive(:local_branches)
.and_return([])
- @repo.local_branches
+ repository.local_branches
end
it_behaves_like 'wrapping gRPC errors', Gitlab::GitalyClient::RefService, :local_branches do
- subject { @repo.local_branches }
+ subject { repository.local_branches }
end
end
@@ -1391,8 +1327,7 @@ describe Gitlab::Git::Repository, :seed_helper do
describe '#fetch_source_branch!' do
let(:local_ref) { 'refs/merge-requests/1/head' }
- let(:repository) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '') }
- let(:source_repository) { Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') }
+ let(:source_repository) { mutable_repository }
after do
ensure_seeds
@@ -1401,7 +1336,8 @@ describe Gitlab::Git::Repository, :seed_helper do
context 'when the branch exists' do
context 'when the commit does not exist locally' do
let(:source_branch) { 'new-branch-for-fetch-source-branch' }
- let(:source_rugged) { Gitlab::GitalyClient::StorageSettings.allow_disk_access { source_repository.rugged } }
+ let(:source_path) { File.join(TestEnv.repos_path, source_repository.relative_path) }
+ let(:source_rugged) { Rugged::Repository.new(source_path) }
let(:new_oid) { new_commit_edit_old_file(source_rugged).oid }
before do
@@ -1513,8 +1449,7 @@ describe Gitlab::Git::Repository, :seed_helper do
end
describe '#set_config' do
- let(:repository) { Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') }
- let(:rugged) { repository_rugged }
+ let(:repository) { mutable_repository }
let(:entries) do
{
'test.foo1' => 'bla bla',
@@ -1526,19 +1461,18 @@ describe Gitlab::Git::Repository, :seed_helper do
it 'can set config settings' do
expect(repository.set_config(entries)).to be_nil
- expect(rugged.config['test.foo1']).to eq('bla bla')
- expect(rugged.config['test.foo2']).to eq('1234')
- expect(rugged.config['test.foo3']).to eq('true')
+ expect(repository_rugged.config['test.foo1']).to eq('bla bla')
+ expect(repository_rugged.config['test.foo2']).to eq('1234')
+ expect(repository_rugged.config['test.foo3']).to eq('true')
end
after do
- entries.keys.each { |k| rugged.config.delete(k) }
+ entries.keys.each { |k| repository_rugged.config.delete(k) }
end
end
describe '#delete_config' do
- let(:repository) { Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '') }
- let(:rugged) { repository_rugged }
+ let(:repository) { mutable_repository }
let(:entries) do
{
'test.foo1' => 'bla bla',
@@ -1549,21 +1483,19 @@ describe Gitlab::Git::Repository, :seed_helper do
it 'can delete config settings' do
entries.each do |key, value|
- rugged.config[key] = value
+ repository_rugged.config[key] = value
end
expect(repository.delete_config(*%w[does.not.exist test.foo1 test.foo2])).to be_nil
- config_keys = rugged.config.each_key.to_a
+ config_keys = repository_rugged.config.each_key.to_a
expect(config_keys).not_to include('test.foo1')
expect(config_keys).not_to include('test.foo2')
end
end
describe '#merge' do
- let(:repository) do
- Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
- end
+ let(:repository) { mutable_repository }
let(:source_sha) { '913c66a37b4a45b9769037c55c2d238bd0942d2e' }
let(:target_branch) { 'test-merge-target-branch' }
@@ -1602,9 +1534,7 @@ describe Gitlab::Git::Repository, :seed_helper do
end
describe '#ff_merge' do
- let(:repository) do
- Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
- end
+ let(:repository) { mutable_repository }
let(:branch_head) { '6d394385cf567f80a8fd85055db1ab4c5295806f' }
let(:source_sha) { 'cfe32cf61b73a0d5e9f13e774abde7ff789b1660' }
let(:target_branch) { 'test-ff-target-branch' }
@@ -1667,9 +1597,7 @@ describe Gitlab::Git::Repository, :seed_helper do
end
describe '#delete_all_refs_except' do
- let(:repository) do
- Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
- end
+ let(:repository) { mutable_repository }
before do
repository.write_ref("refs/delete/a", "0b4bc9a49b562e85de7cc9e834518ea6828729b9")
@@ -1693,12 +1621,7 @@ describe Gitlab::Git::Repository, :seed_helper do
end
describe 'remotes' do
- let(:repository) do
- Gitlab::Git::Repository.new('default', TEST_MUTABLE_REPO_PATH, '')
- end
- let(:rugged) do
- Gitlab::GitalyClient::StorageSettings.allow_disk_access { repository.rugged }
- end
+ let(:repository) { mutable_repository }
let(:remote_name) { 'my-remote' }
let(:url) { 'http://my-repo.git' }
@@ -1711,26 +1634,26 @@ describe Gitlab::Git::Repository, :seed_helper do
it 'added the remote' do
begin
- rugged.remotes.delete(remote_name)
+ repository_rugged.remotes.delete(remote_name)
rescue Rugged::ConfigError
end
repository.add_remote(remote_name, url, mirror_refmap: mirror_refmap)
- expect(rugged.remotes[remote_name]).not_to be_nil
- expect(rugged.config["remote.#{remote_name}.mirror"]).to eq('true')
- expect(rugged.config["remote.#{remote_name}.prune"]).to eq('true')
- expect(rugged.config["remote.#{remote_name}.fetch"]).to eq(mirror_refmap)
+ expect(repository_rugged.remotes[remote_name]).not_to be_nil
+ expect(repository_rugged.config["remote.#{remote_name}.mirror"]).to eq('true')
+ expect(repository_rugged.config["remote.#{remote_name}.prune"]).to eq('true')
+ expect(repository_rugged.config["remote.#{remote_name}.fetch"]).to eq(mirror_refmap)
end
end
describe '#remove_remote' do
it 'removes the remote' do
- rugged.remotes.create(remote_name, url)
+ repository_rugged.remotes.create(remote_name, url)
repository.remove_remote(remote_name)
- expect(rugged.remotes[remote_name]).to be_nil
+ expect(repository_rugged.remotes[remote_name]).to be_nil
end
end
end
@@ -1901,13 +1824,11 @@ describe Gitlab::Git::Repository, :seed_helper do
end
context 'when the diff contains a rename' do
- let(:repo) { Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged }
- let(:end_sha) { new_commit_move_file(repo).oid }
+ let(:end_sha) { new_commit_move_file(repository_rugged).oid }
after do
# Erase our commits so other tests get the original repo
- repo = Gitlab::Git::Repository.new('default', TEST_REPO_PATH, '').rugged
- repo.references.update('refs/heads/master', SeedRepo::LastCommit::ID)
+ repository_rugged.references.update('refs/heads/master', SeedRepo::LastCommit::ID)
end
it 'does not include the renamed file in the sparse checkout' do
@@ -1954,10 +1875,9 @@ describe Gitlab::Git::Repository, :seed_helper do
end
end
- def create_remote_branch(repository, remote_name, branch_name, source_branch_name)
+ def create_remote_branch(remote_name, branch_name, source_branch_name)
source_branch = repository.branches.find { |branch| branch.name == source_branch_name }
- rugged = repository_rugged
- rugged.references.create("refs/remotes/#{remote_name}/#{branch_name}", source_branch.dereferenced_target.sha)
+ repository_rugged.references.create("refs/remotes/#{remote_name}/#{branch_name}", source_branch.dereferenced_target.sha)
end
# Build the options hash that's passed to Rugged::Commit#create
@@ -2035,16 +1955,4 @@ describe Gitlab::Git::Repository, :seed_helper do
line.split("\t").last
end
end
-
- def repository_rugged
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repository.rugged
- end
- end
-
- def repository_path
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repository.path
- end
- end
end
diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb
index dbd64c4bec0..e7da5565c26 100644
--- a/spec/lib/gitlab/git_access_spec.rb
+++ b/spec/lib/gitlab/git_access_spec.rb
@@ -2,6 +2,7 @@ require 'spec_helper'
describe Gitlab::GitAccess do
include TermsHelper
+ include GitHelpers
let(:user) { create(:user) }
@@ -736,21 +737,19 @@ describe Gitlab::GitAccess do
def merge_into_protected_branch
@protected_branch_merge_commit ||= begin
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- project.repository.add_branch(user, unprotected_branch, 'feature')
- rugged = project.repository.rugged
- target_branch = rugged.rev_parse('feature')
- source_branch = project.repository.create_file(
- user,
- 'filename',
- 'This is the file content',
- message: 'This is a good commit message',
- branch_name: unprotected_branch)
- author = { email: "email@example.com", time: Time.now, name: "Example Git User" }
-
- merge_index = rugged.merge_commits(target_branch, source_branch)
- Rugged::Commit.create(rugged, author: author, committer: author, message: "commit message", parents: [target_branch, source_branch], tree: merge_index.write_tree(rugged))
- end
+ project.repository.add_branch(user, unprotected_branch, 'feature')
+ rugged = rugged_repo(project.repository)
+ target_branch = rugged.rev_parse('feature')
+ source_branch = project.repository.create_file(
+ user,
+ 'filename',
+ 'This is the file content',
+ message: 'This is a good commit message',
+ branch_name: unprotected_branch)
+ author = { email: "email@example.com", time: Time.now, name: "Example Git User" }
+
+ merge_index = rugged.merge_commits(target_branch, source_branch)
+ Rugged::Commit.create(rugged, author: author, committer: author, message: "commit message", parents: [target_branch, source_branch], tree: merge_index.write_tree(rugged))
end
end
diff --git a/spec/lib/gitlab/gitaly_client/wiki_service_spec.rb b/spec/lib/gitlab/gitaly_client/wiki_service_spec.rb
index 5f67fe6b952..d82c9c28da0 100644
--- a/spec/lib/gitlab/gitaly_client/wiki_service_spec.rb
+++ b/spec/lib/gitlab/gitaly_client/wiki_service_spec.rb
@@ -39,6 +39,10 @@ describe Gitlab::GitalyClient::WikiService do
expect(wiki_page.title).to eq('My Page')
expect(wiki_page.raw_data).to eq('ab')
expect(wiki_page_version.format).to eq('markdown')
+
+ expect(wiki_page.title).to be_utf8
+ expect(wiki_page.path).to be_utf8
+ expect(wiki_page.name).to be_utf8
end
end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 1ec1fe10744..d669c42ab4a 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -46,6 +46,7 @@ describe Gitlab::UsageData do
git
database
avg_cycle_analytics
+ web_ide_commits
))
end
diff --git a/spec/lib/gitlab/web_ide_commits_counter_spec.rb b/spec/lib/gitlab/web_ide_commits_counter_spec.rb
new file mode 100644
index 00000000000..c51889a1c63
--- /dev/null
+++ b/spec/lib/gitlab/web_ide_commits_counter_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::WebIdeCommitsCounter, :clean_gitlab_redis_shared_state do
+ describe '.increment' do
+ it 'increments the web ide commits counter by 1' do
+ expect do
+ described_class.increment
+ end.to change { described_class.total_count }.from(0).to(1)
+ end
+ end
+
+ describe '.total_count' do
+ it 'returns the total amount of web ide commits' do
+ expect(described_class.total_count).to eq(0)
+ end
+ end
+end
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 48f4e53b93e..666d7e69f89 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -746,7 +746,7 @@ describe MergeRequest do
end
describe "#wipless_title" do
- ['WIP ', 'WIP:', 'WIP: ', '[WIP]', '[WIP] ', ' [WIP] WIP [WIP] WIP: WIP '].each do |wip_prefix|
+ ['WIP ', 'WIP:', 'WIP: ', '[WIP]', '[WIP] ', '[WIP] WIP [WIP] WIP: WIP '].each do |wip_prefix|
it "removes the '#{wip_prefix}' prefix" do
wipless_title = subject.title
subject.title = "#{wip_prefix}#{subject.title}"
diff --git a/spec/models/namespace_spec.rb b/spec/models/namespace_spec.rb
index 22dc81acfda..8913644a3ce 100644
--- a/spec/models/namespace_spec.rb
+++ b/spec/models/namespace_spec.rb
@@ -2,6 +2,7 @@ require 'spec_helper'
describe Namespace do
include ProjectForksHelper
+ include GitHelpers
let!(:namespace) { create(:namespace) }
let(:gitlab_shell) { Gitlab::Shell.new }
@@ -361,9 +362,7 @@ describe Namespace do
end
def project_rugged(project)
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- project.repository.rugged
- end
+ rugged_repo(project.repository)
end
end
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index d15ba89efb5..8b71919544e 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -2,6 +2,7 @@ require 'spec_helper'
describe Project do
include ProjectForksHelper
+ include GitHelpers
describe 'associations' do
it { is_expected.to belong_to(:group) }
@@ -4039,8 +4040,6 @@ describe Project do
end
def rugged_config
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- project.repository.rugged.config
- end
+ rugged_repo(project.repository).config
end
end
diff --git a/spec/models/remote_mirror_spec.rb b/spec/models/remote_mirror_spec.rb
index 269d5deca20..3d316fb3c5b 100644
--- a/spec/models/remote_mirror_spec.rb
+++ b/spec/models/remote_mirror_spec.rb
@@ -1,6 +1,8 @@
require 'rails_helper'
describe RemoteMirror do
+ include GitHelpers
+
describe 'URL validation' do
context 'with a valid URL' do
it 'should be valid' do
@@ -74,9 +76,7 @@ describe RemoteMirror do
mirror.update_attribute(:url, 'http://foo:baz@test.com')
- config = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repo.raw_repository.rugged.config
- end
+ config = rugged_repo(repo).config
expect(config["remote.#{mirror.remote_name}.url"]).to eq('http://foo:baz@test.com')
end
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 784d17e271e..77e549d9528 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -2,6 +2,8 @@ require 'spec_helper'
describe Repository do
include RepoHelpers
+ include GitHelpers
+
TestBlob = Struct.new(:path)
let(:project) { create(:project, :repository) }
@@ -137,9 +139,7 @@ describe Repository do
options = { message: 'test tag message\n',
tagger: { name: 'John Smith', email: 'john@gmail.com' } }
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repository.rugged.tags.create(annotated_tag_name, 'a48e4fc218069f68ef2e769dd8dfea3991362175', options)
- end
+ rugged_repo(repository).tags.create(annotated_tag_name, 'a48e4fc218069f68ef2e769dd8dfea3991362175', options)
double_first = double(committed_date: Time.now - 1.second)
double_last = double(committed_date: Time.now)
@@ -151,9 +151,7 @@ describe Repository do
it { is_expected.to eq(['v1.1.0', 'v1.0.0', annotated_tag_name]) }
after do
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repository.rugged.tags.delete(annotated_tag_name)
- end
+ rugged_repo(repository).tags.delete(annotated_tag_name)
end
end
end
@@ -1678,10 +1676,7 @@ describe Repository do
it 'returns the number of branches' do
expect(repository.branch_count).to be_an(Integer)
- # NOTE: Until rugged goes away, make sure rugged and gitaly are in sync
- rugged_count = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repository.raw_repository.rugged.branches.count
- end
+ rugged_count = rugged_repo(repository).branches.count
expect(repository.branch_count).to eq(rugged_count)
end
@@ -1691,10 +1686,7 @@ describe Repository do
it 'returns the number of tags' do
expect(repository.tag_count).to be_an(Integer)
- # NOTE: Until rugged goes away, make sure rugged and gitaly are in sync
- rugged_count = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repository.raw_repository.rugged.tags.count
- end
+ rugged_count = rugged_repo(repository).tags.count
expect(repository.tag_count).to eq(rugged_count)
end
@@ -2184,9 +2176,7 @@ describe Repository do
end
def create_remote_branch(remote_name, branch_name, target)
- rugged = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- repository.rugged
- end
+ rugged = rugged_repo(repository)
rugged.references.create("refs/remotes/#{remote_name}/#{branch_name}", target.id)
end
diff --git a/spec/models/wiki_page_spec.rb b/spec/models/wiki_page_spec.rb
index 63850939be1..b4732ec0cd5 100644
--- a/spec/models/wiki_page_spec.rb
+++ b/spec/models/wiki_page_spec.rb
@@ -77,7 +77,7 @@ describe WikiPage do
end
describe "#initialize" do
- context "when initialized with an existing gollum page" do
+ context "when initialized with an existing page" do
before do
create_page("test page", "test content")
@page = wiki.wiki.page(title: "test page")
diff --git a/spec/requests/api/commits_spec.rb b/spec/requests/api/commits_spec.rb
index f3fb88474a4..06ccf383362 100644
--- a/spec/requests/api/commits_spec.rb
+++ b/spec/requests/api/commits_spec.rb
@@ -278,6 +278,12 @@ describe API::Commits do
}
end
+ it 'does not increment the usage counters using access token authentication' do
+ expect(::Gitlab::WebIdeCommitsCounter).not_to receive(:increment)
+
+ post api(url, user), valid_c_params
+ end
+
it 'a new file in project repo' do
post api(url, user), valid_c_params
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index e987eee6e91..07d19e3ad29 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -81,6 +81,35 @@ describe API::MergeRequests do
let(:user2) { create(:user) }
it 'returns an array of all merge requests except unauthorized ones' do
+ get api('/merge_requests', user), scope: :all
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(json_response.map { |mr| mr['id'] })
+ .to contain_exactly(merge_request.id, merge_request_closed.id, merge_request_merged.id, merge_request_locked.id, merge_request2.id)
+ end
+
+ it "returns an array of no merge_requests when wip=yes" do
+ get api("/merge_requests", user), wip: 'yes'
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(json_response.length).to eq(0)
+ end
+
+ it "returns an array of no merge_requests when wip=no" do
+ get api("/merge_requests", user), wip: 'no'
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(json_response.map { |mr| mr['id'] })
+ .to contain_exactly(merge_request.id, merge_request_closed.id, merge_request_merged.id, merge_request_locked.id, merge_request2.id)
+ end
+
+ it 'does not return unauthorized merge requests' do
private_project = create(:project, :private)
merge_request3 = create(:merge_request, :simple, source_project: private_project, target_project: private_project, source_branch: 'other-branch')
@@ -244,6 +273,15 @@ describe API::MergeRequests do
expect(response).to have_gitlab_http_status(404)
end
+ it "returns an array of no merge_requests when wip=yes" do
+ get api("/projects/#{project.id}/merge_requests", user), wip: 'yes'
+
+ expect(response).to have_gitlab_http_status(200)
+ expect(response).to include_pagination_headers
+ expect(json_response).to be_an Array
+ expect(json_response.length).to eq(0)
+ end
+
it 'returns merge_request by "iids" array' do
get api(endpoint_path, user), iids: [merge_request.iid, merge_request_closed.iid]
diff --git a/spec/services/git_tag_push_service_spec.rb b/spec/services/git_tag_push_service_spec.rb
index 92159e1e372..2699f6e7bcd 100644
--- a/spec/services/git_tag_push_service_spec.rb
+++ b/spec/services/git_tag_push_service_spec.rb
@@ -2,6 +2,7 @@ require 'spec_helper'
describe GitTagPushService do
include RepoHelpers
+ include GitHelpers
let(:user) { create(:user) }
let(:project) { create(:project, :repository) }
@@ -118,9 +119,7 @@ describe GitTagPushService do
before do
# Create the lightweight tag
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- project.repository.raw_repository.rugged.tags.create(tag_name, newrev)
- end
+ rugged_repo(project.repository).tags.create(tag_name, newrev)
# Clear tag list cache
project.repository.expire_tags_cache
diff --git a/spec/services/merge_requests/squash_service_spec.rb b/spec/services/merge_requests/squash_service_spec.rb
index 8ab09412f55..53bce15735c 100644
--- a/spec/services/merge_requests/squash_service_spec.rb
+++ b/spec/services/merge_requests/squash_service_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe MergeRequests::SquashService do
+ include GitHelpers
+
let(:service) { described_class.new(project, user, {}) }
let(:user) { project.owner }
let(:project) { create(:project, :repository) }
@@ -63,9 +65,7 @@ describe MergeRequests::SquashService do
end
it 'has the same diff as the merge request, but a different SHA' do
- rugged = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- project.repository.rugged
- end
+ rugged = rugged_repo(project.repository)
mr_diff = rugged.diff(merge_request.diff_base_sha, merge_request.diff_head_sha)
squash_diff = rugged.diff(merge_request.diff_start_sha, squash_sha)
diff --git a/spec/services/projects/after_import_service_spec.rb b/spec/services/projects/after_import_service_spec.rb
index cd52bc88f4c..4dd6c6dab86 100644
--- a/spec/services/projects/after_import_service_spec.rb
+++ b/spec/services/projects/after_import_service_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe Projects::AfterImportService do
+ include GitHelpers
+
subject { described_class.new(project) }
let(:project) { create(:project, :repository) }
@@ -53,7 +55,7 @@ describe Projects::AfterImportService do
end
def rugged
- Gitlab::GitalyClient::StorageSettings.allow_disk_access { repository.rugged }
+ rugged_repo(repository)
end
end
end
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index bb3f1501f0e..a80c8a7fe51 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe Projects::CreateService, '#execute' do
+ include GitHelpers
+
let(:gitlab_shell) { Gitlab::Shell.new }
let(:user) { create :user }
let(:opts) do
@@ -295,9 +297,7 @@ describe Projects::CreateService, '#execute' do
it 'writes project full path to .git/config' do
project = create_project(user, opts)
- rugged = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- project.repository.rugged
- end
+ rugged = rugged_repo(project.repository)
expect(rugged.config['gitlab.fullpath']).to eq project.full_path
end
diff --git a/spec/services/projects/hashed_storage/migrate_repository_service_spec.rb b/spec/services/projects/hashed_storage/migrate_repository_service_spec.rb
index 5f67c325223..0e82194e9ee 100644
--- a/spec/services/projects/hashed_storage/migrate_repository_service_spec.rb
+++ b/spec/services/projects/hashed_storage/migrate_repository_service_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe Projects::HashedStorage::MigrateRepositoryService do
+ include GitHelpers
+
let(:gitlab_shell) { Gitlab::Shell.new }
let(:project) { create(:project, :legacy_storage, :repository, :wiki_repo) }
let(:legacy_storage) { Storage::LegacyProject.new(project) }
@@ -38,9 +40,7 @@ describe Projects::HashedStorage::MigrateRepositoryService do
it 'writes project full path to .git/config' do
service.execute
- rugged_config = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- project.repository.rugged.config['gitlab.fullpath']
- end
+ rugged_config = rugged_repo(project.repository).config['gitlab.fullpath']
expect(rugged_config).to eq project.full_path
end
diff --git a/spec/services/projects/transfer_service_spec.rb b/spec/services/projects/transfer_service_spec.rb
index 92c5ac7354a..1411723fb9e 100644
--- a/spec/services/projects/transfer_service_spec.rb
+++ b/spec/services/projects/transfer_service_spec.rb
@@ -1,6 +1,8 @@
require 'spec_helper'
describe Projects::TransferService do
+ include GitHelpers
+
let(:gitlab_shell) { Gitlab::Shell.new }
let(:user) { create(:user) }
let(:group) { create(:group) }
@@ -291,8 +293,6 @@ describe Projects::TransferService do
end
def rugged_config
- Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- project.repository.rugged.config
- end
+ rugged_repo(project.repository).config
end
end
diff --git a/spec/support/helpers/cycle_analytics_helpers.rb b/spec/support/helpers/cycle_analytics_helpers.rb
index e0fceae88de..83035788a56 100644
--- a/spec/support/helpers/cycle_analytics_helpers.rb
+++ b/spec/support/helpers/cycle_analytics_helpers.rb
@@ -1,4 +1,6 @@
module CycleAnalyticsHelpers
+ include GitHelpers
+
def create_commit_referencing_issue(issue, branch_name: generate(:branch))
project.repository.add_branch(user, branch_name, 'master')
create_commit("Commit for ##{issue.iid}", issue.project, user, branch_name)
@@ -9,7 +11,7 @@ module CycleAnalyticsHelpers
oldrev = repository.commit(branch_name)&.sha || Gitlab::Git::BLANK_SHA
if Timecop.frozen? && Gitlab::GitalyClient.feature_enabled?(:operation_user_commit_files)
- mock_gitaly_multi_action_dates(repository.raw, commit_time)
+ mock_gitaly_multi_action_dates(repository, commit_time)
end
commit_shas = Array.new(count) do |index|
@@ -118,18 +120,15 @@ module CycleAnalyticsHelpers
protected: false)
end
- def mock_gitaly_multi_action_dates(raw_repository, commit_time)
- allow(raw_repository).to receive(:multi_action).and_wrap_original do |m, *args|
+ def mock_gitaly_multi_action_dates(repository, commit_time)
+ allow(repository.raw).to receive(:multi_action).and_wrap_original do |m, *args|
new_date = commit_time || Time.now
branch_update = m.call(*args)
if branch_update.newrev
_, opts = args
- commit = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- rugged = raw_repository.rugged
- rugged.rev_parse(branch_update.newrev)
- end
+ commit = rugged_repo(repository).rev_parse(branch_update.newrev)
branch_update.newrev = commit.amend(
update_ref: "#{Gitlab::Git::BRANCH_REF_PREFIX}#{opts[:branch_name]}",
diff --git a/spec/support/helpers/git_helpers.rb b/spec/support/helpers/git_helpers.rb
index fc92bc38561..99a7c39852e 100644
--- a/spec/support/helpers/git_helpers.rb
+++ b/spec/support/helpers/git_helpers.rb
@@ -1,6 +1,12 @@
# frozen_string_literal: true
module GitHelpers
+ def rugged_repo(repository)
+ path = File.join(TestEnv.repos_path, repository.disk_path + '.git')
+
+ Rugged::Repository.new(path)
+ end
+
def project_hook_exists?(project)
Gitlab::GitalyClient::StorageSettings.allow_disk_access do
project_path = project.repository.raw_repository.path
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 93c21a99e59..1190863d88e 100644
--- a/spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb
+++ b/spec/support/shared_examples/uploaders/gitlab_uploader_shared_examples.rb
@@ -33,6 +33,14 @@ shared_examples "builds correct paths" do |**patterns|
it_behaves_like "matches the method pattern", :upload_path
end
+ describe "#relative_path" do
+ it 'is relative' do
+ skip 'Path not set, skipping.' unless subject.path
+
+ expect(Pathname.new(subject.relative_path)).to be_relative
+ end
+ end
+
describe ".absolute_path" do
it_behaves_like "matches the method pattern", :absolute_path do
let(:target) { subject.class }
diff --git a/spec/views/projects/jobs/show.html.haml_spec.rb b/spec/views/projects/jobs/show.html.haml_spec.rb
index 496646dc623..e06a9ecb98b 100644
--- a/spec/views/projects/jobs/show.html.haml_spec.rb
+++ b/spec/views/projects/jobs/show.html.haml_spec.rb
@@ -18,161 +18,6 @@ describe 'projects/jobs/show' do
allow(view).to receive(:can?).and_return(true)
end
- describe 'environment info in job view' do
- context 'job with latest deployment' do
- let(:build) do
- create(:ci_build, :success, :trace_artifact, environment: 'staging')
- end
-
- before do
- create(:environment, name: 'staging')
- create(:deployment, deployable: build)
- end
-
- it 'shows deployment message' do
- expected_text = 'This job is the most recent deployment'
- render
-
- expect(rendered).to have_css(
- '.environment-information', text: expected_text)
- end
- end
-
- context 'job with outdated deployment' do
- let(:build) do
- create(:ci_build, :success, :trace_artifact, environment: 'staging', pipeline: pipeline)
- end
-
- let(:second_build) do
- create(:ci_build, :success, :trace_artifact, environment: 'staging', pipeline: pipeline)
- end
-
- let(:environment) do
- create(:environment, name: 'staging', project: project)
- end
-
- let!(:first_deployment) do
- create(:deployment, environment: environment, deployable: build)
- end
-
- let!(:second_deployment) do
- create(:deployment, environment: environment, deployable: second_build)
- end
-
- it 'shows deployment message' do
- expected_text = 'This job is an out-of-date deployment ' \
- "to staging.\nView the most recent deployment ##{second_deployment.iid}."
- render
-
- expect(rendered).to have_css('.environment-information', text: expected_text)
- end
- end
-
- context 'job failed to deploy' do
- let(:build) do
- create(:ci_build, :failed, :trace_artifact, environment: 'staging', pipeline: pipeline)
- end
-
- let!(:environment) do
- create(:environment, name: 'staging', project: project)
- end
-
- it 'shows deployment message' do
- expected_text = 'The deployment of this job to staging did not succeed.'
- render
-
- expect(rendered).to have_css(
- '.environment-information', text: expected_text)
- end
- end
-
- context 'job will deploy' do
- let(:build) do
- create(:ci_build, :running, :trace_live, environment: 'staging', pipeline: pipeline)
- end
-
- context 'when environment exists' do
- let!(:environment) do
- create(:environment, name: 'staging', project: project)
- end
-
- it 'shows deployment message' do
- expected_text = 'This job is creating a deployment to staging'
- render
-
- expect(rendered).to have_css(
- '.environment-information', text: expected_text)
- end
-
- context 'when it has deployment' do
- let!(:deployment) do
- create(:deployment, environment: environment)
- end
-
- it 'shows that deployment will be overwritten' do
- expected_text = 'This job is creating a deployment to staging'
- render
-
- expect(rendered).to have_css(
- '.environment-information', text: expected_text)
- expect(rendered).to have_css(
- '.environment-information', text: 'latest deployment')
- end
- end
- end
-
- context 'when environment does not exist' do
- it 'shows deployment message' do
- expected_text = 'This job is creating a deployment to staging'
- render
-
- expect(rendered).to have_css(
- '.environment-information', text: expected_text)
- expect(rendered).not_to have_css(
- '.environment-information', text: 'latest deployment')
- end
- end
- end
-
- context 'job that failed to deploy and environment has not been created' do
- let(:build) do
- create(:ci_build, :failed, :trace_artifact, environment: 'staging', pipeline: pipeline)
- end
-
- let!(:environment) do
- create(:environment, name: 'staging', project: project)
- end
-
- it 'shows deployment message' do
- expected_text = 'The deployment of this job to staging did not succeed'
- render
-
- expect(rendered).to have_css(
- '.environment-information', text: expected_text)
- end
- end
-
- context 'job that will deploy and environment has not been created' do
- let(:build) do
- create(:ci_build, :running, :trace_live, environment: 'staging', pipeline: pipeline)
- end
-
- let!(:environment) do
- create(:environment, name: 'staging', project: project)
- end
-
- it 'shows deployment message' do
- expected_text = 'This job is creating a deployment to staging'
- render
-
- expect(rendered).to have_css(
- '.environment-information', text: expected_text)
- expect(rendered).not_to have_css(
- '.environment-information', text: 'latest deployment')
- end
- end
- end
-
context 'when job is running' do
let(:build) { create(:ci_build, :trace_live, :running, pipeline: pipeline) }
diff --git a/spec/workers/git_garbage_collect_worker_spec.rb b/spec/workers/git_garbage_collect_worker_spec.rb
index 30e67e67e0e..a159f24f876 100644
--- a/spec/workers/git_garbage_collect_worker_spec.rb
+++ b/spec/workers/git_garbage_collect_worker_spec.rb
@@ -3,6 +3,8 @@ require 'fileutils'
require 'spec_helper'
describe GitGarbageCollectWorker do
+ include GitHelpers
+
let(:project) { create(:project, :repository) }
let(:shell) { Gitlab::Shell.new }
let!(:lease_uuid) { SecureRandom.uuid }
@@ -197,9 +199,7 @@ describe GitGarbageCollectWorker do
# Create a new commit on a random new branch
def create_objects(project)
- rugged = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- project.repository.rugged
- end
+ rugged = rugged_repo(project.repository)
old_commit = rugged.branches.first.target
new_commit_sha = Rugged::Commit.create(
rugged,
diff --git a/spec/workers/repository_remove_remote_worker_spec.rb b/spec/workers/repository_remove_remote_worker_spec.rb
index a653f6f926c..6ddb653d142 100644
--- a/spec/workers/repository_remove_remote_worker_spec.rb
+++ b/spec/workers/repository_remove_remote_worker_spec.rb
@@ -2,6 +2,7 @@ require 'rails_helper'
describe RepositoryRemoveRemoteWorker do
include ExclusiveLeaseHelpers
+ include GitHelpers
describe '#perform' do
let!(:project) { create(:project, :repository) }
@@ -50,9 +51,7 @@ describe RepositoryRemoveRemoteWorker do
end
def create_remote_branch(remote_name, branch_name, target)
- rugged = Gitlab::GitalyClient::StorageSettings.allow_disk_access do
- project.repository.rugged
- end
+ rugged = rugged_repo(project.repository)
rugged.references.create("refs/remotes/#{remote_name}/#{branch_name}", target.id)
end