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>2020-04-28 15:09:44 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-04-28 15:09:44 +0300
commitc74b7b5e4345702a1d59c72d923c3580ef157a59 (patch)
tree0d6cc261341fa36babe44e497dc26153da611b7b /spec
parent0f59ad0c29c8679957c716317c842f606177f223 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/wikis_controller_spec.rb5
-rw-r--r--spec/features/projects/environments_pod_logs_spec.rb2
-rw-r--r--spec/features/projects/pipelines/pipeline_spec.rb21
-rw-r--r--spec/features/projects/serverless/functions_spec.rb2
-rw-r--r--spec/features/projects/wiki/user_creates_wiki_page_spec.rb27
-rw-r--r--spec/frontend/broadcast_notification_spec.js35
-rw-r--r--spec/frontend/reports/accessibility_report/grouped_accessibility_reports_app_spec.js133
-rw-r--r--spec/frontend/reports/accessibility_report/store/actions_spec.js16
-rw-r--r--spec/frontend/reports/accessibility_report/store/getters_spec.js157
-rw-r--r--spec/frontend/reports/accessibility_report/store/mutations_spec.js14
-rw-r--r--spec/lib/gitlab/diff/file_spec.rb55
-rw-r--r--spec/models/ci/pipeline_spec.rb38
-rw-r--r--spec/support/capybara.rb11
-rw-r--r--spec/support/kubeclient.rb10
-rw-r--r--spec/support/shared_examples/models/wiki_shared_examples.rb38
-rw-r--r--spec/support/webmock.rb18
16 files changed, 559 insertions, 23 deletions
diff --git a/spec/controllers/projects/wikis_controller_spec.rb b/spec/controllers/projects/wikis_controller_spec.rb
index edfabb2a1c1..b4bbf76ce18 100644
--- a/spec/controllers/projects/wikis_controller_spec.rb
+++ b/spec/controllers/projects/wikis_controller_spec.rb
@@ -98,13 +98,12 @@ describe Projects::WikisController do
let(:id) { wiki_title }
it 'limits the retrieved pages for the sidebar' do
- expect(controller).to receive(:load_wiki).and_return(project_wiki)
- expect(project_wiki).to receive(:list_pages).with(limit: 15).and_call_original
-
subject
expect(response).to have_gitlab_http_status(:ok)
expect(assigns(:page).title).to eq(wiki_title)
+ expect(assigns(:sidebar_wiki_entries)).to contain_exactly(an_instance_of(WikiPage))
+ expect(assigns(:sidebar_limited)).to be(false)
end
context 'when page content encoding is invalid' do
diff --git a/spec/features/projects/environments_pod_logs_spec.rb b/spec/features/projects/environments_pod_logs_spec.rb
index a51f121bf59..32eaf690950 100644
--- a/spec/features/projects/environments_pod_logs_spec.rb
+++ b/spec/features/projects/environments_pod_logs_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe 'Environment > Pod Logs', :js do
+describe 'Environment > Pod Logs', :js, :kubeclient do
include KubernetesHelpers
let(:pod_names) { %w(kube-pod) }
diff --git a/spec/features/projects/pipelines/pipeline_spec.rb b/spec/features/projects/pipelines/pipeline_spec.rb
index e8846b5b617..aad57bd9b16 100644
--- a/spec/features/projects/pipelines/pipeline_spec.rb
+++ b/spec/features/projects/pipelines/pipeline_spec.rb
@@ -19,32 +19,32 @@ describe 'Pipeline', :js do
shared_context 'pipeline builds' do
let!(:build_passed) do
create(:ci_build, :success,
- pipeline: pipeline, stage: 'build', name: 'build')
+ pipeline: pipeline, stage: 'build', stage_idx: 0, name: 'build')
end
let!(:build_failed) do
create(:ci_build, :failed,
- pipeline: pipeline, stage: 'test', name: 'test')
+ pipeline: pipeline, stage: 'test', stage_idx: 1, name: 'test')
end
let!(:build_preparing) do
create(:ci_build, :preparing,
- pipeline: pipeline, stage: 'deploy', name: 'prepare')
+ pipeline: pipeline, stage: 'deploy', stage_idx: 2, name: 'prepare')
end
let!(:build_running) do
create(:ci_build, :running,
- pipeline: pipeline, stage: 'deploy', name: 'deploy')
+ pipeline: pipeline, stage: 'deploy', stage_idx: 3, name: 'deploy')
end
let!(:build_manual) do
create(:ci_build, :manual,
- pipeline: pipeline, stage: 'deploy', name: 'manual-build')
+ pipeline: pipeline, stage: 'deploy', stage_idx: 3, name: 'manual-build')
end
let!(:build_scheduled) do
create(:ci_build, :scheduled,
- pipeline: pipeline, stage: 'deploy', name: 'delayed-job')
+ pipeline: pipeline, stage: 'deploy', stage_idx: 3, name: 'delayed-job')
end
let!(:build_external) do
@@ -307,9 +307,12 @@ describe 'Pipeline', :js do
context 'when the pipeline has manual stage' do
before do
- create(:ci_build, :manual, pipeline: pipeline, stage: 'publish', name: 'CentOS')
- create(:ci_build, :manual, pipeline: pipeline, stage: 'publish', name: 'Debian')
- create(:ci_build, :manual, pipeline: pipeline, stage: 'publish', name: 'OpenSUDE')
+ create(:ci_build, :manual, pipeline: pipeline, stage_idx: 10, stage: 'publish', name: 'CentOS')
+ create(:ci_build, :manual, pipeline: pipeline, stage_idx: 10, stage: 'publish', name: 'Debian')
+ create(:ci_build, :manual, pipeline: pipeline, stage_idx: 10, stage: 'publish', name: 'OpenSUDE')
+
+ # force to update stages statuses
+ Ci::ProcessPipelineService.new(pipeline).execute
visit_pipeline
end
diff --git a/spec/features/projects/serverless/functions_spec.rb b/spec/features/projects/serverless/functions_spec.rb
index e494a0e9626..4c89af29339 100644
--- a/spec/features/projects/serverless/functions_spec.rb
+++ b/spec/features/projects/serverless/functions_spec.rb
@@ -40,7 +40,7 @@ describe 'Functions', :js do
it_behaves_like "it's missing knative installation"
end
- context 'when the user has a cluster and knative installed and visits the serverless page' do
+ context 'when the user has a cluster and knative installed and visits the serverless page', :kubeclient do
let(:cluster) { create(:cluster, :project, :provided_by_gcp, projects: [project]) }
let(:service) { cluster.platform_kubernetes }
let(:environment) { create(:environment, project: project) }
diff --git a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
index fa737f3b57d..5678ebcb72a 100644
--- a/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
+++ b/spec/features/projects/wiki/user_creates_wiki_page_spec.rb
@@ -312,6 +312,7 @@ describe "User creates wiki page" do
visit(project_wikis_path(project))
expect(page).to have_content('another')
+ expect(page).not_to have_link('View All Pages')
end
context 'when there is a customized sidebar' do
@@ -328,17 +329,31 @@ describe "User creates wiki page" do
end
end
- context 'when there are more than 15 existing pages' do
+ context 'when there are 15 existing pages' do
before do
- create(:wiki_page, wiki: wiki, title: 'home', content: 'home')
- (1..14).each { |i| create(:wiki_page, wiki: wiki, title: "page-#{i}", content: "page #{i}") }
+ (1..5).each { |i| create(:wiki_page, wiki: wiki, title: "my page #{i}") }
+ (6..10).each { |i| create(:wiki_page, wiki: wiki, title: "parent/my page #{i}") }
+ (11..15).each { |i| create(:wiki_page, wiki: wiki, title: "grandparent/parent/my page #{i}") }
end
- it 'renders a default sidebar when there is no customized sidebar' do
+ it 'shows all pages in the sidebar' do
visit(project_wikis_path(project))
- expect(page).to have_content('View All Pages')
- expect(page).to have_content('page 1')
+ (1..15).each { |i| expect(page).to have_content("my page #{i}") }
+ expect(page).not_to have_link('View All Pages')
+ end
+
+ context 'when there are more than 15 existing pages' do
+ before do
+ create(:wiki_page, wiki: wiki, title: 'my page 16')
+ end
+
+ it 'shows the first 15 pages in the sidebar' do
+ visit(project_wikis_path(project))
+
+ expect(page).to have_text('my page', count: 15)
+ expect(page).to have_link('View All Pages')
+ end
end
end
end
diff --git a/spec/frontend/broadcast_notification_spec.js b/spec/frontend/broadcast_notification_spec.js
new file mode 100644
index 00000000000..8d433946632
--- /dev/null
+++ b/spec/frontend/broadcast_notification_spec.js
@@ -0,0 +1,35 @@
+import Cookies from 'js-cookie';
+import initBroadcastNotifications from '~/broadcast_notification';
+
+describe('broadcast message on dismiss', () => {
+ const dismiss = () => {
+ const button = document.querySelector('.js-dismiss-current-broadcast-notification');
+ button.click();
+ };
+ const endsAt = '2020-01-01T00:00:00Z';
+
+ beforeEach(() => {
+ setFixtures(`
+ <div class="js-broadcast-notification-1">
+ <button class="js-dismiss-current-broadcast-notification" data-id="1" data-expire-date="${endsAt}"></button>
+ </div>
+ `);
+
+ initBroadcastNotifications();
+ });
+
+ it('removes broadcast message', () => {
+ dismiss();
+
+ expect(document.querySelector('.js-broadcast-notification-1')).toBeNull();
+ });
+
+ it('calls Cookies.set', () => {
+ jest.spyOn(Cookies, 'set');
+ dismiss();
+
+ expect(Cookies.set).toHaveBeenCalledWith('hide_broadcast_message_1', true, {
+ expires: new Date(endsAt),
+ });
+ });
+});
diff --git a/spec/frontend/reports/accessibility_report/grouped_accessibility_reports_app_spec.js b/spec/frontend/reports/accessibility_report/grouped_accessibility_reports_app_spec.js
new file mode 100644
index 00000000000..3336b696e5a
--- /dev/null
+++ b/spec/frontend/reports/accessibility_report/grouped_accessibility_reports_app_spec.js
@@ -0,0 +1,133 @@
+import { mount, createLocalVue } from '@vue/test-utils';
+import Vuex from 'vuex';
+import GroupedAccessibilityReportsApp from '~/reports/accessibility_report/grouped_accessibility_reports_app.vue';
+import AccessibilityIssueBody from '~/reports/accessibility_report/components/accessibility_issue_body.vue';
+import store from '~/reports/accessibility_report/store';
+import { comparedReportResult } from './mock_data';
+
+const localVue = createLocalVue();
+localVue.use(Vuex);
+
+describe('Grouped accessibility reports app', () => {
+ const Component = localVue.extend(GroupedAccessibilityReportsApp);
+ let wrapper;
+ let mockStore;
+
+ const mountComponent = () => {
+ wrapper = mount(Component, {
+ store: mockStore,
+ localVue,
+ propsData: {
+ baseEndpoint: 'base_endpoint.json',
+ headEndpoint: 'head_endpoint.json',
+ },
+ methods: {
+ fetchReport: () => {},
+ },
+ });
+ };
+
+ const findHeader = () => wrapper.find('[data-testid="report-section-code-text"]');
+
+ beforeEach(() => {
+ mockStore = store();
+ mountComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('while loading', () => {
+ beforeEach(() => {
+ mockStore.state.isLoading = true;
+ mountComponent();
+ });
+
+ it('renders loading state', () => {
+ expect(findHeader().text()).toEqual('Accessibility scanning results are being parsed');
+ });
+ });
+
+ describe('with error', () => {
+ beforeEach(() => {
+ mockStore.state.isLoading = false;
+ mockStore.state.hasError = true;
+ mountComponent();
+ });
+
+ it('renders error state', () => {
+ expect(findHeader().text()).toEqual('Accessibility scanning failed loading results');
+ });
+ });
+
+ describe('with a report', () => {
+ describe('with no issues', () => {
+ beforeEach(() => {
+ mockStore.state.report = {
+ summary: {
+ errors: 0,
+ warnings: 0,
+ },
+ };
+ });
+
+ it('renders no issues header', () => {
+ expect(findHeader().text()).toContain(
+ 'Accessibility scanning detected no issues for the source branch only',
+ );
+ });
+ });
+
+ describe('with one issue', () => {
+ beforeEach(() => {
+ mockStore.state.report = {
+ summary: {
+ errors: 0,
+ warnings: 1,
+ },
+ };
+ });
+
+ it('renders one issue header', () => {
+ expect(findHeader().text()).toContain(
+ 'Accessibility scanning detected 1 issue for the source branch only',
+ );
+ });
+ });
+
+ describe('with multiple issues', () => {
+ beforeEach(() => {
+ mockStore.state.report = {
+ summary: {
+ errors: 1,
+ warnings: 1,
+ },
+ };
+ });
+
+ it('renders multiple issues header', () => {
+ expect(findHeader().text()).toContain(
+ 'Accessibility scanning detected 2 issues for the source branch only',
+ );
+ });
+ });
+
+ describe('with issues to show', () => {
+ beforeEach(() => {
+ mockStore.state.report = comparedReportResult;
+ });
+
+ it('renders custom accessibility issue body', () => {
+ const issueBody = wrapper.find(AccessibilityIssueBody);
+
+ expect(issueBody.props('issue').name).toEqual(comparedReportResult.new_errors[0].name);
+ expect(issueBody.props('issue').code).toEqual(comparedReportResult.new_errors[0].code);
+ expect(issueBody.props('issue').message).toEqual(
+ comparedReportResult.new_errors[0].message,
+ );
+ expect(issueBody.props('isNew')).toEqual(true);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/reports/accessibility_report/store/actions_spec.js b/spec/frontend/reports/accessibility_report/store/actions_spec.js
index 4e156cd6736..d8fbb030a62 100644
--- a/spec/frontend/reports/accessibility_report/store/actions_spec.js
+++ b/spec/frontend/reports/accessibility_report/store/actions_spec.js
@@ -16,6 +16,22 @@ describe('Accessibility Reports actions', () => {
localState = localStore.state;
});
+ describe('setEndpoints', () => {
+ it('should commit SET_ENDPOINTS mutation', done => {
+ const baseEndpoint = 'base_endpoint.json';
+ const headEndpoint = 'head_endpoint.json';
+
+ testAction(
+ actions.setEndpoints,
+ { baseEndpoint, headEndpoint },
+ localState,
+ [{ type: types.SET_ENDPOINTS, payload: { baseEndpoint, headEndpoint } }],
+ [],
+ done,
+ );
+ });
+ });
+
describe('fetchReport', () => {
let mock;
diff --git a/spec/frontend/reports/accessibility_report/store/getters_spec.js b/spec/frontend/reports/accessibility_report/store/getters_spec.js
new file mode 100644
index 00000000000..3f267f73504
--- /dev/null
+++ b/spec/frontend/reports/accessibility_report/store/getters_spec.js
@@ -0,0 +1,157 @@
+import * as getters from '~/reports/accessibility_report/store/getters';
+import createStore from '~/reports/accessibility_report/store';
+import { LOADING, ERROR, SUCCESS, STATUS_FAILED } from '~/reports/constants';
+
+describe('Accessibility reports store getters', () => {
+ let localState;
+ let localStore;
+
+ beforeEach(() => {
+ localStore = createStore();
+ localState = localStore.state;
+ });
+
+ describe('summaryStatus', () => {
+ describe('when summary is loading', () => {
+ it('returns loading status', () => {
+ localState.isLoading = true;
+
+ expect(getters.summaryStatus(localState)).toEqual(LOADING);
+ });
+ });
+
+ describe('when summary has error', () => {
+ it('returns error status', () => {
+ localState.hasError = true;
+
+ expect(getters.summaryStatus(localState)).toEqual(ERROR);
+ });
+ });
+
+ describe('when summary has failed status', () => {
+ it('returns loading status', () => {
+ localState.status = STATUS_FAILED;
+
+ expect(getters.summaryStatus(localState)).toEqual(ERROR);
+ });
+ });
+
+ describe('when summary has successfully loaded', () => {
+ it('returns loading status', () => {
+ expect(getters.summaryStatus(localState)).toEqual(SUCCESS);
+ });
+ });
+ });
+
+ describe('groupedSummaryText', () => {
+ describe('when state is loading', () => {
+ it('returns the loading summary message', () => {
+ localState.isLoading = true;
+ const result = 'Accessibility scanning results are being parsed';
+
+ expect(getters.groupedSummaryText(localState)).toEqual(result);
+ });
+ });
+
+ describe('when state has error', () => {
+ it('returns the error summary message', () => {
+ localState.hasError = true;
+ const result = 'Accessibility scanning failed loading results';
+
+ expect(getters.groupedSummaryText(localState)).toEqual(result);
+ });
+ });
+
+ describe('when state has successfully loaded', () => {
+ describe('when report has errors', () => {
+ it('returns summary message containing number of errors', () => {
+ localState.report = {
+ summary: {
+ errors: 1,
+ warnings: 1,
+ },
+ };
+ const result = 'Accessibility scanning detected 2 issues for the source branch only';
+
+ expect(getters.groupedSummaryText(localState)).toEqual(result);
+ });
+ });
+
+ describe('when report has no errors', () => {
+ it('returns summary message containing no errors', () => {
+ localState.report = {
+ summary: {
+ errors: 0,
+ warnings: 0,
+ },
+ };
+ const result = 'Accessibility scanning detected no issues for the source branch only';
+
+ expect(getters.groupedSummaryText(localState)).toEqual(result);
+ });
+ });
+ });
+ });
+
+ describe('shouldRenderIssuesList', () => {
+ describe('when has issues to render', () => {
+ it('returns true', () => {
+ localState.report = {
+ existing_errors: [{ name: 'Issue' }],
+ };
+
+ expect(getters.shouldRenderIssuesList(localState)).toEqual(true);
+ });
+ });
+
+ describe('when does not have issues to render', () => {
+ it('returns false', () => {
+ localState.report = {
+ status: 'success',
+ summary: { errors: 0, warnings: 0 },
+ };
+
+ expect(getters.shouldRenderIssuesList(localState)).toEqual(false);
+ });
+ });
+ });
+
+ describe('unresolvedIssues', () => {
+ it('returns concatenated array of unresolved errors, warnings, and notes', () => {
+ localState.report = {
+ existing_errors: [1],
+ existing_warnings: [2],
+ existing_notes: [3],
+ };
+ const result = [1, 2, 3];
+
+ expect(getters.unresolvedIssues(localState)).toEqual(result);
+ });
+ });
+
+ describe('resolvedIssues', () => {
+ it('returns concatenated array of resolved errors, warnings, and notes', () => {
+ localState.report = {
+ resolved_errors: [1],
+ resolved_warnings: [2],
+ resolved_notes: [3],
+ };
+ const result = [1, 2, 3];
+
+ expect(getters.resolvedIssues(localState)).toEqual(result);
+ });
+ });
+
+ describe('newIssues', () => {
+ it('returns concatenated array of new errors, warnings, and notes', () => {
+ localState.report = {
+ new_errors: [1],
+ new_warnings: [2],
+ new_notes: [3],
+ };
+ const result = [1, 2, 3];
+
+ expect(getters.newIssues(localState)).toEqual(result);
+ });
+ });
+});
diff --git a/spec/frontend/reports/accessibility_report/store/mutations_spec.js b/spec/frontend/reports/accessibility_report/store/mutations_spec.js
index 88e3d1f7e16..13a1ae2f545 100644
--- a/spec/frontend/reports/accessibility_report/store/mutations_spec.js
+++ b/spec/frontend/reports/accessibility_report/store/mutations_spec.js
@@ -10,6 +10,20 @@ describe('Accessibility Reports mutations', () => {
localState = localStore.state;
});
+ describe('SET_ENDPOINTS', () => {
+ it('sets base and head endpoints to give values', () => {
+ const baseEndpoint = 'base_endpoint.json';
+ const headEndpoint = 'head_endpoint.json';
+ mutations.SET_ENDPOINTS(localState, {
+ baseEndpoint,
+ headEndpoint,
+ });
+
+ expect(localState.baseEndpoint).toEqual(baseEndpoint);
+ expect(localState.headEndpoint).toEqual(headEndpoint);
+ });
+ });
+
describe('REQUEST_REPORT', () => {
it('sets isLoading to true', () => {
mutations.REQUEST_REPORT(localState);
diff --git a/spec/lib/gitlab/diff/file_spec.rb b/spec/lib/gitlab/diff/file_spec.rb
index 61d7400b95e..d1592e60d3d 100644
--- a/spec/lib/gitlab/diff/file_spec.rb
+++ b/spec/lib/gitlab/diff/file_spec.rb
@@ -567,6 +567,61 @@ describe Gitlab::Diff::File do
end
end
+ describe '#alternate_viewer' do
+ subject { diff_file.alternate_viewer }
+
+ where(:viewer_class) do
+ [
+ DiffViewer::Image,
+ DiffViewer::Collapsed,
+ DiffViewer::NotDiffable,
+ DiffViewer::Text,
+ DiffViewer::NoPreview,
+ DiffViewer::Added,
+ DiffViewer::Deleted,
+ DiffViewer::ModeChanged,
+ DiffViewer::ModeChanged,
+ DiffViewer::NoPreview
+ ]
+ end
+
+ with_them do
+ let(:viewer) { viewer_class.new(diff_file) }
+
+ before do
+ allow(diff_file).to receive(:viewer).and_return(viewer)
+ end
+
+ it { is_expected.to be_nil }
+ end
+
+ context 'when viewer is DiffViewer::Renamed' do
+ let(:viewer) { DiffViewer::Renamed.new(diff_file) }
+
+ before do
+ allow(diff_file).to receive(:viewer).and_return(viewer)
+ end
+
+ context 'when it can be rendered as text' do
+ it { is_expected.to be_a(DiffViewer::Text) }
+ end
+
+ context 'when it can be rendered as image' do
+ let(:commit) { project.commit('2f63565e7aac07bcdadb654e253078b727143ec4') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('files/images/6049019_460s.jpg') }
+
+ it { is_expected.to be_a(DiffViewer::Image) }
+ end
+
+ context 'when it is something else' do
+ let(:commit) { project.commit('ae73cb07c9eeaf35924a10f713b364d32b2dd34f') }
+ let(:diff_file) { commit.diffs.diff_file_with_new_path('Gemfile.zip') }
+
+ it { is_expected.to be_nil }
+ end
+ end
+ end
+
describe '#rendered_as_text?' do
context 'when the simple viewer is text-based' do
let(:commit) { project.commit('570e7b2abdd848b95f2f578043fc23bd6f6fd24d') }
diff --git a/spec/models/ci/pipeline_spec.rb b/spec/models/ci/pipeline_spec.rb
index c9eddd76a24..cae81540cd0 100644
--- a/spec/models/ci/pipeline_spec.rb
+++ b/spec/models/ci/pipeline_spec.rb
@@ -954,7 +954,10 @@ describe Ci::Pipeline, :mailer do
context 'when using legacy stages' do
before do
- stub_feature_flags(ci_pipeline_persisted_stages: false)
+ stub_feature_flags(
+ ci_pipeline_persisted_stages: false,
+ ci_atomic_processing: false
+ )
end
it 'returns legacy stages in valid order' do
@@ -962,9 +965,40 @@ describe Ci::Pipeline, :mailer do
end
end
+ context 'when using atomic processing' do
+ before do
+ stub_feature_flags(
+ ci_atomic_processing: true
+ )
+ end
+
+ context 'when pipelines is not complete' do
+ it 'returns stages in valid order' do
+ expect(subject).to all(be_a Ci::Stage)
+ expect(subject.map(&:name))
+ .to eq %w[sanity build test deploy cleanup]
+ end
+ end
+
+ context 'when pipeline is complete' do
+ before do
+ pipeline.succeed!
+ end
+
+ it 'returns stages in valid order' do
+ expect(subject).to all(be_a Ci::Stage)
+ expect(subject.map(&:name))
+ .to eq %w[sanity build test deploy cleanup]
+ end
+ end
+ end
+
context 'when using persisted stages' do
before do
- stub_feature_flags(ci_pipeline_persisted_stages: true)
+ stub_feature_flags(
+ ci_pipeline_persisted_stages: true,
+ ci_atomic_processing: false
+ )
end
context 'when pipelines is not complete' do
diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb
index e80b69e4fd5..38f9ccf23f5 100644
--- a/spec/support/capybara.rb
+++ b/spec/support/capybara.rb
@@ -95,12 +95,23 @@ RSpec.configure do |config|
config.include CapybaraHelpers, type: :feature
config.before(:context, :js) do
+ # This prevents Selenium from creating thousands of connections while waiting for
+ # an element to appear
+ webmock_enable_with_http_connect_on_start!
+
next if $capybara_server_already_started
TestEnv.eager_load_driver_server
$capybara_server_already_started = true
end
+ config.after(:context, :js) do
+ # WebMock doesn't stub connections, so we need to restore the original behavior
+ # to prevent many specs from failing:
+ # https://github.com/bblimke/webmock/blob/master/README.md#connecting-on-nethttpstart
+ webmock_enable!
+ end
+
config.before(:example, :js) do
session = Capybara.current_session
diff --git a/spec/support/kubeclient.rb b/spec/support/kubeclient.rb
new file mode 100644
index 00000000000..56c5800c801
--- /dev/null
+++ b/spec/support/kubeclient.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+RSpec.configure do |config|
+ # Feature specs call webmock_enable_with_http_connect_on_start! by
+ # default. This is needed to prevent Kubeclient from connecting to a
+ # host before the request is stubbed.
+ config.before(:each, :kubeclient) do
+ webmock_enable!
+ end
+end
diff --git a/spec/support/shared_examples/models/wiki_shared_examples.rb b/spec/support/shared_examples/models/wiki_shared_examples.rb
index 48a1bf58302..84569e95e11 100644
--- a/spec/support/shared_examples/models/wiki_shared_examples.rb
+++ b/spec/support/shared_examples/models/wiki_shared_examples.rb
@@ -148,6 +148,44 @@ RSpec.shared_examples 'wiki model' do
end
end
+ describe '#sidebar_entries' do
+ before do
+ (1..5).each { |i| create(:wiki_page, wiki: wiki, title: "my page #{i}") }
+ (6..10).each { |i| create(:wiki_page, wiki: wiki, title: "parent/my page #{i}") }
+ (11..15).each { |i| create(:wiki_page, wiki: wiki, title: "grandparent/parent/my page #{i}") }
+ end
+
+ def total_pages(entries)
+ entries.sum do |entry|
+ entry.is_a?(WikiDirectory) ? entry.pages.size : 1
+ end
+ end
+
+ context 'when the number of pages does not exceed the limit' do
+ it 'returns all pages grouped by directory and limited is false' do
+ entries, limited = subject.sidebar_entries
+
+ expect(entries.size).to be(7)
+ expect(total_pages(entries)).to be(15)
+ expect(limited).to be(false)
+ end
+ end
+
+ context 'when the number of pages exceeds the limit' do
+ before do
+ create(:wiki_page, wiki: wiki, title: 'my page 16')
+ end
+
+ it 'returns 15 pages grouped by directory and limited is true' do
+ entries, limited = subject.sidebar_entries
+
+ expect(entries.size).to be(8)
+ expect(total_pages(entries)).to be(15)
+ expect(limited).to be(true)
+ end
+ end
+ end
+
describe '#find_page' do
before do
subject.create_page('index page', 'This is an awesome Gollum Wiki')
diff --git a/spec/support/webmock.rb b/spec/support/webmock.rb
index 57acc3b63b1..f952f7f0985 100644
--- a/spec/support/webmock.rb
+++ b/spec/support/webmock.rb
@@ -15,4 +15,20 @@ def webmock_allowed_hosts
end.compact.uniq
end
-WebMock.disable_net_connect!(allow_localhost: true, allow: webmock_allowed_hosts)
+# This prevents Selenium/WebMock from spawning thousands of connections
+# while waiting for an element to appear via Capybara's find:
+# https://github.com/teamcapybara/capybara/issues/2322#issuecomment-619321520
+def webmock_enable_with_http_connect_on_start!
+ webmock_enable!(net_http_connect_on_start: true)
+end
+
+def webmock_enable!(options = {})
+ WebMock.disable_net_connect!(
+ {
+ allow_localhost: true,
+ allow: webmock_allowed_hosts
+ }.merge(options)
+ )
+end
+
+webmock_enable!