diff options
Diffstat (limited to 'spec/frontend/monitoring')
4 files changed, 281 insertions, 0 deletions
diff --git a/spec/frontend/monitoring/components/date_time_picker/date_time_picker_input_spec.js b/spec/frontend/monitoring/components/date_time_picker/date_time_picker_input_spec.js new file mode 100644 index 00000000000..1315e1226a4 --- /dev/null +++ b/spec/frontend/monitoring/components/date_time_picker/date_time_picker_input_spec.js @@ -0,0 +1,66 @@ +import { mount } from '@vue/test-utils'; +import DateTimePickerInput from '~/monitoring/components/date_time_picker/date_time_picker_input.vue'; + +const inputLabel = 'This is a label'; +const inputValue = 'something'; + +describe('DateTimePickerInput', () => { + let wrapper; + + const createComponent = (propsData = {}) => { + wrapper = mount(DateTimePickerInput, { + propsData: { + state: null, + value: '', + label: '', + ...propsData, + }, + sync: false, + }); + }; + + afterEach(() => { + wrapper.destroy(); + }); + + it('renders label above the input', () => { + createComponent({ + label: inputLabel, + }); + + expect(wrapper.find('.gl-form-group label').text()).toBe(inputLabel); + }); + + it('renders the same `ID` for input and `for` for label', () => { + createComponent({ label: inputLabel }); + + expect(wrapper.find('.gl-form-group label').attributes('for')).toBe( + wrapper.find('input').attributes('id'), + ); + }); + + it('renders valid input in gray color instead of green', () => { + createComponent({ + state: true, + }); + + expect(wrapper.find('input').classes('is-valid')).toBe(false); + }); + + it('renders invalid input in red color', () => { + createComponent({ + state: false, + }); + + expect(wrapper.find('input').classes('is-invalid')).toBe(true); + }); + + it('input event is emitted when focus is lost', () => { + createComponent(); + jest.spyOn(wrapper.vm, '$emit'); + wrapper.find('input').setValue(inputValue); + wrapper.find('input').trigger('blur'); + + expect(wrapper.vm.$emit).toHaveBeenCalledWith('input', inputValue); + }); +}); diff --git a/spec/frontend/monitoring/components/date_time_picker/date_time_picker_spec.js b/spec/frontend/monitoring/components/date_time_picker/date_time_picker_spec.js new file mode 100644 index 00000000000..be544435671 --- /dev/null +++ b/spec/frontend/monitoring/components/date_time_picker/date_time_picker_spec.js @@ -0,0 +1,157 @@ +import { mount } from '@vue/test-utils'; +import DateTimePicker from '~/monitoring/components/date_time_picker/date_time_picker.vue'; +import { timeWindows } from '~/monitoring/constants'; + +const timeWindowsCount = Object.keys(timeWindows).length; +const selectedTimeWindow = { + start: '2019-10-10T07:00:00.000Z', + end: '2019-10-13T07:00:00.000Z', +}; +const selectedTimeWindowText = `3 days`; + +describe('DateTimePicker', () => { + let dateTimePicker; + + const dropdownToggle = () => dateTimePicker.find('.dropdown-toggle'); + const dropdownMenu = () => dateTimePicker.find('.dropdown-menu'); + const applyButtonElement = () => dateTimePicker.find('button[variant="success"]').element; + const cancelButtonElement = () => dateTimePicker.find('button.btn-secondary').element; + const fillInputAndBlur = (input, val) => { + dateTimePicker.find(input).setValue(val); + dateTimePicker.find(input).trigger('blur'); + }; + + const createComponent = props => { + dateTimePicker = mount(DateTimePicker, { + propsData: { + timeWindows, + selectedTimeWindow, + ...props, + }, + sync: false, + }); + }; + + afterEach(() => { + dateTimePicker.destroy(); + }); + + it('renders dropdown toggle button with selected text', done => { + createComponent(); + dateTimePicker.vm.$nextTick(() => { + expect(dropdownToggle().text()).toBe(selectedTimeWindowText); + done(); + }); + }); + + it('renders dropdown with 2 custom time range inputs', () => { + createComponent(); + dateTimePicker.vm.$nextTick(() => { + expect(dateTimePicker.findAll('input').length).toBe(2); + }); + }); + + it('renders inputs with h/m/s truncated if its all 0s', done => { + createComponent({ + selectedTimeWindow: { + start: '2019-10-10T00:00:00.000Z', + end: '2019-10-14T00:10:00.000Z', + }, + }); + dateTimePicker.vm.$nextTick(() => { + expect(dateTimePicker.find('#custom-time-from').element.value).toBe('2019-10-10'); + expect(dateTimePicker.find('#custom-time-to').element.value).toBe('2019-10-14 00:10:00'); + done(); + }); + }); + + it(`renders dropdown with ${timeWindowsCount} items in quick range`, done => { + createComponent(); + dropdownToggle().trigger('click'); + dateTimePicker.vm.$nextTick(() => { + expect(dateTimePicker.findAll('.dropdown-item').length).toBe(timeWindowsCount); + done(); + }); + }); + + it(`renders dropdown with correct quick range item selected`, done => { + createComponent(); + dropdownToggle().trigger('click'); + dateTimePicker.vm.$nextTick(() => { + expect(dateTimePicker.find('.dropdown-item.active').text()).toBe(selectedTimeWindowText); + + expect(dateTimePicker.find('.dropdown-item.active svg').isVisible()).toBe(true); + done(); + }); + }); + + it('renders a disabled apply button on load', () => { + createComponent(); + + expect(applyButtonElement().getAttribute('disabled')).toBe('disabled'); + }); + + it('displays inline error message if custom time range inputs are invalid', done => { + createComponent(); + fillInputAndBlur('#custom-time-from', '2019-10-01abc'); + fillInputAndBlur('#custom-time-to', '2019-10-10abc'); + + dateTimePicker.vm.$nextTick(() => { + expect(dateTimePicker.findAll('.invalid-feedback').length).toBe(2); + done(); + }); + }); + + it('keeps apply button disabled with invalid custom time range inputs', done => { + createComponent(); + fillInputAndBlur('#custom-time-from', '2019-10-01abc'); + fillInputAndBlur('#custom-time-to', '2019-09-19'); + + dateTimePicker.vm.$nextTick(() => { + expect(applyButtonElement().getAttribute('disabled')).toBe('disabled'); + done(); + }); + }); + + it('enables apply button with valid custom time range inputs', done => { + createComponent(); + fillInputAndBlur('#custom-time-from', '2019-10-01'); + fillInputAndBlur('#custom-time-to', '2019-10-19'); + + dateTimePicker.vm.$nextTick(() => { + expect(applyButtonElement().getAttribute('disabled')).toBeNull(); + done(); + }); + }); + + it('returns an object when apply is clicked', done => { + createComponent(); + fillInputAndBlur('#custom-time-from', '2019-10-01'); + fillInputAndBlur('#custom-time-to', '2019-10-19'); + + dateTimePicker.vm.$nextTick(() => { + jest.spyOn(dateTimePicker.vm, '$emit'); + applyButtonElement().click(); + + expect(dateTimePicker.vm.$emit).toHaveBeenCalledWith('onApply', { + end: '2019-10-19T00:00:00Z', + start: '2019-10-01T00:00:00Z', + }); + done(); + }); + }); + + it('hides the popover with cancel button', done => { + createComponent(); + dropdownToggle().trigger('click'); + + dateTimePicker.vm.$nextTick(() => { + cancelButtonElement().click(); + + dateTimePicker.vm.$nextTick(() => { + expect(dropdownMenu().classes('show')).toBe(false); + done(); + }); + }); + }); +}); diff --git a/spec/frontend/monitoring/embed/embed_spec.js b/spec/frontend/monitoring/embed/embed_spec.js index 1ce14e2418a..5de1a7c4c3b 100644 --- a/spec/frontend/monitoring/embed/embed_spec.js +++ b/spec/frontend/monitoring/embed/embed_spec.js @@ -74,5 +74,9 @@ describe('Embed', () => { expect(wrapper.find(MonitorTimeSeriesChart).exists()).toBe(true); expect(wrapper.findAll(MonitorTimeSeriesChart).length).toBe(2); }); + + it('includes groupId with dashboardUrl', () => { + expect(wrapper.find(MonitorTimeSeriesChart).props('groupId')).toBe(TEST_HOST); + }); }); }); diff --git a/spec/frontend/monitoring/utils_spec.js b/spec/frontend/monitoring/utils_spec.js new file mode 100644 index 00000000000..1e8d5753885 --- /dev/null +++ b/spec/frontend/monitoring/utils_spec.js @@ -0,0 +1,54 @@ +import * as monitoringUtils from '~/monitoring/utils'; + +describe('Snowplow Events', () => { + const generatedLink = 'http://chart.link.com'; + const chartTitle = 'Some metric chart'; + + describe('trackGenerateLinkToChartEventOptions', () => { + it('should return Cluster Monitoring options if located on Cluster Health Dashboard', () => { + document.body.dataset.page = 'groups:clusters:show'; + + expect(monitoringUtils.generateLinkToChartOptions(generatedLink)).toEqual({ + category: 'Cluster Monitoring', + action: 'generate_link_to_cluster_metric_chart', + label: 'Chart link', + property: generatedLink, + }); + }); + + it('should return Incident Management event options if located on Metrics Dashboard', () => { + document.body.dataset.page = 'metrics:show'; + + expect(monitoringUtils.generateLinkToChartOptions(generatedLink)).toEqual({ + category: 'Incident Management::Embedded metrics', + action: 'generate_link_to_metrics_chart', + label: 'Chart link', + property: generatedLink, + }); + }); + }); + + describe('trackDownloadCSVEvent', () => { + it('should return Cluster Monitoring options if located on Cluster Health Dashboard', () => { + document.body.dataset.page = 'groups:clusters:show'; + + expect(monitoringUtils.downloadCSVOptions(chartTitle)).toEqual({ + category: 'Cluster Monitoring', + action: 'download_csv_of_cluster_metric_chart', + label: 'Chart title', + property: chartTitle, + }); + }); + + it('should return Incident Management event options if located on Metrics Dashboard', () => { + document.body.dataset.page = 'metriss:show'; + + expect(monitoringUtils.downloadCSVOptions(chartTitle)).toEqual({ + category: 'Incident Management::Embedded metrics', + action: 'download_csv_of_metrics_dashboard_chart', + label: 'Chart title', + property: chartTitle, + }); + }); + }); +}); |