summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2019-11-26 00:06:28 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2019-11-26 00:06:28 +0000
commit9615736987b94a783845354ba881008e49d39238 (patch)
tree0620a1d06e44df92fa936b7a86e57d282f690181
parenteb7390edf3afd52174b786fff1e06d5ffae0cec5 (diff)
downloadgitlab-ce-9615736987b94a783845354ba881008e49d39238.tar.gz
Add latest changes from gitlab-org/gitlab@master
-rw-r--r--app/controllers/admin/jobs_controller.rb20
-rw-r--r--app/controllers/projects/jobs_controller.rb29
-rw-r--r--app/finders/jobs_finder.rb51
-rw-r--r--app/models/ci/build.rb15
-rw-r--r--app/models/ci/pipeline.rb12
-rw-r--r--changelogs/unreleased/35616-broken-anchor-for-learn-more-about-interacting-with-security-report.yml5
-rw-r--r--doc/development/build_test_package.md6
-rw-r--r--doc/development/img/build_package_v12_6.pngbin0 -> 124510 bytes
-rw-r--r--doc/development/img/trigger_build_package_v12_6.pngbin0 -> 141603 bytes
-rw-r--r--doc/development/img/trigger_ss1.pngbin35756 -> 0 bytes
-rw-r--r--doc/development/img/trigger_ss2.pngbin36082 -> 0 bytes
-rw-r--r--locale/gitlab.pot9
-rw-r--r--spec/finders/jobs_finder_spec.rb89
-rw-r--r--spec/frontend/vue_shared/components/markdown/field_spec.js179
-rw-r--r--spec/javascripts/vue_shared/components/markdown/field_spec.js173
-rw-r--r--spec/models/ci/pipeline_spec.rb49
16 files changed, 361 insertions, 276 deletions
diff --git a/app/controllers/admin/jobs_controller.rb b/app/controllers/admin/jobs_controller.rb
index 0c1afdc3d3b..892f6dc657c 100644
--- a/app/controllers/admin/jobs_controller.rb
+++ b/app/controllers/admin/jobs_controller.rb
@@ -1,25 +1,15 @@
# frozen_string_literal: true
class Admin::JobsController < Admin::ApplicationController
- # rubocop: disable CodeReuse/ActiveRecord
def index
+ # We need all builds for tabs counters
+ @all_builds = JobsFinder.new(current_user: current_user).execute
+
@scope = params[:scope]
- @all_builds = Ci::Build
- @builds = @all_builds.order('id DESC')
- @builds =
- case @scope
- when 'pending'
- @builds.pending.reverse_order
- when 'running'
- @builds.running.reverse_order
- when 'finished'
- @builds.finished
- else
- @builds
- end
+ @builds = JobsFinder.new(current_user: current_user, params: params).execute
+ @builds = @builds.eager_load_everything
@builds = @builds.page(params[:page]).per(30)
end
- # rubocop: enable CodeReuse/ActiveRecord
def cancel_all
Ci::Build.running_or_pending.each(&:cancel)
diff --git a/app/controllers/projects/jobs_controller.rb b/app/controllers/projects/jobs_controller.rb
index 1d914ab6011..9480900b57a 100644
--- a/app/controllers/projects/jobs_controller.rb
+++ b/app/controllers/projects/jobs_controller.rb
@@ -17,34 +17,15 @@ class Projects::JobsController < Projects::ApplicationController
layout 'project'
- # rubocop: disable CodeReuse/ActiveRecord
def index
+ # We need all builds for tabs counters
+ @all_builds = JobsFinder.new(current_user: current_user, project: @project).execute
+
@scope = params[:scope]
- @all_builds = project.builds.relevant
- @builds = @all_builds.order('ci_builds.id DESC')
- @builds =
- case @scope
- when 'pending'
- @builds.pending.reverse_order
- when 'running'
- @builds.running.reverse_order
- when 'finished'
- @builds.finished
- else
- @builds
- end
- @builds = @builds.includes([
- { pipeline: [:project, :user] },
- :job_artifacts_archive,
- :metadata,
- :trigger_request,
- :project,
- :user,
- :tags
- ])
+ @builds = JobsFinder.new(current_user: current_user, project: @project, params: params).execute
+ @builds = @builds.eager_load_everything
@builds = @builds.page(params[:page]).per(30).without_count
end
- # rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def show
diff --git a/app/finders/jobs_finder.rb b/app/finders/jobs_finder.rb
new file mode 100644
index 00000000000..bac18e69618
--- /dev/null
+++ b/app/finders/jobs_finder.rb
@@ -0,0 +1,51 @@
+# frozen_string_literal: true
+
+class JobsFinder
+ include Gitlab::Allowable
+
+ def initialize(current_user:, project: nil, params: {})
+ @current_user = current_user
+ @project = project
+ @params = params
+ end
+
+ def execute
+ builds = init_collection.order_id_desc
+ filter_by_scope(builds)
+ rescue Gitlab::Access::AccessDeniedError
+ Ci::Build.none
+ end
+
+ private
+
+ attr_reader :current_user, :project, :params
+
+ def init_collection
+ project ? project_builds : all_builds
+ end
+
+ def all_builds
+ raise Gitlab::Access::AccessDeniedError unless current_user&.admin?
+
+ Ci::Build.all
+ end
+
+ def project_builds
+ raise Gitlab::Access::AccessDeniedError unless can?(current_user, :read_build, project)
+
+ project.builds.relevant
+ end
+
+ def filter_by_scope(builds)
+ case params[:scope]
+ when 'pending'
+ builds.pending.reverse_order
+ when 'running'
+ builds.running.reverse_order
+ when 'finished'
+ builds.finished
+ else
+ builds
+ end
+ end
+end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 59bff4e2d2b..4679e8b74d7 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -120,6 +120,20 @@ module Ci
scope :eager_load_job_artifacts, -> { includes(:job_artifacts) }
+ scope :eager_load_everything, -> do
+ includes(
+ [
+ { pipeline: [:project, :user] },
+ :job_artifacts_archive,
+ :metadata,
+ :trigger_request,
+ :project,
+ :user,
+ :tags
+ ]
+ )
+ end
+
scope :with_exposed_artifacts, -> do
joins(:metadata).merge(Ci::BuildMetadata.with_exposed_artifacts)
.includes(:metadata, :job_artifacts_metadata)
@@ -161,6 +175,7 @@ module Ci
end
scope :queued_before, ->(time) { where(arel_table[:queued_at].lt(time)) }
+ scope :order_id_desc, -> { order('ci_builds.id DESC') }
acts_as_taggable
diff --git a/app/models/ci/pipeline.rb b/app/models/ci/pipeline.rb
index 6d38b58c301..b411bc296c5 100644
--- a/app/models/ci/pipeline.rb
+++ b/app/models/ci/pipeline.rb
@@ -772,18 +772,10 @@ module Ci
triggered_by_merge_request? && target_sha.present?
end
- def merge_train_pipeline?
- merge_request_pipeline? && merge_train_ref?
- end
-
def merge_request_ref?
MergeRequest.merge_request_ref?(ref)
end
- def merge_train_ref?
- MergeRequest.merge_train_ref?(ref)
- end
-
def matches_sha_or_source_sha?(sha)
self.sha == sha || self.source_sha == sha
end
@@ -816,9 +808,7 @@ module Ci
return unless merge_request_event?
strong_memoize(:merge_request_event_type) do
- if merge_train_pipeline?
- :merge_train
- elsif merge_request_pipeline?
+ if merge_request_pipeline?
:merged_result
elsif detached_merge_request_pipeline?
:detached
diff --git a/changelogs/unreleased/35616-broken-anchor-for-learn-more-about-interacting-with-security-report.yml b/changelogs/unreleased/35616-broken-anchor-for-learn-more-about-interacting-with-security-report.yml
new file mode 100644
index 00000000000..6babed09767
--- /dev/null
+++ b/changelogs/unreleased/35616-broken-anchor-for-learn-more-about-interacting-with-security-report.yml
@@ -0,0 +1,5 @@
+---
+title: Use correct fragment identifier for vulnerability help path
+merge_request: 20524
+author:
+type: fixed
diff --git a/doc/development/build_test_package.md b/doc/development/build_test_package.md
index f58ac79b6f4..d478d6e1653 100644
--- a/doc/development/build_test_package.md
+++ b/doc/development/build_test_package.md
@@ -9,16 +9,16 @@ that will create:
- A deb package for Ubuntu 16.04, available as a build artifact, and
- A docker image, which is pushed to [Omnibus GitLab's container
registry](https://gitlab.com/gitlab-org/omnibus-gitlab/container_registry)
- (images titled `gitlab-foss` and `gitlab-ee` respectively and image tag is the
+ (images titled `gitlab-ce` and `gitlab-ee` respectively and image tag is the
commit which triggered the pipeline).
When you push a commit to either the GitLab CE or GitLab EE project, the
pipeline for that commit will have a `build-package` manual action you can
trigger.
-![Manual actions](img/trigger_ss1.png)
+![Manual actions](img/build_package_v12_6.png)
-![Build package manual action](img/trigger_ss2.png)
+![Build package manual action](img/trigger_build_package_v12_6.png)
## Specifying versions of components
diff --git a/doc/development/img/build_package_v12_6.png b/doc/development/img/build_package_v12_6.png
new file mode 100644
index 00000000000..c3d99e6c6ce
--- /dev/null
+++ b/doc/development/img/build_package_v12_6.png
Binary files differ
diff --git a/doc/development/img/trigger_build_package_v12_6.png b/doc/development/img/trigger_build_package_v12_6.png
new file mode 100644
index 00000000000..6f5879bd8c4
--- /dev/null
+++ b/doc/development/img/trigger_build_package_v12_6.png
Binary files differ
diff --git a/doc/development/img/trigger_ss1.png b/doc/development/img/trigger_ss1.png
deleted file mode 100644
index addbc551f73..00000000000
--- a/doc/development/img/trigger_ss1.png
+++ /dev/null
Binary files differ
diff --git a/doc/development/img/trigger_ss2.png b/doc/development/img/trigger_ss2.png
deleted file mode 100644
index 02ef3810a59..00000000000
--- a/doc/development/img/trigger_ss2.png
+++ /dev/null
Binary files differ
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index a4f92ede7dc..e703e87f0d6 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -5257,14 +5257,15 @@ msgid_plural "CycleAnalytics|%d projects selected"
msgstr[0] ""
msgstr[1] ""
-msgid "CycleAnalytics|%{stageName}"
-msgid_plural "CycleAnalytics|%d stages selected"
-msgstr[0] ""
-msgstr[1] ""
+msgid "CycleAnalytics|%{stageCount} stages selected"
+msgstr ""
msgid "CycleAnalytics|All stages"
msgstr ""
+msgid "CycleAnalytics|No stages selected"
+msgstr ""
+
msgid "CycleAnalytics|Stages"
msgstr ""
diff --git a/spec/finders/jobs_finder_spec.rb b/spec/finders/jobs_finder_spec.rb
new file mode 100644
index 00000000000..675d170b90e
--- /dev/null
+++ b/spec/finders/jobs_finder_spec.rb
@@ -0,0 +1,89 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe JobsFinder, '#execute' do
+ set(:user) { create(:user) }
+ set(:admin) { create(:user, :admin) }
+ set(:project) { create(:project, :private, public_builds: false) }
+ set(:pipeline) { create(:ci_pipeline, project: project) }
+ set(:job_1) { create(:ci_build) }
+ set(:job_2) { create(:ci_build, :running) }
+ set(:job_3) { create(:ci_build, :success, pipeline: pipeline) }
+
+ let(:params) { {} }
+
+ context 'no project' do
+ subject { described_class.new(current_user: admin, params: params).execute }
+
+ it 'returns all jobs' do
+ expect(subject).to match_array([job_1, job_2, job_3])
+ end
+
+ context 'non admin user' do
+ let(:admin) { user }
+
+ it 'returns no jobs' do
+ expect(subject).to be_empty
+ end
+ end
+
+ context 'without user' do
+ let(:admin) { nil }
+
+ it 'returns no jobs' do
+ expect(subject).to be_empty
+ end
+ end
+
+ context 'scope is present' do
+ let(:jobs) { [job_1, job_2, job_3] }
+
+ where(:scope, :index) do
+ [
+ ['pending', 0],
+ ['running', 1],
+ ['finished', 2]
+ ]
+ end
+
+ with_them do
+ let(:params) { { scope: scope } }
+
+ it { expect(subject).to match_array([jobs[index]]) }
+ end
+ end
+ end
+
+ context 'a project is present' do
+ subject { described_class.new(current_user: user, project: project, params: params).execute }
+
+ context 'user has access to the project' do
+ before do
+ project.add_maintainer(user)
+ end
+
+ it 'returns jobs for the specified project' do
+ expect(subject).to match_array([job_3])
+ end
+ end
+
+ context 'user has no access to project builds' do
+ before do
+ project.add_guest(user)
+ end
+
+ it 'returns no jobs' do
+ expect(subject).to be_empty
+ end
+ end
+
+ context 'without user' do
+ let(:user) { nil }
+
+ it 'returns no jobs' do
+ expect(subject).to be_empty
+ end
+ end
+ end
+end
diff --git a/spec/frontend/vue_shared/components/markdown/field_spec.js b/spec/frontend/vue_shared/components/markdown/field_spec.js
new file mode 100644
index 00000000000..b006f72b8ee
--- /dev/null
+++ b/spec/frontend/vue_shared/components/markdown/field_spec.js
@@ -0,0 +1,179 @@
+import { mount, createLocalVue } from '@vue/test-utils';
+import fieldComponent from '~/vue_shared/components/markdown/field.vue';
+import { TEST_HOST } from 'spec/test_constants';
+import AxiosMockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+import $ from 'jquery';
+
+const markdownPreviewPath = `${TEST_HOST}/preview`;
+const markdownDocsPath = `${TEST_HOST}/docs`;
+
+function assertMarkdownTabs(isWrite, writeLink, previewLink, wrapper) {
+ expect(writeLink.element.parentNode.classList.contains('active')).toEqual(isWrite);
+ expect(previewLink.element.parentNode.classList.contains('active')).toEqual(!isWrite);
+ expect(wrapper.find('.md-preview-holder').element.style.display).toEqual(isWrite ? 'none' : '');
+}
+
+function createComponent() {
+ const wrapper = mount(fieldComponent, {
+ propsData: {
+ markdownDocsPath,
+ markdownPreviewPath,
+ },
+ slots: {
+ textarea: '<textarea>testing\n123</textarea>',
+ },
+ template: `
+ <field-component
+ markdown-preview-path="${markdownPreviewPath}"
+ markdown-docs-path="${markdownDocsPath}"
+ >
+ <textarea
+ slot="textarea"
+ v-model="text">
+ <slot>this is a test</slot>
+ </textarea>
+ </field-component>
+ `,
+ sync: false,
+ });
+ return wrapper;
+}
+
+const getPreviewLink = wrapper => wrapper.find('.nav-links .js-preview-link');
+const getWriteLink = wrapper => wrapper.find('.nav-links .js-write-link');
+const getMarkdownButton = wrapper => wrapper.find('.js-md');
+const getAllMarkdownButtons = wrapper => wrapper.findAll('.js-md');
+
+describe('Markdown field component', () => {
+ let axiosMock;
+ const localVue = createLocalVue();
+
+ beforeEach(() => {
+ axiosMock = new AxiosMockAdapter(axios);
+ });
+
+ afterEach(() => {
+ axiosMock.restore();
+ });
+
+ describe('mounted', () => {
+ let wrapper;
+ const previewHTML = '<p>markdown preview</p>';
+ let previewLink;
+ let writeLink;
+
+ it('renders textarea inside backdrop', () => {
+ wrapper = createComponent();
+ expect(wrapper.find('.zen-backdrop textarea').element).not.toBeNull();
+ });
+
+ describe('markdown preview', () => {
+ beforeEach(() => {
+ axiosMock.onPost(markdownPreviewPath).reply(200, { body: previewHTML });
+ });
+
+ it('sets preview link as active', () => {
+ wrapper = createComponent();
+ previewLink = getPreviewLink(wrapper);
+ previewLink.trigger('click');
+
+ return localVue.nextTick().then(() => {
+ expect(previewLink.element.parentNode.classList.contains('active')).toBeTruthy();
+ });
+ });
+
+ it('shows preview loading text', () => {
+ wrapper = createComponent();
+ previewLink = getPreviewLink(wrapper);
+ previewLink.trigger('click');
+
+ localVue.nextTick(() => {
+ expect(wrapper.find('.md-preview-holder').element.textContent.trim()).toContain(
+ 'Loading…',
+ );
+ });
+ });
+
+ it('renders markdown preview', () => {
+ wrapper = createComponent();
+ previewLink = getPreviewLink(wrapper);
+ previewLink.trigger('click');
+
+ setTimeout(() => {
+ expect(wrapper.find('.md-preview-holder').element.innerHTML).toContain(previewHTML);
+ });
+ });
+
+ it('renders GFM with jQuery', () => {
+ wrapper = createComponent();
+ previewLink = getPreviewLink(wrapper);
+ jest.spyOn($.fn, 'renderGFM');
+
+ previewLink.trigger('click');
+
+ setTimeout(() => {
+ expect($.fn.renderGFM).toHaveBeenCalled();
+ }, 0);
+ });
+
+ it('clicking already active write or preview link does nothing', () => {
+ wrapper = createComponent();
+ writeLink = getWriteLink(wrapper);
+ previewLink = getPreviewLink(wrapper);
+
+ writeLink.trigger('click');
+ return localVue
+ .nextTick()
+ .then(() => assertMarkdownTabs(true, writeLink, previewLink, wrapper))
+ .then(() => writeLink.trigger('click'))
+ .then(() => localVue.nextTick())
+ .then(() => assertMarkdownTabs(true, writeLink, previewLink, wrapper))
+ .then(() => previewLink.trigger('click'))
+ .then(() => localVue.nextTick())
+ .then(() => assertMarkdownTabs(false, writeLink, previewLink, wrapper))
+ .then(() => previewLink.trigger('click'))
+ .then(() => localVue.nextTick())
+ .then(() => assertMarkdownTabs(false, writeLink, previewLink, wrapper));
+ });
+ });
+
+ describe('markdown buttons', () => {
+ it('converts single words', () => {
+ wrapper = createComponent();
+ const textarea = wrapper.find('textarea').element;
+ textarea.setSelectionRange(0, 7);
+ const markdownButton = getMarkdownButton(wrapper);
+ markdownButton.trigger('click');
+
+ localVue.nextTick(() => {
+ expect(textarea.value).toContain('**testing**');
+ });
+ });
+
+ it('converts a line', () => {
+ wrapper = createComponent();
+ const textarea = wrapper.find('textarea').element;
+ textarea.setSelectionRange(0, 0);
+ const markdownButton = getAllMarkdownButtons(wrapper).wrappers[5];
+ markdownButton.trigger('click');
+
+ localVue.nextTick(() => {
+ expect(textarea.value).toContain('* testing');
+ });
+ });
+
+ it('converts multiple lines', () => {
+ wrapper = createComponent();
+ const textarea = wrapper.find('textarea').element;
+ textarea.setSelectionRange(0, 50);
+ const markdownButton = getAllMarkdownButtons(wrapper).wrappers[5];
+ markdownButton.trigger('click');
+
+ localVue.nextTick(() => {
+ expect(textarea.value).toContain('* testing\n* 123');
+ });
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/vue_shared/components/markdown/field_spec.js b/spec/javascripts/vue_shared/components/markdown/field_spec.js
deleted file mode 100644
index da984175f9f..00000000000
--- a/spec/javascripts/vue_shared/components/markdown/field_spec.js
+++ /dev/null
@@ -1,173 +0,0 @@
-import $ from 'jquery';
-import '~/behaviors/markdown/render_gfm';
-import Vue from 'vue';
-import AxiosMockAdapter from 'axios-mock-adapter';
-import axios from '~/lib/utils/axios_utils';
-import fieldComponent from '~/vue_shared/components/markdown/field.vue';
-import { TEST_HOST } from 'spec/test_constants';
-
-function assertMarkdownTabs(isWrite, writeLink, previewLink, vm) {
- expect(writeLink.parentNode.classList.contains('active')).toEqual(isWrite);
- expect(previewLink.parentNode.classList.contains('active')).toEqual(!isWrite);
- expect(vm.$el.querySelector('.md-preview-holder').style.display).toEqual(isWrite ? 'none' : '');
-}
-
-describe('Markdown field component', () => {
- const markdownPreviewPath = `${TEST_HOST}/preview`;
- const markdownDocsPath = `${TEST_HOST}/docs`;
- let axiosMock;
- let vm;
-
- beforeEach(done => {
- axiosMock = new AxiosMockAdapter(axios);
- vm = new Vue({
- components: {
- fieldComponent,
- },
- data() {
- return {
- text: 'testing\n123',
- };
- },
- template: `
- <field-component
- markdown-preview-path="${markdownPreviewPath}"
- markdown-docs-path="${markdownDocsPath}"
- >
- <textarea
- slot="textarea"
- v-model="text">
- </textarea>
- </field-component>
- `,
- }).$mount();
-
- Vue.nextTick(done);
- });
-
- afterEach(() => {
- axiosMock.restore();
- });
-
- describe('mounted', () => {
- const previewHTML = '<p>markdown preview</p>';
-
- it('renders textarea inside backdrop', () => {
- expect(vm.$el.querySelector('.zen-backdrop textarea')).not.toBeNull();
- });
-
- describe('markdown preview', () => {
- let previewLink;
- let writeLink;
-
- beforeEach(() => {
- axiosMock.onPost(markdownPreviewPath).replyOnce(200, { body: previewHTML });
-
- previewLink = vm.$el.querySelector('.nav-links .js-preview-link');
- writeLink = vm.$el.querySelector('.nav-links .js-write-link');
- });
-
- it('sets preview link as active', done => {
- previewLink.click();
-
- Vue.nextTick(() => {
- expect(previewLink.parentNode.classList.contains('active')).toBeTruthy();
-
- done();
- });
- });
-
- it('shows preview loading text', done => {
- previewLink.click();
-
- Vue.nextTick(() => {
- expect(vm.$el.querySelector('.md-preview-holder').textContent.trim()).toContain(
- 'Loading…',
- );
-
- done();
- });
- });
-
- it('renders markdown preview', done => {
- previewLink.click();
-
- setTimeout(() => {
- expect(vm.$el.querySelector('.md-preview-holder').innerHTML).toContain(previewHTML);
-
- done();
- });
- });
-
- it('renders GFM with jQuery', done => {
- spyOn($.fn, 'renderGFM');
-
- previewLink.click();
-
- setTimeout(() => {
- expect($.fn.renderGFM).toHaveBeenCalled();
-
- done();
- }, 0);
- });
-
- it('clicking already active write or preview link does nothing', done => {
- writeLink.click();
- Vue.nextTick()
- .then(() => assertMarkdownTabs(true, writeLink, previewLink, vm))
- .then(() => writeLink.click())
- .then(() => Vue.nextTick())
- .then(() => assertMarkdownTabs(true, writeLink, previewLink, vm))
- .then(() => previewLink.click())
- .then(() => Vue.nextTick())
- .then(() => assertMarkdownTabs(false, writeLink, previewLink, vm))
- .then(() => previewLink.click())
- .then(() => Vue.nextTick())
- .then(() => assertMarkdownTabs(false, writeLink, previewLink, vm))
- .then(done)
- .catch(done.fail);
- });
- });
-
- describe('markdown buttons', () => {
- it('converts single words', done => {
- const textarea = vm.$el.querySelector('textarea');
-
- textarea.setSelectionRange(0, 7);
- vm.$el.querySelector('.js-md').click();
-
- Vue.nextTick(() => {
- expect(textarea.value).toContain('**testing**');
-
- done();
- });
- });
-
- it('converts a line', done => {
- const textarea = vm.$el.querySelector('textarea');
-
- textarea.setSelectionRange(0, 0);
- vm.$el.querySelectorAll('.js-md')[5].click();
-
- Vue.nextTick(() => {
- expect(textarea.value).toContain('* testing');
-
- done();
- });
- });
-
- it('converts multiple lines', done => {
- const textarea = vm.$el.querySelector('textarea');
-
- textarea.setSelectionRange(0, 50);
- vm.$el.querySelectorAll('.js-md')[5].click();
-
- Vue.nextTick(() => {
- expect(textarea.value).toContain('* testing\n* 123');
-
- done();
- });
- });
- });
- });
-});
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index 977f1fdd267..d34919d17fe 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -199,25 +199,6 @@ describe Ci::Pipeline, :mailer do
end
end
- describe '#merge_train_pipeline?' do
- subject { pipeline.merge_train_pipeline? }
-
- let!(:pipeline) do
- create(:ci_pipeline, source: :merge_request_event, merge_request: merge_request, ref: ref, target_sha: 'xxx')
- end
-
- let(:merge_request) { create(:merge_request) }
- let(:ref) { 'refs/merge-requests/1/train' }
-
- it { is_expected.to be_truthy }
-
- context 'when ref is merge ref' do
- let(:ref) { 'refs/merge-requests/1/merge' }
-
- it { is_expected.to be_falsy }
- end
- end
-
describe '#merge_request_ref?' do
subject { pipeline.merge_request_ref? }
@@ -228,43 +209,19 @@ describe Ci::Pipeline, :mailer do
end
end
- describe '#merge_train_ref?' do
- subject { pipeline.merge_train_ref? }
-
- it 'calls Mergetrain#merge_train_ref?' do
- expect(MergeRequest).to receive(:merge_train_ref?).with(pipeline.ref)
-
- subject
- end
- end
-
describe '#merge_request_event_type' do
subject { pipeline.merge_request_event_type }
- before do
- allow(pipeline).to receive(:merge_request_event?) { true }
- end
-
- context 'when pipeline is merge train pipeline' do
- before do
- allow(pipeline).to receive(:merge_train_pipeline?) { true }
- end
-
- it { is_expected.to eq(:merge_train) }
- end
+ let(:pipeline) { merge_request.all_pipelines.last }
context 'when pipeline is merge request pipeline' do
- before do
- allow(pipeline).to receive(:merge_request_pipeline?) { true }
- end
+ let(:merge_request) { create(:merge_request, :with_merge_request_pipeline) }
it { is_expected.to eq(:merged_result) }
end
context 'when pipeline is detached merge request pipeline' do
- before do
- allow(pipeline).to receive(:detached_merge_request_pipeline?) { true }
- end
+ let(:merge_request) { create(:merge_request, :with_detached_merge_request_pipeline) }
it { is_expected.to eq(:detached) }
end