2021-11-12 12:10:27 +00:00
import {
GlForm ,
GlFormSelect ,
GlFormInput ,
GlToggle ,
GlFormTextarea ,
GlTab ,
GlLink ,
} from '@gitlab/ui' ;
2021-02-14 18:09:20 +00:00
import { mount } from '@vue/test-utils' ;
2021-03-25 21:09:13 +00:00
import { nextTick } from 'vue' ;
import { extendedWrapper } from 'helpers/vue_test_utils_helper' ;
2020-11-16 21:09:02 +00:00
import waitForPromises from 'helpers/wait_for_promises' ;
2021-01-22 03:09:04 +00:00
import MappingBuilder from '~/alerts_settings/components/alert_mapping_builder.vue' ;
2021-02-14 18:09:20 +00:00
import AlertsSettingsForm from '~/alerts_settings/components/alerts_settings_form.vue' ;
2020-11-04 12:09:14 +00:00
import { typeSet } from '~/alerts_settings/constants' ;
2021-02-23 21:10:44 +00:00
import alertFields from '../mocks/alert_fields.json' ;
import parsedMapping from '../mocks/parsed_mapping.json' ;
2020-10-29 00:08:36 +00:00
2021-03-31 06:08:58 +00:00
const scrollIntoViewMock = jest . fn ( ) ;
HTMLElement . prototype . scrollIntoView = scrollIntoViewMock ;
2021-02-04 21:09:06 +00:00
describe ( 'AlertsSettingsForm' , ( ) => {
2020-10-29 00:08:36 +00:00
let wrapper ;
2020-11-16 21:09:02 +00:00
const mockToastShow = jest . fn ( ) ;
2020-10-29 00:08:36 +00:00
2021-03-11 15:09:10 +00:00
const createComponent = ( { data = { } , props = { } , multiIntegrations = true } = { } ) => {
2021-03-25 21:09:13 +00:00
wrapper = extendedWrapper (
mount ( AlertsSettingsForm , {
data ( ) {
return { ... data } ;
2021-02-23 21:10:44 +00:00
} ,
2021-03-25 21:09:13 +00:00
propsData : {
loading : false ,
canAddIntegration : true ,
... props ,
2020-11-16 21:09:02 +00:00
} ,
2021-03-25 21:09:13 +00:00
provide : {
multiIntegrations ,
} ,
mocks : {
$apollo : {
query : jest . fn ( ) ,
} ,
$toast : {
show : mockToastShow ,
} ,
} ,
} ) ,
) ;
2020-10-29 00:08:36 +00:00
} ;
2021-03-05 15:09:12 +00:00
const findForm = ( ) => wrapper . findComponent ( GlForm ) ;
const findSelect = ( ) => wrapper . findComponent ( GlFormSelect ) ;
const findFormFields = ( ) => wrapper . findAllComponents ( GlFormInput ) ;
const findFormToggle = ( ) => wrapper . findComponent ( GlToggle ) ;
2021-03-25 21:09:13 +00:00
const findSamplePayloadSection = ( ) => wrapper . findByTestId ( 'sample-payload-section' ) ;
2021-01-22 03:09:04 +00:00
const findMappingBuilder = ( ) => wrapper . findComponent ( MappingBuilder ) ;
2021-03-25 21:09:13 +00:00
const findSubmitButton = ( ) => wrapper . findByTestId ( 'integration-form-submit' ) ;
const findMultiSupportText = ( ) => wrapper . findByTestId ( 'multi-integrations-not-supported' ) ;
const findJsonTestSubmit = ( ) => wrapper . findByTestId ( 'send-test-alert' ) ;
2020-11-12 09:08:57 +00:00
const findJsonTextArea = ( ) => wrapper . find ( ` [id = "test-payload"] ` ) ;
2021-03-25 21:09:13 +00:00
const findActionBtn = ( ) => wrapper . findByTestId ( 'payload-action-btn' ) ;
2021-03-05 15:09:12 +00:00
const findTabs = ( ) => wrapper . findAllComponents ( GlTab ) ;
2020-10-29 00:08:36 +00:00
afterEach ( ( ) => {
if ( wrapper ) {
wrapper . destroy ( ) ;
}
} ) ;
2021-01-22 03:09:04 +00:00
const selectOptionAtIndex = async ( index ) => {
const options = findSelect ( ) . findAll ( 'option' ) ;
await options . at ( index ) . setSelected ( ) ;
} ;
const enableIntegration = ( index , value ) => {
findFormFields ( ) . at ( index ) . setValue ( value ) ;
2021-11-03 15:13:48 +00:00
findFormToggle ( ) . vm . $emit ( 'change' , true ) ;
2021-01-22 03:09:04 +00:00
} ;
2020-10-29 00:08:36 +00:00
describe ( 'with default values' , ( ) => {
beforeEach ( ( ) => {
createComponent ( ) ;
} ) ;
it ( 'render the initial form with only an integration type dropdown' , ( ) => {
expect ( findForm ( ) . exists ( ) ) . toBe ( true ) ;
expect ( findSelect ( ) . exists ( ) ) . toBe ( true ) ;
2020-11-09 12:09:24 +00:00
expect ( findMultiSupportText ( ) . exists ( ) ) . toBe ( false ) ;
2021-03-02 18:11:20 +00:00
expect ( findFormFields ( ) ) . toHaveLength ( 0 ) ;
2020-10-29 00:08:36 +00:00
} ) ;
it ( 'shows the rest of the form when the dropdown is used' , async ( ) => {
2021-01-22 03:09:04 +00:00
await selectOptionAtIndex ( 1 ) ;
2020-11-04 12:09:14 +00:00
2020-12-23 12:10:26 +00:00
expect ( findFormFields ( ) . at ( 0 ) . isVisible ( ) ) . toBe ( true ) ;
2020-11-04 12:09:14 +00:00
} ) ;
2020-11-09 12:09:24 +00:00
2020-12-03 21:09:35 +00:00
it ( 'disables the dropdown and shows help text when multi integrations are not supported' , async ( ) => {
2020-11-09 12:09:24 +00:00
createComponent ( { props : { canAddIntegration : false } } ) ;
expect ( findSelect ( ) . attributes ( 'disabled' ) ) . toBe ( 'disabled' ) ;
expect ( findMultiSupportText ( ) . exists ( ) ) . toBe ( true ) ;
} ) ;
2020-12-03 21:09:35 +00:00
2021-03-02 18:11:20 +00:00
it ( 'hides the name input when the selected value is prometheus' , async ( ) => {
2020-12-03 21:09:35 +00:00
createComponent ( ) ;
2021-01-22 03:09:04 +00:00
await selectOptionAtIndex ( 2 ) ;
2021-03-02 18:11:20 +00:00
expect ( findFormFields ( ) . at ( 0 ) . attributes ( 'id' ) ) . not . toBe ( 'name-integration' ) ;
} ) ;
2021-11-12 12:10:27 +00:00
it ( 'verify pricing link url' , ( ) => {
createComponent ( { props : { canAddIntegration : false } } ) ;
const link = findMultiSupportText ( ) . findComponent ( GlLink ) ;
expect ( link . attributes ( 'href' ) ) . toMatch ( /https:\/\/about.gitlab.(com|cn)\/pricing/ ) ;
} ) ;
2021-03-02 18:11:20 +00:00
describe ( 'form tabs' , ( ) => {
it ( 'renders 3 tabs' , ( ) => {
expect ( findTabs ( ) ) . toHaveLength ( 3 ) ;
} ) ;
2020-12-03 21:09:35 +00:00
2021-03-02 18:11:20 +00:00
it ( 'only first tab is enabled on integration create' , ( ) => {
createComponent ( {
data : {
currentIntegration : null ,
} ,
} ) ;
const tabs = findTabs ( ) ;
expect ( tabs . at ( 0 ) . find ( '[role="tabpanel"]' ) . classes ( 'disabled' ) ) . toBe ( false ) ;
expect ( tabs . at ( 1 ) . find ( '[role="tabpanel"]' ) . classes ( 'disabled' ) ) . toBe ( true ) ;
expect ( tabs . at ( 2 ) . find ( '[role="tabpanel"]' ) . classes ( 'disabled' ) ) . toBe ( true ) ;
} ) ;
it ( 'all tabs are enabled on integration edit' , ( ) => {
createComponent ( {
data : {
currentIntegration : { id : 1 } ,
} ,
} ) ;
const tabs = findTabs ( ) ;
expect ( tabs . at ( 0 ) . find ( '[role="tabpanel"]' ) . classes ( 'disabled' ) ) . toBe ( false ) ;
expect ( tabs . at ( 1 ) . find ( '[role="tabpanel"]' ) . classes ( 'disabled' ) ) . toBe ( false ) ;
expect ( tabs . at ( 2 ) . find ( '[role="tabpanel"]' ) . classes ( 'disabled' ) ) . toBe ( false ) ;
} ) ;
2020-12-03 21:09:35 +00:00
} ) ;
2020-11-04 12:09:14 +00:00
} ) ;
2020-11-05 18:08:48 +00:00
describe ( 'submitting integration form' , ( ) => {
2021-01-22 03:09:04 +00:00
describe ( 'HTTP' , ( ) => {
it ( 'create with custom mapping' , async ( ) => {
2021-02-04 21:09:06 +00:00
createComponent ( {
multiIntegrations : true ,
props : { alertFields } ,
} ) ;
2020-11-05 18:08:48 +00:00
2021-01-22 03:09:04 +00:00
const integrationName = 'Test integration' ;
await selectOptionAtIndex ( 1 ) ;
2020-11-05 18:08:48 +00:00
2021-01-22 03:09:04 +00:00
enableIntegration ( 0 , integrationName ) ;
2020-11-05 18:08:48 +00:00
2021-02-23 21:10:44 +00:00
const sampleMapping = parsedMapping . payloadAttributeMappings ;
2021-01-22 03:09:04 +00:00
findMappingBuilder ( ) . vm . $emit ( 'onMappingUpdate' , sampleMapping ) ;
findForm ( ) . trigger ( 'submit' ) ;
2020-11-05 18:08:48 +00:00
2021-03-25 21:09:13 +00:00
expect ( wrapper . emitted ( 'create-new-integration' ) [ 0 ] [ 0 ] ) . toMatchObject ( {
type : typeSet . http ,
variables : {
name : integrationName ,
active : true ,
payloadAttributeMappings : sampleMapping ,
payloadExample : '{}' ,
2021-01-22 03:09:04 +00:00
} ,
2021-03-25 21:09:13 +00:00
} ) ;
2021-01-22 03:09:04 +00:00
} ) ;
2020-11-05 18:08:48 +00:00
2021-01-22 03:09:04 +00:00
it ( 'update' , ( ) => {
createComponent ( {
data : {
2021-03-25 21:09:13 +00:00
integrationForm : { id : '1' , name : 'Test integration pre' , type : typeSet . http } ,
currentIntegration : { id : '1' } ,
2021-01-22 03:09:04 +00:00
} ,
props : {
loading : false ,
} ,
} ) ;
2021-03-25 21:09:13 +00:00
2021-01-22 03:09:04 +00:00
const updatedIntegrationName = 'Test integration post' ;
enableIntegration ( 0 , updatedIntegrationName ) ;
2020-11-05 18:08:48 +00:00
2021-01-22 03:09:04 +00:00
const submitBtn = findSubmitButton ( ) ;
expect ( submitBtn . exists ( ) ) . toBe ( true ) ;
expect ( submitBtn . text ( ) ) . toBe ( 'Save integration' ) ;
2020-11-05 18:08:48 +00:00
2021-03-25 21:09:13 +00:00
submitBtn . trigger ( 'click' ) ;
expect ( wrapper . emitted ( 'update-integration' ) [ 0 ] [ 0 ] ) . toMatchObject ( {
type : typeSet . http ,
variables : {
name : updatedIntegrationName ,
active : true ,
payloadAttributeMappings : [ ] ,
payloadExample : '{}' ,
} ,
} ) ;
2020-11-05 18:08:48 +00:00
} ) ;
2021-01-22 03:09:04 +00:00
} ) ;
2020-11-05 18:08:48 +00:00
2021-01-22 03:09:04 +00:00
describe ( 'PROMETHEUS' , ( ) => {
it ( 'create' , async ( ) => {
createComponent ( ) ;
await selectOptionAtIndex ( 2 ) ;
const apiUrl = 'https://test.com' ;
2021-03-02 18:11:20 +00:00
enableIntegration ( 0 , apiUrl ) ;
2021-01-22 03:09:04 +00:00
const submitBtn = findSubmitButton ( ) ;
expect ( submitBtn . exists ( ) ) . toBe ( true ) ;
expect ( submitBtn . text ( ) ) . toBe ( 'Save integration' ) ;
2020-11-04 12:09:14 +00:00
2021-01-22 03:09:04 +00:00
findForm ( ) . trigger ( 'submit' ) ;
2020-11-04 12:09:14 +00:00
2021-03-25 21:09:13 +00:00
expect ( wrapper . emitted ( 'create-new-integration' ) [ 0 ] [ 0 ] ) . toMatchObject ( {
type : typeSet . prometheus ,
variables : { apiUrl , active : true } ,
} ) ;
2020-11-05 18:08:48 +00:00
} ) ;
2021-01-22 03:09:04 +00:00
it ( 'update' , ( ) => {
createComponent ( {
data : {
2021-03-25 21:09:13 +00:00
integrationForm : { id : '1' , apiUrl : 'https://test-pre.com' , type : typeSet . prometheus } ,
currentIntegration : { id : '1' } ,
2021-01-22 03:09:04 +00:00
} ,
props : {
loading : false ,
} ,
} ) ;
2020-11-04 12:09:14 +00:00
2021-01-22 03:09:04 +00:00
const apiUrl = 'https://test-post.com' ;
2021-03-02 18:11:20 +00:00
enableIntegration ( 0 , apiUrl ) ;
2020-11-04 12:09:14 +00:00
2021-01-22 03:09:04 +00:00
const submitBtn = findSubmitButton ( ) ;
expect ( submitBtn . exists ( ) ) . toBe ( true ) ;
expect ( submitBtn . text ( ) ) . toBe ( 'Save integration' ) ;
2020-10-29 00:08:36 +00:00
2021-01-22 03:09:04 +00:00
findForm ( ) . trigger ( 'submit' ) ;
2020-10-29 00:08:36 +00:00
2021-03-25 21:09:13 +00:00
expect ( wrapper . emitted ( 'update-integration' ) [ 0 ] [ 0 ] ) . toMatchObject ( {
type : typeSet . prometheus ,
variables : { apiUrl , active : true } ,
} ) ;
2021-01-22 03:09:04 +00:00
} ) ;
2020-10-29 00:08:36 +00:00
} ) ;
} ) ;
2020-10-30 09:08:39 +00:00
2020-11-10 12:08:57 +00:00
describe ( 'submitting the integration with a JSON test payload' , ( ) => {
beforeEach ( ( ) => {
createComponent ( {
data : {
2020-11-12 15:09:09 +00:00
currentIntegration : { id : '1' , name : 'Test' } ,
2020-11-10 12:08:57 +00:00
active : true ,
} ,
props : {
loading : false ,
} ,
} ) ;
} ) ;
it ( 'should not allow a user to test invalid JSON' , async ( ) => {
await findJsonTextArea ( ) . setValue ( 'Invalid JSON' ) ;
jest . runAllTimers ( ) ;
2021-03-25 21:09:13 +00:00
await nextTick ( ) ;
2020-11-10 12:08:57 +00:00
2021-01-22 03:09:04 +00:00
const jsonTestSubmit = findJsonTestSubmit ( ) ;
expect ( jsonTestSubmit . exists ( ) ) . toBe ( true ) ;
2021-03-02 18:11:20 +00:00
expect ( jsonTestSubmit . text ( ) ) . toBe ( 'Send' ) ;
2021-01-22 03:09:04 +00:00
expect ( jsonTestSubmit . props ( 'disabled' ) ) . toBe ( true ) ;
2020-11-10 12:08:57 +00:00
} ) ;
it ( 'should allow for the form to be automatically saved if the test payload is successfully submitted' , async ( ) => {
await findJsonTextArea ( ) . setValue ( '{ "value": "value" }' ) ;
jest . runAllTimers ( ) ;
2021-03-25 21:09:13 +00:00
await nextTick ( ) ;
2020-11-10 12:08:57 +00:00
expect ( findJsonTestSubmit ( ) . props ( 'disabled' ) ) . toBe ( false ) ;
} ) ;
} ) ;
2020-11-12 09:08:57 +00:00
describe ( 'Test payload section for HTTP integration' , ( ) => {
2021-02-23 21:10:44 +00:00
const validSamplePayload = JSON . stringify ( alertFields ) ;
const emptySamplePayload = '{}' ;
2020-10-30 09:08:39 +00:00
beforeEach ( ( ) => {
2020-11-12 09:08:57 +00:00
createComponent ( {
2021-03-25 21:09:13 +00:00
multiIntegrations : true ,
2021-02-23 21:10:44 +00:00
data : {
2021-03-25 21:09:13 +00:00
integrationForm : { type : typeSet . http } ,
2020-11-12 09:08:57 +00:00
currentIntegration : {
2021-03-25 21:09:13 +00:00
payloadExample : emptySamplePayload ,
2020-11-12 09:08:57 +00:00
} ,
2021-02-23 21:10:44 +00:00
active : false ,
resetPayloadAndMappingConfirmed : false ,
2020-11-12 09:08:57 +00:00
} ,
2021-02-23 21:10:44 +00:00
props : { alertFields } ,
2020-11-12 09:08:57 +00:00
} ) ;
2020-10-30 09:08:39 +00:00
} ) ;
2020-11-12 09:08:57 +00:00
describe . each `
2022-10-07 09:10:18 +00:00
context | payload | resetPayloadAndMappingConfirmed | disabled
$ { 'valid payload, confirmed and enabled' } | $ { validSamplePayload } | $ { true } | $ { undefined }
$ { 'empty payload, confirmed and enabled' } | $ { emptySamplePayload } | $ { true } | $ { undefined }
$ { 'valid payload, unconfirmed and disabled' } | $ { validSamplePayload } | $ { false } | $ { 'disabled' }
$ { 'empty payload, unconfirmed and enabled' } | $ { emptySamplePayload } | $ { false } | $ { undefined }
` ('given $ context', ({ payload, resetPayloadAndMappingConfirmed, disabled }) => {
2021-02-23 21:10:44 +00:00
const payloadResetMsg = resetPayloadAndMappingConfirmed
? 'was confirmed'
: 'was not confirmed' ;
2020-11-12 09:08:57 +00:00
const enabledState = disabled === 'disabled' ? 'disabled' : 'enabled' ;
2021-03-25 21:09:13 +00:00
const validPayloadMsg = payload === emptySamplePayload ? 'not valid' : 'valid' ;
2020-11-12 09:08:57 +00:00
2021-03-25 21:09:13 +00:00
it ( ` textarea should be ${ enabledState } when payload reset ${ payloadResetMsg } and payload is ${ validPayloadMsg } ` , async ( ) => {
2021-12-29 15:10:45 +00:00
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
2020-11-12 09:08:57 +00:00
wrapper . setData ( {
2021-03-25 21:09:13 +00:00
currentIntegration : { payloadExample : payload } ,
2021-02-23 21:10:44 +00:00
resetPayloadAndMappingConfirmed ,
2020-11-12 09:08:57 +00:00
} ) ;
2021-03-25 21:09:13 +00:00
await nextTick ( ) ;
2022-09-13 12:12:50 +00:00
expect (
findSamplePayloadSection ( ) . findComponent ( GlFormTextarea ) . attributes ( 'disabled' ) ,
) . toBe ( disabled ) ;
2020-11-12 09:08:57 +00:00
} ) ;
2020-10-30 09:08:39 +00:00
} ) ;
2020-11-12 09:08:57 +00:00
describe ( 'action buttons for sample payload' , ( ) => {
describe . each `
2022-10-07 09:10:18 +00:00
context | resetPayloadAndMappingConfirmed | payloadExample | caption
$ { 'valid payload, unconfirmed' } | $ { false } | $ { validSamplePayload } | $ { 'Edit payload' }
$ { 'empty payload, confirmed' } | $ { true } | $ { emptySamplePayload } | $ { 'Parse payload fields' }
$ { 'valid payload, confirmed' } | $ { true } | $ { validSamplePayload } | $ { 'Parse payload fields' }
$ { 'empty payload, unconfirmed' } | $ { false } | $ { emptySamplePayload } | $ { 'Parse payload fields' }
` ('given $ context', ({ resetPayloadAndMappingConfirmed, payloadExample, caption }) => {
2021-02-23 21:10:44 +00:00
const samplePayloadMsg = payloadExample ? 'was provided' : 'was not provided' ;
const payloadResetMsg = resetPayloadAndMappingConfirmed
? 'was confirmed'
: 'was not confirmed' ;
2020-11-12 09:08:57 +00:00
it ( ` shows ${ caption } button when sample payload ${ samplePayloadMsg } and payload reset ${ payloadResetMsg } ` , async ( ) => {
2021-12-29 15:10:45 +00:00
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
2020-11-12 09:08:57 +00:00
wrapper . setData ( {
2021-02-23 21:10:44 +00:00
currentIntegration : {
payloadExample ,
} ,
resetPayloadAndMappingConfirmed ,
2020-11-12 09:08:57 +00:00
} ) ;
2021-03-25 21:09:13 +00:00
await nextTick ( ) ;
2020-11-16 21:09:02 +00:00
expect ( findActionBtn ( ) . text ( ) ) . toBe ( caption ) ;
} ) ;
} ) ;
} ) ;
describe ( 'Parsing payload' , ( ) => {
2021-02-23 21:10:44 +00:00
beforeEach ( ( ) => {
2021-12-29 15:10:45 +00:00
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
2020-11-16 21:09:02 +00:00
wrapper . setData ( {
2021-02-23 21:10:44 +00:00
resetPayloadAndMappingConfirmed : true ,
2020-11-12 09:08:57 +00:00
} ) ;
2021-02-23 21:10:44 +00:00
} ) ;
2020-11-16 21:09:02 +00:00
2021-02-23 21:10:44 +00:00
it ( 'displays a toast message on successful parse' , async ( ) => {
jest . spyOn ( wrapper . vm . $apollo , 'query' ) . mockResolvedValue ( {
data : {
project : { alertManagementPayloadFields : [ ] } ,
} ,
} ) ;
2020-11-16 21:09:02 +00:00
findActionBtn ( ) . vm . $emit ( 'click' ) ;
await waitForPromises ( ) ;
expect ( mockToastShow ) . toHaveBeenCalledWith (
'Sample payload has been parsed. You can now map the fields.' ,
) ;
2020-11-12 09:08:57 +00:00
} ) ;
2021-02-23 21:10:44 +00:00
it ( 'displays an error message under payload field on unsuccessful parse' , async ( ) => {
const errorMessage = 'Error parsing paylod' ;
jest . spyOn ( wrapper . vm . $apollo , 'query' ) . mockRejectedValue ( { message : errorMessage } ) ;
findActionBtn ( ) . vm . $emit ( 'click' ) ;
await waitForPromises ( ) ;
2021-03-02 18:11:20 +00:00
expect ( findSamplePayloadSection ( ) . find ( '.invalid-feedback' ) . text ( ) ) . toBe ( errorMessage ) ;
2021-02-23 21:10:44 +00:00
} ) ;
2020-11-12 09:08:57 +00:00
} ) ;
} ) ;
describe ( 'Mapping builder section' , ( ) => {
describe . each `
2021-03-11 15:09:10 +00:00
alertFieldsProvided | multiIntegrations | integrationOption | visible
$ { true } | $ { true } | $ { 1 } | $ { true }
$ { true } | $ { true } | $ { 2 } | $ { false }
$ { true } | $ { false } | $ { 1 } | $ { false }
$ { false } | $ { true } | $ { 1 } | $ { false }
2022-10-07 09:10:18 +00:00
` (
'given alertFieldsProvided: $alertFieldsProvided, multiIntegrations: $multiIntegrations, integrationOption: $integrationOption, visible: $visible' ,
( { alertFieldsProvided , multiIntegrations , integrationOption , visible } ) => {
const visibleMsg = visible ? 'rendered' : 'not rendered' ;
const alertFieldsMsg = alertFieldsProvided ? 'provided' : 'not provided' ;
const integrationType = integrationOption === 1 ? typeSet . http : typeSet . prometheus ;
const multiIntegrationsEnabled = multiIntegrations ? 'enabled' : 'not enabled' ;
it ( ` is ${ visibleMsg } when multiIntegrations are ${ multiIntegrationsEnabled } , integration type is ${ integrationType } and alert fields are ${ alertFieldsMsg } ` , async ( ) => {
createComponent ( {
multiIntegrations ,
props : {
alertFields : alertFieldsProvided ? alertFields : [ ] ,
} ,
} ) ;
await selectOptionAtIndex ( integrationOption ) ;
2020-11-12 09:08:57 +00:00
2022-10-07 09:10:18 +00:00
expect ( findMappingBuilder ( ) . exists ( ) ) . toBe ( visible ) ;
2021-02-04 21:09:06 +00:00
} ) ;
2022-10-07 09:10:18 +00:00
} ,
) ;
2020-10-30 09:08:39 +00:00
} ) ;
2021-03-25 21:09:13 +00:00
describe ( 'Form validation' , ( ) => {
beforeEach ( ( ) => {
createComponent ( ) ;
} ) ;
2021-03-31 06:08:58 +00:00
it ( 'should not be able to submit when no integration type is selected' , async ( ) => {
await selectOptionAtIndex ( 0 ) ;
2021-03-25 21:09:13 +00:00
expect ( findSubmitButton ( ) . attributes ( 'disabled' ) ) . toBe ( 'disabled' ) ;
} ) ;
2021-03-31 06:08:58 +00:00
it ( 'should not be able to submit when HTTP integration form is invalid' , async ( ) => {
await selectOptionAtIndex ( 1 ) ;
await findFormFields ( ) . at ( 0 ) . vm . $emit ( 'input' , '' ) ;
2021-03-25 21:09:13 +00:00
expect ( findSubmitButton ( ) . attributes ( 'disabled' ) ) . toBe ( 'disabled' ) ;
} ) ;
it ( 'should be able to submit when HTTP integration form is valid' , async ( ) => {
await selectOptionAtIndex ( 1 ) ;
2021-03-31 06:08:58 +00:00
await findFormFields ( ) . at ( 0 ) . vm . $emit ( 'input' , 'Name' ) ;
2021-03-25 21:09:13 +00:00
expect ( findSubmitButton ( ) . attributes ( 'disabled' ) ) . toBe ( undefined ) ;
} ) ;
2021-03-31 06:08:58 +00:00
it ( 'should not be able to submit when Prometheus integration form is invalid' , async ( ) => {
await selectOptionAtIndex ( 2 ) ;
await findFormFields ( ) . at ( 0 ) . vm . $emit ( 'input' , '' ) ;
2021-03-25 21:09:13 +00:00
expect ( findSubmitButton ( ) . attributes ( 'disabled' ) ) . toBe ( 'disabled' ) ;
} ) ;
it ( 'should be able to submit when Prometheus integration form is valid' , async ( ) => {
await selectOptionAtIndex ( 2 ) ;
2021-03-31 06:08:58 +00:00
await findFormFields ( ) . at ( 0 ) . vm . $emit ( 'input' , 'http://valid.url' ) ;
2021-03-25 21:09:13 +00:00
expect ( findSubmitButton ( ) . attributes ( 'disabled' ) ) . toBe ( undefined ) ;
} ) ;
it ( 'should be able to submit when form is dirty' , async ( ) => {
2021-12-29 15:10:45 +00:00
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
2021-03-25 21:09:13 +00:00
wrapper . setData ( {
currentIntegration : { type : typeSet . http , name : 'Existing integration' } ,
} ) ;
await nextTick ( ) ;
2021-03-31 06:08:58 +00:00
await findFormFields ( ) . at ( 0 ) . vm . $emit ( 'input' , 'Updated name' ) ;
2021-03-25 21:09:13 +00:00
expect ( findSubmitButton ( ) . attributes ( 'disabled' ) ) . toBe ( undefined ) ;
} ) ;
it ( 'should not be able to submit when form is pristine' , async ( ) => {
2021-12-29 15:10:45 +00:00
// setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
// eslint-disable-next-line no-restricted-syntax
2021-03-25 21:09:13 +00:00
wrapper . setData ( {
currentIntegration : { type : typeSet . http , name : 'Existing integration' } ,
} ) ;
await nextTick ( ) ;
expect ( findSubmitButton ( ) . attributes ( 'disabled' ) ) . toBe ( 'disabled' ) ;
} ) ;
2021-03-31 06:08:58 +00:00
it ( 'should disable submit button after click on validation failure' , async ( ) => {
await selectOptionAtIndex ( 1 ) ;
findSubmitButton ( ) . trigger ( 'click' ) ;
await nextTick ( ) ;
expect ( findSubmitButton ( ) . attributes ( 'disabled' ) ) . toBe ( 'disabled' ) ;
} ) ;
it ( 'should scroll to invalid field on validation failure' , async ( ) => {
await selectOptionAtIndex ( 1 ) ;
findSubmitButton ( ) . trigger ( 'click' ) ;
expect ( scrollIntoViewMock ) . toHaveBeenCalledWith ( { behavior : 'smooth' , block : 'center' } ) ;
} ) ;
2021-03-25 21:09:13 +00:00
} ) ;
2020-10-29 00:08:36 +00:00
} ) ;