2021-01-29 00:20:46 +05:30
import {
GlForm ,
GlFormSelect ,
GlCollapse ,
GlFormInput ,
GlToggle ,
GlFormTextarea ,
} from '@gitlab/ui' ;
2021-03-11 19:13:27 +05:30
import { mount } from '@vue/test-utils' ;
2021-01-29 00:20:46 +05:30
import waitForPromises from 'helpers/wait_for_promises' ;
2021-03-11 19:13:27 +05:30
import MappingBuilder from '~/alerts_settings/components/alert_mapping_builder.vue' ;
2021-02-22 17:27:13 +05:30
import AlertsSettingsForm from '~/alerts_settings/components/alerts_settings_form.vue' ;
2021-01-29 00:20:46 +05:30
import { typeSet } from '~/alerts_settings/constants' ;
2021-03-11 19:13:27 +05:30
import alertFields from '../mocks/alertFields.json' ;
import { defaultAlertSettingsConfig } from './util' ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
describe ( 'AlertsSettingsForm' , ( ) => {
2021-01-29 00:20:46 +05:30
let wrapper ;
const mockToastShow = jest . fn ( ) ;
const createComponent = ( {
data = { } ,
props = { } ,
multipleHttpIntegrationsCustomMapping = false ,
2021-03-11 19:13:27 +05:30
multiIntegrations = true ,
2021-01-29 00:20:46 +05:30
} = { } ) => {
wrapper = mount ( AlertsSettingsForm , {
data ( ) {
return { ... data } ;
} ,
propsData : {
loading : false ,
canAddIntegration : true ,
... props ,
} ,
provide : {
... defaultAlertSettingsConfig ,
2021-03-11 19:13:27 +05:30
glFeatures : { multipleHttpIntegrationsCustomMapping } ,
multiIntegrations ,
2021-01-29 00:20:46 +05:30
} ,
mocks : {
$toast : {
show : mockToastShow ,
} ,
} ,
} ) ;
} ;
const findForm = ( ) => wrapper . find ( GlForm ) ;
const findSelect = ( ) => wrapper . find ( GlFormSelect ) ;
const findFormSteps = ( ) => wrapper . find ( GlCollapse ) ;
const findFormFields = ( ) => wrapper . findAll ( GlFormInput ) ;
const findFormToggle = ( ) => wrapper . find ( GlToggle ) ;
const findTestPayloadSection = ( ) => wrapper . find ( ` [id = "test-integration"] ` ) ;
const findMappingBuilderSection = ( ) => wrapper . find ( ` [id = "mapping-builder"] ` ) ;
2021-03-11 19:13:27 +05:30
const findMappingBuilder = ( ) => wrapper . findComponent ( MappingBuilder ) ;
2021-01-29 00:20:46 +05:30
const findSubmitButton = ( ) => wrapper . find ( ` [type = "submit"] ` ) ;
const findMultiSupportText = ( ) =>
wrapper . find ( ` [data-testid="multi-integrations-not-supported"] ` ) ;
const findJsonTestSubmit = ( ) => wrapper . find ( ` [data-testid="integration-test-and-submit"] ` ) ;
const findJsonTextArea = ( ) => wrapper . find ( ` [id = "test-payload"] ` ) ;
const findActionBtn = ( ) => wrapper . find ( ` [data-testid="payload-action-btn"] ` ) ;
afterEach ( ( ) => {
if ( wrapper ) {
wrapper . destroy ( ) ;
wrapper = null ;
}
} ) ;
2021-03-11 19:13:27 +05:30
const selectOptionAtIndex = async ( index ) => {
const options = findSelect ( ) . findAll ( 'option' ) ;
await options . at ( index ) . setSelected ( ) ;
} ;
const enableIntegration = ( index , value ) => {
findFormFields ( ) . at ( index ) . setValue ( value ) ;
findFormToggle ( ) . trigger ( 'click' ) ;
} ;
2021-01-29 00:20:46 +05:30
describe ( 'with default values' , ( ) => {
beforeEach ( ( ) => {
createComponent ( ) ;
} ) ;
it ( 'renders the initial template' , ( ) => {
2021-03-11 19:13:27 +05:30
expect ( wrapper . element ) . toMatchSnapshot ( ) ;
2021-01-29 00:20:46 +05:30
} ) ;
it ( 'render the initial form with only an integration type dropdown' , ( ) => {
expect ( findForm ( ) . exists ( ) ) . toBe ( true ) ;
expect ( findSelect ( ) . exists ( ) ) . toBe ( true ) ;
expect ( findMultiSupportText ( ) . exists ( ) ) . toBe ( false ) ;
expect ( findFormSteps ( ) . attributes ( 'visible' ) ) . toBeUndefined ( ) ;
} ) ;
it ( 'shows the rest of the form when the dropdown is used' , async ( ) => {
2021-03-11 19:13:27 +05:30
await selectOptionAtIndex ( 1 ) ;
2021-01-29 00:20:46 +05:30
2021-03-08 18:12:59 +05:30
expect ( findFormFields ( ) . at ( 0 ) . isVisible ( ) ) . toBe ( true ) ;
2021-01-29 00:20:46 +05:30
} ) ;
2021-02-22 17:27:13 +05:30
it ( 'disables the dropdown and shows help text when multi integrations are not supported' , async ( ) => {
2021-01-29 00:20:46 +05:30
createComponent ( { props : { canAddIntegration : false } } ) ;
expect ( findSelect ( ) . attributes ( 'disabled' ) ) . toBe ( 'disabled' ) ;
expect ( findMultiSupportText ( ) . exists ( ) ) . toBe ( true ) ;
} ) ;
2021-02-22 17:27:13 +05:30
it ( 'disabled the name input when the selected value is prometheus' , async ( ) => {
createComponent ( ) ;
2021-03-11 19:13:27 +05:30
await selectOptionAtIndex ( 2 ) ;
2021-02-22 17:27:13 +05:30
2021-03-08 18:12:59 +05:30
expect ( findFormFields ( ) . at ( 0 ) . attributes ( 'disabled' ) ) . toBe ( 'disabled' ) ;
2021-02-22 17:27:13 +05:30
} ) ;
2021-01-29 00:20:46 +05:30
} ) ;
describe ( 'submitting integration form' , ( ) => {
2021-03-11 19:13:27 +05:30
describe ( 'HTTP' , ( ) => {
it ( 'create' , async ( ) => {
createComponent ( ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
const integrationName = 'Test integration' ;
await selectOptionAtIndex ( 1 ) ;
enableIntegration ( 0 , integrationName ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
const submitBtn = findSubmitButton ( ) ;
expect ( submitBtn . exists ( ) ) . toBe ( true ) ;
expect ( submitBtn . text ( ) ) . toBe ( 'Save integration' ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
findForm ( ) . trigger ( 'submit' ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
expect ( wrapper . emitted ( 'create-new-integration' ) [ 0 ] ) . toEqual ( [
{ type : typeSet . http , variables : { name : integrationName , active : true } } ,
] ) ;
} ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
it ( 'create with custom mapping' , async ( ) => {
createComponent ( {
multipleHttpIntegrationsCustomMapping : true ,
multiIntegrations : true ,
props : { alertFields } ,
} ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
const integrationName = 'Test integration' ;
await selectOptionAtIndex ( 1 ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
enableIntegration ( 0 , integrationName ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
const sampleMapping = { field : 'test' } ;
findMappingBuilder ( ) . vm . $emit ( 'onMappingUpdate' , sampleMapping ) ;
findForm ( ) . trigger ( 'submit' ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
expect ( wrapper . emitted ( 'create-new-integration' ) [ 0 ] ) . toEqual ( [
{
type : typeSet . http ,
variables : {
name : integrationName ,
active : true ,
payloadAttributeMappings : sampleMapping ,
payloadExample : null ,
} ,
} ,
] ) ;
} ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
it ( 'update' , ( ) => {
createComponent ( {
data : {
selectedIntegration : typeSet . http ,
currentIntegration : { id : '1' , name : 'Test integration pre' } ,
} ,
props : {
loading : false ,
} ,
} ) ;
const updatedIntegrationName = 'Test integration post' ;
enableIntegration ( 0 , updatedIntegrationName ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
const submitBtn = findSubmitButton ( ) ;
expect ( submitBtn . exists ( ) ) . toBe ( true ) ;
expect ( submitBtn . text ( ) ) . toBe ( 'Save integration' ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
findForm ( ) . trigger ( 'submit' ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
expect ( wrapper . emitted ( 'update-integration' ) [ 0 ] ) . toEqual ( [
{ type : typeSet . http , variables : { name : updatedIntegrationName , active : true } } ,
] ) ;
2021-01-29 00:20:46 +05:30
} ) ;
2021-03-11 19:13:27 +05:30
} ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
describe ( 'PROMETHEUS' , ( ) => {
it ( 'create' , async ( ) => {
createComponent ( ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
await selectOptionAtIndex ( 2 ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
const apiUrl = 'https://test.com' ;
enableIntegration ( 1 , apiUrl ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
findFormToggle ( ) . trigger ( 'click' ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
const submitBtn = findSubmitButton ( ) ;
expect ( submitBtn . exists ( ) ) . toBe ( true ) ;
expect ( submitBtn . text ( ) ) . toBe ( 'Save integration' ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
findForm ( ) . trigger ( 'submit' ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
expect ( wrapper . emitted ( 'create-new-integration' ) [ 0 ] ) . toEqual ( [
{ type : typeSet . prometheus , variables : { apiUrl , active : true } } ,
] ) ;
2021-01-29 00:20:46 +05:30
} ) ;
2021-03-11 19:13:27 +05:30
it ( 'update' , ( ) => {
createComponent ( {
data : {
selectedIntegration : typeSet . prometheus ,
currentIntegration : { id : '1' , apiUrl : 'https://test-pre.com' } ,
} ,
props : {
loading : false ,
} ,
} ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
const apiUrl = 'https://test-post.com' ;
enableIntegration ( 1 , apiUrl ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
const submitBtn = findSubmitButton ( ) ;
expect ( submitBtn . exists ( ) ) . toBe ( true ) ;
expect ( submitBtn . text ( ) ) . toBe ( 'Save integration' ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
findForm ( ) . trigger ( 'submit' ) ;
2021-01-29 00:20:46 +05:30
2021-03-11 19:13:27 +05:30
expect ( wrapper . emitted ( 'update-integration' ) [ 0 ] ) . toEqual ( [
{ type : typeSet . prometheus , variables : { apiUrl , active : true } } ,
] ) ;
} ) ;
2021-01-29 00:20:46 +05:30
} ) ;
} ) ;
describe ( 'submitting the integration with a JSON test payload' , ( ) => {
beforeEach ( ( ) => {
createComponent ( {
data : {
selectedIntegration : typeSet . http ,
currentIntegration : { id : '1' , name : 'Test' } ,
active : true ,
} ,
props : {
loading : false ,
} ,
} ) ;
} ) ;
it ( 'should not allow a user to test invalid JSON' , async ( ) => {
jest . useFakeTimers ( ) ;
await findJsonTextArea ( ) . setValue ( 'Invalid JSON' ) ;
jest . runAllTimers ( ) ;
await wrapper . vm . $nextTick ( ) ;
2021-03-11 19:13:27 +05:30
const jsonTestSubmit = findJsonTestSubmit ( ) ;
expect ( jsonTestSubmit . exists ( ) ) . toBe ( true ) ;
expect ( jsonTestSubmit . text ( ) ) . toBe ( 'Save and test payload' ) ;
expect ( jsonTestSubmit . props ( 'disabled' ) ) . toBe ( true ) ;
2021-01-29 00:20:46 +05:30
} ) ;
it ( 'should allow for the form to be automatically saved if the test payload is successfully submitted' , async ( ) => {
jest . useFakeTimers ( ) ;
await findJsonTextArea ( ) . setValue ( '{ "value": "value" }' ) ;
jest . runAllTimers ( ) ;
await wrapper . vm . $nextTick ( ) ;
expect ( findJsonTestSubmit ( ) . props ( 'disabled' ) ) . toBe ( false ) ;
} ) ;
} ) ;
describe ( 'Test payload section for HTTP integration' , ( ) => {
beforeEach ( ( ) => {
createComponent ( {
multipleHttpIntegrationsCustomMapping : true ,
props : {
currentIntegration : {
type : typeSet . http ,
} ,
2021-03-11 19:13:27 +05:30
alertFields ,
2021-01-29 00:20:46 +05:30
} ,
} ) ;
} ) ;
describe . each `
active | resetSamplePayloadConfirmed | disabled
$ { true } | $ { true } | $ { undefined }
$ { false } | $ { true } | $ { 'disabled' }
$ { true } | $ { false } | $ { 'disabled' }
$ { false } | $ { false } | $ { 'disabled' }
` ('', ({ active, resetSamplePayloadConfirmed, disabled }) => {
const payloadResetMsg = resetSamplePayloadConfirmed ? 'was confirmed' : 'was not confirmed' ;
const enabledState = disabled === 'disabled' ? 'disabled' : 'enabled' ;
const activeState = active ? 'active' : 'not active' ;
it ( ` textarea should be ${ enabledState } when payload reset ${ payloadResetMsg } and current integration is ${ activeState } ` , async ( ) => {
wrapper . setData ( {
customMapping : { samplePayload : true } ,
active ,
resetSamplePayloadConfirmed ,
} ) ;
await wrapper . vm . $nextTick ( ) ;
2021-03-08 18:12:59 +05:30
expect ( findTestPayloadSection ( ) . find ( GlFormTextarea ) . attributes ( 'disabled' ) ) . toBe ( disabled ) ;
2021-01-29 00:20:46 +05:30
} ) ;
} ) ;
describe ( 'action buttons for sample payload' , ( ) => {
describe . each `
resetSamplePayloadConfirmed | samplePayload | caption
$ { false } | $ { true } | $ { 'Edit payload' }
$ { true } | $ { false } | $ { 'Submit payload' }
$ { true } | $ { true } | $ { 'Submit payload' }
$ { false } | $ { false } | $ { 'Submit payload' }
` ('', ({ resetSamplePayloadConfirmed, samplePayload, caption }) => {
const samplePayloadMsg = samplePayload ? 'was provided' : 'was not provided' ;
const payloadResetMsg = resetSamplePayloadConfirmed ? 'was confirmed' : 'was not confirmed' ;
it ( ` shows ${ caption } button when sample payload ${ samplePayloadMsg } and payload reset ${ payloadResetMsg } ` , async ( ) => {
wrapper . setData ( {
selectedIntegration : typeSet . http ,
customMapping : { samplePayload } ,
resetSamplePayloadConfirmed ,
} ) ;
await wrapper . vm . $nextTick ( ) ;
expect ( findActionBtn ( ) . text ( ) ) . toBe ( caption ) ;
} ) ;
} ) ;
} ) ;
describe ( 'Parsing payload' , ( ) => {
it ( 'displays a toast message on successful parse' , async ( ) => {
jest . useFakeTimers ( ) ;
wrapper . setData ( {
selectedIntegration : typeSet . http ,
customMapping : { samplePayload : false } ,
} ) ;
await wrapper . vm . $nextTick ( ) ;
findActionBtn ( ) . vm . $emit ( 'click' ) ;
jest . advanceTimersByTime ( 1000 ) ;
await waitForPromises ( ) ;
expect ( mockToastShow ) . toHaveBeenCalledWith (
'Sample payload has been parsed. You can now map the fields.' ,
) ;
} ) ;
} ) ;
} ) ;
describe ( 'Mapping builder section' , ( ) => {
describe . each `
2021-03-11 19:13:27 +05:30
alertFieldsProvided | multiIntegrations | featureFlag | integrationOption | visible
$ { true } | $ { true } | $ { true } | $ { 1 } | $ { true }
$ { true } | $ { true } | $ { true } | $ { 2 } | $ { false }
$ { true } | $ { true } | $ { false } | $ { 1 } | $ { false }
$ { true } | $ { true } | $ { false } | $ { 2 } | $ { false }
$ { true } | $ { false } | $ { true } | $ { 1 } | $ { false }
$ { false } | $ { true } | $ { true } | $ { 1 } | $ { false }
` ('', ({ alertFieldsProvided, multiIntegrations, featureFlag, integrationOption, visible }) => {
2021-01-29 00:20:46 +05:30
const visibleMsg = visible ? 'is rendered' : 'is not rendered' ;
const featureFlagMsg = featureFlag ? 'is enabled' : 'is disabled' ;
2021-03-11 19:13:27 +05:30
const alertFieldsMsg = alertFieldsProvided ? 'are provided' : 'are not provided' ;
2021-01-29 00:20:46 +05:30
const integrationType = integrationOption === 1 ? typeSet . http : typeSet . prometheus ;
2021-03-11 19:13:27 +05:30
it ( ` ${ visibleMsg } when multipleHttpIntegrationsCustomMapping feature flag ${ featureFlagMsg } and integration type is ${ integrationType } and alert fields ${ alertFieldsMsg } ` , async ( ) => {
createComponent ( {
multipleHttpIntegrationsCustomMapping : featureFlag ,
multiIntegrations ,
props : {
alertFields : alertFieldsProvided ? alertFields : [ ] ,
} ,
} ) ;
await selectOptionAtIndex ( integrationOption ) ;
2021-01-29 00:20:46 +05:30
expect ( findMappingBuilderSection ( ) . exists ( ) ) . toBe ( visible ) ;
} ) ;
} ) ;
} ) ;
} ) ;