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
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2023-04-03 21:08:58 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2023-04-03 21:08:58 +0300
commit7c8468c5ba828e1c1afe6ba0b25c77c130a69413 (patch)
tree3104d62bff9040a19756b9d407003eed14314f77 /spec/frontend
parent2a7fd3827b0838a900399b0c3440942cdaa09c75 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
-rw-r--r--spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/rules_item_spec.js70
-rw-r--r--spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer_spec.js57
-rw-r--r--spec/frontend/fixtures/projects.rb2
-rw-r--r--spec/frontend/packages_and_registries/package_registry/pages/list_spec.js56
-rw-r--r--spec/frontend/projects/commit/components/branches_dropdown_spec.js4
-rw-r--r--spec/frontend/sidebar/components/subscriptions/subscriptions_spec.js61
-rw-r--r--spec/frontend/vue_shared/components/markdown/markdown_editor_spec.js10
7 files changed, 220 insertions, 40 deletions
diff --git a/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/rules_item_spec.js b/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/rules_item_spec.js
new file mode 100644
index 00000000000..659ccb25996
--- /dev/null
+++ b/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/rules_item_spec.js
@@ -0,0 +1,70 @@
+import RulesItem from '~/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/rules_item.vue';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import {
+ JOB_TEMPLATE,
+ JOB_RULES_WHEN,
+ JOB_RULES_START_IN,
+} from '~/ci/pipeline_editor/components/job_assistant_drawer/constants';
+
+describe('Rules item', () => {
+ let wrapper;
+
+ const findRulesWhenSelect = () => wrapper.findByTestId('rules-when-select');
+ const findRulesStartInNumberInput = () => wrapper.findByTestId('rules-start-in-number-input');
+ const findRulesStartInUnitSelect = () => wrapper.findByTestId('rules-start-in-unit-select');
+ const findRulesAllowFailureCheckBox = () => wrapper.findByTestId('rules-allow-failure-checkbox');
+
+ const dummyRulesWhen = JOB_RULES_WHEN.delayed.value;
+ const dummyRulesStartInNumber = 2;
+ const dummyRulesStartInUnit = JOB_RULES_START_IN.week.value;
+ const dummyRulesAllowFailure = true;
+
+ const createComponent = () => {
+ wrapper = shallowMountExtended(RulesItem, {
+ propsData: {
+ isStartValid: true,
+ job: JSON.parse(JSON.stringify(JOB_TEMPLATE)),
+ },
+ });
+ };
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('should emit update job event when filling inputs', () => {
+ expect(wrapper.emitted('update-job')).toBeUndefined();
+
+ findRulesWhenSelect().vm.$emit('input', dummyRulesWhen);
+
+ expect(wrapper.emitted('update-job')).toHaveLength(1);
+ expect(wrapper.emitted('update-job')[0]).toEqual([
+ 'rules[0].when',
+ JOB_RULES_WHEN.delayed.value,
+ ]);
+
+ findRulesStartInNumberInput().vm.$emit('input', dummyRulesStartInNumber);
+
+ expect(wrapper.emitted('update-job')).toHaveLength(2);
+ expect(wrapper.emitted('update-job')[1]).toEqual([
+ 'rules[0].start_in',
+ `2 ${JOB_RULES_START_IN.second.value}s`,
+ ]);
+
+ findRulesStartInUnitSelect().vm.$emit('input', dummyRulesStartInUnit);
+
+ expect(wrapper.emitted('update-job')).toHaveLength(3);
+ expect(wrapper.emitted('update-job')[2]).toEqual([
+ 'rules[0].start_in',
+ `2 ${dummyRulesStartInUnit}s`,
+ ]);
+
+ findRulesAllowFailureCheckBox().vm.$emit('input', dummyRulesAllowFailure);
+
+ expect(wrapper.emitted('update-job')).toHaveLength(4);
+ expect(wrapper.emitted('update-job')[3]).toEqual([
+ 'rules[0].allow_failure',
+ dummyRulesAllowFailure,
+ ]);
+ });
+});
diff --git a/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer_spec.js b/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer_spec.js
index 356de5b11e9..e03cd19da65 100644
--- a/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer_spec.js
+++ b/spec/frontend/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer_spec.js
@@ -5,6 +5,8 @@ import { stringify } from 'yaml';
import JobAssistantDrawer from '~/ci/pipeline_editor/components/job_assistant_drawer/job_assistant_drawer.vue';
import JobSetupItem from '~/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/job_setup_item.vue';
import ImageItem from '~/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/image_item.vue';
+import RulesItem from '~/ci/pipeline_editor/components/job_assistant_drawer/accordion_items/rules_item.vue';
+import { JOB_RULES_WHEN } from '~/ci/pipeline_editor/components/job_assistant_drawer/constants';
import getRunnerTags from '~/ci/pipeline_editor/graphql/queries/runner_tags.query.graphql';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -23,10 +25,14 @@ describe('Job assistant drawer', () => {
const dummyJobScript = 'b';
const dummyImageName = 'c';
const dummyImageEntrypoint = 'd';
+ const dummyRulesWhen = JOB_RULES_WHEN.delayed.value;
+ const dummyRulesStartIn = '1 second';
+ const dummyRulesAllowFailure = true;
const findDrawer = () => wrapper.findComponent(GlDrawer);
const findJobSetupItem = () => wrapper.findComponent(JobSetupItem);
const findImageItem = () => wrapper.findComponent(ImageItem);
+ const findRulesItem = () => wrapper.findComponent(RulesItem);
const findConfirmButton = () => wrapper.findByTestId('confirm-button');
const findCancelButton = () => wrapper.findByTestId('cancel-button');
@@ -68,6 +74,10 @@ describe('Job assistant drawer', () => {
expect(findImageItem().exists()).toBe(true);
});
+ it('should contain rules accordion', () => {
+ expect(findRulesItem().exists()).toBe(true);
+ });
+
it('should emit close job assistant drawer event when closing the drawer', () => {
expect(wrapper.emitted('close-job-assistant-drawer')).toBeUndefined();
@@ -84,7 +94,7 @@ describe('Job assistant drawer', () => {
expect(wrapper.emitted('close-job-assistant-drawer')).toHaveLength(1);
});
- it('trigger validate if job name is empty', async () => {
+ it('should block submit if job name is empty', async () => {
findJobSetupItem().vm.$emit('update-job', 'script', 'b');
findConfirmButton().trigger('click');
@@ -95,12 +105,25 @@ describe('Job assistant drawer', () => {
expect(wrapper.emitted('updateCiConfig')).toBeUndefined();
});
+ it('should block submit if rules when is delayed and start in is out of range', async () => {
+ findRulesItem().vm.$emit('update-job', 'rules[0].when', JOB_RULES_WHEN.delayed.value);
+ findRulesItem().vm.$emit('update-job', 'rules[0].start_in', '2 weeks');
+ findConfirmButton().trigger('click');
+
+ await nextTick();
+
+ expect(wrapper.emitted('updateCiConfig')).toBeUndefined();
+ });
+
describe('when enter valid input', () => {
beforeEach(() => {
findJobSetupItem().vm.$emit('update-job', 'name', dummyJobName);
findJobSetupItem().vm.$emit('update-job', 'script', dummyJobScript);
findImageItem().vm.$emit('update-job', 'image.name', dummyImageName);
findImageItem().vm.$emit('update-job', 'image.entrypoint', [dummyImageEntrypoint]);
+ findRulesItem().vm.$emit('update-job', 'rules[0].allow_failure', dummyRulesAllowFailure);
+ findRulesItem().vm.$emit('update-job', 'rules[0].when', dummyRulesWhen);
+ findRulesItem().vm.$emit('update-job', 'rules[0].start_in', dummyRulesStartIn);
});
it('passes correct prop to accordions', () => {
@@ -113,6 +136,13 @@ describe('Job assistant drawer', () => {
name: dummyImageName,
entrypoint: [dummyImageEntrypoint],
},
+ rules: [
+ {
+ allow_failure: dummyRulesAllowFailure,
+ when: dummyRulesWhen,
+ start_in: dummyRulesStartIn,
+ },
+ ],
});
});
});
@@ -138,6 +168,24 @@ describe('Job assistant drawer', () => {
expect(findJobSetupItem().props('job')).toMatchObject({ name: '', script: '' });
});
+ it('should omit keys with default value when click add button', () => {
+ findRulesItem().vm.$emit('update-job', 'rules[0].allow_failure', false);
+ findRulesItem().vm.$emit('update-job', 'rules[0].when', JOB_RULES_WHEN.onSuccess.value);
+ findRulesItem().vm.$emit('update-job', 'rules[0].start_in', dummyRulesStartIn);
+ findConfirmButton().trigger('click');
+
+ expect(wrapper.emitted('updateCiConfig')).toStrictEqual([
+ [
+ `${wrapper.props('ciFileContent')}\n${stringify({
+ [dummyJobName]: {
+ script: dummyJobScript,
+ image: { name: dummyImageName, entrypoint: [dummyImageEntrypoint] },
+ },
+ })}`,
+ ],
+ ]);
+ });
+
it('should update correct ci content when click add button', () => {
findConfirmButton().trigger('click');
@@ -147,6 +195,13 @@ describe('Job assistant drawer', () => {
[dummyJobName]: {
script: dummyJobScript,
image: { name: dummyImageName, entrypoint: [dummyImageEntrypoint] },
+ rules: [
+ {
+ allow_failure: dummyRulesAllowFailure,
+ when: dummyRulesWhen,
+ start_in: dummyRulesStartIn,
+ },
+ ],
},
})}`,
],
diff --git a/spec/frontend/fixtures/projects.rb b/spec/frontend/fixtures/projects.rb
index 2ccf2c0392f..8cd651c5b36 100644
--- a/spec/frontend/fixtures/projects.rb
+++ b/spec/frontend/fixtures/projects.rb
@@ -67,7 +67,7 @@ RSpec.describe 'Projects (JavaScript fixtures)', type: :controller do
end
end
- describe 'Storage', feature_category: :subscription_cost_management do
+ describe 'Storage', feature_category: :consumables_cost_management do
describe GraphQL::Query, type: :request do
include GraphqlHelpers
context 'project storage statistics query' do
diff --git a/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js b/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js
index 60bb055b1db..6cfc80966b5 100644
--- a/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/pages/list_spec.js
@@ -1,9 +1,11 @@
-import { GlEmptyState, GlSprintf, GlLink } from '@gitlab/ui';
+import { GlButton, GlEmptyState, GlSprintf, GlLink } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import { s__ } from '~/locale';
import { WORKSPACE_GROUP, WORKSPACE_PROJECT } from '~/issues/constants';
import ListPage from '~/packages_and_registries/package_registry/pages/list.vue';
import PackageTitle from '~/packages_and_registries/package_registry/components/list/package_title.vue';
@@ -30,6 +32,7 @@ describe('PackagesListApp', () => {
emptyListIllustration: 'emptyListIllustration',
isGroupPage: true,
fullPath: 'gitlab-org',
+ settingsPath: 'settings-path',
};
const PackageList = {
@@ -49,6 +52,7 @@ describe('PackagesListApp', () => {
const findListComponent = () => wrapper.findComponent(PackageList);
const findEmptyState = () => wrapper.findComponent(GlEmptyState);
const findDeletePackages = () => wrapper.findComponent(DeletePackages);
+ const findSettingsLink = () => wrapper.findComponent(GlButton);
const mountComponent = ({
resolver = jest.fn().mockResolvedValue(packagesListQuery()),
@@ -71,9 +75,13 @@ describe('PackagesListApp', () => {
GlLoadingIcon,
GlSprintf,
GlLink,
+ PackageTitle,
PackageList,
DeletePackages,
},
+ directives: {
+ GlTooltip: createMockDirective('gl-tooltip'),
+ },
});
};
@@ -103,6 +111,52 @@ describe('PackagesListApp', () => {
});
});
+ describe('link to settings', () => {
+ describe('when settings path is not provided', () => {
+ beforeEach(() => {
+ mountComponent({
+ provide: {
+ ...defaultProvide,
+ settingsPath: '',
+ },
+ });
+ });
+
+ it('is not rendered', () => {
+ expect(findSettingsLink().exists()).toBe(false);
+ });
+ });
+
+ describe('when settings path is provided', () => {
+ const label = s__('PackageRegistry|Configure in settings');
+
+ beforeEach(() => {
+ mountComponent();
+ });
+
+ it('is rendered', () => {
+ expect(findSettingsLink().exists()).toBe(true);
+ });
+
+ it('has the right icon', () => {
+ expect(findSettingsLink().props('icon')).toBe('settings');
+ });
+
+ it('has the right attributes', () => {
+ expect(findSettingsLink().attributes()).toMatchObject({
+ 'aria-label': label,
+ href: defaultProvide.settingsPath,
+ });
+ });
+
+ it('sets tooltip with right label', () => {
+ const tooltip = getBinding(findSettingsLink().element, 'gl-tooltip');
+
+ expect(tooltip.value).toBe(label);
+ });
+ });
+ });
+
describe('search component', () => {
it('exists', () => {
mountComponent();
diff --git a/spec/frontend/projects/commit/components/branches_dropdown_spec.js b/spec/frontend/projects/commit/components/branches_dropdown_spec.js
index 0e68bd21cd4..5210abe154d 100644
--- a/spec/frontend/projects/commit/components/branches_dropdown_spec.js
+++ b/spec/frontend/projects/commit/components/branches_dropdown_spec.js
@@ -68,13 +68,11 @@ describe('BranchesDropdown', () => {
describe('When searching', () => {
it('invokes fetchBranches', async () => {
- const spy = jest.spyOn(wrapper.vm, 'fetchBranches');
-
findDropdown().vm.$emit('search', '_anything_');
await nextTick();
- expect(spy).toHaveBeenCalledWith('_anything_');
+ expect(spyFetchBranches).toHaveBeenCalledWith(expect.any(Object), '_anything_');
});
});
});
diff --git a/spec/frontend/sidebar/components/subscriptions/subscriptions_spec.js b/spec/frontend/sidebar/components/subscriptions/subscriptions_spec.js
index cae21189ee0..b644b7a9421 100644
--- a/spec/frontend/sidebar/components/subscriptions/subscriptions_spec.js
+++ b/spec/frontend/sidebar/components/subscriptions/subscriptions_spec.js
@@ -1,23 +1,24 @@
import { GlToggle } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import { extendedWrapper } from 'helpers/vue_test_utils_helper';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { mockTracking } from 'helpers/tracking_helper';
import Subscriptions from '~/sidebar/components/subscriptions/subscriptions.vue';
import eventHub from '~/sidebar/event_hub';
describe('Subscriptions', () => {
let wrapper;
+ let trackingSpy;
const findToggleButton = () => wrapper.findComponent(GlToggle);
+ const findTooltip = () => wrapper.findComponent({ ref: 'tooltip' });
- const mountComponent = (propsData) =>
- extendedWrapper(
- shallowMount(Subscriptions, {
- propsData,
- }),
- );
+ const mountComponent = (propsData) => {
+ wrapper = shallowMountExtended(Subscriptions, {
+ propsData,
+ });
+ };
it('shows loading spinner when loading', () => {
- wrapper = mountComponent({
+ mountComponent({
loading: true,
subscribed: undefined,
});
@@ -26,7 +27,7 @@ describe('Subscriptions', () => {
});
it('is toggled "off" when currently not subscribed', () => {
- wrapper = mountComponent({
+ mountComponent({
subscribed: false,
});
@@ -34,7 +35,7 @@ describe('Subscriptions', () => {
});
it('is toggled "on" when currently subscribed', () => {
- wrapper = mountComponent({
+ mountComponent({
subscribed: true,
});
@@ -43,44 +44,38 @@ describe('Subscriptions', () => {
it('toggleSubscription method emits `toggleSubscription` event on eventHub and Component', () => {
const id = 42;
- wrapper = mountComponent({ subscribed: true, id });
+ mountComponent({ subscribed: true, id });
const eventHubSpy = jest.spyOn(eventHub, '$emit');
- const wrapperEmitSpy = jest.spyOn(wrapper.vm, '$emit');
- wrapper.vm.toggleSubscription();
+ findToggleButton().vm.$emit('change');
expect(eventHubSpy).toHaveBeenCalledWith('toggleSubscription', id);
- expect(wrapperEmitSpy).toHaveBeenCalledWith('toggleSubscription', id);
- eventHubSpy.mockRestore();
- wrapperEmitSpy.mockRestore();
+ expect(wrapper.emitted('toggleSubscription')).toEqual([[id]]);
});
it('tracks the event when toggled', () => {
- wrapper = mountComponent({ subscribed: true });
-
- const wrapperTrackSpy = jest.spyOn(wrapper.vm, 'track');
+ trackingSpy = mockTracking('_category_', undefined, jest.spyOn);
+ mountComponent({ subscribed: true });
- wrapper.vm.toggleSubscription();
+ findToggleButton().vm.$emit('change');
- expect(wrapperTrackSpy).toHaveBeenCalledWith('toggle_button', {
+ expect(trackingSpy).toHaveBeenCalledWith(undefined, 'toggle_button', {
+ category: undefined,
+ label: 'right_sidebar',
property: 'notifications',
value: 0,
});
- wrapperTrackSpy.mockRestore();
});
it('onClickCollapsedIcon method emits `toggleSidebar` event on component', () => {
- wrapper = mountComponent({ subscribed: true });
- const spy = jest.spyOn(wrapper.vm, '$emit');
-
- wrapper.vm.onClickCollapsedIcon();
+ mountComponent({ subscribed: true });
+ findTooltip().trigger('click');
- expect(spy).toHaveBeenCalledWith('toggleSidebar');
- spy.mockRestore();
+ expect(wrapper.emitted('toggleSidebar')).toHaveLength(1);
});
it('has visually hidden label', () => {
- wrapper = mountComponent();
+ mountComponent();
expect(findToggleButton().props()).toMatchObject({
label: 'Notifications',
@@ -92,7 +87,7 @@ describe('Subscriptions', () => {
const subscribeDisabledDescription = 'Notifications have been disabled';
beforeEach(() => {
- wrapper = mountComponent({
+ mountComponent({
subscribed: false,
projectEmailsDisabled: true,
subscribeDisabledDescription,
@@ -103,9 +98,7 @@ describe('Subscriptions', () => {
expect(wrapper.findByTestId('subscription-title').text()).toContain(
subscribeDisabledDescription,
);
- expect(wrapper.findComponent({ ref: 'tooltip' }).attributes('title')).toBe(
- subscribeDisabledDescription,
- );
+ expect(findTooltip().attributes('title')).toBe(subscribeDisabledDescription);
});
it('does not render the toggle button', () => {
diff --git a/spec/frontend/vue_shared/components/markdown/markdown_editor_spec.js b/spec/frontend/vue_shared/components/markdown/markdown_editor_spec.js
index 7bda37bcaa8..3964d895b4b 100644
--- a/spec/frontend/vue_shared/components/markdown/markdown_editor_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/markdown_editor_spec.js
@@ -346,6 +346,16 @@ describe('vue_shared/component/markdown/markdown_editor', () => {
});
});
+ describe('when contentEditor is disabled', () => {
+ it('resets the editingMode to markdownField', async () => {
+ localStorage.setItem('gl-markdown-editor-mode', 'contentEditor');
+
+ buildWrapper({ propsData: { autosaveKey: 'issue/1234', enableContentEditor: false } });
+
+ expect(wrapper.vm.editingMode).toBe(EDITING_MODE_MARKDOWN_FIELD);
+ });
+ });
+
describe(`when editingMode is ${EDITING_MODE_CONTENT_EDITOR}`, () => {
beforeEach(async () => {
buildWrapper({ propsData: { autosaveKey: 'issue/1234' } });