Commit fa75c660 authored by Fatih Acet's avatar Fatih Acet

Merge branch 'alerts-dropdown-to-modal' into 'master'

Alerts dropdown to modal - EE1

See merge request gitlab-org/gitlab-ee!14760
parents 3d0cbfb1 4eb0e397
...@@ -369,7 +369,7 @@ export default { ...@@ -369,7 +369,7 @@ export default {
</div> </div>
<div v-if="!showEmptyState"> <div v-if="!showEmptyState">
<graph-group <graph-group
v-for="groupData in groups" v-for="(groupData, index) in groups"
:key="`${groupData.group}.${groupData.priority}`" :key="`${groupData.group}.${groupData.priority}`"
:name="groupData.group" :name="groupData.group"
:show-panels="showPanels" :show-panels="showPanels"
...@@ -381,6 +381,7 @@ export default { ...@@ -381,6 +381,7 @@ export default {
:key="`panel-type-${graphIndex}`" :key="`panel-type-${graphIndex}`"
:graph-data="graphData" :graph-data="graphData"
:dashboard-width="elWidth" :dashboard-width="elWidth"
:index="`${index}-${graphIndex}`"
/> />
</template> </template>
<template v-else> <template v-else>
...@@ -399,6 +400,7 @@ export default { ...@@ -399,6 +400,7 @@ export default {
:alerts-endpoint="alertsEndpoint" :alerts-endpoint="alertsEndpoint"
:relevant-queries="graphData.queries" :relevant-queries="graphData.queries"
:alerts-to-manage="getGraphAlerts(graphData.queries)" :alerts-to-manage="getGraphAlerts(graphData.queries)"
:modal-id="`alert-modal-${index}-${graphIndex}`"
@setAlerts="setAlerts" @setAlerts="setAlerts"
/> />
</monitor-area-chart> </monitor-area-chart>
......
...@@ -20,6 +20,11 @@ export default { ...@@ -20,6 +20,11 @@ export default {
type: Number, type: Number,
required: true, required: true,
}, },
index: {
type: String,
required: false,
default: '',
},
}, },
computed: { computed: {
...mapState('monitoringDashboard', ['deploymentData', 'projectPath']), ...mapState('monitoringDashboard', ['deploymentData', 'projectPath']),
...@@ -64,6 +69,7 @@ export default { ...@@ -64,6 +69,7 @@ export default {
:alerts-endpoint="alertsEndpoint" :alerts-endpoint="alertsEndpoint"
:relevant-queries="graphData.queries" :relevant-queries="graphData.queries"
:alerts-to-manage="getGraphAlerts(graphData.queries)" :alerts-to-manage="getGraphAlerts(graphData.queries)"
:modal-id="`alert-modal-${index}`"
@setAlerts="setAlerts" @setAlerts="setAlerts"
/> />
</monitor-area-chart> </monitor-area-chart>
......
<script> <script>
import { s__ } from '~/locale'; import { s__ } from '~/locale';
import createFlash from '~/flash';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import AlertWidgetForm from './alert_widget_form.vue'; import AlertWidgetForm from './alert_widget_form.vue';
import AlertsService from '../services/alerts_service'; import AlertsService from '../services/alerts_service';
import { alertsValidator, queriesValidator } from '../validators'; import { alertsValidator, queriesValidator } from '../validators';
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon, GlModal, GlModalDirective } from '@gitlab/ui';
export default { export default {
components: { components: {
Icon, Icon,
AlertWidgetForm, AlertWidgetForm,
GlLoadingIcon, GlLoadingIcon,
GlModal,
},
directives: {
GlModal: GlModalDirective,
}, },
props: { props: {
alertsEndpoint: { alertsEndpoint: {
...@@ -32,13 +37,16 @@ export default { ...@@ -32,13 +37,16 @@ export default {
required: true, required: true,
validator: queriesValidator, validator: queriesValidator,
}, },
modalId: {
type: String,
required: true,
},
}, },
data() { data() {
return { return {
service: null, service: null,
errorMessage: null, errorMessage: null,
isLoading: false, isLoading: false,
isOpen: false,
apiAction: 'create', apiAction: 'create',
}; };
}, },
...@@ -56,11 +64,6 @@ export default { ...@@ -56,11 +64,6 @@ export default {
? s__('PrometheusAlerts|Alert set') ? s__('PrometheusAlerts|Alert set')
: s__('PrometheusAlerts|No alert set'); : s__('PrometheusAlerts|No alert set');
}, },
dropdownTitle() {
return this.apiAction === 'create'
? s__('PrometheusAlerts|Add alert')
: s__('PrometheusAlerts|Edit alert');
},
hasAlerts() { hasAlerts() {
return Boolean(Object.keys(this.alertsToManage).length); return Boolean(Object.keys(this.alertsToManage).length);
}, },
...@@ -71,15 +74,6 @@ export default { ...@@ -71,15 +74,6 @@ export default {
return gon.features && gon.features.prometheusComputedAlerts; return gon.features && gon.features.prometheusComputedAlerts;
}, },
}, },
watch: {
isOpen(open) {
if (open) {
document.addEventListener('click', this.handleOutsideClick);
} else {
document.removeEventListener('click', this.handleOutsideClick);
}
},
},
created() { created() {
this.service = new AlertsService({ alertsEndpoint: this.alertsEndpoint }); this.service = new AlertsService({ alertsEndpoint: this.alertsEndpoint });
this.fetchAlertData(); this.fetchAlertData();
...@@ -105,7 +99,7 @@ export default { ...@@ -105,7 +99,7 @@ export default {
this.isLoading = false; this.isLoading = false;
}) })
.catch(() => { .catch(() => {
this.errorMessage = s__('PrometheusAlerts|Error fetching alert'); createFlash(s__('PrometheusAlerts|Error fetching alert'));
this.isLoading = false; this.isLoading = false;
}); });
}, },
...@@ -121,19 +115,8 @@ export default { ...@@ -121,19 +115,8 @@ export default {
return `${alertQuery.label} ${alert.operator} ${alert.threshold}`; return `${alertQuery.label} ${alert.operator} ${alert.threshold}`;
}, },
handleDropdownToggle() { hideModal() {
this.isOpen = !this.isOpen; this.$root.$emit('bv::hide::modal', this.modalId);
},
handleDropdownClose() {
this.isOpen = false;
},
handleOutsideClick(event) {
if (
!this.$refs.dropdownMenu.contains(event.target) &&
!this.$refs.dropdownMenuToggle.contains(event.target)
) {
this.isOpen = false;
}
}, },
handleSetApiAction(apiAction) { handleSetApiAction(apiAction) {
this.apiAction = apiAction; this.apiAction = apiAction;
...@@ -146,7 +129,7 @@ export default { ...@@ -146,7 +129,7 @@ export default {
.then(alertAttributes => { .then(alertAttributes => {
this.setAlert(alertAttributes, prometheus_metric_id); this.setAlert(alertAttributes, prometheus_metric_id);
this.isLoading = false; this.isLoading = false;
this.handleDropdownClose(); this.hideModal();
}) })
.catch(() => { .catch(() => {
this.errorMessage = s__('PrometheusAlerts|Error creating alert'); this.errorMessage = s__('PrometheusAlerts|Error creating alert');
...@@ -161,7 +144,7 @@ export default { ...@@ -161,7 +144,7 @@ export default {
.then(alertAttributes => { .then(alertAttributes => {
this.setAlert(alertAttributes, this.alertsToManage[alert].metricId); this.setAlert(alertAttributes, this.alertsToManage[alert].metricId);
this.isLoading = false; this.isLoading = false;
this.handleDropdownClose(); this.hideModal();
}) })
.catch(() => { .catch(() => {
this.errorMessage = s__('PrometheusAlerts|Error saving alert'); this.errorMessage = s__('PrometheusAlerts|Error saving alert');
...@@ -175,7 +158,7 @@ export default { ...@@ -175,7 +158,7 @@ export default {
.then(() => { .then(() => {
this.removeAlert(alert); this.removeAlert(alert);
this.isLoading = false; this.isLoading = false;
this.handleDropdownClose(); this.hideModal();
}) })
.catch(() => { .catch(() => {
this.errorMessage = s__('PrometheusAlerts|Error deleting alert'); this.errorMessage = s__('PrometheusAlerts|Error deleting alert');
...@@ -189,49 +172,32 @@ export default { ...@@ -189,49 +172,32 @@ export default {
<template> <template>
<div class="prometheus-alert-widget dropdown d-flex align-items-center"> <div class="prometheus-alert-widget dropdown d-flex align-items-center">
<span v-if="errorMessage" class="alert-error-message"> {{ errorMessage }} </span> <span v-if="errorMessage" class="alert-error-message"> {{ errorMessage }} </span>
<span v-else class="alert-current-setting"> <span v-else class="alert-current-setting text-secondary">
<gl-loading-icon v-show="isLoading" :inline="true" /> <gl-loading-icon v-show="isLoading" :inline="true" />
{{ alertSummary }} {{ alertSummary }}
</span> </span>
<button <button
ref="dropdownMenuToggle" ref="dropdownMenuToggle"
v-gl-modal="modalId"
:aria-label="alertStatus" :aria-label="alertStatus"
class="btn btn-sm alert-dropdown-button" class="btn btn-sm mx-2 alert-dropdown-button"
type="button" type="button"
@click="handleDropdownToggle"
> >
<icon :name="alertIcon" :size="16" aria-hidden="true" /> <icon :name="alertIcon" :size="16" aria-hidden="true" />
<icon :size="16" name="arrow-down" aria-hidden="true" class="chevron" />
</button> </button>
<div
ref="dropdownMenu" <alert-widget-form
:class="{ show: isOpen, 'h-auto': supportsComputedAlerts }" ref="widgetForm"
class="dropdown-menu alert-dropdown-menu" :disabled="formDisabled"
> :alerts-to-manage="alertsToManage"
<div class="dropdown-title m0"> :relevant-queries="relevantQueries"
<span>{{ dropdownTitle }}</span> :error-message="errorMessage"
<button :modal-id="modalId"
class="dropdown-title-button dropdown-menu-close" @create="handleCreate"
type="button" @update="handleUpdate"
aria-label="Close" @delete="handleDelete"
@click="handleDropdownClose" @cancel="hideModal"
> @setAction="handleSetApiAction"
<icon :size="12" name="close" aria-hidden="true" /> />
</button>
</div>
<div :class="{ 'mh-100': supportsComputedAlerts }" class="dropdown-content">
<alert-widget-form
ref="widgetForm"
:disabled="formDisabled"
:alerts-to-manage="alertsToManage"
:relevant-queries="relevantQueries"
@create="handleCreate"
@update="handleUpdate"
@delete="handleDelete"
@cancel="handleDropdownClose"
@setAction="handleSetApiAction"
/>
</div>
</div>
</div> </div>
</template> </template>
...@@ -9,6 +9,7 @@ import { ...@@ -9,6 +9,7 @@ import {
GlFormInput, GlFormInput,
GlDropdown, GlDropdown,
GlDropdownItem, GlDropdownItem,
GlModal,
GlTooltipDirective, GlTooltipDirective,
} from '@gitlab/ui'; } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
...@@ -39,6 +40,7 @@ export default { ...@@ -39,6 +40,7 @@ export default {
GlFormInput, GlFormInput,
GlDropdown, GlDropdown,
GlDropdownItem, GlDropdownItem,
GlModal,
Icon, Icon,
}, },
directives: { directives: {
...@@ -49,6 +51,11 @@ export default { ...@@ -49,6 +51,11 @@ export default {
type: Boolean, type: Boolean,
required: true, required: true,
}, },
errorMessage: {
type: String,
required: false,
default: '',
},
alertsToManage: { alertsToManage: {
type: Object, type: Object,
required: false, required: false,
...@@ -60,6 +67,10 @@ export default { ...@@ -60,6 +67,10 @@ export default {
required: true, required: true,
validator: queriesValidator, validator: queriesValidator,
}, },
modalId: {
type: String,
required: true,
},
}, },
data() { data() {
return { return {
...@@ -112,6 +123,11 @@ export default { ...@@ -112,6 +123,11 @@ export default {
isSubmitDisabled() { isSubmitDisabled() {
return this.disabled || (this.submitAction === 'create' && !this.haveValuesChanged); return this.disabled || (this.submitAction === 'create' && !this.haveValuesChanged);
}, },
dropdownTitle() {
return this.submitAction === 'create'
? s__('PrometheusAlerts|Add alert')
: s__('PrometheusAlerts|Edit alert');
},
}, },
watch: { watch: {
alertsToManage() { alertsToManage() {
...@@ -143,7 +159,6 @@ export default { ...@@ -143,7 +159,6 @@ export default {
this.$emit('cancel'); this.$emit('cancel');
}, },
handleSubmit() { handleSubmit() {
this.$refs.submitButton.blur();
this.$emit(this.submitAction, { this.$emit(this.submitAction, {
alert: this.selectedAlert.alert_path, alert: this.selectedAlert.alert_path,
operator: this.operator, operator: this.operator,
...@@ -170,98 +185,89 @@ export default { ...@@ -170,98 +185,89 @@ export default {
</script> </script>
<template> <template>
<div class="alert-form"> <gl-modal
<gl-form-group ref="alertModal"
v-if="supportsComputedAlerts" :title="dropdownTitle"
:label="$options.alertQueryText.label" :modal-id="modalId"
:valid-feedback="$options.alertQueryText.validFeedback" :ok-variant="submitAction === 'delete' ? 'danger' : 'success'"
:invalid-feedback="$options.alertQueryText.invalidFeedback" :ok-title="submitActionText"
:state="isValidQuery" :ok-disabled="formDisabled"
> class="prometheus-alert-widget d-flex align-items-center"
<gl-form-input v-model.trim="alertQuery" :state="isValidQuery" /> @ok="handleSubmit"
<template #description> >
<div class="d-flex align-items-center"> <span v-if="errorMessage" class="alert-error-message"> {{ errorMessage }} </span>
{{ __('Single or combined queries') }} <div class="alert-form">
<icon <gl-form-group
v-gl-tooltip-directive="$options.alertQueryText.descriptionTooltip" v-if="supportsComputedAlerts"
name="question" :label="$options.alertQueryText.label"
class="prepend-left-4" :valid-feedback="$options.alertQueryText.validFeedback"
/> :invalid-feedback="$options.alertQueryText.invalidFeedback"
</div> :state="isValidQuery"
</template>
</gl-form-group>
<gl-dropdown
v-else
:text="queryDropdownLabel"
class="form-group"
toggle-class="dropdown-menu-toggle"
>
<gl-dropdown-item
v-for="query in relevantQueries"
:key="query.metricId"
@click="selectQuery(query.metricId)"
>
{{ `${query.label} (${query.unit})` }}
</gl-dropdown-item>
</gl-dropdown>
<div :aria-label="s__('PrometheusAlerts|Operator')" class="form-group btn-group" role="group">
<button
:class="{ active: operator === operators.greaterThan }"
:disabled="formDisabled"
type="button"
class="btn btn-default"
@click="operator = operators.greaterThan"
>
{{ operators.greaterThan }}
</button>
<button
:class="{ active: operator === operators.equalTo }"
:disabled="formDisabled"
type="button"
class="btn btn-default"
@click="operator = operators.equalTo"
>
{{ operators.equalTo }}
</button>
<button
:class="{ active: operator === operators.lessThan }"
:disabled="formDisabled"
type="button"
class="btn btn-default"
@click="operator = operators.lessThan"
>
{{ operators.lessThan }}
</button>
</div>
<div class="form-group">
<label>{{ s__('PrometheusAlerts|Threshold') }}</label>
<input
v-model.number="threshold"
:disabled="formDisabled"
type="number"
class="form-control"
/>
</div>
<div class="action-group">
<button
ref="cancelButton"
:disabled="formDisabled"
type="button"
class="btn btn-default prepend-left-8"
@click="handleCancel"
> >
{{ __('Cancel') }} <gl-form-input v-model.trim="alertQuery" :state="isValidQuery" />
</button> <template #description>
<button <div class="d-flex align-items-center">
ref="submitButton" {{ __('Single or combined queries') }}
:class="submitButtonClass" <icon
:disabled="isSubmitDisabled" v-gl-tooltip-directive="$options.alertQueryText.descriptionTooltip"
type="button" name="question"
class="btn btn-inverted prepend-left-8" class="prepend-left-4"
@click="handleSubmit" />
</div>
</template>
</gl-form-group>
<gl-dropdown
v-else
:text="queryDropdownLabel"
class="form-group"
toggle-class="dropdown-menu-toggle"
> >
{{ submitActionText }} <gl-dropdown-item
</button> v-for="query in relevantQueries"
:key="query.metricId"
@click="selectQuery(query.metricId)"
>
{{ `${query.label} (${query.unit})` }}
</gl-dropdown-item>
</gl-dropdown>
<div :aria-label="s__('PrometheusAlerts|Operator')" class="form-group btn-group" role="group">
<button
:class="{ active: operator === operators.greaterThan }"
:disabled="formDisabled"
type="button"
class="btn btn-default"
@click="operator = operators.greaterThan"
>
{{ operators.greaterThan }}
</button>
<button
:class="{ active: operator === operators.equalTo }"
:disabled="formDisabled"
type="button"
class="btn btn-default"
@click="operator = operators.equalTo"
>
{{ operators.equalTo }}
</button>
<button
:class="{ active: operator === operators.lessThan }"
:disabled="formDisabled"
type="button"
class="btn btn-default"
@click="operator = operators.lessThan"
>
{{ operators.lessThan }}
</button>
</div>
<div class="form-group">
<label>{{ s__('PrometheusAlerts|Threshold') }}</label>
<input
v-model.number="threshold"
:disabled="formDisabled"
type="number"
class="form-control"
/>
</div>
</div> </div>
</div> </gl-modal>
</template> </template>
...@@ -166,11 +166,6 @@ ...@@ -166,11 +166,6 @@
vertical-align: middle; vertical-align: middle;
} }
.alert-current-setting {
color: $gl-text-color-disabled;
vertical-align: middle;
}
.alert-form { .alert-form {
padding: $gl-padding $gl-padding $gl-padding-8; padding: $gl-padding $gl-padding $gl-padding-8;
......
---
title: Move metrics alerts form to modal
merge_request: 14760
author:
type: changed
import { shallowMount } from '@vue/test-utils';
import AlertWidgetForm from 'ee/monitoring/components/alert_widget_form.vue';
import { GlModal } from '@gitlab/ui';
describe('AlertWidgetForm', () => {
let wrapper;
const metricId = '8';
const alertPath = 'alert';
const relevantQueries = [{ metricId, alert_path: alertPath, label: 'alert-label' }];
const defaultProps = {
disabled: false,
relevantQueries,
modalId: 'alert-modal-1',
};
const propsWithAlertData = {
...defaultProps,
alertsToManage: {
alert: { alert_path: alertPath, operator: '<', threshold: 5, metricId },
},
};
function createComponent(props = {}) {
const propsData = {
...defaultProps,
...props,
};
wrapper = shallowMount(AlertWidgetForm, {
propsData,
});
}
const modal = () => wrapper.find(GlModal);
const modalTitle = () => modal().attributes('title');
const submitText = () => modal().attributes('ok-title');
afterEach(() => {
if (wrapper) wrapper.destroy();
});
it('disables the form when disabled prop is set', () => {
createComponent({ disabled: true });
expect(modal().attributes('ok-disabled')).toBe('true');
});
it('disables the form if no query is selected', () => {
createComponent();
expect(modal().attributes('ok-disabled')).toBe('true');
});
it('shows correct title and button text', () => {
expect(modalTitle()).toBe('Add alert');
expect(submitText()).toBe('Add');
});
it('emits a "create" event when form submitted without existing alert', () => {
createComponent();
wrapper.vm.selectQuery('9');
wrapper.vm.operator = '>';
wrapper.vm.threshold = 900;
wrapper.vm.handleSubmit();
expect(wrapper.emitted().create[0]).toEqual([
{
alert: undefined,
operator: '>',
threshold: 900,
prometheus_metric_id: '9',
},
]);
});
describe('with existing alert', () => {
beforeEach(() => {
createComponent(propsWithAlertData);
wrapper.vm.selectQuery(metricId);
});
it('updates button text', () => {
expect(modalTitle()).toBe('Edit alert');
expect(submitText()).toBe('Delete');
});
it('emits "delete" event when form values unchanged', () => {
wrapper.vm.handleSubmit();
expect(wrapper.emitted().delete[0]).toEqual([
{
alert: 'alert',
operator: '<',
threshold: 5,
prometheus_metric_id: '8',
},
]);
});
it('emits "update" event when form changed', () => {
wrapper.vm.threshold = 11;
wrapper.vm.handleSubmit();
expect(wrapper.emitted().update[0]).toEqual([
{
alert: 'alert',
operator: '<',
threshold: 11,
prometheus_metric_id: '8',
},
]);
});
});
});
import Vue from 'vue';
import AlertWidgetForm from 'ee/monitoring/components/alert_widget_form.vue';
import mountComponent from 'spec/helpers/vue_mount_component_helper';
describe('AlertWidgetForm', () => {
let AlertWidgetFormComponent;
let vm;
const metricId = '8';
const alertPath = 'alert';
const relevantQueries = [{ metricId, alert_path: alertPath, label: 'alert-label' }];
const props = {
disabled: false,
relevantQueries,
};
const propsWithAlertData = {
...props,
relevantQueries,
alertsToManage: {
alert: { alert_path: alertPath, operator: '<', threshold: 5, metricId },
},
};
beforeAll(() => {
AlertWidgetFormComponent = Vue.extend(AlertWidgetForm);
});
afterEach(() => {
if (vm) vm.$destroy();
});
it('disables the input when disabled prop is set', () => {
vm = mountComponent(AlertWidgetFormComponent, { ...props, disabled: true });
vm.prometheusMetricId = 6;
expect(vm.$refs.cancelButton).toBeDisabled();
expect(vm.$refs.submitButton).toBeDisabled();
});
it('disables the input if no query is selected', () => {
vm = mountComponent(AlertWidgetFormComponent, props);
expect(vm.$refs.cancelButton).toBeDisabled();
expect(vm.$refs.submitButton).toBeDisabled();
});
it('emits a "create" event when form submitted without existing alert', done => {
vm = mountComponent(AlertWidgetFormComponent, props);
expect(vm.$refs.submitButton.innerText).toContain('Add');
vm.$once('create', alert => {
expect(alert).toEqual({
alert: undefined,
operator: '<',
threshold: 5,
prometheus_metric_id: '8',
});
done();
});
// the button should be disabled until an operator and threshold are selected
expect(vm.$refs.submitButton).toBeDisabled();
vm.selectQuery('8');
vm.operator = '<';
vm.threshold = 5;
Vue.nextTick(() => {
vm.$refs.submitButton.click();
});
});
it('emits a "delete" event when form submitted with existing alert and no changes are made', done => {
vm = mountComponent(AlertWidgetFormComponent, propsWithAlertData);
vm.selectQuery('8');
vm.$once('delete', alert => {
expect(alert).toEqual({
alert: 'alert',
operator: '<',
threshold: 5,
prometheus_metric_id: '8',
});
done();
});
Vue.nextTick(() => {
expect(vm.$refs.submitButton.innerText).toContain('Delete');
vm.$refs.submitButton.click();
});
});
it('emits a "update" event when form submitted with existing alert', done => {
vm = mountComponent(AlertWidgetFormComponent, propsWithAlertData);
vm.selectQuery('8');
vm.$once('update', alert => {
expect(alert).toEqual({
alert: 'alert',
operator: '=',
threshold: 5,
prometheus_metric_id: '8',
});
done();
});
Vue.nextTick(() => {
expect(vm.$refs.submitButton.innerText).toContain('Delete');
// change operator to allow update
vm.operator = '=';
Vue.nextTick(() => {
expect(vm.$refs.submitButton.innerText).toContain('Save');
vm.$refs.submitButton.click();
});
});
});
});
...@@ -16,6 +16,7 @@ describe('AlertWidget', () => { ...@@ -16,6 +16,7 @@ describe('AlertWidget', () => {
alertsEndpoint: '', alertsEndpoint: '',
relevantQueries, relevantQueries,
alertsToManage: {}, alertsToManage: {},
modalId: 'alert-modal-1',
}; };
const propsWithAlert = { const propsWithAlert = {
...@@ -75,14 +76,14 @@ describe('AlertWidget', () => { ...@@ -75,14 +76,14 @@ describe('AlertWidget', () => {
}); });
it('displays an error message when fetch fails', done => { it('displays an error message when fetch fails', done => {
const spy = spyOnDependency(AlertWidget, 'createFlash');
spyOn(AlertsService.prototype, 'readAlert').and.returnValue(Promise.reject()); spyOn(AlertsService.prototype, 'readAlert').and.returnValue(Promise.reject());
vm = mountComponent(AlertWidgetComponent, propsWithAlert, '#alert-widget'); vm = mountComponent(AlertWidgetComponent, propsWithAlert, '#alert-widget');
setTimeout(() => setTimeout(() =>
vm.$nextTick(() => { vm.$nextTick(() => {
expect(vm.errorMessage).toBe('Error fetching alert');
expect(vm.isLoading).toEqual(false); expect(vm.isLoading).toEqual(false);
expect(vm.$el.querySelector('.alert-error-message')).toBeVisible(); expect(spy).toHaveBeenCalled();
done(); done();
}), }),
); );
...@@ -128,46 +129,6 @@ describe('AlertWidget', () => { ...@@ -128,46 +129,6 @@ describe('AlertWidget', () => {
expect(vm.$el.querySelector('.alert-current-setting')).toBeVisible(); expect(vm.$el.querySelector('.alert-current-setting')).toBeVisible();
}); });
it('opens and closes a dropdown menu by clicking close button', done => {
vm = mountComponent(AlertWidgetComponent, props);
expect(vm.isOpen).toEqual(false);
expect(vm.$el.querySelector('.alert-dropdown-menu')).toBeHidden();
vm.$el.querySelector('.alert-dropdown-button').click();
Vue.nextTick(() => {
expect(vm.isOpen).toEqual(true);
vm.$el.querySelector('.dropdown-menu-close').click();
Vue.nextTick(() => {
expect(vm.isOpen).toEqual(false);
done();
});
});
});
it('opens and closes a dropdown menu by clicking outside the menu', done => {
vm = mountComponent(AlertWidgetComponent, props);
expect(vm.isOpen).toEqual(false);
expect(vm.$el.querySelector('.alert-dropdown-menu')).toBeHidden();
vm.$el.querySelector('.alert-dropdown-button').click();
Vue.nextTick(() => {
expect(vm.isOpen).toEqual(true);
document.body.click();
Vue.nextTick(() => {
expect(vm.isOpen).toEqual(false);
done();
});
});
});
it('creates an alert with an appropriate handler', done => { it('creates an alert with an appropriate handler', done => {
const alertParams = { const alertParams = {
operator: '<', operator: '<',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment