From 9a93fd9ec4e765873d49c3d8e29ca165b43ba083 Mon Sep 17 00:00:00 2001 From: Phil Hughes Date: Sat, 19 Aug 2017 20:41:23 +0100 Subject: Fixed fly-out nav jumping Closes #36699 --- spec/javascripts/fly_out_nav_spec.js | 34 ++++++++++------------------------ 1 file changed, 10 insertions(+), 24 deletions(-) (limited to 'spec/javascripts') diff --git a/spec/javascripts/fly_out_nav_spec.js b/spec/javascripts/fly_out_nav_spec.js index 2e81a1b056b..0847e463577 100644 --- a/spec/javascripts/fly_out_nav_spec.js +++ b/spec/javascripts/fly_out_nav_spec.js @@ -1,4 +1,3 @@ -import Cookies from 'js-cookie'; import { calculateTop, showSubLevelItems, @@ -11,6 +10,7 @@ import { getHideSubItemsInterval, documentMouseMove, getHeaderHeight, + setSidebar, } from '~/fly_out_nav'; import bp from '~/breakpoints'; @@ -113,7 +113,6 @@ describe('Fly out sidebar navigation', () => { clientX: el.getBoundingClientRect().left + 20, clientY: el.getBoundingClientRect().top + 10, }); - console.log(el); expect( getHideSubItemsInterval(), @@ -283,7 +282,7 @@ describe('Fly out sidebar navigation', () => { describe('canShowActiveSubItems', () => { afterEach(() => { - Cookies.remove('sidebar_collapsed'); + setSidebar(null); }); it('returns true by default', () => { @@ -292,36 +291,23 @@ describe('Fly out sidebar navigation', () => { ).toBeTruthy(); }); - it('returns false when cookie is false & element is active', () => { - Cookies.set('sidebar_collapsed', 'false'); + it('returns false when active & expanded sidebar', () => { + const sidebar = document.createElement('div'); el.classList.add('active'); - expect( - canShowActiveSubItems(el), - ).toBeFalsy(); - }); - - it('returns true when cookie is false & element is active', () => { - Cookies.set('sidebar_collapsed', 'true'); - el.classList.add('active'); + setSidebar(sidebar); expect( canShowActiveSubItems(el), - ).toBeTruthy(); + ).toBeFalsy(); }); - it('returns true when element is active & breakpoint is sm', () => { - breakpointSize = 'sm'; + it('returns true when active & collapsed sidebar', () => { + const sidebar = document.createElement('div'); + sidebar.classList.add('sidebar-icons-only'); el.classList.add('active'); - expect( - canShowActiveSubItems(el), - ).toBeTruthy(); - }); - - it('returns true when element is active & breakpoint is md', () => { - breakpointSize = 'md'; - el.classList.add('active'); + setSidebar(sidebar); expect( canShowActiveSubItems(el), -- cgit v1.2.1 From 4b892a5f078973fc5fcbcaa3156d4a196be6bccc Mon Sep 17 00:00:00 2001 From: Mike Greiling Date: Wed, 30 Aug 2017 11:11:19 -0500 Subject: update specs to match reorganized monitoring components --- spec/javascripts/monitoring/dashboard_spec.js | 49 ++++++++ .../javascripts/monitoring/dashboard_state_spec.js | 110 +++++++++++++++++ .../monitoring/graph/deployment_spec.js | 137 +++++++++++++++++++++ spec/javascripts/monitoring/graph/flag_spec.js | 76 ++++++++++++ spec/javascripts/monitoring/graph/legend_spec.js | 111 +++++++++++++++++ spec/javascripts/monitoring/graph_row_spec.js | 62 ++++++++++ spec/javascripts/monitoring/graph_spec.js | 107 ++++++++++++++++ .../monitoring/monitoring_column_spec.js | 109 ---------------- .../monitoring/monitoring_deployment_spec.js | 137 --------------------- .../javascripts/monitoring/monitoring_flag_spec.js | 76 ------------ .../monitoring/monitoring_legends_spec.js | 111 ----------------- spec/javascripts/monitoring/monitoring_row_spec.js | 57 --------- spec/javascripts/monitoring/monitoring_spec.js | 49 -------- .../monitoring/monitoring_state_spec.js | 110 ----------------- 14 files changed, 652 insertions(+), 649 deletions(-) create mode 100644 spec/javascripts/monitoring/dashboard_spec.js create mode 100644 spec/javascripts/monitoring/dashboard_state_spec.js create mode 100644 spec/javascripts/monitoring/graph/deployment_spec.js create mode 100644 spec/javascripts/monitoring/graph/flag_spec.js create mode 100644 spec/javascripts/monitoring/graph/legend_spec.js create mode 100644 spec/javascripts/monitoring/graph_row_spec.js create mode 100644 spec/javascripts/monitoring/graph_spec.js delete mode 100644 spec/javascripts/monitoring/monitoring_column_spec.js delete mode 100644 spec/javascripts/monitoring/monitoring_deployment_spec.js delete mode 100644 spec/javascripts/monitoring/monitoring_flag_spec.js delete mode 100644 spec/javascripts/monitoring/monitoring_legends_spec.js delete mode 100644 spec/javascripts/monitoring/monitoring_row_spec.js delete mode 100644 spec/javascripts/monitoring/monitoring_spec.js delete mode 100644 spec/javascripts/monitoring/monitoring_state_spec.js (limited to 'spec/javascripts') diff --git a/spec/javascripts/monitoring/dashboard_spec.js b/spec/javascripts/monitoring/dashboard_spec.js new file mode 100644 index 00000000000..752fdfb4614 --- /dev/null +++ b/spec/javascripts/monitoring/dashboard_spec.js @@ -0,0 +1,49 @@ +import Vue from 'vue'; +import Dashboard from '~/monitoring/components/dashboard.vue'; +import { MonitorMockInterceptor } from './mock_data'; + +describe('Dashboard', () => { + const fixtureName = 'environments/metrics/metrics.html.raw'; + let DashboardComponent; + let component; + preloadFixtures(fixtureName); + + beforeEach(() => { + loadFixtures(fixtureName); + DashboardComponent = Vue.extend(Dashboard); + }); + + describe('no metrics are available yet', () => { + it('shows a getting started empty state when no metrics are present', () => { + component = new DashboardComponent({ + el: document.querySelector('#prometheus-graphs'), + }); + + component.$mount(); + expect(component.$el.querySelector('#prometheus-graphs')).toBe(null); + expect(component.state).toEqual('gettingStarted'); + }); + }); + + describe('requests information to the server', () => { + beforeEach(() => { + document.querySelector('#prometheus-graphs').setAttribute('data-has-metrics', 'true'); + Vue.http.interceptors.push(MonitorMockInterceptor); + }); + + afterEach(() => { + Vue.http.interceptors = _.without(Vue.http.interceptors, MonitorMockInterceptor); + }); + + it('shows up a loading state', (done) => { + component = new DashboardComponent({ + el: document.querySelector('#prometheus-graphs'), + }); + component.$mount(); + Vue.nextTick(() => { + expect(component.state).toEqual('loading'); + done(); + }); + }); + }); +}); diff --git a/spec/javascripts/monitoring/dashboard_state_spec.js b/spec/javascripts/monitoring/dashboard_state_spec.js new file mode 100644 index 00000000000..e8f7042e131 --- /dev/null +++ b/spec/javascripts/monitoring/dashboard_state_spec.js @@ -0,0 +1,110 @@ +import Vue from 'vue'; +import EmptyState from '~/monitoring/components/empty_state.vue'; +import { statePaths } from './mock_data'; + +const createComponent = (propsData) => { + const Component = Vue.extend(EmptyState); + + return new Component({ + propsData, + }).$mount(); +}; + +function getTextFromNode(component, selector) { + return component.$el.querySelector(selector).firstChild.nodeValue.trim(); +} + +describe('EmptyState', () => { + describe('Computed props', () => { + it('currentState', () => { + const component = createComponent({ + selectedState: 'gettingStarted', + settingsPath: statePaths.settingsPath, + documentationPath: statePaths.documentationPath, + }); + + expect(component.currentState).toBe(component.states.gettingStarted); + }); + + it('buttonPath returns settings path for the state "gettingStarted"', () => { + const component = createComponent({ + selectedState: 'gettingStarted', + settingsPath: statePaths.settingsPath, + documentationPath: statePaths.documentationPath, + }); + + expect(component.buttonPath).toEqual(statePaths.settingsPath); + expect(component.buttonPath).not.toEqual(statePaths.documentationPath); + }); + + it('buttonPath returns documentation path for any of the other states', () => { + const component = createComponent({ + selectedState: 'loading', + settingsPath: statePaths.settingsPath, + documentationPath: statePaths.documentationPath, + }); + + expect(component.buttonPath).toEqual(statePaths.documentationPath); + expect(component.buttonPath).not.toEqual(statePaths.settingsPath); + }); + + it('showButtonDescription returns a description with a link for the unableToConnect state', () => { + const component = createComponent({ + selectedState: 'unableToConnect', + settingsPath: statePaths.settingsPath, + documentationPath: statePaths.documentationPath, + }); + + expect(component.showButtonDescription).toEqual(true); + }); + + it('showButtonDescription returns the description without a link for any other state', () => { + const component = createComponent({ + selectedState: 'loading', + settingsPath: statePaths.settingsPath, + documentationPath: statePaths.documentationPath, + }); + + expect(component.showButtonDescription).toEqual(false); + }); + }); + + it('should show the gettingStarted state', () => { + const component = createComponent({ + selectedState: 'gettingStarted', + settingsPath: statePaths.settingsPath, + documentationPath: statePaths.documentationPath, + }); + + expect(component.$el.querySelector('svg')).toBeDefined(); + expect(getTextFromNode(component, '.state-title')).toEqual(component.states.gettingStarted.title); + expect(getTextFromNode(component, '.state-description')).toEqual(component.states.gettingStarted.description); + expect(getTextFromNode(component, '.btn-success')).toEqual(component.states.gettingStarted.buttonText); + }); + + it('should show the loading state', () => { + const component = createComponent({ + selectedState: 'loading', + settingsPath: statePaths.settingsPath, + documentationPath: statePaths.documentationPath, + }); + + expect(component.$el.querySelector('svg')).toBeDefined(); + expect(getTextFromNode(component, '.state-title')).toEqual(component.states.loading.title); + expect(getTextFromNode(component, '.state-description')).toEqual(component.states.loading.description); + expect(getTextFromNode(component, '.btn-success')).toEqual(component.states.loading.buttonText); + }); + + it('should show the unableToConnect state', () => { + const component = createComponent({ + selectedState: 'unableToConnect', + settingsPath: statePaths.settingsPath, + documentationPath: statePaths.documentationPath, + }); + + expect(component.$el.querySelector('svg')).toBeDefined(); + expect(getTextFromNode(component, '.state-title')).toEqual(component.states.unableToConnect.title); + expect(component.$el.querySelector('.state-description a')).toBeDefined(); + expect(getTextFromNode(component, '.btn-success')).toEqual(component.states.unableToConnect.buttonText); + }); +}); diff --git a/spec/javascripts/monitoring/graph/deployment_spec.js b/spec/javascripts/monitoring/graph/deployment_spec.js new file mode 100644 index 00000000000..c2ff38ffab9 --- /dev/null +++ b/spec/javascripts/monitoring/graph/deployment_spec.js @@ -0,0 +1,137 @@ +import Vue from 'vue'; +import GraphDeployment from '~/monitoring/components/graph/deployment.vue'; +import { deploymentData } from '../mock_data'; + +const createComponent = (propsData) => { + const Component = Vue.extend(GraphDeployment); + + return new Component({ + propsData, + }).$mount(); +}; + +describe('MonitoringDeployment', () => { + const reducedDeploymentData = [deploymentData[0]]; + reducedDeploymentData[0].ref = reducedDeploymentData[0].ref.name; + reducedDeploymentData[0].xPos = 10; + reducedDeploymentData[0].time = new Date(reducedDeploymentData[0].created_at); + describe('Methods', () => { + it('refText shows the ref when a tag is available', () => { + reducedDeploymentData[0].tag = '1.0'; + const component = createComponent({ + showDeployInfo: false, + deploymentData: reducedDeploymentData, + graphHeight: 300, + graphHeightOffset: 120, + }); + + expect( + component.refText(reducedDeploymentData[0]), + ).toEqual(reducedDeploymentData[0].ref); + }); + + it('refText shows the sha when no tag is available', () => { + reducedDeploymentData[0].tag = null; + const component = createComponent({ + showDeployInfo: false, + deploymentData: reducedDeploymentData, + graphHeight: 300, + graphHeightOffset: 120, + }); + + expect( + component.refText(reducedDeploymentData[0]), + ).toContain('f5bcd1'); + }); + + it('nameDeploymentClass creates a class with the prefix deploy-info-', () => { + const component = createComponent({ + showDeployInfo: false, + deploymentData: reducedDeploymentData, + graphHeight: 300, + graphHeightOffset: 120, + }); + + expect( + component.nameDeploymentClass(reducedDeploymentData[0]), + ).toContain('deploy-info'); + }); + + it('transformDeploymentGroup translates an available deployment', () => { + const component = createComponent({ + showDeployInfo: false, + deploymentData: reducedDeploymentData, + graphHeight: 300, + graphHeightOffset: 120, + }); + + expect( + component.transformDeploymentGroup(reducedDeploymentData[0]), + ).toContain('translate(11, 20)'); + }); + + it('hides the deployment flag', () => { + reducedDeploymentData[0].showDeploymentFlag = false; + const component = createComponent({ + showDeployInfo: true, + deploymentData: reducedDeploymentData, + graphHeight: 300, + graphHeightOffset: 120, + }); + + expect(component.$el.querySelector('.js-deploy-info-box')).toBeNull(); + }); + + it('shows the deployment flag', () => { + reducedDeploymentData[0].showDeploymentFlag = true; + const component = createComponent({ + showDeployInfo: true, + deploymentData: reducedDeploymentData, + graphHeight: 300, + graphHeightOffset: 120, + }); + + expect( + component.$el.querySelector('.js-deploy-info-box').style.display, + ).not.toEqual('display: none;'); + }); + + it('shows the refText inside a text element with the deploy-info-text class', () => { + reducedDeploymentData[0].showDeploymentFlag = true; + const component = createComponent({ + showDeployInfo: true, + deploymentData: reducedDeploymentData, + graphHeight: 300, + graphHeightOffset: 120, + }); + + expect( + component.$el.querySelector('.deploy-info-text').firstChild.nodeValue.trim(), + ).toEqual(component.refText(reducedDeploymentData[0])); + }); + + it('should contain a hidden gradient', () => { + const component = createComponent({ + showDeployInfo: true, + deploymentData: reducedDeploymentData, + graphHeight: 300, + graphHeightOffset: 120, + }); + + expect(component.$el.querySelector('#shadow-gradient')).not.toBeNull(); + }); + + describe('Computed props', () => { + it('calculatedHeight', () => { + const component = createComponent({ + showDeployInfo: true, + deploymentData: reducedDeploymentData, + graphHeight: 300, + graphHeightOffset: 120, + }); + + expect(component.calculatedHeight).toEqual(180); + }); + }); + }); +}); diff --git a/spec/javascripts/monitoring/graph/flag_spec.js b/spec/javascripts/monitoring/graph/flag_spec.js new file mode 100644 index 00000000000..731076a7d2a --- /dev/null +++ b/spec/javascripts/monitoring/graph/flag_spec.js @@ -0,0 +1,76 @@ +import Vue from 'vue'; +import GraphFlag from '~/monitoring/components/graph/flag.vue'; + +const createComponent = (propsData) => { + const Component = Vue.extend(GraphFlag); + + return new Component({ + propsData, + }).$mount(); +}; + +function getCoordinate(component, selector, coordinate) { + const coordinateVal = component.$el.querySelector(selector).getAttribute(coordinate); + return parseInt(coordinateVal, 10); +} + +describe('GraphFlag', () => { + it('has a line and a circle located at the currentXCoordinate and currentYCoordinate', () => { + const component = createComponent({ + currentXCoordinate: 200, + currentYCoordinate: 100, + currentFlagPosition: 100, + currentData: { + time: new Date('2017-06-04T18:17:33.501Z'), + value: '1.49609375', + }, + graphHeight: 300, + graphHeightOffset: 120, + }); + + expect(getCoordinate(component, '.selected-metric-line', 'x1')) + .toEqual(component.currentXCoordinate); + expect(getCoordinate(component, '.selected-metric-line', 'x2')) + .toEqual(component.currentXCoordinate); + expect(getCoordinate(component, '.circle-metric', 'cx')) + .toEqual(component.currentXCoordinate); + expect(getCoordinate(component, '.circle-metric', 'cy')) + .toEqual(component.currentYCoordinate); + }); + + it('has a SVG with the class rect-text-metric at the currentFlagPosition', () => { + const component = createComponent({ + currentXCoordinate: 200, + currentYCoordinate: 100, + currentFlagPosition: 100, + currentData: { + time: new Date('2017-06-04T18:17:33.501Z'), + value: '1.49609375', + }, + graphHeight: 300, + graphHeightOffset: 120, + }); + + const svg = component.$el.querySelector('.rect-text-metric'); + expect(svg.tagName).toEqual('svg'); + expect(parseInt(svg.getAttribute('x'), 10)).toEqual(component.currentFlagPosition); + }); + + describe('Computed props', () => { + it('calculatedHeight', () => { + const component = createComponent({ + currentXCoordinate: 200, + currentYCoordinate: 100, + currentFlagPosition: 100, + currentData: { + time: new Date('2017-06-04T18:17:33.501Z'), + value: '1.49609375', + }, + graphHeight: 300, + graphHeightOffset: 120, + }); + + expect(component.calculatedHeight).toEqual(180); + }); + }); +}); diff --git a/spec/javascripts/monitoring/graph/legend_spec.js b/spec/javascripts/monitoring/graph/legend_spec.js new file mode 100644 index 00000000000..e877832dffd --- /dev/null +++ b/spec/javascripts/monitoring/graph/legend_spec.js @@ -0,0 +1,111 @@ +import Vue from 'vue'; +import GraphLegend from '~/monitoring/components/graph/legend.vue'; +import measurements from '~/monitoring/utils/measurements'; + +const createComponent = (propsData) => { + const Component = Vue.extend(GraphLegend); + + return new Component({ + propsData, + }).$mount(); +}; + +function getTextFromNode(component, selector) { + return component.$el.querySelector(selector).firstChild.nodeValue.trim(); +} + +describe('GraphLegend', () => { + describe('Computed props', () => { + it('textTransform', () => { + const component = createComponent({ + graphWidth: 500, + graphHeight: 300, + margin: measurements.large.margin, + measurements: measurements.large, + areaColorRgb: '#f0f0f0', + legendTitle: 'Title', + yAxisLabel: 'Values', + metricUsage: 'Value', + }); + + expect(component.textTransform).toContain('translate(15, 120) rotate(-90)'); + }); + + it('xPosition', () => { + const component = createComponent({ + graphWidth: 500, + graphHeight: 300, + margin: measurements.large.margin, + measurements: measurements.large, + areaColorRgb: '#f0f0f0', + legendTitle: 'Title', + yAxisLabel: 'Values', + metricUsage: 'Value', + }); + + expect(component.xPosition).toEqual(180); + }); + + it('yPosition', () => { + const component = createComponent({ + graphWidth: 500, + graphHeight: 300, + margin: measurements.large.margin, + measurements: measurements.large, + areaColorRgb: '#f0f0f0', + legendTitle: 'Title', + yAxisLabel: 'Values', + metricUsage: 'Value', + }); + + expect(component.yPosition).toEqual(240); + }); + + it('rectTransform', () => { + const component = createComponent({ + graphWidth: 500, + graphHeight: 300, + margin: measurements.large.margin, + measurements: measurements.large, + areaColorRgb: '#f0f0f0', + legendTitle: 'Title', + yAxisLabel: 'Values', + metricUsage: 'Value', + }); + + expect(component.rectTransform).toContain('translate(0, 120) rotate(-90)'); + }); + }); + + it('has 2 rect-axis-text rect svg elements', () => { + const component = createComponent({ + graphWidth: 500, + graphHeight: 300, + margin: measurements.large.margin, + measurements: measurements.large, + areaColorRgb: '#f0f0f0', + legendTitle: 'Title', + yAxisLabel: 'Values', + metricUsage: 'Value', + }); + + expect(component.$el.querySelectorAll('.rect-axis-text').length).toEqual(2); + }); + + it('contains text to signal the usage, title and time', () => { + const component = createComponent({ + graphWidth: 500, + graphHeight: 300, + margin: measurements.large.margin, + measurements: measurements.large, + areaColorRgb: '#f0f0f0', + legendTitle: 'Title', + yAxisLabel: 'Values', + metricUsage: 'Value', + }); + + expect(getTextFromNode(component, '.text-metric-title')).toEqual(component.legendTitle); + expect(getTextFromNode(component, '.text-metric-usage')).toEqual(component.metricUsage); + expect(getTextFromNode(component, '.label-axis-text')).toEqual(component.yAxisLabel); + }); +}); diff --git a/spec/javascripts/monitoring/graph_row_spec.js b/spec/javascripts/monitoring/graph_row_spec.js new file mode 100644 index 00000000000..dd485473ccf --- /dev/null +++ b/spec/javascripts/monitoring/graph_row_spec.js @@ -0,0 +1,62 @@ +import Vue from 'vue'; +import GraphRow from '~/monitoring/components/graph_row.vue'; +import MonitoringMixins from '~/monitoring/mixins/monitoring_mixins'; +import { deploymentData, singleRowMetrics } from './mock_data'; + +const createComponent = (propsData) => { + const Component = Vue.extend(GraphRow); + + return new Component({ + propsData, + }).$mount(); +}; + +describe('GraphRow', () => { + beforeEach(() => { + spyOn(MonitoringMixins.methods, 'formatDeployments').and.returnValue({}); + }); + + describe('Computed props', () => { + it('bootstrapClass is set to col-md-6 when rowData is higher/equal to 2', () => { + const component = createComponent({ + rowData: singleRowMetrics, + updateAspectRatio: false, + deploymentData, + }); + + expect(component.bootstrapClass).toEqual('col-md-6'); + }); + + it('bootstrapClass is set to col-md-12 when rowData is lower than 2', () => { + const component = createComponent({ + rowData: [singleRowMetrics[0]], + updateAspectRatio: false, + deploymentData, + }); + + expect(component.bootstrapClass).toEqual('col-md-12'); + }); + }); + + it('has one column', () => { + const component = createComponent({ + rowData: singleRowMetrics, + updateAspectRatio: false, + deploymentData, + }); + + expect(component.$el.querySelectorAll('.prometheus-svg-container').length) + .toEqual(component.rowData.length); + }); + + it('has two columns', () => { + const component = createComponent({ + rowData: singleRowMetrics, + updateAspectRatio: false, + deploymentData, + }); + + expect(component.$el.querySelectorAll('.col-md-6').length) + .toEqual(component.rowData.length); + }); +}); diff --git a/spec/javascripts/monitoring/graph_spec.js b/spec/javascripts/monitoring/graph_spec.js new file mode 100644 index 00000000000..6d6fe410113 --- /dev/null +++ b/spec/javascripts/monitoring/graph_spec.js @@ -0,0 +1,107 @@ +import Vue from 'vue'; +import _ from 'underscore'; +import Graph from '~/monitoring/components/graph.vue'; +import MonitoringMixins from '~/monitoring/mixins/monitoring_mixins'; +import eventHub from '~/monitoring/event_hub'; +import { deploymentData, singleRowMetrics } from './mock_data'; + +const createComponent = (propsData) => { + const Component = Vue.extend(Graph); + + return new Component({ + propsData, + }).$mount(); +}; + +describe('Graph', () => { + beforeEach(() => { + spyOn(MonitoringMixins.methods, 'formatDeployments').and.returnValue({}); + }); + + it('has a title', () => { + const component = createComponent({ + graphData: singleRowMetrics[0], + classType: 'col-md-6', + updateAspectRatio: false, + deploymentData, + }); + + expect(component.$el.querySelector('.text-center').innerText.trim()).toBe(component.graphData.title); + }); + + it('creates a path for the line and area of the graph', (done) => { + const component = createComponent({ + graphData: singleRowMetrics[0], + classType: 'col-md-6', + updateAspectRatio: false, + deploymentData, + }); + + Vue.nextTick(() => { + expect(component.area).toBeDefined(); + expect(component.line).toBeDefined(); + expect(typeof component.area).toEqual('string'); + expect(typeof component.line).toEqual('string'); + expect(_.isFunction(component.xScale)).toBe(true); + expect(_.isFunction(component.yScale)).toBe(true); + done(); + }); + }); + + describe('Computed props', () => { + it('axisTransform translates an element Y position depending of its height', () => { + const component = createComponent({ + graphData: singleRowMetrics[0], + classType: 'col-md-6', + updateAspectRatio: false, + deploymentData, + }); + + const transformedHeight = `${component.graphHeight - 100}`; + expect(component.axisTransform.indexOf(transformedHeight)) + .not.toEqual(-1); + }); + + it('outterViewBox gets a width and height property based on the DOM size of the element', () => { + const component = createComponent({ + graphData: singleRowMetrics[0], + classType: 'col-md-6', + updateAspectRatio: false, + deploymentData, + }); + + const viewBoxArray = component.outterViewBox.split(' '); + expect(typeof component.outterViewBox).toEqual('string'); + expect(viewBoxArray[2]).toEqual(component.graphWidth.toString()); + expect(viewBoxArray[3]).toEqual(component.graphHeight.toString()); + }); + }); + + it('sends an event to the eventhub when it has finished resizing', (done) => { + const component = createComponent({ + graphData: singleRowMetrics[0], + classType: 'col-md-6', + updateAspectRatio: false, + deploymentData, + }); + spyOn(eventHub, '$emit'); + + component.updateAspectRatio = true; + Vue.nextTick(() => { + expect(eventHub.$emit).toHaveBeenCalled(); + done(); + }); + }); + + it('has a title for the y-axis and the chart legend that comes from the backend', () => { + const component = createComponent({ + graphData: singleRowMetrics[0], + classType: 'col-md-6', + updateAspectRatio: false, + deploymentData, + }); + + expect(component.yAxisLabel).toEqual(component.graphData.y_label); + expect(component.legendTitle).toEqual(component.graphData.queries[0].label); + }); +}); diff --git a/spec/javascripts/monitoring/monitoring_column_spec.js b/spec/javascripts/monitoring/monitoring_column_spec.js deleted file mode 100644 index c423024dce0..00000000000 --- a/spec/javascripts/monitoring/monitoring_column_spec.js +++ /dev/null @@ -1,109 +0,0 @@ -import Vue from 'vue'; -import _ from 'underscore'; -import MonitoringColumn from '~/monitoring/components/monitoring_column.vue'; -import MonitoringMixins from '~/monitoring/mixins/monitoring_mixins'; -import eventHub from '~/monitoring/event_hub'; -import { deploymentData, singleRowMetrics } from './mock_data'; - -const createComponent = (propsData) => { - const Component = Vue.extend(MonitoringColumn); - - return new Component({ - propsData, - }).$mount(); -}; - -describe('MonitoringColumn', () => { - beforeEach(() => { - spyOn(MonitoringMixins.methods, 'formatDeployments').and.callFake(function fakeFormat() { - return {}; - }); - }); - - it('has a title', () => { - const component = createComponent({ - columnData: singleRowMetrics[0], - classType: 'col-md-6', - updateAspectRatio: false, - deploymentData, - }); - - expect(component.$el.querySelector('.text-center').innerText.trim()).toBe(component.columnData.title); - }); - - it('creates a path for the line and area of the graph', (done) => { - const component = createComponent({ - columnData: singleRowMetrics[0], - classType: 'col-md-6', - updateAspectRatio: false, - deploymentData, - }); - - Vue.nextTick(() => { - expect(component.area).toBeDefined(); - expect(component.line).toBeDefined(); - expect(typeof component.area).toEqual('string'); - expect(typeof component.line).toEqual('string'); - expect(_.isFunction(component.xScale)).toBe(true); - expect(_.isFunction(component.yScale)).toBe(true); - done(); - }); - }); - - describe('Computed props', () => { - it('axisTransform translates an element Y position depending of its height', () => { - const component = createComponent({ - columnData: singleRowMetrics[0], - classType: 'col-md-6', - updateAspectRatio: false, - deploymentData, - }); - - const transformedHeight = `${component.graphHeight - 100}`; - expect(component.axisTransform.indexOf(transformedHeight)) - .not.toEqual(-1); - }); - - it('outterViewBox gets a width and height property based on the DOM size of the element', () => { - const component = createComponent({ - columnData: singleRowMetrics[0], - classType: 'col-md-6', - updateAspectRatio: false, - deploymentData, - }); - - const viewBoxArray = component.outterViewBox.split(' '); - expect(typeof component.outterViewBox).toEqual('string'); - expect(viewBoxArray[2]).toEqual(component.graphWidth.toString()); - expect(viewBoxArray[3]).toEqual(component.graphHeight.toString()); - }); - }); - - it('sends an event to the eventhub when it has finished resizing', (done) => { - const component = createComponent({ - columnData: singleRowMetrics[0], - classType: 'col-md-6', - updateAspectRatio: false, - deploymentData, - }); - spyOn(eventHub, '$emit'); - - component.updateAspectRatio = true; - Vue.nextTick(() => { - expect(eventHub.$emit).toHaveBeenCalled(); - done(); - }); - }); - - it('has a title for the y-axis and the chart legend that comes from the backend', () => { - const component = createComponent({ - columnData: singleRowMetrics[0], - classType: 'col-md-6', - updateAspectRatio: false, - deploymentData, - }); - - expect(component.yAxisLabel).toEqual(component.columnData.y_label); - expect(component.legendTitle).toEqual(component.columnData.queries[0].label); - }); -}); diff --git a/spec/javascripts/monitoring/monitoring_deployment_spec.js b/spec/javascripts/monitoring/monitoring_deployment_spec.js deleted file mode 100644 index 5cc5b514824..00000000000 --- a/spec/javascripts/monitoring/monitoring_deployment_spec.js +++ /dev/null @@ -1,137 +0,0 @@ -import Vue from 'vue'; -import MonitoringState from '~/monitoring/components/monitoring_deployment.vue'; -import { deploymentData } from './mock_data'; - -const createComponent = (propsData) => { - const Component = Vue.extend(MonitoringState); - - return new Component({ - propsData, - }).$mount(); -}; - -describe('MonitoringDeployment', () => { - const reducedDeploymentData = [deploymentData[0]]; - reducedDeploymentData[0].ref = reducedDeploymentData[0].ref.name; - reducedDeploymentData[0].xPos = 10; - reducedDeploymentData[0].time = new Date(reducedDeploymentData[0].created_at); - describe('Methods', () => { - it('refText shows the ref when a tag is available', () => { - reducedDeploymentData[0].tag = '1.0'; - const component = createComponent({ - showDeployInfo: false, - deploymentData: reducedDeploymentData, - graphHeight: 300, - graphHeightOffset: 120, - }); - - expect( - component.refText(reducedDeploymentData[0]), - ).toEqual(reducedDeploymentData[0].ref); - }); - - it('refText shows the sha when no tag is available', () => { - reducedDeploymentData[0].tag = null; - const component = createComponent({ - showDeployInfo: false, - deploymentData: reducedDeploymentData, - graphHeight: 300, - graphHeightOffset: 120, - }); - - expect( - component.refText(reducedDeploymentData[0]), - ).toContain('f5bcd1'); - }); - - it('nameDeploymentClass creates a class with the prefix deploy-info-', () => { - const component = createComponent({ - showDeployInfo: false, - deploymentData: reducedDeploymentData, - graphHeight: 300, - graphHeightOffset: 120, - }); - - expect( - component.nameDeploymentClass(reducedDeploymentData[0]), - ).toContain('deploy-info'); - }); - - it('transformDeploymentGroup translates an available deployment', () => { - const component = createComponent({ - showDeployInfo: false, - deploymentData: reducedDeploymentData, - graphHeight: 300, - graphHeightOffset: 120, - }); - - expect( - component.transformDeploymentGroup(reducedDeploymentData[0]), - ).toContain('translate(11, 20)'); - }); - - it('hides the deployment flag', () => { - reducedDeploymentData[0].showDeploymentFlag = false; - const component = createComponent({ - showDeployInfo: true, - deploymentData: reducedDeploymentData, - graphHeight: 300, - graphHeightOffset: 120, - }); - - expect(component.$el.querySelector('.js-deploy-info-box')).toBeNull(); - }); - - it('shows the deployment flag', () => { - reducedDeploymentData[0].showDeploymentFlag = true; - const component = createComponent({ - showDeployInfo: true, - deploymentData: reducedDeploymentData, - graphHeight: 300, - graphHeightOffset: 120, - }); - - expect( - component.$el.querySelector('.js-deploy-info-box').style.display, - ).not.toEqual('display: none;'); - }); - - it('shows the refText inside a text element with the deploy-info-text class', () => { - reducedDeploymentData[0].showDeploymentFlag = true; - const component = createComponent({ - showDeployInfo: true, - deploymentData: reducedDeploymentData, - graphHeight: 300, - graphHeightOffset: 120, - }); - - expect( - component.$el.querySelector('.deploy-info-text').firstChild.nodeValue.trim(), - ).toEqual(component.refText(reducedDeploymentData[0])); - }); - - it('should contain a hidden gradient', () => { - const component = createComponent({ - showDeployInfo: true, - deploymentData: reducedDeploymentData, - graphHeight: 300, - graphHeightOffset: 120, - }); - - expect(component.$el.querySelector('#shadow-gradient')).not.toBeNull(); - }); - - describe('Computed props', () => { - it('calculatedHeight', () => { - const component = createComponent({ - showDeployInfo: true, - deploymentData: reducedDeploymentData, - graphHeight: 300, - graphHeightOffset: 120, - }); - - expect(component.calculatedHeight).toEqual(180); - }); - }); - }); -}); diff --git a/spec/javascripts/monitoring/monitoring_flag_spec.js b/spec/javascripts/monitoring/monitoring_flag_spec.js deleted file mode 100644 index 3861a95ff07..00000000000 --- a/spec/javascripts/monitoring/monitoring_flag_spec.js +++ /dev/null @@ -1,76 +0,0 @@ -import Vue from 'vue'; -import MonitoringFlag from '~/monitoring/components/monitoring_flag.vue'; - -const createComponent = (propsData) => { - const Component = Vue.extend(MonitoringFlag); - - return new Component({ - propsData, - }).$mount(); -}; - -function getCoordinate(component, selector, coordinate) { - const coordinateVal = component.$el.querySelector(selector).getAttribute(coordinate); - return parseInt(coordinateVal, 10); -} - -describe('MonitoringFlag', () => { - it('has a line and a circle located at the currentXCoordinate and currentYCoordinate', () => { - const component = createComponent({ - currentXCoordinate: 200, - currentYCoordinate: 100, - currentFlagPosition: 100, - currentData: { - time: new Date('2017-06-04T18:17:33.501Z'), - value: '1.49609375', - }, - graphHeight: 300, - graphHeightOffset: 120, - }); - - expect(getCoordinate(component, '.selected-metric-line', 'x1')) - .toEqual(component.currentXCoordinate); - expect(getCoordinate(component, '.selected-metric-line', 'x2')) - .toEqual(component.currentXCoordinate); - expect(getCoordinate(component, '.circle-metric', 'cx')) - .toEqual(component.currentXCoordinate); - expect(getCoordinate(component, '.circle-metric', 'cy')) - .toEqual(component.currentYCoordinate); - }); - - it('has a SVG with the class rect-text-metric at the currentFlagPosition', () => { - const component = createComponent({ - currentXCoordinate: 200, - currentYCoordinate: 100, - currentFlagPosition: 100, - currentData: { - time: new Date('2017-06-04T18:17:33.501Z'), - value: '1.49609375', - }, - graphHeight: 300, - graphHeightOffset: 120, - }); - - const svg = component.$el.querySelector('.rect-text-metric'); - expect(svg.tagName).toEqual('svg'); - expect(parseInt(svg.getAttribute('x'), 10)).toEqual(component.currentFlagPosition); - }); - - describe('Computed props', () => { - it('calculatedHeight', () => { - const component = createComponent({ - currentXCoordinate: 200, - currentYCoordinate: 100, - currentFlagPosition: 100, - currentData: { - time: new Date('2017-06-04T18:17:33.501Z'), - value: '1.49609375', - }, - graphHeight: 300, - graphHeightOffset: 120, - }); - - expect(component.calculatedHeight).toEqual(180); - }); - }); -}); diff --git a/spec/javascripts/monitoring/monitoring_legends_spec.js b/spec/javascripts/monitoring/monitoring_legends_spec.js deleted file mode 100644 index 4c69b81e650..00000000000 --- a/spec/javascripts/monitoring/monitoring_legends_spec.js +++ /dev/null @@ -1,111 +0,0 @@ -import Vue from 'vue'; -import MonitoringLegends from '~/monitoring/components/monitoring_legends.vue'; -import measurements from '~/monitoring/utils/measurements'; - -const createComponent = (propsData) => { - const Component = Vue.extend(MonitoringLegends); - - return new Component({ - propsData, - }).$mount(); -}; - -function getTextFromNode(component, selector) { - return component.$el.querySelector(selector).firstChild.nodeValue.trim(); -} - -describe('MonitoringLegends', () => { - describe('Computed props', () => { - it('textTransform', () => { - const component = createComponent({ - graphWidth: 500, - graphHeight: 300, - margin: measurements.large.margin, - measurements: measurements.large, - areaColorRgb: '#f0f0f0', - legendTitle: 'Title', - yAxisLabel: 'Values', - metricUsage: 'Value', - }); - - expect(component.textTransform).toContain('translate(15, 120) rotate(-90)'); - }); - - it('xPosition', () => { - const component = createComponent({ - graphWidth: 500, - graphHeight: 300, - margin: measurements.large.margin, - measurements: measurements.large, - areaColorRgb: '#f0f0f0', - legendTitle: 'Title', - yAxisLabel: 'Values', - metricUsage: 'Value', - }); - - expect(component.xPosition).toEqual(180); - }); - - it('yPosition', () => { - const component = createComponent({ - graphWidth: 500, - graphHeight: 300, - margin: measurements.large.margin, - measurements: measurements.large, - areaColorRgb: '#f0f0f0', - legendTitle: 'Title', - yAxisLabel: 'Values', - metricUsage: 'Value', - }); - - expect(component.yPosition).toEqual(240); - }); - - it('rectTransform', () => { - const component = createComponent({ - graphWidth: 500, - graphHeight: 300, - margin: measurements.large.margin, - measurements: measurements.large, - areaColorRgb: '#f0f0f0', - legendTitle: 'Title', - yAxisLabel: 'Values', - metricUsage: 'Value', - }); - - expect(component.rectTransform).toContain('translate(0, 120) rotate(-90)'); - }); - }); - - it('has 2 rect-axis-text rect svg elements', () => { - const component = createComponent({ - graphWidth: 500, - graphHeight: 300, - margin: measurements.large.margin, - measurements: measurements.large, - areaColorRgb: '#f0f0f0', - legendTitle: 'Title', - yAxisLabel: 'Values', - metricUsage: 'Value', - }); - - expect(component.$el.querySelectorAll('.rect-axis-text').length).toEqual(2); - }); - - it('contains text to signal the usage, title and time', () => { - const component = createComponent({ - graphWidth: 500, - graphHeight: 300, - margin: measurements.large.margin, - measurements: measurements.large, - areaColorRgb: '#f0f0f0', - legendTitle: 'Title', - yAxisLabel: 'Values', - metricUsage: 'Value', - }); - - expect(getTextFromNode(component, '.text-metric-title')).toEqual(component.legendTitle); - expect(getTextFromNode(component, '.text-metric-usage')).toEqual(component.metricUsage); - expect(getTextFromNode(component, '.label-axis-text')).toEqual(component.yAxisLabel); - }); -}); diff --git a/spec/javascripts/monitoring/monitoring_row_spec.js b/spec/javascripts/monitoring/monitoring_row_spec.js deleted file mode 100644 index a82480e8342..00000000000 --- a/spec/javascripts/monitoring/monitoring_row_spec.js +++ /dev/null @@ -1,57 +0,0 @@ -import Vue from 'vue'; -import MonitoringRow from '~/monitoring/components/monitoring_row.vue'; -import { deploymentData, singleRowMetrics } from './mock_data'; - -const createComponent = (propsData) => { - const Component = Vue.extend(MonitoringRow); - - return new Component({ - propsData, - }).$mount(); -}; - -describe('MonitoringRow', () => { - describe('Computed props', () => { - it('bootstrapClass is set to col-md-6 when rowData is higher/equal to 2', () => { - const component = createComponent({ - rowData: singleRowMetrics, - updateAspectRatio: false, - deploymentData, - }); - - expect(component.bootstrapClass).toEqual('col-md-6'); - }); - - it('bootstrapClass is set to col-md-12 when rowData is lower than 2', () => { - const component = createComponent({ - rowData: [singleRowMetrics[0]], - updateAspectRatio: false, - deploymentData, - }); - - expect(component.bootstrapClass).toEqual('col-md-12'); - }); - }); - - it('has one column', () => { - const component = createComponent({ - rowData: singleRowMetrics, - updateAspectRatio: false, - deploymentData, - }); - - expect(component.$el.querySelectorAll('.prometheus-svg-container').length) - .toEqual(component.rowData.length); - }); - - it('has two columns', () => { - const component = createComponent({ - rowData: singleRowMetrics, - updateAspectRatio: false, - deploymentData, - }); - - expect(component.$el.querySelectorAll('.col-md-6').length) - .toEqual(component.rowData.length); - }); -}); diff --git a/spec/javascripts/monitoring/monitoring_spec.js b/spec/javascripts/monitoring/monitoring_spec.js deleted file mode 100644 index 6c7b691baa4..00000000000 --- a/spec/javascripts/monitoring/monitoring_spec.js +++ /dev/null @@ -1,49 +0,0 @@ -import Vue from 'vue'; -import Monitoring from '~/monitoring/components/monitoring.vue'; -import { MonitorMockInterceptor } from './mock_data'; - -describe('Monitoring', () => { - const fixtureName = 'environments/metrics/metrics.html.raw'; - let MonitoringComponent; - let component; - preloadFixtures(fixtureName); - - beforeEach(() => { - loadFixtures(fixtureName); - MonitoringComponent = Vue.extend(Monitoring); - }); - - describe('no metrics are available yet', () => { - it('shows a getting started empty state when no metrics are present', () => { - component = new MonitoringComponent({ - el: document.querySelector('#prometheus-graphs'), - }); - - component.$mount(); - expect(component.$el.querySelector('#prometheus-graphs')).toBe(null); - expect(component.state).toEqual('gettingStarted'); - }); - }); - - describe('requests information to the server', () => { - beforeEach(() => { - document.querySelector('#prometheus-graphs').setAttribute('data-has-metrics', 'true'); - Vue.http.interceptors.push(MonitorMockInterceptor); - }); - - afterEach(() => { - Vue.http.interceptors = _.without(Vue.http.interceptors, MonitorMockInterceptor); - }); - - it('shows up a loading state', (done) => { - component = new MonitoringComponent({ - el: document.querySelector('#prometheus-graphs'), - }); - component.$mount(); - Vue.nextTick(() => { - expect(component.state).toEqual('loading'); - done(); - }); - }); - }); -}); diff --git a/spec/javascripts/monitoring/monitoring_state_spec.js b/spec/javascripts/monitoring/monitoring_state_spec.js deleted file mode 100644 index 4c0c558502f..00000000000 --- a/spec/javascripts/monitoring/monitoring_state_spec.js +++ /dev/null @@ -1,110 +0,0 @@ -import Vue from 'vue'; -import MonitoringState from '~/monitoring/components/monitoring_state.vue'; -import { statePaths } from './mock_data'; - -const createComponent = (propsData) => { - const Component = Vue.extend(MonitoringState); - - return new Component({ - propsData, - }).$mount(); -}; - -function getTextFromNode(component, selector) { - return component.$el.querySelector(selector).firstChild.nodeValue.trim(); -} - -describe('MonitoringState', () => { - describe('Computed props', () => { - it('currentState', () => { - const component = createComponent({ - selectedState: 'gettingStarted', - settingsPath: statePaths.settingsPath, - documentationPath: statePaths.documentationPath, - }); - - expect(component.currentState).toBe(component.states.gettingStarted); - }); - - it('buttonPath returns settings path for the state "gettingStarted"', () => { - const component = createComponent({ - selectedState: 'gettingStarted', - settingsPath: statePaths.settingsPath, - documentationPath: statePaths.documentationPath, - }); - - expect(component.buttonPath).toEqual(statePaths.settingsPath); - expect(component.buttonPath).not.toEqual(statePaths.documentationPath); - }); - - it('buttonPath returns documentation path for any of the other states', () => { - const component = createComponent({ - selectedState: 'loading', - settingsPath: statePaths.settingsPath, - documentationPath: statePaths.documentationPath, - }); - - expect(component.buttonPath).toEqual(statePaths.documentationPath); - expect(component.buttonPath).not.toEqual(statePaths.settingsPath); - }); - - it('showButtonDescription returns a description with a link for the unableToConnect state', () => { - const component = createComponent({ - selectedState: 'unableToConnect', - settingsPath: statePaths.settingsPath, - documentationPath: statePaths.documentationPath, - }); - - expect(component.showButtonDescription).toEqual(true); - }); - - it('showButtonDescription returns the description without a link for any other state', () => { - const component = createComponent({ - selectedState: 'loading', - settingsPath: statePaths.settingsPath, - documentationPath: statePaths.documentationPath, - }); - - expect(component.showButtonDescription).toEqual(false); - }); - }); - - it('should show the gettingStarted state', () => { - const component = createComponent({ - selectedState: 'gettingStarted', - settingsPath: statePaths.settingsPath, - documentationPath: statePaths.documentationPath, - }); - - expect(component.$el.querySelector('svg')).toBeDefined(); - expect(getTextFromNode(component, '.state-title')).toEqual(component.states.gettingStarted.title); - expect(getTextFromNode(component, '.state-description')).toEqual(component.states.gettingStarted.description); - expect(getTextFromNode(component, '.btn-success')).toEqual(component.states.gettingStarted.buttonText); - }); - - it('should show the loading state', () => { - const component = createComponent({ - selectedState: 'loading', - settingsPath: statePaths.settingsPath, - documentationPath: statePaths.documentationPath, - }); - - expect(component.$el.querySelector('svg')).toBeDefined(); - expect(getTextFromNode(component, '.state-title')).toEqual(component.states.loading.title); - expect(getTextFromNode(component, '.state-description')).toEqual(component.states.loading.description); - expect(getTextFromNode(component, '.btn-success')).toEqual(component.states.loading.buttonText); - }); - - it('should show the unableToConnect state', () => { - const component = createComponent({ - selectedState: 'unableToConnect', - settingsPath: statePaths.settingsPath, - documentationPath: statePaths.documentationPath, - }); - - expect(component.$el.querySelector('svg')).toBeDefined(); - expect(getTextFromNode(component, '.state-title')).toEqual(component.states.unableToConnect.title); - expect(component.$el.querySelector('.state-description a')).toBeDefined(); - expect(getTextFromNode(component, '.btn-success')).toEqual(component.states.unableToConnect.buttonText); - }); -}); -- cgit v1.2.1 From cc81a40dccc64e66c464626a7af2003efe671dbc Mon Sep 17 00:00:00 2001 From: Clement Ho Date: Wed, 30 Aug 2017 18:50:06 +0000 Subject: Fix invalid attribute used for time-ago-tooltip component --- spec/javascripts/issue_show/components/edited_spec.js | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'spec/javascripts') diff --git a/spec/javascripts/issue_show/components/edited_spec.js b/spec/javascripts/issue_show/components/edited_spec.js index a0d0750ae34..2061def699b 100644 --- a/spec/javascripts/issue_show/components/edited_spec.js +++ b/spec/javascripts/issue_show/components/edited_spec.js @@ -46,4 +46,14 @@ describe('edited', () => { expect(editedComponent.$el.querySelector('.author_link')).toBeFalsy(); expect(editedComponent.$el.querySelector('time')).toBeTruthy(); }); + + it('renders time ago tooltip at the bottom', () => { + const editedComponent = new EditedComponent({ + propsData: { + updatedAt: '2017-05-15T12:31:04.428Z', + }, + }).$mount(); + + expect(editedComponent.$el.querySelector('time').dataset.placement).toEqual('bottom'); + }); }); -- cgit v1.2.1