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>2023-07-28 18:09:45 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-07-28 18:09:45 +0300
commitd62fd6e04c272d48dccde4033529ca97c27502f6 (patch)
treee3bbea524f4bccb92048fd8a52a42b757618b57b /spec
parentaaff41e10e8c03e545af9ba157e79f67686972a0 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/frontend/search/sidebar/components/app_spec.js34
-rw-r--r--spec/frontend/search/sidebar/components/blobs_filters_spec.js28
-rw-r--r--spec/frontend/search/sidebar/components/filters_spec.js80
-rw-r--r--spec/frontend/search/sidebar/components/filters_template_spec.js167
-rw-r--r--spec/frontend/search/sidebar/components/issues_filters_spec.js106
-rw-r--r--spec/frontend/search/sidebar/components/language_filter_spec.js70
-rw-r--r--spec/frontend/search/sidebar/components/merge_requests_filters_spec.js28
-rw-r--r--spec/frontend/search/store/actions_spec.js22
-rw-r--r--spec/frontend/search/store/getters_spec.js12
-rw-r--r--spec/frontend/super_sidebar/components/context_header_spec.js50
-rw-r--r--spec/frontend/super_sidebar/components/context_switcher_toggle_spec.js33
-rw-r--r--spec/frontend/super_sidebar/components/sidebar_menu_spec.js1
-rw-r--r--spec/frontend/super_sidebar/components/sidebar_peek_behavior_spec.js17
-rw-r--r--spec/frontend/super_sidebar/components/super_sidebar_spec.js24
-rw-r--r--spec/frontend/super_sidebar/components/user_bar_spec.js54
-rw-r--r--spec/frontend/super_sidebar/mock_data.js21
-rw-r--r--spec/helpers/application_settings_helper_spec.rb4
-rw-r--r--spec/helpers/nav_helper_spec.rb36
-rw-r--r--spec/helpers/sidebars_helper_spec.rb30
-rw-r--r--spec/requests/api/settings_spec.rb5
-rw-r--r--spec/spec_helper.rb6
-rw-r--r--spec/support/shared_examples/helpers/super_sidebar_shared_examples.rb35
22 files changed, 597 insertions, 266 deletions
diff --git a/spec/frontend/search/sidebar/components/app_spec.js b/spec/frontend/search/sidebar/components/app_spec.js
index ba492833ec4..aace9c8f83e 100644
--- a/spec/frontend/search/sidebar/components/app_spec.js
+++ b/spec/frontend/search/sidebar/components/app_spec.js
@@ -4,9 +4,10 @@ import Vuex from 'vuex';
import { MOCK_QUERY } from 'jest/search/mock_data';
import GlobalSearchSidebar from '~/search/sidebar/components/app.vue';
import IssuesFilters from '~/search/sidebar/components/issues_filters.vue';
+import MergeRequestsFilters from '~/search/sidebar/components/merge_requests_filters.vue';
+import BlobsFilters from '~/search/sidebar/components/blobs_filters.vue';
import ScopeLegacyNavigation from '~/search/sidebar/components/scope_legacy_navigation.vue';
import ScopeSidebarNavigation from '~/search/sidebar/components/scope_sidebar_navigation.vue';
-import LanguageFilter from '~/search/sidebar/components/language_filter/index.vue';
Vue.use(Vuex);
@@ -17,7 +18,7 @@ describe('GlobalSearchSidebar', () => {
currentScope: jest.fn(() => 'issues'),
};
- const createComponent = (initialState = {}, featureFlags = {}) => {
+ const createComponent = (initialState = {}) => {
const store = new Vuex.Store({
state: {
urlQuery: MOCK_QUERY,
@@ -28,19 +29,15 @@ describe('GlobalSearchSidebar', () => {
wrapper = shallowMount(GlobalSearchSidebar, {
store,
- provide: {
- glFeatures: {
- ...featureFlags,
- },
- },
});
};
const findSidebarSection = () => wrapper.find('section');
- const findFilters = () => wrapper.findComponent(IssuesFilters);
+ const findIssuesFilters = () => wrapper.findComponent(IssuesFilters);
+ const findMergeRequestsFilters = () => wrapper.findComponent(MergeRequestsFilters);
+ const findBlobsFilters = () => wrapper.findComponent(BlobsFilters);
const findScopeLegacyNavigation = () => wrapper.findComponent(ScopeLegacyNavigation);
const findScopeSidebarNavigation = () => wrapper.findComponent(ScopeSidebarNavigation);
- const findLanguageAggregation = () => wrapper.findComponent(LanguageFilter);
describe('renders properly', () => {
describe('always', () => {
@@ -53,23 +50,18 @@ describe('GlobalSearchSidebar', () => {
});
describe.each`
- scope | showFilters | showsLanguage
- ${'issues'} | ${true} | ${false}
- ${'merge_requests'} | ${true} | ${false}
- ${'projects'} | ${false} | ${false}
- ${'blobs'} | ${false} | ${true}
- `('sidebar scope: $scope', ({ scope, showFilters, showsLanguage }) => {
+ scope | filter
+ ${'issues'} | ${findIssuesFilters}
+ ${'merge_requests'} | ${findMergeRequestsFilters}
+ ${'blobs'} | ${findBlobsFilters}
+ `('with sidebar $scope scope:', ({ scope, filter }) => {
beforeEach(() => {
getterSpies.currentScope = jest.fn(() => scope);
createComponent({ urlQuery: { scope } });
});
- it(`${!showFilters ? "doesn't" : ''} shows filters`, () => {
- expect(findFilters().exists()).toBe(showFilters);
- });
-
- it(`${!showsLanguage ? "doesn't" : ''} shows language filters`, () => {
- expect(findLanguageAggregation().exists()).toBe(showsLanguage);
+ it(`shows filter ${filter.name.replace('find', '')}`, () => {
+ expect(filter().exists()).toBe(true);
});
});
diff --git a/spec/frontend/search/sidebar/components/blobs_filters_spec.js b/spec/frontend/search/sidebar/components/blobs_filters_spec.js
new file mode 100644
index 00000000000..ff93e6f32e4
--- /dev/null
+++ b/spec/frontend/search/sidebar/components/blobs_filters_spec.js
@@ -0,0 +1,28 @@
+import { shallowMount } from '@vue/test-utils';
+import BlobsFilters from '~/search/sidebar/components/blobs_filters.vue';
+import LanguageFilter from '~/search/sidebar/components/language_filter/index.vue';
+import FiltersTemplate from '~/search/sidebar/components/filters_template.vue';
+
+describe('GlobalSearch BlobsFilters', () => {
+ let wrapper;
+
+ const findLanguageFilter = () => wrapper.findComponent(LanguageFilter);
+ const findFiltersTemplate = () => wrapper.findComponent(FiltersTemplate);
+
+ const createComponent = () => {
+ wrapper = shallowMount(BlobsFilters);
+ };
+
+ describe('Renders correctly', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+ it('renders FiltersTemplate', () => {
+ expect(findLanguageFilter().exists()).toBe(true);
+ });
+
+ it('renders ConfidentialityFilter', () => {
+ expect(findFiltersTemplate().exists()).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/search/sidebar/components/filters_spec.js b/spec/frontend/search/sidebar/components/filters_spec.js
index 546a84ff040..42508d7e216 100644
--- a/spec/frontend/search/sidebar/components/filters_spec.js
+++ b/spec/frontend/search/sidebar/components/filters_spec.js
@@ -1,4 +1,3 @@
-import { GlButton, GlLink } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
@@ -36,11 +35,8 @@ describe('GlobalSearchSidebarFilters', () => {
});
};
- const findSidebarForm = () => wrapper.find('form');
const findStatusFilter = () => wrapper.findComponent(StatusFilter);
const findConfidentialityFilter = () => wrapper.findComponent(ConfidentialityFilter);
- const findApplyButton = () => wrapper.findComponent(GlButton);
- const findResetLinkButton = () => wrapper.findComponent(GlLink);
describe('Renders correctly', () => {
beforeEach(() => {
@@ -53,82 +49,6 @@ describe('GlobalSearchSidebarFilters', () => {
it('renders ConfidentialityFilter', () => {
expect(findConfidentialityFilter().exists()).toBe(true);
});
-
- it('renders ApplyButton', () => {
- expect(findApplyButton().exists()).toBe(true);
- });
- });
-
- describe('ApplyButton', () => {
- describe('when sidebarDirty is false', () => {
- beforeEach(() => {
- createComponent({ sidebarDirty: false });
- });
-
- it('disables the button', () => {
- expect(findApplyButton().attributes('disabled')).toBeDefined();
- });
- });
-
- describe('when sidebarDirty is true', () => {
- beforeEach(() => {
- createComponent({ sidebarDirty: true });
- });
-
- it('enables the button', () => {
- expect(findApplyButton().attributes('disabled')).toBe(undefined);
- });
- });
- });
-
- describe('ResetLinkButton', () => {
- describe('with no filter selected', () => {
- beforeEach(() => {
- createComponent({ urlQuery: {} });
- });
-
- it('does not render', () => {
- expect(findResetLinkButton().exists()).toBe(false);
- });
- });
-
- describe('with filter selected', () => {
- beforeEach(() => {
- createComponent({ urlQuery: MOCK_QUERY });
- });
-
- it('does render', () => {
- expect(findResetLinkButton().exists()).toBe(true);
- });
- });
-
- describe('with filter selected and user updated query back to default', () => {
- beforeEach(() => {
- createComponent({ urlQuery: MOCK_QUERY, query: {} });
- });
-
- it('does render', () => {
- expect(findResetLinkButton().exists()).toBe(true);
- });
- });
- });
-
- describe('actions', () => {
- beforeEach(() => {
- createComponent({});
- });
-
- it('clicking ApplyButton calls applyQuery', () => {
- findSidebarForm().trigger('submit');
-
- expect(actionSpies.applyQuery).toHaveBeenCalled();
- });
-
- it('clicking ResetLinkButton calls resetQuery', () => {
- findResetLinkButton().vm.$emit('click');
-
- expect(actionSpies.resetQuery).toHaveBeenCalled();
- });
});
describe.each`
diff --git a/spec/frontend/search/sidebar/components/filters_template_spec.js b/spec/frontend/search/sidebar/components/filters_template_spec.js
new file mode 100644
index 00000000000..11c7c541b54
--- /dev/null
+++ b/spec/frontend/search/sidebar/components/filters_template_spec.js
@@ -0,0 +1,167 @@
+import { GlForm, GlButton, GlLink } from '@gitlab/ui';
+import Vue from 'vue';
+import Vuex from 'vuex';
+
+import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { MOCK_QUERY, MOCK_AGGREGATIONS } from 'jest/search/mock_data';
+
+import FiltersTemplate from '~/search/sidebar/components/filters_template.vue';
+
+import {
+ TRACKING_ACTION_CLICK,
+ TRACKING_LABEL_APPLY,
+ TRACKING_LABEL_RESET,
+} from '~/search/sidebar/constants/index';
+
+Vue.use(Vuex);
+
+describe('GlobalSearchSidebarLanguageFilter', () => {
+ let wrapper;
+ let trackingSpy;
+
+ const actionSpies = {
+ applyQuery: jest.fn(),
+ resetQuery: jest.fn(),
+ };
+
+ const getterSpies = {
+ currentScope: jest.fn(() => 'issues'),
+ };
+
+ const createComponent = (initialState) => {
+ const store = new Vuex.Store({
+ state: {
+ query: MOCK_QUERY,
+ urlQuery: MOCK_QUERY,
+ aggregations: MOCK_AGGREGATIONS,
+ sidebarDirty: false,
+ ...initialState,
+ },
+ actions: actionSpies,
+ getters: getterSpies,
+ });
+
+ wrapper = shallowMountExtended(FiltersTemplate, {
+ store,
+ slots: {
+ default: '<p>Filters Content</p>',
+ },
+ });
+ };
+
+ const findForm = () => wrapper.findComponent(GlForm);
+ const findDividers = () => wrapper.findAll('hr');
+ const findApplyButton = () => wrapper.findComponent(GlButton);
+ const findResetButton = () => wrapper.findComponent(GlLink);
+ const findSlotContent = () => wrapper.findByText('Filters Content');
+
+ describe('Renders correctly', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('renders form', () => {
+ expect(findForm().exists()).toBe(true);
+ });
+
+ it('renders dividers', () => {
+ expect(findDividers()).toHaveLength(2);
+ });
+
+ it('renders slot content', () => {
+ expect(findSlotContent().exists()).toBe(true);
+ });
+
+ it('renders ApplyButton', () => {
+ expect(findApplyButton().exists()).toBe(true);
+ });
+
+ it('renders reset button', () => {
+ expect(findResetButton().exists()).toBe(false);
+ });
+ });
+
+ describe('resetButton', () => {
+ describe.each`
+ description | sidebarDirty | queryLangFilters | exists
+ ${'sidebar dirty only'} | ${true} | ${[]} | ${true}
+ ${'query filters only'} | ${false} | ${['JSON', 'C']} | ${false}
+ ${'sidebar dirty and query filters'} | ${true} | ${['JSON', 'C']} | ${true}
+ ${'sidebar not dirty and no query filters'} | ${false} | ${[]} | ${false}
+ `('$description', ({ sidebarDirty, queryLangFilters, exists }) => {
+ beforeEach(() => {
+ getterSpies.queryLanguageFilters = jest.fn(() => queryLangFilters);
+
+ const query = {
+ ...MOCK_QUERY,
+ language: queryLangFilters,
+ state: undefined,
+ labels: undefined,
+ confidential: undefined,
+ };
+
+ createComponent({
+ sidebarDirty,
+ query,
+ urlQuery: query,
+ });
+ });
+
+ it(`button is ${exists ? 'shown' : 'hidden'}`, () => {
+ expect(findResetButton().exists()).toBe(exists);
+ });
+ });
+ });
+
+ describe('ApplyButton', () => {
+ describe('when sidebarDirty is false', () => {
+ beforeEach(() => {
+ createComponent({ sidebarDirty: false });
+ });
+
+ it('disables the button', () => {
+ expect(findApplyButton().attributes('disabled')).toBeDefined();
+ });
+ });
+
+ describe('when sidebarDirty is true', () => {
+ beforeEach(() => {
+ createComponent({ sidebarDirty: true });
+ });
+
+ it('enables the button', () => {
+ expect(findApplyButton().attributes('disabled')).toBe(undefined);
+ });
+ });
+ });
+
+ describe('actions', () => {
+ beforeEach(() => {
+ createComponent({ sidebarDirty: true });
+ trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
+ });
+
+ afterEach(() => {
+ unmockTracking();
+ });
+
+ it('clicking ApplyButton calls applyQuery', () => {
+ findForm().vm.$emit('submit', { preventDefault: () => {} });
+
+ expect(actionSpies.applyQuery).toHaveBeenCalled();
+ expect(trackingSpy).toHaveBeenCalledWith(TRACKING_ACTION_CLICK, TRACKING_LABEL_APPLY, {
+ label: getterSpies.currentScope(),
+ });
+ });
+
+ it('clicking resetButton calls resetQuery', () => {
+ findResetButton().vm.$emit('click');
+
+ expect(actionSpies.resetQuery).toHaveBeenCalled();
+ expect(trackingSpy).toHaveBeenCalledWith(TRACKING_ACTION_CLICK, TRACKING_LABEL_RESET, {
+ label: getterSpies.currentScope(),
+ });
+ });
+ });
+});
diff --git a/spec/frontend/search/sidebar/components/issues_filters_spec.js b/spec/frontend/search/sidebar/components/issues_filters_spec.js
new file mode 100644
index 00000000000..cab3a78bd34
--- /dev/null
+++ b/spec/frontend/search/sidebar/components/issues_filters_spec.js
@@ -0,0 +1,106 @@
+import { shallowMount } from '@vue/test-utils';
+import Vue from 'vue';
+import Vuex from 'vuex';
+import { MOCK_QUERY } from 'jest/search/mock_data';
+import IssuesFilters from '~/search/sidebar/components/issues_filters.vue';
+import ConfidentialityFilter from '~/search/sidebar/components/confidentiality_filter/index.vue';
+import StatusFilter from '~/search/sidebar/components/status_filter/index.vue';
+import LabelFilter from '~/search/sidebar/components/label_filter/index.vue';
+
+Vue.use(Vuex);
+
+describe('GlobalSearch IssuesFilters', () => {
+ let wrapper;
+
+ const defaultGetters = {
+ currentScope: () => 'issues',
+ };
+
+ const createComponent = (initialState, ff = true) => {
+ const store = new Vuex.Store({
+ state: {
+ urlQuery: MOCK_QUERY,
+ ...initialState,
+ },
+ getters: defaultGetters,
+ });
+
+ wrapper = shallowMount(IssuesFilters, {
+ store,
+ provide: {
+ glFeatures: {
+ searchIssueLabelAggregation: ff,
+ },
+ },
+ });
+ };
+
+ const findStatusFilter = () => wrapper.findComponent(StatusFilter);
+ const findConfidentialityFilter = () => wrapper.findComponent(ConfidentialityFilter);
+ const findLabelFilter = () => wrapper.findComponent(LabelFilter);
+ const findDividers = () => wrapper.findAll('hr');
+
+ describe('Renders correctly with FF enabled', () => {
+ beforeEach(() => {
+ createComponent({ urlQuery: MOCK_QUERY });
+ });
+ it('renders StatusFilter', () => {
+ expect(findStatusFilter().exists()).toBe(true);
+ });
+
+ it('renders ConfidentialityFilter', () => {
+ expect(findConfidentialityFilter().exists()).toBe(true);
+ });
+
+ it('renders LabelFilter', () => {
+ expect(findLabelFilter().exists()).toBe(true);
+ });
+
+ it('renders dividers correctly', () => {
+ expect(findDividers()).toHaveLength(2);
+ });
+ });
+
+ describe('Renders correctly with FF disabled', () => {
+ beforeEach(() => {
+ createComponent({ urlQuery: MOCK_QUERY }, false);
+ });
+ it('renders StatusFilter', () => {
+ expect(findStatusFilter().exists()).toBe(true);
+ });
+
+ it('renders ConfidentialityFilter', () => {
+ expect(findConfidentialityFilter().exists()).toBe(true);
+ });
+
+ it("doesn't render LabelFilter", () => {
+ expect(findLabelFilter().exists()).toBe(false);
+ });
+
+ it('renders divider correctly', () => {
+ expect(findDividers()).toHaveLength(1);
+ });
+ });
+
+ describe('Renders correctly with wrong scope', () => {
+ beforeEach(() => {
+ defaultGetters.currentScope = () => 'blobs';
+ createComponent({ urlQuery: MOCK_QUERY });
+ });
+ it("doesn't render StatusFilter", () => {
+ expect(findStatusFilter().exists()).toBe(false);
+ });
+
+ it("doesn't render ConfidentialityFilter", () => {
+ expect(findConfidentialityFilter().exists()).toBe(false);
+ });
+
+ it("doesn't render LabelFilter", () => {
+ expect(findLabelFilter().exists()).toBe(false);
+ });
+
+ it("doesn't render dividers", () => {
+ expect(findDividers()).toHaveLength(0);
+ });
+ });
+});
diff --git a/spec/frontend/search/sidebar/components/language_filter_spec.js b/spec/frontend/search/sidebar/components/language_filter_spec.js
index 817199d7cfe..88be8f908d7 100644
--- a/spec/frontend/search/sidebar/components/language_filter_spec.js
+++ b/spec/frontend/search/sidebar/components/language_filter_spec.js
@@ -1,4 +1,4 @@
-import { GlAlert, GlFormCheckbox, GlForm } from '@gitlab/ui';
+import { GlAlert, GlFormCheckbox } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
@@ -13,13 +13,11 @@ import CheckboxFilter from '~/search/sidebar/components/language_filter/checkbox
import {
TRACKING_LABEL_SHOW_MORE,
- TRACKING_CATEGORY,
TRACKING_PROPERTY_MAX,
TRACKING_LABEL_MAX,
TRACKING_LABEL_FILTERS,
TRACKING_ACTION_SHOW,
TRACKING_ACTION_CLICK,
- TRACKING_LABEL_APPLY,
TRACKING_LABEL_ALL,
} from '~/search/sidebar/components/language_filter/tracking';
@@ -61,10 +59,7 @@ describe('GlobalSearchSidebarLanguageFilter', () => {
});
};
- const findForm = () => wrapper.findComponent(GlForm);
const findCheckboxFilter = () => wrapper.findComponent(CheckboxFilter);
- const findApplyButton = () => wrapper.findByTestId('apply-button');
- const findResetButton = () => wrapper.findByTestId('reset-button');
const findShowMoreButton = () => wrapper.findByTestId('show-more-button');
const findAlert = () => wrapper.findComponent(GlAlert);
const findAllCheckboxes = () => wrapper.findAllComponents(GlFormCheckbox);
@@ -80,10 +75,6 @@ describe('GlobalSearchSidebarLanguageFilter', () => {
unmockTracking();
});
- it('renders form', () => {
- expect(findForm().exists()).toBe(true);
- });
-
it('renders checkbox-filter', () => {
expect(findCheckboxFilter().exists()).toBe(true);
});
@@ -93,10 +84,6 @@ describe('GlobalSearchSidebarLanguageFilter', () => {
expect(findAllCheckboxes()).toHaveLength(10);
});
- it('renders ApplyButton', () => {
- expect(findApplyButton().exists()).toBe(true);
- });
-
it('renders Show More button', () => {
expect(findShowMoreButton().exists()).toBe(true);
});
@@ -106,47 +93,6 @@ describe('GlobalSearchSidebarLanguageFilter', () => {
});
});
- describe('resetButton', () => {
- describe.each`
- description | sidebarDirty | queryFilters | exists
- ${'sidebar dirty only'} | ${true} | ${[]} | ${false}
- ${'query filters only'} | ${false} | ${['JSON', 'C']} | ${false}
- ${'sidebar dirty and query filters'} | ${true} | ${['JSON', 'C']} | ${true}
- ${'no sidebar and no query filters'} | ${false} | ${[]} | ${false}
- `('$description', ({ sidebarDirty, queryFilters, exists }) => {
- beforeEach(() => {
- getterSpies.queryLanguageFilters = jest.fn(() => queryFilters);
- createComponent({ sidebarDirty, query: { ...MOCK_QUERY, language: queryFilters } });
- });
-
- it(`button is ${exists ? 'shown' : 'hidden'}`, () => {
- expect(findResetButton().exists()).toBe(exists);
- });
- });
- });
-
- describe('ApplyButton', () => {
- describe('when sidebarDirty is false', () => {
- beforeEach(() => {
- createComponent({ sidebarDirty: false });
- });
-
- it('disables the button', () => {
- expect(findApplyButton().attributes('disabled')).toBeDefined();
- });
- });
-
- describe('when sidebarDirty is true', () => {
- beforeEach(() => {
- createComponent({ sidebarDirty: true });
- });
-
- it('enables the button', () => {
- expect(findApplyButton().attributes('disabled')).toBe(undefined);
- });
- });
- });
-
describe('Show All button works', () => {
beforeEach(() => {
createComponent();
@@ -211,19 +157,5 @@ describe('GlobalSearchSidebarLanguageFilter', () => {
it('uses action fetchAllAggregation', () => {
expect(actionSpies.fetchAllAggregation).toHaveBeenCalled();
});
-
- it('clicking ApplyButton calls applyQuery', () => {
- findForm().vm.$emit('submit', { preventDefault: () => {} });
-
- expect(actionSpies.applyQuery).toHaveBeenCalled();
- });
-
- it('sends tracking information clicking ApplyButton', () => {
- findForm().vm.$emit('submit', { preventDefault: () => {} });
-
- expect(trackingSpy).toHaveBeenCalledWith(TRACKING_ACTION_CLICK, TRACKING_LABEL_APPLY, {
- label: TRACKING_CATEGORY,
- });
- });
});
});
diff --git a/spec/frontend/search/sidebar/components/merge_requests_filters_spec.js b/spec/frontend/search/sidebar/components/merge_requests_filters_spec.js
new file mode 100644
index 00000000000..0932f8e47d2
--- /dev/null
+++ b/spec/frontend/search/sidebar/components/merge_requests_filters_spec.js
@@ -0,0 +1,28 @@
+import { shallowMount } from '@vue/test-utils';
+import MergeRequestsFilters from '~/search/sidebar/components/merge_requests_filters.vue';
+import StatusFilter from '~/search/sidebar/components/status_filter/index.vue';
+import FiltersTemplate from '~/search/sidebar/components/filters_template.vue';
+
+describe('GlobalSearch MergeRequestsFilters', () => {
+ let wrapper;
+
+ const findStatusFilter = () => wrapper.findComponent(StatusFilter);
+ const findFiltersTemplate = () => wrapper.findComponent(FiltersTemplate);
+
+ const createComponent = () => {
+ wrapper = shallowMount(MergeRequestsFilters);
+ };
+
+ describe('Renders correctly', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+ it('renders ConfidentialityFilter', () => {
+ expect(findStatusFilter().exists()).toBe(true);
+ });
+
+ it('renders FiltersTemplate', () => {
+ expect(findFiltersTemplate().exists()).toBe(true);
+ });
+ });
+});
diff --git a/spec/frontend/search/store/actions_spec.js b/spec/frontend/search/store/actions_spec.js
index 2051e731647..a6ec7a06cfb 100644
--- a/spec/frontend/search/store/actions_spec.js
+++ b/spec/frontend/search/store/actions_spec.js
@@ -327,28 +327,6 @@ describe('Global Search Store Actions', () => {
});
});
- describe('resetLanguageQueryWithRedirect', () => {
- it('calls visitUrl and setParams with the state.query', () => {
- return testAction(actions.resetLanguageQueryWithRedirect, null, state, [], [], () => {
- expect(urlUtils.setUrlParams).toHaveBeenCalledWith({ ...state.query, page: null });
- expect(urlUtils.visitUrl).toHaveBeenCalled();
- });
- });
- });
-
- describe('resetLanguageQuery', () => {
- it('calls commit SET_QUERY with value []', () => {
- state = { ...state, query: { ...state.query, language: ['YAML', 'Text', 'Markdown'] } };
- return testAction(
- actions.resetLanguageQuery,
- null,
- state,
- [{ type: types.SET_QUERY, payload: { key: 'language', value: [] } }],
- [],
- );
- });
- });
-
describe('closeLabel', () => {
beforeEach(() => {
state = createState({
diff --git a/spec/frontend/search/store/getters_spec.js b/spec/frontend/search/store/getters_spec.js
index 772acb39a57..66a888037ea 100644
--- a/spec/frontend/search/store/getters_spec.js
+++ b/spec/frontend/search/store/getters_spec.js
@@ -70,18 +70,6 @@ describe('Global Search Store Getters', () => {
});
});
- describe('currentUrlQueryHasLanguageFilters', () => {
- it.each`
- description | lang | result
- ${'has valid language'} | ${{ language: ['a', 'b'] }} | ${true}
- ${'has empty lang'} | ${{ language: [] }} | ${false}
- ${'has no lang'} | ${{}} | ${false}
- `('$description', ({ lang, result }) => {
- state.urlQuery = lang;
- expect(getters.currentUrlQueryHasLanguageFilters(state)).toBe(result);
- });
- });
-
describe('navigationItems', () => {
it('returns the re-mapped navigation data', () => {
state.navigation = MOCK_NAVIGATION;
diff --git a/spec/frontend/super_sidebar/components/context_header_spec.js b/spec/frontend/super_sidebar/components/context_header_spec.js
new file mode 100644
index 00000000000..943b659c997
--- /dev/null
+++ b/spec/frontend/super_sidebar/components/context_header_spec.js
@@ -0,0 +1,50 @@
+import { GlAvatar } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import ContextHeader from '~/super_sidebar/components/context_header.vue';
+
+describe('ContextHeader component', () => {
+ let wrapper;
+
+ const context = {
+ id: 1,
+ title: 'Title',
+ avatar: '/path/to/avatar.png',
+ };
+
+ const findGlAvatar = () => wrapper.getComponent(GlAvatar);
+
+ const createWrapper = (props = {}) => {
+ wrapper = shallowMountExtended(ContextHeader, {
+ propsData: {
+ context,
+ expanded: false,
+ ...props,
+ },
+ });
+ };
+
+ describe('with an avatar', () => {
+ it('passes the correct props to GlAvatar', () => {
+ createWrapper();
+ const avatar = findGlAvatar();
+
+ expect(avatar.props('shape')).toBe('rect');
+ expect(avatar.props('entityName')).toBe(context.title);
+ expect(avatar.props('entityId')).toBe(context.id);
+ expect(avatar.props('src')).toBe(context.avatar);
+ });
+
+ it('renders the avatar with a custom shape', () => {
+ const customShape = 'circle';
+ createWrapper({
+ context: {
+ ...context,
+ avatar_shape: customShape,
+ },
+ });
+ const avatar = findGlAvatar();
+
+ expect(avatar.props('shape')).toBe(customShape);
+ });
+ });
+});
diff --git a/spec/frontend/super_sidebar/components/context_switcher_toggle_spec.js b/spec/frontend/super_sidebar/components/context_switcher_toggle_spec.js
index 7172b60d0fa..c20d3c2745f 100644
--- a/spec/frontend/super_sidebar/components/context_switcher_toggle_spec.js
+++ b/spec/frontend/super_sidebar/components/context_switcher_toggle_spec.js
@@ -1,4 +1,4 @@
-import { GlAvatar } from '@gitlab/ui';
+import { GlIcon } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import ContextSwitcherToggle from '~/super_sidebar/components/context_switcher_toggle.vue';
@@ -11,7 +11,7 @@ describe('ContextSwitcherToggle component', () => {
avatar: '/path/to/avatar.png',
};
- const findGlAvatar = () => wrapper.getComponent(GlAvatar);
+ const findGlIcon = () => wrapper.getComponent(GlIcon);
const createWrapper = (props = {}) => {
wrapper = shallowMountExtended(ContextSwitcherToggle, {
@@ -23,28 +23,17 @@ describe('ContextSwitcherToggle component', () => {
});
};
- describe('with an avatar', () => {
- it('passes the correct props to GlAvatar', () => {
- createWrapper();
- const avatar = findGlAvatar();
+ it('renders "chevron-down" icon when not expanded', () => {
+ createWrapper();
- expect(avatar.props('shape')).toBe('rect');
- expect(avatar.props('entityName')).toBe(context.title);
- expect(avatar.props('entityId')).toBe(context.id);
- expect(avatar.props('src')).toBe(context.avatar);
- });
+ expect(findGlIcon().props('name')).toBe('chevron-down');
+ });
- it('renders the avatar with a custom shape', () => {
- const customShape = 'circle';
- createWrapper({
- context: {
- ...context,
- avatar_shape: customShape,
- },
- });
- const avatar = findGlAvatar();
-
- expect(avatar.props('shape')).toBe(customShape);
+ it('renders "chevron-up" icon when expanded', () => {
+ createWrapper({
+ expanded: true,
});
+
+ expect(findGlIcon().props('name')).toBe('chevron-up');
});
});
diff --git a/spec/frontend/super_sidebar/components/sidebar_menu_spec.js b/spec/frontend/super_sidebar/components/sidebar_menu_spec.js
index ac94f3f8f82..5d9a35fbf70 100644
--- a/spec/frontend/super_sidebar/components/sidebar_menu_spec.js
+++ b/spec/frontend/super_sidebar/components/sidebar_menu_spec.js
@@ -25,6 +25,7 @@ describe('Sidebar Menu', () => {
},
propsData: {
items: sidebarData.current_menu_items,
+ isLoggedIn: sidebarData.is_logged_in,
pinnedItemIds: sidebarData.pinned_items,
panelType: sidebarData.panel_type,
updatePinsUrl: sidebarData.update_pins_url,
diff --git a/spec/frontend/super_sidebar/components/sidebar_peek_behavior_spec.js b/spec/frontend/super_sidebar/components/sidebar_peek_behavior_spec.js
index abd9c1dc44d..94ef072a951 100644
--- a/spec/frontend/super_sidebar/components/sidebar_peek_behavior_spec.js
+++ b/spec/frontend/super_sidebar/components/sidebar_peek_behavior_spec.js
@@ -35,8 +35,10 @@ describe('SidebarPeek component', () => {
let wrapper;
let trackingSpy = null;
- const createComponent = () => {
- wrapper = mount(SidebarPeek);
+ const createComponent = (props = { isMouseOverSidebar: false }) => {
+ wrapper = mount(SidebarPeek, {
+ propsData: props,
+ });
};
const moveMouse = (clientX) => {
@@ -163,6 +165,17 @@ describe('SidebarPeek component', () => {
expect(lastNChangeEvents(2)).toEqual([STATE_OPEN, STATE_CLOSED]);
});
+ it('does not transition to will-close or closed when mouse is over sidebar child element', () => {
+ createComponent({ isMouseOverSidebar: true });
+ moveMouse(0);
+ jest.runOnlyPendingTimers();
+
+ moveMouse(X_SIDEBAR_EDGE);
+ moveMouse(X_AWAY_FROM_SIDEBAR);
+
+ expect(lastNChangeEvents(1)).toEqual([STATE_OPEN]);
+ });
+
it('immediately transitions will-close -> closed if mouse moves far away', () => {
moveMouse(0);
jest.runOnlyPendingTimers();
diff --git a/spec/frontend/super_sidebar/components/super_sidebar_spec.js b/spec/frontend/super_sidebar/components/super_sidebar_spec.js
index 0c785109b5e..7b7b8a7be13 100644
--- a/spec/frontend/super_sidebar/components/super_sidebar_spec.js
+++ b/spec/frontend/super_sidebar/components/super_sidebar_spec.js
@@ -11,6 +11,7 @@ import SidebarPeekBehavior, {
STATE_WILL_CLOSE,
} from '~/super_sidebar/components/sidebar_peek_behavior.vue';
import SidebarPortalTarget from '~/super_sidebar/components/sidebar_portal_target.vue';
+import ContextHeader from '~/super_sidebar/components/context_header.vue';
import ContextSwitcher from '~/super_sidebar/components/context_switcher.vue';
import SidebarMenu from '~/super_sidebar/components/sidebar_menu.vue';
import { sidebarState } from '~/super_sidebar/constants';
@@ -20,7 +21,7 @@ import {
} from '~/super_sidebar/super_sidebar_collapsed_state_manager';
import { stubComponent } from 'helpers/stub_component';
import { mockTracking, unmockTracking } from 'helpers/tracking_helper';
-import { sidebarData as mockSidebarData } from '../mock_data';
+import { sidebarData as mockSidebarData, loggedOutSidebarData } from '../mock_data';
const initialSidebarState = { ...sidebarState };
@@ -42,6 +43,7 @@ describe('SuperSidebar component', () => {
const findSidebar = () => wrapper.findByTestId('super-sidebar');
const findUserBar = () => wrapper.findComponent(UserBar);
+ const findContextHeader = () => wrapper.findComponent(ContextHeader);
const findContextSwitcher = () => wrapper.findComponent(ContextSwitcher);
const findNavContainer = () => wrapper.findByTestId('nav-container');
const findHelpCenter = () => wrapper.findComponent(HelpCenter);
@@ -230,6 +232,15 @@ describe('SuperSidebar component', () => {
expect(findSidebar().classes()).not.toContain(peekHintClass);
},
);
+
+ it('keeps track of if sidebar has mouseover or not', async () => {
+ createWrapper({ sidebarState: { isCollapsed: false, isPeekable: true } });
+ expect(findPeekBehavior().props('isMouseOverSidebar')).toBe(false);
+ await findSidebar().trigger('mouseenter');
+ expect(findPeekBehavior().props('isMouseOverSidebar')).toBe(true);
+ await findSidebar().trigger('mouseleave');
+ expect(findPeekBehavior().props('isMouseOverSidebar')).toBe(false);
+ });
});
describe('nav container', () => {
@@ -259,4 +270,15 @@ describe('SuperSidebar component', () => {
expect(findTrialStatusPopover().exists()).toBe(true);
});
});
+
+ describe('Logged out', () => {
+ beforeEach(() => {
+ createWrapper({ sidebarData: loggedOutSidebarData });
+ });
+
+ it('renders context header instead of context switcher', () => {
+ expect(findContextHeader().exists()).toBe(true);
+ expect(findContextSwitcher().exists()).toBe(false);
+ });
+ });
});
diff --git a/spec/frontend/super_sidebar/components/user_bar_spec.js b/spec/frontend/super_sidebar/components/user_bar_spec.js
index 272e0237219..d90553dfdd3 100644
--- a/spec/frontend/super_sidebar/components/user_bar_spec.js
+++ b/spec/frontend/super_sidebar/components/user_bar_spec.js
@@ -4,6 +4,7 @@ import Vue, { nextTick } from 'vue';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { __ } from '~/locale';
import CreateMenu from '~/super_sidebar/components/create_menu.vue';
+import UserMenu from '~/super_sidebar/components/user_menu.vue';
import SearchModal from '~/super_sidebar/components/global_search/components/global_search.vue';
import BrandLogo from 'jh_else_ce/super_sidebar/components/brand_logo.vue';
import MergeRequestMenu from '~/super_sidebar/components/merge_request_menu.vue';
@@ -11,13 +12,14 @@ import UserBar from '~/super_sidebar/components/user_bar.vue';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import waitForPromises from 'helpers/wait_for_promises';
import { userCounts } from '~/super_sidebar/user_counts_manager';
-import { sidebarData } from '../mock_data';
+import { sidebarData as mockSidebarData, loggedOutSidebarData } from '../mock_data';
import { MOCK_DEFAULT_SEARCH_OPTIONS } from './global_search/mock_data';
describe('UserBar component', () => {
let wrapper;
const findCreateMenu = () => wrapper.findComponent(CreateMenu);
+ const findUserMenu = () => wrapper.findComponent(UserMenu);
const findIssuesCounter = () => wrapper.findByTestId('issues-shortcut-button');
const findMRsCounter = () => wrapper.findByTestId('merge-requests-shortcut-button');
const findTodosCounter = () => wrapper.findByTestId('todos-shortcut-button');
@@ -37,13 +39,13 @@ describe('UserBar component', () => {
});
const createWrapper = ({
hasCollapseButton = true,
- extraSidebarData = {},
+ sidebarData = mockSidebarData,
provideOverrides = {},
} = {}) => {
wrapper = shallowMountExtended(UserBar, {
propsData: {
hasCollapseButton,
- sidebarData: { ...sidebarData, ...extraSidebarData },
+ sidebarData,
},
provide: {
toggleNewNavEndpoint: '/-/profile/preferences',
@@ -63,17 +65,17 @@ describe('UserBar component', () => {
});
it('passes the "Create new..." menu groups to the create-menu component', () => {
- expect(findCreateMenu().props('groups')).toBe(sidebarData.create_new_menu_groups);
+ expect(findCreateMenu().props('groups')).toBe(mockSidebarData.create_new_menu_groups);
});
it('passes the "Merge request" menu groups to the merge_request_menu component', () => {
- expect(findMergeRequestMenu().props('items')).toBe(sidebarData.merge_request_menu);
+ expect(findMergeRequestMenu().props('items')).toBe(mockSidebarData.merge_request_menu);
});
it('renders issues counter', () => {
const isuesCounter = findIssuesCounter();
expect(isuesCounter.props('count')).toBe(userCounts.assigned_issues);
- expect(isuesCounter.props('href')).toBe(sidebarData.issues_dashboard_path);
+ expect(isuesCounter.props('href')).toBe(mockSidebarData.issues_dashboard_path);
expect(isuesCounter.props('label')).toBe(__('Issues'));
expect(isuesCounter.attributes('data-track-action')).toBe('click_link');
expect(isuesCounter.attributes('data-track-label')).toBe('issues_link');
@@ -95,7 +97,7 @@ describe('UserBar component', () => {
describe('Todos counter', () => {
it('renders it', () => {
const todosCounter = findTodosCounter();
- expect(todosCounter.props('href')).toBe(sidebarData.todos_dashboard_path);
+ expect(todosCounter.props('href')).toBe(mockSidebarData.todos_dashboard_path);
expect(todosCounter.props('label')).toBe(__('To-Do list'));
expect(todosCounter.attributes('data-track-action')).toBe('click_link');
expect(todosCounter.attributes('data-track-label')).toBe('todos_link');
@@ -114,7 +116,7 @@ describe('UserBar component', () => {
it('renders branding logo', () => {
expect(findBrandLogo().exists()).toBe(true);
- expect(findBrandLogo().props('logoUrl')).toBe(sidebarData.logo_url);
+ expect(findBrandLogo().props('logoUrl')).toBe(mockSidebarData.logo_url);
});
it('does not render the "Stop impersonating" button', () => {
@@ -134,16 +136,16 @@ describe('UserBar component', () => {
describe('GitLab Next badge', () => {
describe('when on canary', () => {
it('should render a badge to switch off GitLab Next', () => {
- createWrapper({ extraSidebarData: { gitlab_com_and_canary: true } });
+ createWrapper({ sidebarData: { ...mockSidebarData, gitlab_com_and_canary: true } });
const badge = wrapper.findComponent(GlBadge);
expect(badge.text()).toBe('Next');
- expect(badge.attributes('href')).toBe(sidebarData.canary_toggle_com_url);
+ expect(badge.attributes('href')).toBe(mockSidebarData.canary_toggle_com_url);
});
});
describe('when not on canary', () => {
it('should not render the GitLab Next badge', () => {
- createWrapper({ extraSidebarData: { gitlab_com_and_canary: false } });
+ createWrapper({ sidebarData: { ...mockSidebarData, gitlab_com_and_canary: false } });
const badge = wrapper.findComponent(GlBadge);
expect(badge.exists()).toBe(false);
});
@@ -206,8 +208,36 @@ describe('UserBar component', () => {
it('sets the href and data-method attributes', () => {
const btn = findStopImpersonationButton();
- expect(btn.attributes('href')).toBe(sidebarData.stop_impersonation_path);
+ expect(btn.attributes('href')).toBe(mockSidebarData.stop_impersonation_path);
expect(btn.attributes('data-method')).toBe('delete');
});
});
+
+ describe('Logged out', () => {
+ beforeEach(() => {
+ createWrapper({ sidebarData: loggedOutSidebarData, gitlab_com_and_canary: true });
+ });
+
+ it('does not render brand logo', () => {
+ expect(findBrandLogo().exists()).toBe(false);
+ });
+
+ it('does not render Next badge', () => {
+ expect(wrapper.findComponent(GlBadge).exists()).toBe(false);
+ });
+
+ it('does not render create menu', () => {
+ expect(findCreateMenu().exists()).toBe(false);
+ });
+
+ it('does not render user menu', () => {
+ expect(findUserMenu().exists()).toBe(false);
+ });
+
+ it('does not render counters', () => {
+ expect(findIssuesCounter().exists()).toBe(false);
+ expect(findMRsCounter().exists()).toBe(false);
+ expect(findTodosCounter().exists()).toBe(false);
+ });
+ });
});
diff --git a/spec/frontend/super_sidebar/mock_data.js b/spec/frontend/super_sidebar/mock_data.js
index 72c67e34038..df45360a898 100644
--- a/spec/frontend/super_sidebar/mock_data.js
+++ b/spec/frontend/super_sidebar/mock_data.js
@@ -72,6 +72,7 @@ export const mergeRequestMenuGroup = [
];
export const sidebarData = {
+ is_logged_in: true,
current_menu_items: [],
current_context_header: {
title: 'Your Work',
@@ -120,6 +121,26 @@ export const sidebarData = {
],
};
+export const loggedOutSidebarData = {
+ is_logged_in: false,
+ current_menu_items: [],
+ current_context_header: {
+ title: 'Your Work',
+ icon: 'work',
+ },
+ support_path: '/support',
+ display_whats_new: true,
+ whats_new_most_recent_release_items_count: 5,
+ whats_new_version_digest: 1,
+ show_version_check: false,
+ gitlab_version: { major: 16, minor: 0 },
+ gitlab_version_check: { severity: 'success' },
+ search: {
+ search_path: '/search',
+ },
+ panel_type: 'your_work',
+};
+
export const userMenuMockStatus = {
can_update: false,
busy: false,
diff --git a/spec/helpers/application_settings_helper_spec.rb b/spec/helpers/application_settings_helper_spec.rb
index f924704ab54..9d591164547 100644
--- a/spec/helpers/application_settings_helper_spec.rb
+++ b/spec/helpers/application_settings_helper_spec.rb
@@ -74,6 +74,10 @@ RSpec.describe ApplicationSettingsHelper do
expect(helper.visible_attributes).to include(*params)
end
+ it 'contains :namespace_aggregation_schedule_lease_duration_in_seconds' do
+ expect(helper.visible_attributes).to include(:namespace_aggregation_schedule_lease_duration_in_seconds)
+ end
+
context 'when on SaaS', :saas do
it 'does not contain :deactivate_dormant_users' do
expect(helper.visible_attributes).not_to include(:deactivate_dormant_users)
diff --git a/spec/helpers/nav_helper_spec.rb b/spec/helpers/nav_helper_spec.rb
index 4a02b184522..4b83561b265 100644
--- a/spec/helpers/nav_helper_spec.rb
+++ b/spec/helpers/nav_helper_spec.rb
@@ -169,15 +169,39 @@ RSpec.describe NavHelper, feature_category: :navigation do
end
end
- context 'when nil is provided' do
- specify { expect(helper.show_super_sidebar?(nil)).to eq false }
+ shared_examples 'anonymous show_super_sidebar is supposed to' do
+ before do
+ stub_feature_flags(super_sidebar_logged_out: feature_flag)
+ end
+
+ context 'when super_sidebar_logged_out feature flag is disabled' do
+ let(:feature_flag) { false }
+
+ specify { expect(subject).to eq false }
+ end
+
+ context 'when super_sidebar_logged_out feature flag is enabled' do
+ let(:feature_flag) { true }
+
+ specify { expect(subject).to eq true }
+ end
end
- context 'when no user is signed-in' do
- specify do
- allow(helper).to receive(:current_user).and_return(nil)
+ context 'without a user' do
+ context 'with current_user (nil) as a default' do
+ before do
+ allow(helper).to receive(:current_user).and_return(nil)
+ end
+
+ subject { helper.show_super_sidebar? }
+
+ it_behaves_like 'anonymous show_super_sidebar is supposed to'
+ end
+
+ context 'with nil provided as an argument' do
+ subject { helper.show_super_sidebar?(nil) }
- expect(helper.show_super_sidebar?).to eq false
+ it_behaves_like 'anonymous show_super_sidebar is supposed to'
end
end
diff --git a/spec/helpers/sidebars_helper_spec.rb b/spec/helpers/sidebars_helper_spec.rb
index 8d8bbcd2737..1a81fec3a0b 100644
--- a/spec/helpers/sidebars_helper_spec.rb
+++ b/spec/helpers/sidebars_helper_spec.rb
@@ -91,10 +91,16 @@ RSpec.describe SidebarsHelper, feature_category: :navigation do
allow(user).to receive(:pinned_nav_items).and_return({ panel_type => %w[foo bar], 'another_panel' => %w[baz] })
end
+ # Tests for logged-out sidebar context
+ it_behaves_like 'logged-out super-sidebar context'
+
+ # Tests for logged-in sidebar context below
+ it_behaves_like 'shared super sidebar context'
+ it { is_expected.to include({ is_logged_in: true }) }
+
it 'returns sidebar values from user', :use_clean_rails_memory_store_caching do
expect(subject).to include({
- current_context_header: nil,
- current_menu_items: nil,
+ is_logged_in: true,
name: user.name,
username: user.username,
avatar_url: user.avatar_url,
@@ -128,25 +134,10 @@ RSpec.describe SidebarsHelper, feature_category: :navigation do
todos_dashboard_path: dashboard_todos_path,
projects_path: dashboard_projects_path,
groups_path: dashboard_groups_path,
- support_path: helper.support_url,
- display_whats_new: helper.display_whats_new?,
- whats_new_most_recent_release_items_count: helper.whats_new_most_recent_release_items_count,
- whats_new_version_digest: helper.whats_new_version_digest,
- show_version_check: helper.show_version_check?,
- gitlab_version: Gitlab.version_info,
- gitlab_version_check: helper.gitlab_version_check,
gitlab_com_but_not_canary: Gitlab.com_but_not_canary?,
gitlab_com_and_canary: Gitlab.com_and_canary?,
canary_toggle_com_url: Gitlab::Saas.canary_toggle_com_url,
- search: {
- search_path: search_path,
- issues_path: issues_dashboard_path,
- mr_path: merge_requests_dashboard_path,
- autocomplete_path: search_autocomplete_path,
- search_context: helper.header_search_context
- },
pinned_items: %w[foo bar],
- panel_type: panel_type,
update_pins_url: pins_url,
shortcut_links: [
{
@@ -471,8 +462,11 @@ RSpec.describe SidebarsHelper, feature_category: :navigation do
end
describe 'when impersonating' do
+ before do
+ session[:impersonator_id] = 5
+ end
+
it 'sets is_impersonating to `true`' do
- expect(helper).to receive(:session).and_return({ impersonator_id: 1 })
expect(subject[:is_impersonating]).to be(true)
end
end
diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb
index dfaba969153..6179c36b0ea 100644
--- a/spec/requests/api/settings_spec.rb
+++ b/spec/requests/api/settings_spec.rb
@@ -81,6 +81,7 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting, featu
expect(json_response['ci_max_includes']).to eq(150)
expect(json_response['allow_account_deletion']).to eq(true)
expect(json_response['gitlab_shell_operation_limit']).to eq(600)
+ expect(json_response['namespace_aggregation_schedule_lease_duration_in_seconds']).to eq(300)
end
end
@@ -193,7 +194,8 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting, featu
silent_mode_enabled: true,
valid_runner_registrars: ['group'],
allow_account_deletion: false,
- gitlab_shell_operation_limit: 500
+ gitlab_shell_operation_limit: 500,
+ namespace_aggregation_schedule_lease_duration_in_seconds: 400
}
expect(response).to have_gitlab_http_status(:ok)
@@ -270,6 +272,7 @@ RSpec.describe API::Settings, 'Settings', :do_not_mock_admin_mode_setting, featu
expect(json_response['valid_runner_registrars']).to eq(['group'])
expect(json_response['allow_account_deletion']).to be(false)
expect(json_response['gitlab_shell_operation_limit']).to be(500)
+ expect(json_response['namespace_aggregation_schedule_lease_duration_in_seconds']).to be(400)
end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 4d66784d943..651581ba270 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -295,8 +295,14 @@ RSpec.configure do |config|
# Only a few percent of users will be "enrolled" into the new nav with this flag.
# Having it enabled globally would make it impossible to test the current nav.
+ # https://gitlab.com/gitlab-org/gitlab/-/issues/420121
stub_feature_flags(super_sidebar_nav_enrolled: false)
+ # The anonymous super-sidebar is under heavy development and enabling the flag
+ # globally leads to a lot of errors. This issue is for fixing all test to work with the
+ # new nav: https://gitlab.com/gitlab-org/gitlab/-/issues/420119
+ stub_feature_flags(super_sidebar_logged_out: false)
+
# It's disabled in specs because we don't support certain features which
# cause spec failures.
stub_feature_flags(gitlab_error_tracking: false)
diff --git a/spec/support/shared_examples/helpers/super_sidebar_shared_examples.rb b/spec/support/shared_examples/helpers/super_sidebar_shared_examples.rb
new file mode 100644
index 00000000000..636b9870bd7
--- /dev/null
+++ b/spec/support/shared_examples/helpers/super_sidebar_shared_examples.rb
@@ -0,0 +1,35 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'shared super sidebar context' do
+ it 'returns sidebar values for logged-in users and logged-out users', :use_clean_rails_memory_store_caching do
+ expect(subject).to include({
+ current_menu_items: nil,
+ current_context_header: nil,
+ support_path: helper.support_url,
+ display_whats_new: helper.display_whats_new?,
+ whats_new_most_recent_release_items_count: helper.whats_new_most_recent_release_items_count,
+ whats_new_version_digest: helper.whats_new_version_digest,
+ show_version_check: helper.show_version_check?,
+ gitlab_version: Gitlab.version_info,
+ gitlab_version_check: helper.gitlab_version_check,
+ search: {
+ search_path: search_path,
+ issues_path: issues_dashboard_path,
+ mr_path: merge_requests_dashboard_path,
+ autocomplete_path: search_autocomplete_path,
+ search_context: helper.header_search_context
+ },
+ panel_type: panel_type
+ })
+ end
+end
+
+RSpec.shared_examples 'logged-out super-sidebar context' do
+ subject do
+ helper.super_sidebar_context(nil, group: nil, project: nil, panel: panel, panel_type: panel_type)
+ end
+
+ it_behaves_like 'shared super sidebar context'
+
+ it { is_expected.to include({ is_logged_in: false }) }
+end