summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-10 09:08:56 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-10 09:08:56 +0000
commitb4ded0ba7b4d2cdbed5b1f331cf2083a25ee4d7c (patch)
tree6694fa9d8f3e226597cc01dfb8e3e07b50ae85b6 /spec
parent2aaef94c80937d9d188f7b9cbbad2dcd1508c3c1 (diff)
downloadgitlab-ce-b4ded0ba7b4d2cdbed5b1f331cf2083a25ee4d7c.tar.gz
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb12
-rw-r--r--spec/finders/keys_finder_spec.rb200
-rw-r--r--spec/frontend/blob/components/blob_header_viewer_switcher_spec.js109
-rw-r--r--spec/frontend/boards/components/issue_card_inner_scoped_label_spec.js (renamed from spec/javascripts/boards/components/issue_card_inner_scoped_label_spec.js)2
-rw-r--r--spec/frontend/boards/components/issue_due_date_spec.js (renamed from spec/javascripts/boards/components/issue_due_date_spec.js)0
-rw-r--r--spec/frontend/error_tracking/components/error_tracking_list_spec.js29
-rw-r--r--spec/frontend/error_tracking/store/list/mutation_spec.js25
-rw-r--r--spec/lib/banzai/filter/gollum_tags_filter_spec.rb15
-rw-r--r--spec/lib/banzai/filter/table_of_contents_tag_filter_spec.rb23
-rw-r--r--spec/lib/banzai/pipeline/full_pipeline_spec.rb31
-rw-r--r--spec/requests/api/internal/base_spec.rb6
-rw-r--r--spec/services/users/destroy_service_spec.rb9
-rw-r--r--spec/support/helpers/filter_spec_helper.rb4
13 files changed, 334 insertions, 131 deletions
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index 5fe99c0ad1d..8d9a397de9a 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -356,6 +356,18 @@ describe 'Pipeline', :js do
end
end
+ context 'test tabs' do
+ let(:pipeline) { create(:ci_pipeline, :with_test_reports, project: project) }
+
+ it 'shows badge counter in Tests tab' do
+ visit_pipeline
+ wait_for_requests
+
+ expect(pipeline.test_reports.total_count).to eq(4)
+ expect(page.find('.js-test-report-badge-counter').text).to eq(pipeline.test_reports.total_count.to_s)
+ end
+ end
+
context 'retrying jobs' do
before do
visit_pipeline
diff --git a/spec/finders/keys_finder_spec.rb b/spec/finders/keys_finder_spec.rb
index 7605d066ddf..bae4a542484 100644
--- a/spec/finders/keys_finder_spec.rb
+++ b/spec/finders/keys_finder_spec.rb
@@ -3,7 +3,7 @@
require 'spec_helper'
describe KeysFinder do
- subject { described_class.new(user, params).execute }
+ subject { described_class.new(params).execute }
let(:user) { create(:user) }
let(:params) { {} }
@@ -20,159 +20,149 @@ describe KeysFinder do
let!(:key_2) { create(:personal_key, last_used_at: nil, user: user) }
let!(:key_3) { create(:personal_key, last_used_at: 2.days.ago) }
- context 'with a regular user' do
- it 'raises GitLabAccessDeniedError' do
- expect { subject }.to raise_error(KeysFinder::GitLabAccessDeniedError)
- end
- end
+ context 'key_type' do
+ let!(:deploy_key) { create(:deploy_key) }
- context 'with an admin user' do
- let(:user) {create(:admin)}
+ context 'when `key_type` is `ssh`' do
+ before do
+ params[:key_type] = 'ssh'
+ end
+
+ it 'returns only SSH keys' do
+ expect(subject).to contain_exactly(key_1, key_2, key_3)
+ end
+ end
- context 'key_type' do
- let!(:deploy_key) { create(:deploy_key) }
+ context 'when `key_type` is not specified' do
+ it 'returns all types of keys' do
+ expect(subject).to contain_exactly(key_1, key_2, key_3, deploy_key)
+ end
+ end
+ end
- context 'when `key_type` is `ssh`' do
+ context 'fingerprint' do
+ context 'with invalid fingerprint' do
+ context 'with invalid MD5 fingerprint' do
before do
- params[:key_type] = 'ssh'
+ params[:fingerprint] = '11:11:11:11'
end
- it 'returns only SSH keys' do
- expect(subject).to contain_exactly(key_1, key_2, key_3)
+ it 'raises InvalidFingerprint' do
+ expect { subject }.to raise_error(KeysFinder::InvalidFingerprint)
end
end
- context 'when `key_type` is not specified' do
- it 'returns all types of keys' do
- expect(subject).to contain_exactly(key_1, key_2, key_3, deploy_key)
+ context 'with invalid SHA fingerprint' do
+ before do
+ params[:fingerprint] = 'nUhzNyftwAAKs7HufskYTte2g'
+ end
+
+ it 'raises InvalidFingerprint' do
+ expect { subject }.to raise_error(KeysFinder::InvalidFingerprint)
end
end
end
- context 'fingerprint' do
- context 'with invalid fingerprint' do
- context 'with invalid MD5 fingerprint' do
+ context 'with valid fingerprints' do
+ let!(:deploy_key) do
+ create(:deploy_key,
+ user: user,
+ key: 'ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt1017k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=',
+ fingerprint: '8a:4a:12:92:0b:50:47:02:d4:5a:8e:a9:44:4e:08:b4',
+ fingerprint_sha256: '4DPHOVNh53i9dHb5PpY2vjfyf5qniTx1/pBFPoZLDdk')
+ end
+
+ context 'personal key with valid MD5 params' do
+ context 'with an existent fingerprint' do
before do
- params[:fingerprint] = '11:11:11:11'
+ params[:fingerprint] = 'ba:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d1'
end
- it 'raises InvalidFingerprint' do
- expect { subject }.to raise_error(KeysFinder::InvalidFingerprint)
+ it 'returns the key' do
+ expect(subject).to eq(key_1)
+ expect(subject.user).to eq(user)
end
end
- context 'with invalid SHA fingerprint' do
+ context 'deploy key with an existent fingerprint' do
before do
- params[:fingerprint] = 'nUhzNyftwAAKs7HufskYTte2g'
+ params[:fingerprint] = '8a:4a:12:92:0b:50:47:02:d4:5a:8e:a9:44:4e:08:b4'
end
- it 'raises InvalidFingerprint' do
- expect { subject }.to raise_error(KeysFinder::InvalidFingerprint)
+ it 'returns the key' do
+ expect(subject).to eq(deploy_key)
+ expect(subject.user).to eq(user)
end
end
- end
-
- context 'with valid fingerprints' do
- let!(:deploy_key) do
- create(:deploy_key,
- user: user,
- key: 'ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt1017k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=',
- fingerprint: '8a:4a:12:92:0b:50:47:02:d4:5a:8e:a9:44:4e:08:b4',
- fingerprint_sha256: '4DPHOVNh53i9dHb5PpY2vjfyf5qniTx1/pBFPoZLDdk')
- end
-
- context 'personal key with valid MD5 params' do
- context 'with an existent fingerprint' do
- before do
- params[:fingerprint] = 'ba:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d1'
- end
- it 'returns the key' do
- expect(subject).to eq(key_1)
- expect(subject.user).to eq(user)
- end
+ context 'with a non-existent fingerprint' do
+ before do
+ params[:fingerprint] = 'bb:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d2'
end
- context 'deploy key with an existent fingerprint' do
- before do
- params[:fingerprint] = '8a:4a:12:92:0b:50:47:02:d4:5a:8e:a9:44:4e:08:b4'
- end
-
- it 'returns the key' do
- expect(subject).to eq(deploy_key)
- expect(subject.user).to eq(user)
- end
+ it 'returns nil' do
+ expect(subject).to be_nil
end
+ end
+ end
- context 'with a non-existent fingerprint' do
- before do
- params[:fingerprint] = 'bb:81:59:68:d7:6c:cd:02:02:bf:6a:9b:55:4e:af:d2'
- end
+ context 'personal key with valid SHA256 params' do
+ context 'with an existent fingerprint' do
+ before do
+ params[:fingerprint] = 'SHA256:nUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo/lCg'
+ end
- it 'returns nil' do
- expect(subject).to be_nil
- end
+ it 'returns key' do
+ expect(subject).to eq(key_1)
+ expect(subject.user).to eq(user)
end
end
- context 'personal key with valid SHA256 params' do
- context 'with an existent fingerprint' do
- before do
- params[:fingerprint] = 'SHA256:nUhzNyftwADy8AH3wFY31tAKs7HufskYTte2aXo/lCg'
- end
-
- it 'returns key' do
- expect(subject).to eq(key_1)
- expect(subject.user).to eq(user)
- end
+ context 'deploy key with an existent fingerprint' do
+ before do
+ params[:fingerprint] = 'SHA256:4DPHOVNh53i9dHb5PpY2vjfyf5qniTx1/pBFPoZLDdk'
end
- context 'deploy key with an existent fingerprint' do
- before do
- params[:fingerprint] = 'SHA256:4DPHOVNh53i9dHb5PpY2vjfyf5qniTx1/pBFPoZLDdk'
- end
-
- it 'returns key' do
- expect(subject).to eq(deploy_key)
- expect(subject.user).to eq(user)
- end
+ it 'returns key' do
+ expect(subject).to eq(deploy_key)
+ expect(subject.user).to eq(user)
end
+ end
- context 'with a non-existent fingerprint' do
- before do
- params[:fingerprint] = 'SHA256:xTjuFqftwADy8AH3wFY31tAKs7HufskYTte2aXi/mNp'
- end
+ context 'with a non-existent fingerprint' do
+ before do
+ params[:fingerprint] = 'SHA256:xTjuFqftwADy8AH3wFY31tAKs7HufskYTte2aXi/mNp'
+ end
- it 'returns nil' do
- expect(subject).to be_nil
- end
+ it 'returns nil' do
+ expect(subject).to be_nil
end
end
end
end
+ end
- context 'user' do
- context 'without user' do
- it 'contains ssh_keys of all users in the system' do
- expect(subject).to contain_exactly(key_1, key_2, key_3)
- end
+ context 'user' do
+ context 'without user' do
+ it 'contains ssh_keys of all users in the system' do
+ expect(subject).to contain_exactly(key_1, key_2, key_3)
end
+ end
- context 'with user' do
- before do
- params[:user] = user
- end
+ context 'with user' do
+ before do
+ params[:users] = user
+ end
- it 'contains ssh_keys of only the specified users' do
- expect(subject).to contain_exactly(key_1, key_2)
- end
+ it 'contains ssh_keys of only the specified users' do
+ expect(subject).to contain_exactly(key_1, key_2)
end
end
+ end
- context 'sort order' do
- it 'sorts in last_used_at_desc order' do
- expect(subject).to eq([key_3, key_1, key_2])
- end
+ context 'sort order' do
+ it 'sorts in last_used_at_desc order' do
+ expect(subject).to eq([key_3, key_1, key_2])
end
end
end
diff --git a/spec/frontend/blob/components/blob_header_viewer_switcher_spec.js b/spec/frontend/blob/components/blob_header_viewer_switcher_spec.js
new file mode 100644
index 00000000000..ff0b005f441
--- /dev/null
+++ b/spec/frontend/blob/components/blob_header_viewer_switcher_spec.js
@@ -0,0 +1,109 @@
+import { mount } from '@vue/test-utils';
+import BlobHeaderViewerSwitcher from '~/blob/components/blob_header_viewer_switcher.vue';
+import {
+ RICH_BLOB_VIEWER,
+ RICH_BLOB_VIEWER_TITLE,
+ SIMPLE_BLOB_VIEWER,
+ SIMPLE_BLOB_VIEWER_TITLE,
+} from '~/blob/components/constants';
+import { GlButtonGroup, GlButton } from '@gitlab/ui';
+import { Blob } from './mock_data';
+
+describe('Blob Header Viewer Switcher', () => {
+ let wrapper;
+
+ function createComponent(props = {}) {
+ wrapper = mount(BlobHeaderViewerSwitcher, {
+ propsData: {
+ blob: Object.assign({}, Blob, props),
+ },
+ });
+ }
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('intiialization', () => {
+ it('is initialized with rich viewer as preselected when richViewer exists', () => {
+ createComponent();
+ expect(wrapper.vm.viewer).toBe(RICH_BLOB_VIEWER);
+ });
+
+ it('is initialized with simple viewer as preselected when richViewer does not exists', () => {
+ createComponent({ richViewer: null });
+ expect(wrapper.vm.viewer).toBe(SIMPLE_BLOB_VIEWER);
+ });
+ });
+
+ describe('rendering', () => {
+ let btnGroup;
+ let buttons;
+
+ beforeEach(() => {
+ createComponent();
+ btnGroup = wrapper.find(GlButtonGroup);
+ buttons = wrapper.findAll(GlButton);
+ });
+
+ it('renders gl-button-group component', () => {
+ expect(btnGroup.exists()).toBe(true);
+ });
+
+ it('renders exactly 2 buttons with predefined actions', () => {
+ expect(buttons.length).toBe(2);
+ [SIMPLE_BLOB_VIEWER_TITLE, RICH_BLOB_VIEWER_TITLE].forEach((title, i) => {
+ expect(buttons.at(i).attributes('title')).toBe(title);
+ });
+ });
+ });
+
+ describe('viewer changes', () => {
+ let buttons;
+ let simpleBtn;
+ let richBtn;
+
+ beforeEach(() => {
+ createComponent();
+ buttons = wrapper.findAll(GlButton);
+ simpleBtn = buttons.at(0);
+ richBtn = buttons.at(1);
+ });
+
+ it('does not switch the viewer if the selected one is already active', () => {
+ jest.spyOn(wrapper.vm, '$emit');
+
+ expect(wrapper.vm.viewer).toBe(RICH_BLOB_VIEWER);
+ richBtn.vm.$emit('click');
+ expect(wrapper.vm.viewer).toBe(RICH_BLOB_VIEWER);
+ expect(wrapper.vm.$emit).not.toHaveBeenCalled();
+ });
+
+ it('emits an event when a Simple Viewer button is clicked', () => {
+ jest.spyOn(wrapper.vm, '$emit');
+
+ simpleBtn.vm.$emit('click');
+
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.vm.viewer).toBe(SIMPLE_BLOB_VIEWER);
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('switch-viewer', SIMPLE_BLOB_VIEWER);
+ });
+ });
+
+ it('emits an event when a Rich Viewer button is clicked', () => {
+ jest.spyOn(wrapper.vm, '$emit');
+
+ wrapper.setData({ viewer: SIMPLE_BLOB_VIEWER });
+
+ return wrapper.vm
+ .$nextTick()
+ .then(() => {
+ richBtn.vm.$emit('click');
+ })
+ .then(() => {
+ expect(wrapper.vm.viewer).toBe(RICH_BLOB_VIEWER);
+ expect(wrapper.vm.$emit).toHaveBeenCalledWith('switch-viewer', RICH_BLOB_VIEWER);
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/boards/components/issue_card_inner_scoped_label_spec.js b/spec/frontend/boards/components/issue_card_inner_scoped_label_spec.js
index 6ac51ebdb2d..7389cb14ecb 100644
--- a/spec/javascripts/boards/components/issue_card_inner_scoped_label_spec.js
+++ b/spec/frontend/boards/components/issue_card_inner_scoped_label_spec.js
@@ -1,5 +1,5 @@
import Vue from 'vue';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
+import mountComponent from 'helpers/vue_mount_component_helper';
import IssueCardInnerScopedLabel from '~/boards/components/issue_card_inner_scoped_label.vue';
describe('IssueCardInnerScopedLabel Component', () => {
diff --git a/spec/javascripts/boards/components/issue_due_date_spec.js b/spec/frontend/boards/components/issue_due_date_spec.js
index 68e26b68f04..68e26b68f04 100644
--- a/spec/javascripts/boards/components/issue_due_date_spec.js
+++ b/spec/frontend/boards/components/issue_due_date_spec.js
diff --git a/spec/frontend/error_tracking/components/error_tracking_list_spec.js b/spec/frontend/error_tracking/components/error_tracking_list_spec.js
index 9cf73d54d9b..b632b461eb9 100644
--- a/spec/frontend/error_tracking/components/error_tracking_list_spec.js
+++ b/spec/frontend/error_tracking/components/error_tracking_list_spec.js
@@ -62,6 +62,7 @@ describe('ErrorTrackingList', () => {
sortByField: jest.fn(),
fetchPaginatedResults: jest.fn(),
updateStatus: jest.fn(),
+ removeIgnoredResolvedErrors: jest.fn(),
};
const state = {
@@ -221,6 +222,8 @@ describe('ErrorTrackingList', () => {
});
describe('When the ignore button on an error is clicked', () => {
+ const ignoreErrorButton = () => wrapper.find({ ref: 'ignoreError' });
+
beforeEach(() => {
store.state.list.loading = false;
store.state.list.errors = errorsList;
@@ -235,20 +238,30 @@ describe('ErrorTrackingList', () => {
});
it('sends the "ignored" status and error ID', () => {
- wrapper.find({ ref: 'ignoreError' }).trigger('click');
+ ignoreErrorButton().trigger('click');
expect(actions.updateStatus).toHaveBeenCalledWith(
expect.anything(),
{
endpoint: `/project/test/-/error_tracking/${errorsList[0].id}.json`,
- redirectUrl: '/error_tracking',
status: 'ignored',
},
undefined,
);
});
+
+ it('calls an action to remove the item from the list', () => {
+ ignoreErrorButton().trigger('click');
+ expect(actions.removeIgnoredResolvedErrors).toHaveBeenCalledWith(
+ expect.anything(),
+ '1',
+ undefined,
+ );
+ });
});
describe('When the resolve button on an error is clicked', () => {
+ const resolveErrorButton = () => wrapper.find({ ref: 'resolveError' });
+
beforeEach(() => {
store.state.list.loading = false;
store.state.list.errors = errorsList;
@@ -263,17 +276,25 @@ describe('ErrorTrackingList', () => {
});
it('sends "resolved" status and error ID', () => {
- wrapper.find({ ref: 'resolveError' }).trigger('click');
+ resolveErrorButton().trigger('click');
expect(actions.updateStatus).toHaveBeenCalledWith(
expect.anything(),
{
endpoint: `/project/test/-/error_tracking/${errorsList[0].id}.json`,
- redirectUrl: '/error_tracking',
status: 'resolved',
},
undefined,
);
});
+
+ it('calls an action to remove the item from the list', () => {
+ resolveErrorButton().trigger('click');
+ expect(actions.removeIgnoredResolvedErrors).toHaveBeenCalledWith(
+ expect.anything(),
+ '1',
+ undefined,
+ );
+ });
});
describe('When error tracking is disabled and user is not allowed to enable it', () => {
diff --git a/spec/frontend/error_tracking/store/list/mutation_spec.js b/spec/frontend/error_tracking/store/list/mutation_spec.js
index 44a75b6aa1f..65f11aeeda1 100644
--- a/spec/frontend/error_tracking/store/list/mutation_spec.js
+++ b/spec/frontend/error_tracking/store/list/mutation_spec.js
@@ -5,6 +5,7 @@ import * as types from '~/error_tracking/store/list/mutation_types';
const ADD_RECENT_SEARCH = mutations[types.ADD_RECENT_SEARCH];
const CLEAR_RECENT_SEARCHES = mutations[types.CLEAR_RECENT_SEARCHES];
const LOAD_RECENT_SEARCHES = mutations[types.LOAD_RECENT_SEARCHES];
+const REMOVE_IGNORED_RESOLVED_ERRORS = mutations[types.REMOVE_IGNORED_RESOLVED_ERRORS];
describe('Error tracking mutations', () => {
describe('SET_ERRORS', () => {
@@ -114,5 +115,29 @@ describe('Error tracking mutations', () => {
expect(localStorage.getItem).toHaveBeenCalledWith('recent-searches/project/errors.json');
});
});
+
+ describe('REMOVE_IGNORED_RESOLVED_ERRORS', () => {
+ it('removes ignored or resolved errors from list', () => {
+ state.errors = [
+ {
+ id: 1,
+ status: 'unresolved',
+ },
+ {
+ id: 2,
+ status: 'ignored',
+ },
+ {
+ id: 3,
+ status: 'unresolved',
+ },
+ ];
+ const ignoredError = state.errors[2].id;
+
+ REMOVE_IGNORED_RESOLVED_ERRORS(state, ignoredError);
+
+ expect(state.errors).not.toContain(ignoredError);
+ });
+ });
});
});
diff --git a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
index 9d179ef2a49..1580177eaad 100644
--- a/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
+++ b/spec/lib/banzai/filter/gollum_tags_filter_spec.rb
@@ -100,19 +100,4 @@ describe Banzai::Filter::GollumTagsFilter do
expect(doc.at_css('code').text).to eq '[[link-in-backticks]]'
end
end
-
- context 'table of contents' do
- it 'replaces [[<em>TOC</em>]] with ToC result' do
- doc = described_class.call("<p>[[<em>TOC</em>]]</p>", { project_wiki: project_wiki }, { toc: "FOO" })
-
- expect(doc.to_html).to eq("FOO")
- end
-
- it 'handles an empty ToC result' do
- input = "<p>[[<em>TOC</em>]]</p>"
- doc = described_class.call(input, project_wiki: project_wiki)
-
- expect(doc.to_html).to eq ''
- end
- end
end
diff --git a/spec/lib/banzai/filter/table_of_contents_tag_filter_spec.rb b/spec/lib/banzai/filter/table_of_contents_tag_filter_spec.rb
new file mode 100644
index 00000000000..20f32d7347d
--- /dev/null
+++ b/spec/lib/banzai/filter/table_of_contents_tag_filter_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Banzai::Filter::TableOfContentsTagFilter do
+ include FilterSpecHelper
+
+ context 'table of contents' do
+ let(:html) { '<p>[[<em>TOC</em>]]</p>' }
+
+ it 'replaces [[<em>TOC</em>]] with ToC result' do
+ doc = filter(html, {}, { toc: "FOO" })
+
+ expect(doc.to_html).to eq("FOO")
+ end
+
+ it 'handles an empty ToC result' do
+ doc = filter(html)
+
+ expect(doc.to_html).to eq ''
+ end
+ end
+end
diff --git a/spec/lib/banzai/pipeline/full_pipeline_spec.rb b/spec/lib/banzai/pipeline/full_pipeline_spec.rb
index f63b86d1451..4fa39da3eb4 100644
--- a/spec/lib/banzai/pipeline/full_pipeline_spec.rb
+++ b/spec/lib/banzai/pipeline/full_pipeline_spec.rb
@@ -99,4 +99,35 @@ describe Banzai::Pipeline::FullPipeline do
end
end
end
+
+ describe 'table of contents' do
+ let(:project) { create(:project, :public) }
+ let(:markdown) do
+ <<-MARKDOWN.strip_heredoc
+ [[_TOC_]]
+
+ # Header
+ MARKDOWN
+ end
+ let(:invalid_markdown) do
+ <<-MARKDOWN.strip_heredoc
+ test [[_TOC_]]
+
+ # Header
+ MARKDOWN
+ end
+
+ it 'inserts a table of contents' do
+ output = described_class.to_html(markdown, project: project)
+
+ expect(output).to include("<ul class=\"section-nav\">")
+ expect(output).to include("<li><a href=\"#header\">Header</a></li>")
+ end
+
+ it 'does not insert a table of contents' do
+ output = described_class.to_html(invalid_markdown, project: project)
+
+ expect(output).to include("test [[<em>TOC</em>]]")
+ end
+ end
end
diff --git a/spec/requests/api/internal/base_spec.rb b/spec/requests/api/internal/base_spec.rb
index cb10bebfd98..677ea071012 100644
--- a/spec/requests/api/internal/base_spec.rb
+++ b/spec/requests/api/internal/base_spec.rb
@@ -326,7 +326,7 @@ describe API::Internal::Base do
expect(json_response["gitaly"]["repository"]["relative_path"]).to eq(project.repository.gitaly_repository.relative_path)
expect(json_response["gitaly"]["address"]).to eq(Gitlab::GitalyClient.address(project.repository_storage))
expect(json_response["gitaly"]["token"]).to eq(Gitlab::GitalyClient.token(project.repository_storage))
- expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-cache-invalidator' => 'true', 'gitaly-feature-commit-without-batch-check' => 'true', 'gitaly-feature-use-core-delta-islands' => 'true')
+ expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-cache-invalidator' => 'true', 'gitaly-feature-commit-without-batch-check' => 'true', 'gitaly-feature-use-core-delta-islands' => 'true', 'gitaly-feature-use-git-protocol-v2' => 'true')
expect(user.reload.last_activity_on).to eql(Date.today)
end
end
@@ -346,7 +346,7 @@ describe API::Internal::Base do
expect(json_response["gitaly"]["repository"]["relative_path"]).to eq(project.repository.gitaly_repository.relative_path)
expect(json_response["gitaly"]["address"]).to eq(Gitlab::GitalyClient.address(project.repository_storage))
expect(json_response["gitaly"]["token"]).to eq(Gitlab::GitalyClient.token(project.repository_storage))
- expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-cache-invalidator' => 'true', 'gitaly-feature-commit-without-batch-check' => 'true', 'gitaly-feature-use-core-delta-islands' => 'true')
+ expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-cache-invalidator' => 'true', 'gitaly-feature-commit-without-batch-check' => 'true', 'gitaly-feature-use-core-delta-islands' => 'true', 'gitaly-feature-use-git-protocol-v2' => 'true')
expect(user.reload.last_activity_on).to be_nil
end
end
@@ -594,7 +594,7 @@ describe API::Internal::Base do
expect(json_response["gitaly"]["repository"]["relative_path"]).to eq(project.repository.gitaly_repository.relative_path)
expect(json_response["gitaly"]["address"]).to eq(Gitlab::GitalyClient.address(project.repository_storage))
expect(json_response["gitaly"]["token"]).to eq(Gitlab::GitalyClient.token(project.repository_storage))
- expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-cache-invalidator' => 'true', 'gitaly-feature-commit-without-batch-check' => 'true', 'gitaly-feature-use-core-delta-islands' => 'true')
+ expect(json_response["gitaly"]["features"]).to eq('gitaly-feature-inforef-uploadpack-cache' => 'true', 'gitaly-feature-cache-invalidator' => 'true', 'gitaly-feature-commit-without-batch-check' => 'true', 'gitaly-feature-use-core-delta-islands' => 'true', 'gitaly-feature-use-git-protocol-v2' => 'true')
end
end
diff --git a/spec/services/users/destroy_service_spec.rb b/spec/services/users/destroy_service_spec.rb
index d9335cef5cc..f972fb4c5b9 100644
--- a/spec/services/users/destroy_service_spec.rb
+++ b/spec/services/users/destroy_service_spec.rb
@@ -121,10 +121,17 @@ describe Users::DestroyService do
before do
solo_owned.group_members = [member]
- service.execute(user)
+ end
+
+ it 'returns the user with attached errors' do
+ expect(service.execute(user)).to be(user)
+ expect(user.errors.full_messages).to eq([
+ 'You must transfer ownership or delete groups before you can remove user'
+ ])
end
it 'does not delete the user' do
+ service.execute(user)
expect(User.find(user.id)).to eq user
end
end
diff --git a/spec/support/helpers/filter_spec_helper.rb b/spec/support/helpers/filter_spec_helper.rb
index e27b0de2497..c165128040f 100644
--- a/spec/support/helpers/filter_spec_helper.rb
+++ b/spec/support/helpers/filter_spec_helper.rb
@@ -15,7 +15,7 @@ module FilterSpecHelper
# context - Hash context for the filter. (default: {project: project})
#
# Returns a Nokogiri::XML::DocumentFragment
- def filter(html, context = {})
+ def filter(html, context = {}, result = nil)
if defined?(project)
context.reverse_merge!(project: project)
end
@@ -25,7 +25,7 @@ module FilterSpecHelper
context = context.merge(render_context: render_context)
- described_class.call(html, context)
+ described_class.call(html, context, result)
end
# Get an instance of the Filter class