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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-09-27 21:06:20 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2019-09-27 21:06:20 +0300
commit2abb1b54c0305b359b178d6660810e865f619c22 (patch)
treee388953a0566ef9844b0b98cdb34236049721a14 /spec
parent8320f7956d72986f5a7c850874fce4f8b5a8e015 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/boards/lists_controller_spec.rb25
-rw-r--r--spec/features/issues/issues_tabs_spec.rb56
-rw-r--r--spec/frontend/lib/utils/suppress_ajax_errors_during_navigation_spec.js37
-rw-r--r--spec/javascripts/frequent_items/components/app_spec.js7
-rw-r--r--spec/javascripts/lib/utils/common_utils_spec.js10
-rw-r--r--spec/models/ci/build_spec.rb6
-rw-r--r--spec/models/ci/persistent_ref_spec.rb108
-rw-r--r--spec/models/ci/pipeline_spec.rb10
-rw-r--r--spec/models/list_spec.rb12
-rw-r--r--spec/presenters/ci/build_runner_presenter_spec.rb17
-rw-r--r--spec/requests/boards/lists_controller_spec.rb25
-rw-r--r--spec/services/ci/process_pipeline_service_spec.rb16
-rw-r--r--spec/services/ci/register_job_service_spec.rb16
13 files changed, 320 insertions, 25 deletions
diff --git a/spec/controllers/boards/lists_controller_spec.rb b/spec/controllers/boards/lists_controller_spec.rb
index 77b5872fcb3..bc46d02556b 100644
--- a/spec/controllers/boards/lists_controller_spec.rb
+++ b/spec/controllers/boards/lists_controller_spec.rb
@@ -14,6 +14,10 @@ describe Boards::ListsController do
end
describe 'GET index' do
+ before do
+ create(:list, board: board)
+ end
+
it 'returns a successful 200 response' do
read_board_list user: user, board: board
@@ -22,27 +26,22 @@ describe Boards::ListsController do
end
it 'returns a list of board lists' do
- create(:list, board: board)
-
read_board_list user: user, board: board
expect(response).to match_response_schema('lists')
expect(json_response.length).to eq 3
end
- it 'avoids n+1 queries when serializing lists' do
- list_1 = create(:list, board: board)
- list_1.update_preferences_for(user, { collapsed: true })
-
- control_count = ActiveRecord::QueryRecorder.new { read_board_list user: user, board: board }.count
-
- list_2 = create(:list, board: board)
- list_2.update_preferences_for(user, { collapsed: true })
+ context 'when another user has list preferences' do
+ before do
+ board.lists.first.update_preferences_for(guest, collapsed: true)
+ end
- list_3 = create(:list, board: board)
- list_3.update_preferences_for(user, { collapsed: true })
+ it 'returns the complete list of board lists' do
+ read_board_list user: user, board: board
- expect { read_board_list user: user, board: board }.not_to exceed_query_limit(control_count)
+ expect(json_response.length).to eq 3
+ end
end
context 'with unauthorized user' do
diff --git a/spec/features/issues/issues_tabs_spec.rb b/spec/features/issues/issues_tabs_spec.rb
new file mode 100644
index 00000000000..66d55dd9021
--- /dev/null
+++ b/spec/features/issues/issues_tabs_spec.rb
@@ -0,0 +1,56 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe 'Issue page tabs', :js do
+ let(:user) { create(:user) }
+ let(:project) { create(:project, :public) }
+ let(:issue) { create(:issue, author: user, assignees: [user], project: project) }
+
+ describe 'discussions tab counter' do
+ before do
+ stub_licensed_features(design_management: true)
+ stub_feature_flags(design_management_flag: true)
+ allow(Ability).to receive(:allowed?) { true }
+ end
+
+ subject do
+ sign_in(user)
+
+ visit project_issue_path(project, issue)
+
+ wait_for_requests
+
+ find('#discussion')
+ end
+
+ context 'new issue' do
+ it 'displays count of 0' do
+ is_expected.to have_content('Discussion 0')
+ end
+ end
+
+ context 'issue with 2 system notes and 1 discussion' do
+ let!(:discussion) { create(:discussion_note_on_issue, noteable: issue, project: project, note: "This is good") }
+
+ before do
+ create(:system_note, noteable: issue, project: project, author: user, note: 'description updated')
+ create(:system_note, noteable: issue, project: project, author: user, note: 'description updated')
+ end
+
+ it 'displays count of 1' do
+ is_expected.to have_content('Discussion 1')
+ end
+
+ context 'with 1 reply' do
+ before do
+ create(:note, noteable: issue, in_reply_to: discussion, discussion_id: discussion.discussion_id, note: 'I also think this is good')
+ end
+
+ it 'displays count of 2' do
+ is_expected.to have_content('Discussion 2')
+ end
+ end
+ end
+ end
+end
diff --git a/spec/frontend/lib/utils/suppress_ajax_errors_during_navigation_spec.js b/spec/frontend/lib/utils/suppress_ajax_errors_during_navigation_spec.js
new file mode 100644
index 00000000000..89e8459d594
--- /dev/null
+++ b/spec/frontend/lib/utils/suppress_ajax_errors_during_navigation_spec.js
@@ -0,0 +1,37 @@
+import suppressAjaxErrorsDuringNavigation from '~/lib/utils/suppress_ajax_errors_during_navigation';
+import waitForPromises from 'helpers/wait_for_promises';
+
+describe('suppressAjaxErrorsDuringNavigation', () => {
+ const OTHER_ERR_CODE = 'foo';
+ const NAV_ERR_CODE = 'ECONNABORTED';
+
+ it.each`
+ isFeatureFlagEnabled | isUserNavigating | code
+ ${false} | ${false} | ${OTHER_ERR_CODE}
+ ${false} | ${false} | ${NAV_ERR_CODE}
+ ${false} | ${true} | ${OTHER_ERR_CODE}
+ ${false} | ${true} | ${NAV_ERR_CODE}
+ ${true} | ${false} | ${OTHER_ERR_CODE}
+ ${true} | ${false} | ${NAV_ERR_CODE}
+ ${true} | ${true} | ${OTHER_ERR_CODE}
+ `('should return a rejected Promise', ({ isFeatureFlagEnabled, isUserNavigating, code }) => {
+ const err = { code };
+ const actual = suppressAjaxErrorsDuringNavigation(err, isUserNavigating, isFeatureFlagEnabled);
+
+ return expect(actual).rejects.toBe(err);
+ });
+
+ it('should return a Promise that never resolves', () => {
+ const err = { code: NAV_ERR_CODE };
+ const actual = suppressAjaxErrorsDuringNavigation(err, true, true);
+
+ const thenCallback = jest.fn();
+ const catchCallback = jest.fn();
+ actual.then(thenCallback).catch(catchCallback);
+
+ return waitForPromises().then(() => {
+ expect(thenCallback).not.toHaveBeenCalled();
+ expect(catchCallback).not.toHaveBeenCalled();
+ });
+ });
+});
diff --git a/spec/javascripts/frequent_items/components/app_spec.js b/spec/javascripts/frequent_items/components/app_spec.js
index 6814f656f5d..36dd8604d08 100644
--- a/spec/javascripts/frequent_items/components/app_spec.js
+++ b/spec/javascripts/frequent_items/components/app_spec.js
@@ -236,8 +236,15 @@ describe('Frequent Items App Component', () => {
.then(() => {
expect(vm.$el.querySelector('.loading-animation')).toBeDefined();
})
+
+ // This test waits for multiple ticks in order to allow the responses to
+ // propagate through each interceptor installed on the Axios instance.
+ // This shouldn't be necessary; this test should be refactored to avoid this.
+ // https://gitlab.com/gitlab-org/gitlab/issues/32479
+ .then(vm.$nextTick)
.then(vm.$nextTick)
.then(vm.$nextTick)
+
.then(() => {
expect(vm.$el.querySelectorAll('.frequent-items-list-container li').length).toBe(
mockSearchedProjects.length,
diff --git a/spec/javascripts/lib/utils/common_utils_spec.js b/spec/javascripts/lib/utils/common_utils_spec.js
index 85949f2ae86..8956bc92e6b 100644
--- a/spec/javascripts/lib/utils/common_utils_spec.js
+++ b/spec/javascripts/lib/utils/common_utils_spec.js
@@ -943,4 +943,14 @@ describe('common_utils', () => {
expect(commonUtils.isScopedLabel({ title: 'foobar' })).toBe(false);
});
});
+
+ describe('getDashPath', () => {
+ it('returns the path following /-/', () => {
+ expect(commonUtils.getDashPath('/some/-/url-with-dashes-/')).toEqual('url-with-dashes-/');
+ });
+
+ it('returns null when no path follows /-/', () => {
+ expect(commonUtils.getDashPath('/some/url')).toEqual(null);
+ });
+ });
});
diff --git a/spec/models/ci/build_spec.rb b/spec/models/ci/build_spec.rb
index 5c0f8bd392a..8ae56ae2d4b 100644
--- a/spec/models/ci/build_spec.rb
+++ b/spec/models/ci/build_spec.rb
@@ -3079,6 +3079,12 @@ describe Ci::Build do
rescue StateMachines::InvalidTransition
end
+ it 'ensures pipeline ref existence' do
+ expect(job.pipeline.persistent_ref).to receive(:create).once
+
+ run_job_without_exception
+ end
+
shared_examples 'saves data on transition' do
it 'saves timeout' do
expect { job.run! }.to change { job.reload.ensure_metadata.timeout }.from(nil).to(expected_timeout)
diff --git a/spec/models/ci/persistent_ref_spec.rb b/spec/models/ci/persistent_ref_spec.rb
new file mode 100644
index 00000000000..71e0b03dff9
--- /dev/null
+++ b/spec/models/ci/persistent_ref_spec.rb
@@ -0,0 +1,108 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Ci::PersistentRef do
+ it 'cleans up persistent refs after pipeline finished' do
+ pipeline = create(:ci_pipeline, :running)
+
+ expect(pipeline.persistent_ref).to receive(:delete).once
+
+ pipeline.succeed!
+ end
+
+ context '#exist?' do
+ subject { pipeline.persistent_ref.exist? }
+
+ let(:pipeline) { create(:ci_pipeline, sha: sha, project: project) }
+ let(:project) { create(:project, :repository) }
+ let(:sha) { project.repository.commit.sha }
+
+ context 'when a persistent ref does not exist' do
+ it { is_expected.to eq(false) }
+ end
+
+ context 'when a persistent ref exists' do
+ before do
+ pipeline.persistent_ref.create
+ end
+
+ it { is_expected.to eq(true) }
+ end
+ end
+
+ context '#create' do
+ subject { pipeline.persistent_ref.create }
+
+ let(:pipeline) { create(:ci_pipeline, sha: sha, project: project) }
+ let(:project) { create(:project, :repository) }
+ let(:sha) { project.repository.commit.sha }
+
+ context 'when a persistent ref does not exist' do
+ it 'creates a persistent ref' do
+ subject
+
+ expect(pipeline.persistent_ref).to be_exist
+ end
+
+ context 'when depend_on_persistent_pipeline_ref feature flag is disabled' do
+ before do
+ stub_feature_flags(depend_on_persistent_pipeline_ref: false)
+ end
+
+ it 'does not create a persistent ref' do
+ expect(project.repository).not_to receive(:create_ref)
+
+ subject
+ end
+ end
+
+ context 'when sha does not exist in the repository' do
+ let(:sha) { 'not-exist' }
+
+ it 'fails to create a persistent ref' do
+ subject
+
+ expect(pipeline.persistent_ref).not_to be_exist
+ end
+ end
+ end
+
+ context 'when a persistent ref already exists' do
+ before do
+ pipeline.persistent_ref.create
+ end
+
+ it 'does not create a persistent ref' do
+ expect(project.repository).not_to receive(:create_ref)
+
+ subject
+ end
+ end
+ end
+
+ context '#delete' do
+ subject { pipeline.persistent_ref.delete }
+
+ let(:pipeline) { create(:ci_pipeline, sha: sha, project: project) }
+ let(:project) { create(:project, :repository) }
+ let(:sha) { project.repository.commit.sha }
+
+ context 'when a persistent ref exists' do
+ before do
+ pipeline.persistent_ref.create
+ end
+
+ it 'deletes the ref' do
+ expect { subject }.to change { pipeline.persistent_ref.exist? }
+ .from(true).to(false)
+ end
+ end
+
+ context 'when a persistent ref does not exist' do
+ it 'does not raise an error' do
+ expect { subject }.not_to raise_error
+ end
+ end
+ end
+end
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index fdd0cd8a3b7..a00d93ac4ba 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -1318,6 +1318,16 @@ describe Ci::Pipeline, :mailer do
let(:build_b) { create_build('build2', queued_at: 0) }
let(:build_c) { create_build('build3', queued_at: 0) }
+ %w[succeed! drop! cancel! skip!].each do |action|
+ context "when the pipeline recieved #{action} event" do
+ it 'deletes a persistent ref' do
+ expect(pipeline.persistent_ref).to receive(:delete).once
+
+ pipeline.public_send(action)
+ end
+ end
+ end
+
describe '#duration' do
context 'when multiple builds are finished' do
before do
diff --git a/spec/models/list_spec.rb b/spec/models/list_spec.rb
index dc28204d7aa..bc9124e73af 100644
--- a/spec/models/list_spec.rb
+++ b/spec/models/list_spec.rb
@@ -136,18 +136,6 @@ describe List do
expect(preferences).to be_persisted
expect(preferences.collapsed).to eq(true)
end
-
- context 'when preferences are already loaded for user' do
- it 'gets preloaded user preferences' do
- fetched_list = described_class.where(id: list.id).with_preferences_for(user).first
-
- expect(fetched_list).to receive(:preloaded_preferences_for).with(user).and_call_original
-
- preferences = fetched_list.preferences_for(user)
-
- expect(preferences.collapsed).to eq(true)
- end
- end
end
context 'when preferences for user does not exist' do
diff --git a/spec/presenters/ci/build_runner_presenter_spec.rb b/spec/presenters/ci/build_runner_presenter_spec.rb
index a4234d14255..fa8791f2257 100644
--- a/spec/presenters/ci/build_runner_presenter_spec.rb
+++ b/spec/presenters/ci/build_runner_presenter_spec.rb
@@ -207,5 +207,22 @@ describe Ci::BuildRunnerPresenter do
end
end
end
+
+ context 'when persistent pipeline ref exists' do
+ let(:project) { create(:project, :repository) }
+ let(:sha) { project.repository.commit.sha }
+ let(:pipeline) { create(:ci_pipeline, sha: sha, project: project) }
+ let(:build) { create(:ci_build, pipeline: pipeline) }
+
+ before do
+ pipeline.persistent_ref.create
+ end
+
+ it 'exposes the persistent pipeline ref' do
+ is_expected
+ .to contain_exactly("+refs/pipelines/#{pipeline.id}:refs/pipelines/#{pipeline.id}",
+ "+refs/heads/#{build.ref}:refs/remotes/origin/#{build.ref}")
+ end
+ end
end
end
diff --git a/spec/requests/boards/lists_controller_spec.rb b/spec/requests/boards/lists_controller_spec.rb
new file mode 100644
index 00000000000..7451ad93efd
--- /dev/null
+++ b/spec/requests/boards/lists_controller_spec.rb
@@ -0,0 +1,25 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Boards::ListsController do
+ describe '#index' do
+ let(:board) { create(:board) }
+ let(:user) { board.project.owner }
+
+ it 'does not have N+1 queries' do
+ login_as(user)
+
+ # First request has more queries because we create the default `backlog` list
+ get board_lists_path(board)
+
+ create(:list, board: board)
+
+ control_count = ActiveRecord::QueryRecorder.new { get board_lists_path(board) }.count
+
+ create_list(:list, 5, board: board)
+
+ expect { get board_lists_path(board) }.not_to exceed_query_limit(control_count)
+ end
+ end
+end
diff --git a/spec/services/ci/process_pipeline_service_spec.rb b/spec/services/ci/process_pipeline_service_spec.rb
index 1b28d2d4d02..05adec8b745 100644
--- a/spec/services/ci/process_pipeline_service_spec.rb
+++ b/spec/services/ci/process_pipeline_service_spec.rb
@@ -422,6 +422,18 @@ describe Ci::ProcessPipelineService, '#execute' do
end
end
+ context 'when an exception is raised during a persistent ref creation' do
+ before do
+ successful_build('test', stage_idx: 0)
+
+ allow_any_instance_of(Ci::PersistentRef).to receive(:delete_refs) { raise ArgumentError }
+ end
+
+ it 'process the pipeline' do
+ expect { process_pipeline }.not_to raise_error
+ end
+ end
+
context 'when there are manual action in earlier stages' do
context 'when first stage has only optional manual actions' do
before do
@@ -907,6 +919,10 @@ describe Ci::ProcessPipelineService, '#execute' do
create(:ci_build, :created, pipeline: pipeline, name: name, **opts)
end
+ def successful_build(name, **opts)
+ create(:ci_build, :success, pipeline: pipeline, name: name, **opts)
+ end
+
def delayed_options
{ when: 'delayed', options: { script: %w(echo), start_in: '1 minute' } }
end
diff --git a/spec/services/ci/register_job_service_spec.rb b/spec/services/ci/register_job_service_spec.rb
index 874945c8585..2f2c525ccc4 100644
--- a/spec/services/ci/register_job_service_spec.rb
+++ b/spec/services/ci/register_job_service_spec.rb
@@ -501,6 +501,22 @@ module Ci
expect(pending_job).to be_archived_failure
end
end
+
+ context 'when an exception is raised during a persistent ref creation' do
+ before do
+ allow_any_instance_of(Ci::PersistentRef).to receive(:exist?) { false }
+ allow_any_instance_of(Ci::PersistentRef).to receive(:create_ref) { raise ArgumentError }
+ end
+
+ subject { execute(specific_runner, {}) }
+
+ it 'picks the build' do
+ expect(subject).to eq(pending_job)
+
+ pending_job.reload
+ expect(pending_job).to be_running
+ end
+ end
end
describe '#register_success' do