summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/projects/issues_controller_spec.rb7
-rw-r--r--spec/features/groups/navbar_spec.rb13
-rw-r--r--spec/features/projects/navbar_spec.rb4
-rw-r--r--spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap2
-rw-r--r--spec/frontend/monitoring/components/dashboards_dropdown_spec.js34
-rw-r--r--spec/frontend/monitoring/mock_data.js26
-rw-r--r--spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap1
-rw-r--r--spec/frontend/registry/settings/components/settings_form_spec.js26
-rw-r--r--spec/frontend/registry/settings/store/getters_spec.js44
-rw-r--r--spec/frontend/vue_alerts_spec.js87
-rw-r--r--spec/frontend/vue_shared/components/dismissible_alert_spec.js57
-rw-r--r--spec/support/helpers/filter_spec_helper.rb1
-rw-r--r--spec/support/shared_examples/features/navbar_shared_examples.rb19
13 files changed, 282 insertions, 39 deletions
diff --git a/spec/controllers/projects/issues_controller_spec.rb b/spec/controllers/projects/issues_controller_spec.rb
index e5ca2226111..608e4a58e5a 100644
--- a/spec/controllers/projects/issues_controller_spec.rb
+++ b/spec/controllers/projects/issues_controller_spec.rb
@@ -1152,13 +1152,6 @@ describe Projects::IssuesController do
expect(controller).to set_flash[:notice].to(/The issue was successfully deleted\./)
end
- it "deletes the issue" do
- delete :destroy, params: { namespace_id: project.namespace, project_id: project, id: issue.iid, destroy_confirm: true }
-
- expect(response).to have_gitlab_http_status(:found)
- expect(controller).to set_flash[:notice].to(/The issue was successfully deleted\./)
- end
-
it "prevents deletion if destroy_confirm is not set" do
expect(Gitlab::ErrorTracking).to receive(:track_exception).and_call_original
diff --git a/spec/features/groups/navbar_spec.rb b/spec/features/groups/navbar_spec.rb
index e348eb80b1a..5662465d431 100644
--- a/spec/features/groups/navbar_spec.rb
+++ b/spec/features/groups/navbar_spec.rb
@@ -7,14 +7,22 @@ describe 'Group navbar' do
let(:user) { create(:user) }
let(:group) { create(:group) }
+ let(:analytics_nav_item) do
+ {
+ nav_item: _('Analytics'),
+ nav_sub_items: [
+ _('Contribution Analytics')
+ ]
+ }
+ end
+
let(:structure) do
[
{
nav_item: _('Group overview'),
nav_sub_items: [
_('Details'),
- _('Activity'),
- (_('Contribution Analytics') if Gitlab.ee?)
+ _('Activity')
]
},
{
@@ -34,6 +42,7 @@ describe 'Group navbar' do
nav_item: _('Kubernetes'),
nav_sub_items: []
},
+ (analytics_nav_item if Gitlab.ee?),
{
nav_item: _('Members'),
nav_sub_items: []
diff --git a/spec/features/projects/navbar_spec.rb b/spec/features/projects/navbar_spec.rb
index f87bd5ca529..4917a0b0a59 100644
--- a/spec/features/projects/navbar_spec.rb
+++ b/spec/features/projects/navbar_spec.rb
@@ -59,13 +59,13 @@ describe 'Project navbar' do
_('Environments'),
_('Error Tracking'),
_('Serverless'),
- _('Kubernetes'),
- _('Auto DevOps')
+ _('Kubernetes')
]
},
{
nav_item: _('Analytics'),
nav_sub_items: [
+ _('CI / CD Analytics'),
(_('Code Review') if Gitlab.ee?),
_('Cycle Analytics'),
_('Repository Analytics')
diff --git a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
index 2b9668c1b56..2ed93396376 100644
--- a/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
+++ b/spec/frontend/monitoring/components/__snapshots__/dashboard_template_spec.js.snap
@@ -44,7 +44,7 @@ exports[`Dashboard template matches the default snapshot 1`] = `
class="d-flex flex-column overflow-hidden"
>
<gl-dropdown-header-stub
- class="text-center"
+ class="monitor-environment-dropdown-header text-center"
>
Environment
</gl-dropdown-header-stub>
diff --git a/spec/frontend/monitoring/components/dashboards_dropdown_spec.js b/spec/frontend/monitoring/components/dashboards_dropdown_spec.js
index 6af5ab4ba75..51c7b22f242 100644
--- a/spec/frontend/monitoring/components/dashboards_dropdown_spec.js
+++ b/spec/frontend/monitoring/components/dashboards_dropdown_spec.js
@@ -35,13 +35,17 @@ describe('DashboardsDropdown', () => {
const findItems = () => wrapper.findAll(GlDropdownItem);
const findItemAt = i => wrapper.findAll(GlDropdownItem).at(i);
+ const findSearchInput = () => wrapper.find({ ref: 'monitorDashboardsDropdownSearch' });
+ const findNoItemsMsg = () => wrapper.find({ ref: 'monitorDashboardsDropdownMsg' });
+ const setSearchTerm = searchTerm => wrapper.setData({ searchTerm });
describe('when it receives dashboards data', () => {
beforeEach(() => {
wrapper = createComponent();
});
+
it('displays an item for each dashboard', () => {
- expect(wrapper.findAll(GlDropdownItem).length).toEqual(dashboardGitResponse.length);
+ expect(findItems().length).toEqual(dashboardGitResponse.length);
});
it('displays items with the dashboard display name', () => {
@@ -49,6 +53,32 @@ describe('DashboardsDropdown', () => {
expect(findItemAt(1).text()).toBe(dashboardGitResponse[1].display_name);
expect(findItemAt(2).text()).toBe(dashboardGitResponse[2].display_name);
});
+
+ it('displays a search input', () => {
+ expect(findSearchInput().isVisible()).toBe(true);
+ });
+
+ it('hides no message text by default', () => {
+ expect(findNoItemsMsg().isVisible()).toBe(false);
+ });
+
+ it('filters dropdown items when searched for item exists in the list', () => {
+ const searchTerm = 'Default';
+ setSearchTerm(searchTerm);
+
+ return wrapper.vm.$nextTick(() => {
+ expect(findItems()).toHaveLength(1);
+ });
+ });
+
+ it('shows no items found message when searched for item does not exists in the list', () => {
+ const searchTerm = 'does-not-exist';
+ setSearchTerm(searchTerm);
+
+ return wrapper.vm.$nextTick(() => {
+ expect(findNoItemsMsg().isVisible()).toBe(true);
+ });
+ });
});
describe('when a system dashboard is selected', () => {
@@ -224,7 +254,7 @@ describe('DashboardsDropdown', () => {
it('displays an item for each dashboard', () => {
const item = wrapper.findAll({ ref: 'duplicateDashboardItem' });
- expect(findItems().length).toEqual(dashboardGitResponse.length);
+ expect(findItems()).toHaveLength(dashboardGitResponse.length);
expect(item.length).toBe(0);
});
diff --git a/spec/frontend/monitoring/mock_data.js b/spec/frontend/monitoring/mock_data.js
index e3357394551..5fd73b73e0d 100644
--- a/spec/frontend/monitoring/mock_data.js
+++ b/spec/frontend/monitoring/mock_data.js
@@ -518,6 +518,15 @@ export const metricsDashboardPayload = {
],
};
+const customDashboardsData = new Array(30).fill(null).map((_, idx) => ({
+ default: false,
+ display_name: `Custom Dashboard ${idx}`,
+ can_edit: true,
+ system_dashboard: false,
+ project_blob_path: `${mockProjectDir}/blob/master/dashboards/.gitlab/dashboards/dashboard_${idx}.yml`,
+ path: `.gitlab/dashboards/dashboard_${idx}.yml`,
+}));
+
export const dashboardGitResponse = [
{
default: true,
@@ -527,22 +536,7 @@ export const dashboardGitResponse = [
project_blob_path: null,
path: 'config/prometheus/common_metrics.yml',
},
- {
- default: false,
- display_name: 'Custom Dashboard 1',
- can_edit: true,
- system_dashboard: false,
- project_blob_path: `${mockProjectDir}/blob/master/dashboards/.gitlab/dashboards/dashboard_1.yml`,
- path: '.gitlab/dashboards/dashboard_1.yml',
- },
- {
- default: false,
- display_name: 'Custom Dashboard 2',
- can_edit: true,
- system_dashboard: false,
- project_blob_path: `${mockProjectDir}/blob/master/dashboards/.gitlab/dashboards/dashboard_2.yml`,
- path: '.gitlab/dashboards/dashboard_2.yml',
- },
+ ...customDashboardsData,
];
export const graphDataPrometheusQuery = {
diff --git a/spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap b/spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap
index 8d4e1243418..06f73c8f456 100644
--- a/spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap
+++ b/spec/frontend/registry/settings/components/__snapshots__/settings_form_spec.js.snap
@@ -159,6 +159,7 @@ exports[`Settings Form renders 1`] = `
>
<glbutton-stub
class="mr-2 d-block"
+ disabled="true"
size="md"
type="reset"
variant="secondary"
diff --git a/spec/frontend/registry/settings/components/settings_form_spec.js b/spec/frontend/registry/settings/components/settings_form_spec.js
index 5b81d034e14..89dd161ec3e 100644
--- a/spec/frontend/registry/settings/components/settings_form_spec.js
+++ b/spec/frontend/registry/settings/components/settings_form_spec.js
@@ -124,11 +124,35 @@ describe('Settings Form', () => {
form = findForm();
});
- describe('form cancel event', () => {
+ describe('cancel button', () => {
it('has type reset', () => {
expect(findCancelButton().attributes('type')).toBe('reset');
});
+ it('is disabled the form was not changed from his original value', () => {
+ store.dispatch('receiveSettingsSuccess', { foo: 'bar' });
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findCancelButton().attributes('disabled')).toBe('true');
+ });
+ });
+
+ it('is disabled when the form data is loading', () => {
+ store.dispatch('toggleLoading');
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findCancelButton().attributes('disabled')).toBe('true');
+ });
+ });
+
+ it('is enabled when the user changed something in the form and the data is not being loaded', () => {
+ store.dispatch('receiveSettingsSuccess', { foo: 'bar' });
+ store.dispatch('updateSettings', { foo: 'baz' });
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findCancelButton().attributes('disabled')).toBe(undefined);
+ });
+ });
+ });
+
+ describe('form cancel event', () => {
it('calls the appropriate function', () => {
dispatchSpy.mockReturnValue();
form.trigger('reset');
diff --git a/spec/frontend/registry/settings/store/getters_spec.js b/spec/frontend/registry/settings/store/getters_spec.js
new file mode 100644
index 00000000000..d9ee53766d6
--- /dev/null
+++ b/spec/frontend/registry/settings/store/getters_spec.js
@@ -0,0 +1,44 @@
+import * as getters from '~/registry/settings/store/getters';
+import * as utils from '~/registry/settings/utils';
+import { formOptions } from '../mock_data';
+
+describe('Getters registry settings store', () => {
+ const settings = {
+ cadence: 'foo',
+ keep_n: 'bar',
+ older_than: 'baz',
+ };
+
+ describe.each`
+ getter | variable | formOption
+ ${'getCadence'} | ${'cadence'} | ${'cadence'}
+ ${'getKeepN'} | ${'keep_n'} | ${'keepN'}
+ ${'getOlderThan'} | ${'older_than'} | ${'olderThan'}
+ `('Options getter', ({ getter, variable, formOption }) => {
+ beforeEach(() => {
+ utils.findDefaultOption = jest.fn();
+ });
+
+ it(`${getter} returns ${variable} when ${variable} exists in settings`, () => {
+ expect(getters[getter]({ settings })).toBe(settings[variable]);
+ });
+
+ it(`${getter} calls findDefaultOption when ${variable} does not exists in settings`, () => {
+ getters[getter]({ settings: {}, formOptions });
+ expect(utils.findDefaultOption).toHaveBeenCalledWith(formOptions[formOption]);
+ });
+ });
+
+ describe('getIsDisabled', () => {
+ it('returns false when original is equal to settings', () => {
+ const same = { foo: 'bar' };
+ expect(getters.getIsEdited({ original: same, settings: same })).toBe(false);
+ });
+
+ it('returns true when original is different from settings', () => {
+ expect(getters.getIsEdited({ original: { foo: 'bar' }, settings: { foo: 'baz' } })).toBe(
+ true,
+ );
+ });
+ });
+});
diff --git a/spec/frontend/vue_alerts_spec.js b/spec/frontend/vue_alerts_spec.js
new file mode 100644
index 00000000000..b2ee6f895a8
--- /dev/null
+++ b/spec/frontend/vue_alerts_spec.js
@@ -0,0 +1,87 @@
+import Vue from 'vue';
+import initVueAlerts from '~/vue_alerts';
+import { setHTMLFixture } from 'helpers/fixtures';
+import { TEST_HOST } from 'helpers/test_constants';
+
+describe('VueAlerts', () => {
+ const alerts = [
+ {
+ title: 'Lorem',
+ html: 'Lorem <strong>Ipsum</strong>',
+ dismissible: true,
+ primaryButtonText: 'Okay!',
+ primaryButtonLink: `${TEST_HOST}/okay`,
+ variant: 'tip',
+ },
+ {
+ title: 'Hello',
+ html: 'Hello <strong>World</strong>',
+ dismissible: false,
+ primaryButtonText: 'No!',
+ primaryButtonLink: `${TEST_HOST}/no`,
+ variant: 'info',
+ },
+ ];
+
+ beforeEach(() => {
+ setHTMLFixture(
+ alerts
+ .map(
+ x => `
+ <div class="js-vue-alert"
+ data-dismissible="${x.dismissible}"
+ data-title="${x.title}"
+ data-primary-button-text="${x.primaryButtonText}"
+ data-primary-button-link="${x.primaryButtonLink}"
+ data-variant="${x.variant}">${x.html}</div>
+ `,
+ )
+ .join('\n'),
+ );
+ });
+
+ const findJsHooks = () => document.querySelectorAll('.js-vue-alert');
+ const findAlerts = () => document.querySelectorAll('.gl-alert');
+ const findAlertDismiss = alert => alert.querySelector('.gl-alert-dismiss');
+
+ const serializeAlert = alert => ({
+ title: alert.querySelector('.gl-alert-title').textContent.trim(),
+ html: alert.querySelector('.gl-alert-body div').innerHTML,
+ dismissible: Boolean(alert.querySelector('.gl-alert-dismiss')),
+ primaryButtonText: alert.querySelector('.gl-alert-action').textContent.trim(),
+ primaryButtonLink: alert.querySelector('.gl-alert-action').href,
+ variant: [...alert.classList].find(x => x.match('gl-alert-')).replace('gl-alert-', ''),
+ });
+
+ it('starts with only JsHooks', () => {
+ expect(findJsHooks().length).toEqual(alerts.length);
+ expect(findAlerts().length).toEqual(0);
+ });
+
+ describe('when mounted', () => {
+ beforeEach(() => {
+ initVueAlerts();
+ });
+
+ it('replaces JsHook with GlAlert', () => {
+ expect(findJsHooks().length).toEqual(0);
+ expect(findAlerts().length).toEqual(alerts.length);
+ });
+
+ it('passes along props to gl-alert', () => {
+ expect([...findAlerts()].map(serializeAlert)).toEqual(alerts);
+ });
+
+ describe('when dismissed', () => {
+ beforeEach(() => {
+ findAlertDismiss(findAlerts()[0]).click();
+
+ return Vue.nextTick();
+ });
+
+ it('hides the alert', () => {
+ expect(findAlerts().length).toEqual(alerts.length - 1);
+ });
+ });
+ });
+});
diff --git a/spec/frontend/vue_shared/components/dismissible_alert_spec.js b/spec/frontend/vue_shared/components/dismissible_alert_spec.js
new file mode 100644
index 00000000000..17905254292
--- /dev/null
+++ b/spec/frontend/vue_shared/components/dismissible_alert_spec.js
@@ -0,0 +1,57 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlAlert } from '@gitlab/ui';
+import DismissibleAlert from '~/vue_shared/components/dismissible_alert.vue';
+
+const TEST_HTML = 'Hello World! <strong>Foo</strong>';
+
+describe('vue_shared/components/dismissible_alert', () => {
+ const testAlertProps = {
+ primaryButtonText: 'Lorem ipsum',
+ primaryButtonLink: '/lorem/ipsum',
+ };
+
+ let wrapper;
+
+ const createComponent = (props = {}) => {
+ wrapper = shallowMount(DismissibleAlert, {
+ propsData: {
+ html: TEST_HTML,
+ ...testAlertProps,
+ ...props,
+ },
+ });
+ };
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ const findAlert = () => wrapper.find(GlAlert);
+
+ describe('with default', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('shows alert', () => {
+ const alert = findAlert();
+
+ expect(alert.exists()).toBe(true);
+ expect(alert.props()).toEqual(expect.objectContaining(testAlertProps));
+ });
+
+ it('shows given HTML', () => {
+ expect(findAlert().html()).toContain(TEST_HTML);
+ });
+
+ describe('when dismissed', () => {
+ beforeEach(() => {
+ findAlert().vm.$emit('dismiss');
+ });
+
+ it('hides the alert', () => {
+ expect(findAlert().exists()).toBe(false);
+ });
+ });
+ });
+});
diff --git a/spec/support/helpers/filter_spec_helper.rb b/spec/support/helpers/filter_spec_helper.rb
index 45d49696e06..279f87efb46 100644
--- a/spec/support/helpers/filter_spec_helper.rb
+++ b/spec/support/helpers/filter_spec_helper.rb
@@ -55,6 +55,7 @@ module FilterSpecHelper
def reference_pipeline(context = {})
context.reverse_merge!(project: project) if defined?(project)
+ context.reverse_merge!(current_user: current_user) if defined?(current_user)
filters = [
Banzai::Filter::AutolinkFilter,
diff --git a/spec/support/shared_examples/features/navbar_shared_examples.rb b/spec/support/shared_examples/features/navbar_shared_examples.rb
index a963739878e..91a4048fa7c 100644
--- a/spec/support/shared_examples/features/navbar_shared_examples.rb
+++ b/spec/support/shared_examples/features/navbar_shared_examples.rb
@@ -1,20 +1,23 @@
# frozen_string_literal: true
RSpec.shared_examples 'verified navigation bar' do
+ let(:expected_structure) do
+ structure.compact!
+ structure.each { |s| s[:nav_sub_items].compact! }
+ structure
+ end
+
it 'renders correctly' do
- current_structure = page.find_all('.sidebar-top-level-items > li', class: ['!hidden']).map do |item|
+ current_structure = page.all('.sidebar-top-level-items > li', class: ['!hidden']).map do |item|
nav_item = item.find_all('a').first.text.gsub(/\s+\d+$/, '') # remove counts at the end
- nav_sub_items = item
- .find_all('.sidebar-sub-level-items a')
- .map(&:text)
- .drop(1) # remove the first hidden item
+ nav_sub_items = item.all('.sidebar-sub-level-items > li', class: ['!fly-out-top-item']).map do |list_item|
+ list_item.all('a').first.text
+ end
{ nav_item: nav_item, nav_sub_items: nav_sub_items }
end
- structure.each { |s| s[:nav_sub_items].compact! }
-
- expect(current_structure).to eq(structure)
+ expect(current_structure).to eq(expected_structure)
end
end