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>2022-02-15 00:12:27 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-02-15 00:12:27 +0300
commite916a9880b4ea8c7cd4d521b4260c4732e8e2978 (patch)
treedcc8f147c8152b25b738a7fbbfac79040ea6ae8d /spec/frontend
parent4db74ea1477fe70d132bf75f1bf3f1a728fc72e4 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
-rw-r--r--spec/frontend/groups/components/invite_members_banner_spec.js1
-rw-r--r--spec/frontend/invite_members/components/invite_members_modal_spec.js2
-rw-r--r--spec/frontend/invite_members/components/invite_members_trigger_spec.js1
-rw-r--r--spec/frontend/mocks_spec.js11
-rw-r--r--spec/frontend/notebook/cells/code_spec.js12
-rw-r--r--spec/frontend/notebook/cells/output/index_spec.js36
-rw-r--r--spec/frontend/notebook/cells/prompt_spec.js14
-rw-r--r--spec/frontend/notebook/index_spec.js20
-rw-r--r--spec/frontend/notes/deprecated_notes_spec.js81
-rw-r--r--spec/frontend/pager_spec.js57
-rw-r--r--spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js6
-rw-r--r--spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js1
-rw-r--r--spec/frontend/pipeline_wizard/components/widgets/text_spec.js152
-rw-r--r--spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_pipeline_failed_spec.js.snap2
14 files changed, 249 insertions, 147 deletions
diff --git a/spec/frontend/groups/components/invite_members_banner_spec.js b/spec/frontend/groups/components/invite_members_banner_spec.js
index ef784018205..1924f400861 100644
--- a/spec/frontend/groups/components/invite_members_banner_spec.js
+++ b/spec/frontend/groups/components/invite_members_banner_spec.js
@@ -76,7 +76,6 @@ describe('InviteMembersBanner', () => {
it('calls openModal through the eventHub', () => {
expect(eventHub.$emit).toHaveBeenCalledWith('openModal', {
- inviteeType: 'members',
source: 'invite_members_banner',
});
});
diff --git a/spec/frontend/invite_members/components/invite_members_modal_spec.js b/spec/frontend/invite_members/components/invite_members_modal_spec.js
index 090efc4d4c3..15a366474e4 100644
--- a/spec/frontend/invite_members/components/invite_members_modal_spec.js
+++ b/spec/frontend/invite_members/components/invite_members_modal_spec.js
@@ -694,7 +694,7 @@ describe('InviteMembersModal', () => {
});
it('tracks the view for learn_gitlab source', () => {
- eventHub.$emit('openModal', { inviteeType: 'members', source: LEARN_GITLAB });
+ eventHub.$emit('openModal', { source: LEARN_GITLAB });
expect(ExperimentTracking).toHaveBeenCalledWith(INVITE_MEMBERS_FOR_TASK.name);
expect(ExperimentTracking.prototype.event).toHaveBeenCalledWith(LEARN_GITLAB);
diff --git a/spec/frontend/invite_members/components/invite_members_trigger_spec.js b/spec/frontend/invite_members/components/invite_members_trigger_spec.js
index 429b6fad24a..28402c8331c 100644
--- a/spec/frontend/invite_members/components/invite_members_trigger_spec.js
+++ b/spec/frontend/invite_members/components/invite_members_trigger_spec.js
@@ -71,7 +71,6 @@ describe.each(triggerItems)('with triggerElement as %s', (triggerItem) => {
findButton().vm.$emit('click');
expect(spy).toHaveBeenCalledWith('openModal', {
- inviteeType: 'members',
source: triggerSource,
});
});
diff --git a/spec/frontend/mocks_spec.js b/spec/frontend/mocks_spec.js
index 110c418e579..0813d2073b9 100644
--- a/spec/frontend/mocks_spec.js
+++ b/spec/frontend/mocks_spec.js
@@ -8,13 +8,10 @@ describe('Mock auto-injection', () => {
failMock = jest.spyOn(global, 'fail').mockImplementation();
});
- it('~/lib/utils/axios_utils', () => {
- return Promise.all([
- expect(axios.get('http://gitlab.com')).rejects.toThrow('Unexpected unmocked request'),
- setImmediate(() => {
- expect(failMock).toHaveBeenCalledTimes(1);
- }),
- ]);
+ it('~/lib/utils/axios_utils', async () => {
+ await expect(axios.get('http://gitlab.com')).rejects.toThrow('Unexpected unmocked request');
+
+ expect(failMock).toHaveBeenCalledTimes(1);
});
it('jQuery.ajax()', () => {
diff --git a/spec/frontend/notebook/cells/code_spec.js b/spec/frontend/notebook/cells/code_spec.js
index 6a51731c909..9a2db061278 100644
--- a/spec/frontend/notebook/cells/code_spec.js
+++ b/spec/frontend/notebook/cells/code_spec.js
@@ -25,12 +25,10 @@ describe('Code component', () => {
};
describe('without output', () => {
- beforeEach((done) => {
+ beforeEach(() => {
vm = setupComponent(json.cells[0]);
- setImmediate(() => {
- done();
- });
+ return nextTick();
});
it('does not render output prompt', () => {
@@ -39,12 +37,10 @@ describe('Code component', () => {
});
describe('with output', () => {
- beforeEach((done) => {
+ beforeEach(() => {
vm = setupComponent(json.cells[2]);
- setImmediate(() => {
- done();
- });
+ return nextTick();
});
it('does not render output prompt', () => {
diff --git a/spec/frontend/notebook/cells/output/index_spec.js b/spec/frontend/notebook/cells/output/index_spec.js
index 7ece73d375c..8e04e4c146c 100644
--- a/spec/frontend/notebook/cells/output/index_spec.js
+++ b/spec/frontend/notebook/cells/output/index_spec.js
@@ -1,4 +1,4 @@
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import json from 'test_fixtures/blob/notebook/basic.json';
import CodeComponent from '~/notebook/cells/output/index.vue';
@@ -18,13 +18,11 @@ describe('Output component', () => {
};
describe('text output', () => {
- beforeEach((done) => {
+ beforeEach(() => {
const textType = json.cells[2];
createComponent(textType.outputs[0]);
- setImmediate(() => {
- done();
- });
+ return nextTick();
});
it('renders as plain text', () => {
@@ -37,13 +35,11 @@ describe('Output component', () => {
});
describe('image output', () => {
- beforeEach((done) => {
+ beforeEach(() => {
const imageType = json.cells[3];
createComponent(imageType.outputs[0]);
- setImmediate(() => {
- done();
- });
+ return nextTick();
});
it('renders as an image', () => {
@@ -86,13 +82,11 @@ describe('Output component', () => {
});
describe('svg output', () => {
- beforeEach((done) => {
+ beforeEach(() => {
const svgType = json.cells[5];
createComponent(svgType.outputs[0]);
- setImmediate(() => {
- done();
- });
+ return nextTick();
});
it('renders as an svg', () => {
@@ -101,13 +95,11 @@ describe('Output component', () => {
});
describe('default to plain text', () => {
- beforeEach((done) => {
+ beforeEach(() => {
const unknownType = json.cells[6];
createComponent(unknownType.outputs[0]);
- setImmediate(() => {
- done();
- });
+ return nextTick();
});
it('renders as plain text', () => {
@@ -119,16 +111,14 @@ describe('Output component', () => {
expect(vm.$el.querySelector('.prompt span')).not.toBeNull();
});
- it("renders as plain text when doesn't recognise other types", (done) => {
+ it("renders as plain text when doesn't recognise other types", async () => {
const unknownType = json.cells[7];
createComponent(unknownType.outputs[0]);
- setImmediate(() => {
- expect(vm.$el.querySelector('pre')).not.toBeNull();
- expect(vm.$el.textContent.trim()).toContain('testing');
+ await nextTick();
- done();
- });
+ expect(vm.$el.querySelector('pre')).not.toBeNull();
+ expect(vm.$el.textContent.trim()).toContain('testing');
});
});
});
diff --git a/spec/frontend/notebook/cells/prompt_spec.js b/spec/frontend/notebook/cells/prompt_spec.js
index 8cdcd1f84de..89b2d7b2b90 100644
--- a/spec/frontend/notebook/cells/prompt_spec.js
+++ b/spec/frontend/notebook/cells/prompt_spec.js
@@ -1,4 +1,4 @@
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import PromptComponent from '~/notebook/cells/prompt.vue';
const Component = Vue.extend(PromptComponent);
@@ -7,7 +7,7 @@ describe('Prompt component', () => {
let vm;
describe('input', () => {
- beforeEach((done) => {
+ beforeEach(() => {
vm = new Component({
propsData: {
type: 'In',
@@ -16,9 +16,7 @@ describe('Prompt component', () => {
});
vm.$mount();
- setImmediate(() => {
- done();
- });
+ return nextTick();
});
it('renders in label', () => {
@@ -31,7 +29,7 @@ describe('Prompt component', () => {
});
describe('output', () => {
- beforeEach((done) => {
+ beforeEach(() => {
vm = new Component({
propsData: {
type: 'Out',
@@ -40,9 +38,7 @@ describe('Prompt component', () => {
});
vm.$mount();
- setImmediate(() => {
- done();
- });
+ return nextTick();
});
it('renders in label', () => {
diff --git a/spec/frontend/notebook/index_spec.js b/spec/frontend/notebook/index_spec.js
index cd531d628b3..475c41a72f6 100644
--- a/spec/frontend/notebook/index_spec.js
+++ b/spec/frontend/notebook/index_spec.js
@@ -1,5 +1,5 @@
import { mount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import json from 'test_fixtures/blob/notebook/basic.json';
import jsonWithWorksheet from 'test_fixtures/blob/notebook/worksheets.json';
import Notebook from '~/notebook/index.vue';
@@ -17,12 +17,10 @@ describe('Notebook component', () => {
}
describe('without JSON', () => {
- beforeEach((done) => {
+ beforeEach(() => {
vm = buildComponent({});
- setImmediate(() => {
- done();
- });
+ return nextTick();
});
it('does not render', () => {
@@ -31,12 +29,10 @@ describe('Notebook component', () => {
});
describe('with JSON', () => {
- beforeEach((done) => {
+ beforeEach(() => {
vm = buildComponent(json);
- setImmediate(() => {
- done();
- });
+ return nextTick();
});
it('renders cells', () => {
@@ -57,12 +53,10 @@ describe('Notebook component', () => {
});
describe('with worksheets', () => {
- beforeEach((done) => {
+ beforeEach(() => {
vm = buildComponent(jsonWithWorksheet);
- setImmediate(() => {
- done();
- });
+ return nextTick();
});
it('renders cells', () => {
diff --git a/spec/frontend/notes/deprecated_notes_spec.js b/spec/frontend/notes/deprecated_notes_spec.js
index 34623f8aa13..7c52920da90 100644
--- a/spec/frontend/notes/deprecated_notes_spec.js
+++ b/spec/frontend/notes/deprecated_notes_spec.js
@@ -5,6 +5,7 @@ import $ from 'jquery';
import '~/behaviors/markdown/render_gfm';
import { createSpyObj } from 'helpers/jest_helpers';
import { TEST_HOST } from 'helpers/test_constants';
+import waitForPromises from 'helpers/wait_for_promises';
import { setTestTimeoutOnce } from 'helpers/timeout';
import axios from '~/lib/utils/axios_utils';
import * as urlUtility from '~/lib/utils/url_utility';
@@ -549,15 +550,14 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => {
expect($notesContainer.find('.note.being-posted').length).toBeGreaterThan(0);
});
- it('should remove placeholder note when new comment is done posting', (done) => {
+ it('should remove placeholder note when new comment is done posting', async () => {
mockNotesPost();
$('.js-comment-button').click();
- setImmediate(() => {
- expect($notesContainer.find('.note.being-posted').length).toEqual(0);
- done();
- });
+ await waitForPromises();
+
+ expect($notesContainer.find('.note.being-posted').length).toEqual(0);
});
describe('postComment', () => {
@@ -584,40 +584,37 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => {
});
});
- it('should show actual note element when new comment is done posting', (done) => {
+ it('should show actual note element when new comment is done posting', async () => {
mockNotesPost();
$('.js-comment-button').click();
- setImmediate(() => {
- expect($notesContainer.find(`#note_${note.id}`).length).toBeGreaterThan(0);
- done();
- });
+ await waitForPromises();
+
+ expect($notesContainer.find(`#note_${note.id}`).length).toBeGreaterThan(0);
});
- it('should reset Form when new comment is done posting', (done) => {
+ it('should reset Form when new comment is done posting', async () => {
mockNotesPost();
$('.js-comment-button').click();
- setImmediate(() => {
- expect($form.find('textarea.js-note-text').val()).toEqual('');
- done();
- });
+ await waitForPromises();
+
+ expect($form.find('textarea.js-note-text').val()).toEqual('');
});
- it('should show flash error message when new comment failed to be posted', (done) => {
+ it('should show flash error message when new comment failed to be posted', async () => {
mockNotesPostError();
jest.spyOn(notes, 'addFlash');
$('.js-comment-button').click();
- setImmediate(() => {
- expect(notes.addFlash).toHaveBeenCalled();
- // JSDom doesn't support the :visible selector yet
- expect(notes.flashContainer.style.display).not.toBe('none');
- done();
- });
+ await waitForPromises();
+
+ expect(notes.addFlash).toHaveBeenCalled();
+ // JSDom doesn't support the :visible selector yet
+ expect(notes.flashContainer.style.display).not.toBe('none');
});
});
@@ -657,16 +654,15 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => {
$form.find('textarea.js-note-text').val(sampleComment);
});
- it('should remove quick action placeholder when comment with quick actions is done posting', (done) => {
+ it('should remove quick action placeholder when comment with quick actions is done posting', async () => {
jest.spyOn(gl.awardsHandler, 'addAwardToEmojiBar');
$('.js-comment-button').click();
expect($notesContainer.find('.note.being-posted').length).toEqual(1); // Placeholder shown
- setImmediate(() => {
- expect($notesContainer.find('.note.being-posted').length).toEqual(0); // Placeholder removed
- done();
- });
+ await waitForPromises();
+
+ expect($notesContainer.find('.note.being-posted').length).toEqual(0); // Placeholder removed
});
});
@@ -692,16 +688,15 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => {
$form.find('textarea.js-note-text').val(sampleComment);
});
- it('should show message placeholder including lines starting with slash', (done) => {
+ it('should show message placeholder including lines starting with slash', async () => {
$('.js-comment-button').click();
expect($notesContainer.find('.note.being-posted').length).toEqual(1); // Placeholder shown
expect($notesContainer.find('.note-body p').text()).toEqual(sampleComment); // No quick action processing
- setImmediate(() => {
- expect($notesContainer.find('.note.being-posted').length).toEqual(0); // Placeholder removed
- done();
- });
+ await waitForPromises();
+
+ expect($notesContainer.find('.note.being-posted').length).toEqual(0); // Placeholder removed
});
});
@@ -730,23 +725,21 @@ describe.skip('Old Notes (~/deprecated_notes.js)', () => {
$form.find('textarea.js-note-text').html(sampleComment);
});
- it('should not render a script tag', (done) => {
+ it('should not render a script tag', async () => {
$('.js-comment-button').click();
- setImmediate(() => {
- const $noteEl = $notesContainer.find(`#note_${note.id}`);
- $noteEl.find('.js-note-edit').click();
- $noteEl.find('textarea.js-note-text').html(updatedComment);
- $noteEl.find('.js-comment-save-button').click();
+ await waitForPromises();
- const $updatedNoteEl = $notesContainer
- .find(`#note_${note.id}`)
- .find('.js-task-list-container');
+ const $noteEl = $notesContainer.find(`#note_${note.id}`);
+ $noteEl.find('.js-note-edit').click();
+ $noteEl.find('textarea.js-note-text').html(updatedComment);
+ $noteEl.find('.js-comment-save-button').click();
- expect($updatedNoteEl.find('.note-text').text().trim()).toEqual('');
+ const $updatedNoteEl = $notesContainer
+ .find(`#note_${note.id}`)
+ .find('.js-task-list-container');
- done();
- });
+ expect($updatedNoteEl.find('.note-text').text().trim()).toEqual('');
});
});
diff --git a/spec/frontend/pager_spec.js b/spec/frontend/pager_spec.js
index ff352303143..043ea470436 100644
--- a/spec/frontend/pager_spec.js
+++ b/spec/frontend/pager_spec.js
@@ -1,6 +1,7 @@
import MockAdapter from 'axios-mock-adapter';
import $ from 'jquery';
import { TEST_HOST } from 'helpers/test_constants';
+import waitForPromises from 'helpers/wait_for_promises';
import axios from '~/lib/utils/axios_utils';
import { removeParams } from '~/lib/utils/url_utility';
import Pager from '~/pager';
@@ -64,67 +65,59 @@ describe('pager', () => {
Pager.init();
});
- it('shows loader while loading next page', (done) => {
+ it('shows loader while loading next page', async () => {
mockSuccess();
jest.spyOn(Pager.loading, 'show').mockImplementation(() => {});
Pager.getOld();
- setImmediate(() => {
- expect(Pager.loading.show).toHaveBeenCalled();
+ await waitForPromises();
- done();
- });
+ expect(Pager.loading.show).toHaveBeenCalled();
});
- it('hides loader on success', (done) => {
+ it('hides loader on success', async () => {
mockSuccess();
jest.spyOn(Pager.loading, 'hide').mockImplementation(() => {});
Pager.getOld();
- setImmediate(() => {
- expect(Pager.loading.hide).toHaveBeenCalled();
+ await waitForPromises();
- done();
- });
+ expect(Pager.loading.hide).toHaveBeenCalled();
});
- it('hides loader on error', (done) => {
+ it('hides loader on error', async () => {
mockError();
jest.spyOn(Pager.loading, 'hide').mockImplementation(() => {});
Pager.getOld();
- setImmediate(() => {
- expect(Pager.loading.hide).toHaveBeenCalled();
+ await waitForPromises();
- done();
- });
+ expect(Pager.loading.hide).toHaveBeenCalled();
});
- it('sends request to url with offset and limit params', (done) => {
+ it('sends request to url with offset and limit params', async () => {
Pager.offset = 100;
Pager.limit = 20;
Pager.getOld();
- setImmediate(() => {
- const [url, params] = axios.get.mock.calls[0];
+ await waitForPromises();
- expect(params).toEqual({
- params: {
- limit: 20,
- offset: 100,
- },
- });
+ const [url, params] = axios.get.mock.calls[0];
- expect(url).toBe('/some_list');
-
- done();
+ expect(params).toEqual({
+ params: {
+ limit: 20,
+ offset: 100,
+ },
});
+
+ expect(url).toBe('/some_list');
});
- it('disables if return count is less than limit', (done) => {
+ it('disables if return count is less than limit', async () => {
Pager.offset = 0;
Pager.limit = 20;
@@ -132,12 +125,10 @@ describe('pager', () => {
jest.spyOn(Pager.loading, 'hide').mockImplementation(() => {});
Pager.getOld();
- setImmediate(() => {
- expect(Pager.loading.hide).toHaveBeenCalled();
- expect(Pager.disable).toBe(true);
+ await waitForPromises();
- done();
- });
+ expect(Pager.loading.hide).toHaveBeenCalled();
+ expect(Pager.disable).toBe(true);
});
describe('has data-href attribute from list element', () => {
diff --git a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js
index 395e5d87ac1..3b113f4dcd7 100644
--- a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js
+++ b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js
@@ -114,11 +114,7 @@ describe('Learn GitLab Section Link', () => {
it('calls the eventHub', () => {
openInviteMembesrModalLink().vm.$emit('click');
- expect(eventHub.$emit).toHaveBeenCalledWith('openModal', {
- inviteeType: 'members',
- source: 'learn_gitlab',
- tasksToBeDoneEnabled: true,
- });
+ expect(eventHub.$emit).toHaveBeenCalledWith('openModal', { source: 'learn_gitlab' });
});
it('tracks the click', async () => {
diff --git a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js
index f6e3a72b5e0..ee682b18af3 100644
--- a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js
+++ b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js
@@ -80,7 +80,6 @@ describe('Learn GitLab', () => {
expect(spy).toHaveBeenCalledWith('openModal', {
mode: 'celebrate',
- inviteeType: 'members',
source: 'learn-gitlab',
});
expect(cookieSpy).toHaveBeenCalledWith(INVITE_MODAL_OPEN_COOKIE);
diff --git a/spec/frontend/pipeline_wizard/components/widgets/text_spec.js b/spec/frontend/pipeline_wizard/components/widgets/text_spec.js
new file mode 100644
index 00000000000..a11c0214d15
--- /dev/null
+++ b/spec/frontend/pipeline_wizard/components/widgets/text_spec.js
@@ -0,0 +1,152 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlFormGroup, GlFormInput } from '@gitlab/ui';
+import TextWidget from '~/pipeline_wizard/components/widgets/text.vue';
+import { mountExtended } from 'helpers/vue_test_utils_helper';
+
+describe('Pipeline Wizard - Text Widget', () => {
+ const defaultProps = {
+ label: 'This label',
+ description: 'some description',
+ placeholder: 'some placeholder',
+ pattern: '^[a-z]+$',
+ invalidFeedback: 'some feedback',
+ };
+
+ let wrapper;
+
+ const findGlFormGroup = () => wrapper.findComponent(GlFormGroup);
+ const findGlFormGroupInvalidFeedback = () => findGlFormGroup().find('.invalid-feedback');
+ const findGlFormInput = () => wrapper.findComponent(GlFormInput);
+
+ const createComponent = (props = {}, mountFn = mountExtended) => {
+ wrapper = mountFn(TextWidget, {
+ propsData: {
+ ...defaultProps,
+ ...props,
+ },
+ });
+ };
+
+ afterEach(() => {
+ if (wrapper) {
+ wrapper.destroy();
+ }
+ });
+
+ it('creates an input element with the correct label', () => {
+ createComponent();
+
+ expect(wrapper.findByLabelText(defaultProps.label).exists()).toBe(true);
+ });
+
+ it('passes the description', () => {
+ createComponent({}, shallowMount);
+
+ expect(findGlFormGroup().attributes('description')).toBe(defaultProps.description);
+ });
+
+ it('sets the "text" type on the input component', () => {
+ createComponent();
+
+ expect(findGlFormInput().attributes('type')).toBe('text');
+ });
+
+ it('passes the placeholder', () => {
+ createComponent();
+
+ expect(findGlFormInput().attributes('placeholder')).toBe(defaultProps.placeholder);
+ });
+
+ it('emits an update event on input', async () => {
+ createComponent();
+
+ const localValue = 'somevalue';
+ await findGlFormInput().setValue(localValue);
+
+ expect(wrapper.emitted('input')).toEqual([[localValue]]);
+ });
+
+ it('passes invalid feedback message', () => {
+ createComponent();
+
+ expect(findGlFormGroupInvalidFeedback().text()).toBe(defaultProps.invalidFeedback);
+ });
+
+ it('provides invalid feedback', async () => {
+ createComponent({ validate: true });
+
+ await findGlFormInput().setValue('invalid%99');
+
+ expect(findGlFormGroup().classes()).toContain('is-invalid');
+ expect(findGlFormInput().classes()).toContain('is-invalid');
+ });
+
+ it('provides valid feedback', async () => {
+ createComponent({ validate: true });
+
+ await findGlFormInput().setValue('valid');
+
+ expect(findGlFormGroup().classes()).toContain('is-valid');
+ expect(findGlFormInput().classes()).toContain('is-valid');
+ });
+
+ it('does not show validation state when untouched', () => {
+ createComponent({ value: 'invalid99' });
+
+ expect(findGlFormGroup().classes()).not.toContain('is-valid');
+ expect(findGlFormGroup().classes()).not.toContain('is-invalid');
+ });
+
+ it('shows invalid state on blur', async () => {
+ createComponent();
+
+ await findGlFormInput().setValue('invalid%99');
+
+ expect(findGlFormGroup().classes()).not.toContain('is-invalid');
+
+ await findGlFormInput().trigger('blur');
+
+ expect(findGlFormInput().classes()).toContain('is-invalid');
+ expect(findGlFormGroup().classes()).toContain('is-invalid');
+ });
+
+ it('shows invalid state when toggling `validate` prop', async () => {
+ createComponent({
+ required: true,
+ validate: false,
+ });
+
+ expect(findGlFormGroup().classes()).not.toContain('is-invalid');
+
+ await wrapper.setProps({ validate: true });
+
+ expect(findGlFormGroup().classes()).toContain('is-invalid');
+ });
+
+ it('does not update validation if not required', async () => {
+ createComponent({
+ pattern: null,
+ validate: true,
+ });
+
+ expect(findGlFormGroup().classes()).not.toContain('is-invalid');
+ });
+
+ it('sets default value', () => {
+ const defaultValue = 'foo';
+ createComponent({
+ default: defaultValue,
+ });
+
+ expect(wrapper.findByLabelText(defaultProps.label).element.value).toBe(defaultValue);
+ });
+
+ it('emits default value on setup', () => {
+ const defaultValue = 'foo';
+ createComponent({
+ default: defaultValue,
+ });
+
+ expect(wrapper.emitted('input')).toEqual([[defaultValue]]);
+ });
+});
diff --git a/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_pipeline_failed_spec.js.snap b/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_pipeline_failed_spec.js.snap
index a124008b36a..98297630792 100644
--- a/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_pipeline_failed_spec.js.snap
+++ b/spec/frontend/vue_mr_widget/components/states/__snapshots__/mr_widget_pipeline_failed_spec.js.snap
@@ -16,7 +16,7 @@ exports[`PipelineFailed should render error message with a disabled merge button
class="bold"
>
<gl-sprintf-stub
- message="The pipeline for this merge request did not complete. Push a new commit to fix the failure, or check the %{linkStart}troubleshooting documentation%{linkEnd} to see other possible actions."
+ message="Merge blocked: pipeline must succeed. Push a commit that fixes the failure, or %{linkStart}learn about other solutions.%{linkEnd}"
/>
</span>
</div>