diff options
Diffstat (limited to 'spec/frontend/webhooks/components/form_url_app_spec.js')
-rw-r--r-- | spec/frontend/webhooks/components/form_url_app_spec.js | 125 |
1 files changed, 112 insertions, 13 deletions
diff --git a/spec/frontend/webhooks/components/form_url_app_spec.js b/spec/frontend/webhooks/components/form_url_app_spec.js index 16e0a3f549e..45a39d2dd58 100644 --- a/spec/frontend/webhooks/components/form_url_app_spec.js +++ b/spec/frontend/webhooks/components/form_url_app_spec.js @@ -1,10 +1,14 @@ import { nextTick } from 'vue'; -import { GlFormRadio, GlFormRadioGroup, GlLink } from '@gitlab/ui'; +import { GlFormGroup, GlFormRadio, GlFormRadioGroup, GlLink } from '@gitlab/ui'; +import { scrollToElement } from '~/lib/utils/common_utils'; import FormUrlApp from '~/webhooks/components/form_url_app.vue'; import FormUrlMaskItem from '~/webhooks/components/form_url_mask_item.vue'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import { setHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; + +jest.mock('~/lib/utils/common_utils'); describe('FormUrlApp', () => { let wrapper; @@ -26,8 +30,11 @@ describe('FormUrlApp', () => { const findAllUrlMaskItems = () => wrapper.findAllComponents(FormUrlMaskItem); const findAddItem = () => wrapper.findComponent(GlLink); const findFormUrl = () => wrapper.findByTestId('form-url'); + const findFormUrlGroup = () => wrapper.findAllComponents(GlFormGroup).at(0); const findFormUrlPreview = () => wrapper.findByTestId('form-url-preview'); const findUrlMaskSection = () => wrapper.findByTestId('url-mask-section'); + const findFormEl = () => document.querySelector('.js-webhook-form'); + const submitForm = () => findFormEl().dispatchEvent(new Event('submit')); describe('template', () => { it('renders radio buttons for URL masking', () => { @@ -60,8 +67,10 @@ describe('FormUrlApp', () => { expect(findAllUrlMaskItems()).toHaveLength(1); const firstItem = findAllUrlMaskItems().at(0); - expect(firstItem.props('itemKey')).toBeNull(); - expect(firstItem.props('itemValue')).toBeNull(); + expect(firstItem.props()).toMatchObject({ + itemKey: null, + itemValue: null, + }); }); }); @@ -90,12 +99,18 @@ describe('FormUrlApp', () => { expect(findAllUrlMaskItems()).toHaveLength(2); const firstItem = findAllUrlMaskItems().at(0); - expect(firstItem.props('itemKey')).toBe(mockItem1.key); - expect(firstItem.props('itemValue')).toBe(mockItem1.value); + expect(firstItem.props()).toMatchObject({ + itemKey: mockItem1.key, + itemValue: mockItem1.value, + isEditing: true, + }); const secondItem = findAllUrlMaskItems().at(1); - expect(secondItem.props('itemKey')).toBe(mockItem2.key); - expect(secondItem.props('itemValue')).toBe(mockItem2.value); + expect(secondItem.props()).toMatchObject({ + itemKey: mockItem2.key, + itemValue: mockItem2.value, + isEditing: true, + }); }); describe('on mask item input', () => { @@ -106,8 +121,10 @@ describe('FormUrlApp', () => { firstItem.vm.$emit('input', mockInput); await nextTick(); - expect(firstItem.props('itemKey')).toBe(mockInput.key); - expect(firstItem.props('itemValue')).toBe(mockInput.value); + expect(firstItem.props()).toMatchObject({ + itemKey: mockInput.key, + itemValue: mockInput.value, + }); }); }); @@ -119,8 +136,10 @@ describe('FormUrlApp', () => { expect(findAllUrlMaskItems()).toHaveLength(3); const lastItem = findAllUrlMaskItems().at(-1); - expect(lastItem.props('itemKey')).toBeNull(); - expect(lastItem.props('itemValue')).toBeNull(); + expect(lastItem.props()).toMatchObject({ + itemKey: null, + itemValue: null, + }); }); }); @@ -133,8 +152,88 @@ describe('FormUrlApp', () => { expect(findAllUrlMaskItems()).toHaveLength(1); const newFirstItem = findAllUrlMaskItems().at(0); - expect(newFirstItem.props('itemKey')).toBe(mockItem2.key); - expect(newFirstItem.props('itemValue')).toBe(mockItem2.value); + expect(newFirstItem.props()).toMatchObject({ + itemKey: mockItem2.key, + itemValue: mockItem2.value, + }); + }); + }); + }); + + describe('validations', () => { + const inputRequiredText = FormUrlApp.i18n.inputRequired; + + beforeEach(() => { + setHTMLFixture('<form class="js-webhook-form"></form>'); + }); + + afterEach(() => { + resetHTMLFixture(); + }); + + it.each` + url | state | scrollToElementCalls + ${null} | ${undefined} | ${1} + ${''} | ${undefined} | ${1} + ${'https://example.com/'} | ${'true'} | ${0} + `('when URL is `$url`, state is `$state`', async ({ url, state, scrollToElementCalls }) => { + createComponent({ + props: { initialUrl: url }, + }); + + submitForm(); + await nextTick(); + + expect(findFormUrlGroup().attributes('state')).toBe(state); + expect(scrollToElement).toHaveBeenCalledTimes(scrollToElementCalls); + expect(findFormUrlGroup().attributes('invalid-feedback')).toBe(inputRequiredText); + }); + + it.each` + key | value | keyInvalidFeedback | valueInvalidFeedback | scrollToElementCalls + ${null} | ${null} | ${inputRequiredText} | ${inputRequiredText} | ${1} + ${null} | ${'random'} | ${inputRequiredText} | ${FormUrlApp.i18n.valuePartOfUrl} | ${1} + ${null} | ${'secret'} | ${inputRequiredText} | ${null} | ${1} + ${'key'} | ${null} | ${null} | ${inputRequiredText} | ${1} + ${'key'} | ${'secret'} | ${null} | ${null} | ${0} + `( + 'when key is `$key` and value is `$value`', + async ({ key, value, keyInvalidFeedback, valueInvalidFeedback, scrollToElementCalls }) => { + createComponent({ + props: { initialUrl: 'http://example.com?password=secret' }, + }); + findRadioGroup().vm.$emit('input', true); + await nextTick(); + + const maskItem = findAllUrlMaskItems().at(0); + const mockInput = { index: 0, key, value }; + maskItem.vm.$emit('input', mockInput); + + submitForm(); + await nextTick(); + + expect(maskItem.props('keyInvalidFeedback')).toBe(keyInvalidFeedback); + expect(maskItem.props('valueInvalidFeedback')).toBe(valueInvalidFeedback); + expect(scrollToElement).toHaveBeenCalledTimes(scrollToElementCalls); + }, + ); + + describe('when initialUrlVariables is passed', () => { + it('does not validate empty values', async () => { + const initialUrlVariables = [{ key: 'key' }]; + + createComponent({ + props: { initialUrl: 'url', initialUrlVariables }, + }); + + submitForm(); + await nextTick(); + + const maskItem = findAllUrlMaskItems().at(0); + + expect(maskItem.props('keyInvalidFeedback')).toBeNull(); + expect(maskItem.props('valueInvalidFeedback')).toBeNull(); + expect(scrollToElement).not.toHaveBeenCalled(); }); }); }); |