diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-16 03:08:12 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-05-16 03:08:12 +0300 |
commit | d3a59e10d72cfa967a405e3d47f89416eedf5a07 (patch) | |
tree | 47aabaa78e6cc520ca20a3182837c07980d3bf15 /spec/frontend | |
parent | 95ab36cd97f9f527ad624f80c6830eca28eeb7bf (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend')
-rw-r--r-- | spec/frontend/monitoring/components/variables/custom_variable_spec.js | 52 | ||||
-rw-r--r-- | spec/frontend/monitoring/components/variables/text_variable_spec.js | 59 | ||||
-rw-r--r-- | spec/frontend/monitoring/components/variables_section_spec.js | 75 | ||||
-rw-r--r-- | spec/frontend/monitoring/mock_data.js | 15 | ||||
-rw-r--r-- | spec/frontend/monitoring/store/actions_spec.js | 34 | ||||
-rw-r--r-- | spec/frontend/monitoring/store/getters_spec.js | 26 | ||||
-rw-r--r-- | spec/frontend/monitoring/store/mutations_spec.js | 15 | ||||
-rw-r--r-- | spec/frontend/monitoring/store/utils_spec.js | 22 | ||||
-rw-r--r-- | spec/frontend/monitoring/utils_spec.js | 112 |
9 files changed, 323 insertions, 87 deletions
diff --git a/spec/frontend/monitoring/components/variables/custom_variable_spec.js b/spec/frontend/monitoring/components/variables/custom_variable_spec.js new file mode 100644 index 00000000000..5a2b26219b6 --- /dev/null +++ b/spec/frontend/monitoring/components/variables/custom_variable_spec.js @@ -0,0 +1,52 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlDropdown, GlDropdownItem } from '@gitlab/ui'; +import CustomVariable from '~/monitoring/components/variables/custom_variable.vue'; + +describe('Custom variable component', () => { + let wrapper; + const propsData = { + name: 'env', + label: 'Select environment', + value: 'Production', + options: [{ text: 'Production', value: 'prod' }, { text: 'Canary', value: 'canary' }], + }; + const createShallowWrapper = () => { + wrapper = shallowMount(CustomVariable, { + propsData, + }); + }; + + const findDropdown = () => wrapper.find(GlDropdown); + const findDropdownItems = () => wrapper.findAll(GlDropdownItem); + + it('renders dropdown element when all necessary props are passed', () => { + createShallowWrapper(); + + expect(findDropdown()).toExist(); + }); + + it('renders dropdown element with a text', () => { + createShallowWrapper(); + + expect(findDropdown().attributes('text')).toBe(propsData.value); + }); + + it('renders all the dropdown items', () => { + createShallowWrapper(); + + expect(findDropdownItems()).toHaveLength(propsData.options.length); + }); + + it('changing dropdown items triggers update', () => { + createShallowWrapper(); + jest.spyOn(wrapper.vm, '$emit'); + + findDropdownItems() + .at(1) + .vm.$emit('click'); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.vm.$emit).toHaveBeenCalledWith('onUpdate', 'env', 'canary'); + }); + }); +}); diff --git a/spec/frontend/monitoring/components/variables/text_variable_spec.js b/spec/frontend/monitoring/components/variables/text_variable_spec.js new file mode 100644 index 00000000000..f01584ae8bc --- /dev/null +++ b/spec/frontend/monitoring/components/variables/text_variable_spec.js @@ -0,0 +1,59 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlFormInput } from '@gitlab/ui'; +import TextVariable from '~/monitoring/components/variables/text_variable.vue'; + +describe('Text variable component', () => { + let wrapper; + const propsData = { + name: 'pod', + label: 'Select pod', + value: 'test-pod', + }; + const createShallowWrapper = () => { + wrapper = shallowMount(TextVariable, { + propsData, + }); + }; + + const findInput = () => wrapper.find(GlFormInput); + + it('renders a text input when all props are passed', () => { + createShallowWrapper(); + + expect(findInput()).toExist(); + }); + + it('always has a default value', () => { + createShallowWrapper(); + + return wrapper.vm.$nextTick(() => { + expect(findInput().attributes('value')).toBe(propsData.value); + }); + }); + + it('triggers keyup enter', () => { + createShallowWrapper(); + jest.spyOn(wrapper.vm, '$emit'); + + findInput().element.value = 'prod-pod'; + findInput().trigger('input'); + findInput().trigger('keyup.enter'); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.vm.$emit).toHaveBeenCalledWith('onUpdate', 'pod', 'prod-pod'); + }); + }); + + it('triggers blur enter', () => { + createShallowWrapper(); + jest.spyOn(wrapper.vm, '$emit'); + + findInput().element.value = 'canary-pod'; + findInput().trigger('input'); + findInput().trigger('blur'); + + return wrapper.vm.$nextTick(() => { + expect(wrapper.vm.$emit).toHaveBeenCalledWith('onUpdate', 'pod', 'canary-pod'); + }); + }); +}); diff --git a/spec/frontend/monitoring/components/variables_section_spec.js b/spec/frontend/monitoring/components/variables_section_spec.js index 6bd8b18881b..2fb7b753de0 100644 --- a/spec/frontend/monitoring/components/variables_section_spec.js +++ b/spec/frontend/monitoring/components/variables_section_spec.js @@ -1,10 +1,13 @@ import { shallowMount } from '@vue/test-utils'; import Vuex from 'vuex'; -import { GlFormInput } from '@gitlab/ui'; import VariablesSection from '~/monitoring/components/variables_section.vue'; +import CustomVariable from '~/monitoring/components/variables/custom_variable.vue'; +import TextVariable from '~/monitoring/components/variables/text_variable.vue'; import { updateHistory, mergeUrlParams } from '~/lib/utils/url_utility'; import { createStore } from '~/monitoring/stores'; +import { convertVariablesForURL } from '~/monitoring/utils'; import * as types from '~/monitoring/stores/mutation_types'; +import { mockTemplatingDataResponses } from '../mock_data'; jest.mock('~/lib/utils/url_utility', () => ({ updateHistory: jest.fn(), @@ -15,8 +18,9 @@ describe('Metrics dashboard/variables section component', () => { let store; let wrapper; const sampleVariables = { - 'var-label1': 'pod', - 'var-label2': 'main', + label1: mockTemplatingDataResponses.simpleText.simpleText, + label2: mockTemplatingDataResponses.advText.advText, + label3: mockTemplatingDataResponses.simpleCustom.simpleCustom, }; const createShallowWrapper = () => { @@ -25,8 +29,8 @@ describe('Metrics dashboard/variables section component', () => { }); }; - const findAllFormInputs = () => wrapper.findAll(GlFormInput); - const getInputAt = i => findAllFormInputs().at(i); + const findTextInput = () => wrapper.findAll(TextVariable); + const findCustomInput = () => wrapper.findAll(CustomVariable); beforeEach(() => { store = createStore(); @@ -36,9 +40,9 @@ describe('Metrics dashboard/variables section component', () => { it('does not show the variables section', () => { createShallowWrapper(); - const allInputs = findAllFormInputs(); + const allInputs = findTextInput().length + findCustomInput().length; - expect(allInputs).toHaveLength(0); + expect(allInputs).toBe(0); }); it('shows the variables section', () => { @@ -46,15 +50,15 @@ describe('Metrics dashboard/variables section component', () => { wrapper.vm.$store.commit(`monitoringDashboard/${types.SET_VARIABLES}`, sampleVariables); return wrapper.vm.$nextTick(() => { - const allInputs = findAllFormInputs(); + const allInputs = findTextInput().length + findCustomInput().length; - expect(allInputs).toHaveLength(Object.keys(sampleVariables).length); + expect(allInputs).toBe(Object.keys(sampleVariables).length); }); }); describe('when changing the variable inputs', () => { const fetchDashboardData = jest.fn(); - const setVariableValues = jest.fn(); + const updateVariableValues = jest.fn(); beforeEach(() => { store = new Vuex.Store({ @@ -67,7 +71,7 @@ describe('Metrics dashboard/variables section component', () => { }, actions: { fetchDashboardData, - setVariableValues, + updateVariableValues, }, }, }, @@ -76,39 +80,44 @@ describe('Metrics dashboard/variables section component', () => { createShallowWrapper(); }); - it('merges the url params and refreshes the dashboard when a form input is blurred', () => { - const firstInput = getInputAt(0); + it('merges the url params and refreshes the dashboard when a text-based variables inputs are updated', () => { + const firstInput = findTextInput().at(0); - firstInput.element.value = 'POD'; - firstInput.vm.$emit('input'); - firstInput.trigger('blur'); + firstInput.vm.$emit('onUpdate', 'label1', 'test'); - expect(setVariableValues).toHaveBeenCalled(); - expect(mergeUrlParams).toHaveBeenCalledWith(sampleVariables, window.location.href); - expect(updateHistory).toHaveBeenCalled(); - expect(fetchDashboardData).toHaveBeenCalled(); + return wrapper.vm.$nextTick(() => { + expect(updateVariableValues).toHaveBeenCalled(); + expect(mergeUrlParams).toHaveBeenCalledWith( + convertVariablesForURL(sampleVariables), + window.location.href, + ); + expect(updateHistory).toHaveBeenCalled(); + expect(fetchDashboardData).toHaveBeenCalled(); + }); }); - it('merges the url params and refreshes the dashboard when a form input has received an enter key press', () => { - const firstInput = getInputAt(0); + it('merges the url params and refreshes the dashboard when a custom-based variables inputs are updated', () => { + const firstInput = findCustomInput().at(0); - firstInput.element.value = 'POD'; - firstInput.vm.$emit('input'); - firstInput.trigger('keyup.enter'); + firstInput.vm.$emit('onUpdate', 'label1', 'test'); - expect(setVariableValues).toHaveBeenCalled(); - expect(mergeUrlParams).toHaveBeenCalledWith(sampleVariables, window.location.href); - expect(updateHistory).toHaveBeenCalled(); - expect(fetchDashboardData).toHaveBeenCalled(); + return wrapper.vm.$nextTick(() => { + expect(updateVariableValues).toHaveBeenCalled(); + expect(mergeUrlParams).toHaveBeenCalledWith( + convertVariablesForURL(sampleVariables), + window.location.href, + ); + expect(updateHistory).toHaveBeenCalled(); + expect(fetchDashboardData).toHaveBeenCalled(); + }); }); it('does not merge the url params and refreshes the dashboard if the value entered is not different that is what currently stored', () => { - const firstInput = getInputAt(0); + const firstInput = findTextInput().at(0); - firstInput.vm.$emit('input'); - firstInput.trigger('keyup.enter'); + firstInput.vm.$emit('onUpdate', 'label1', 'Simple text'); - expect(setVariableValues).not.toHaveBeenCalled(); + expect(updateVariableValues).not.toHaveBeenCalled(); expect(mergeUrlParams).not.toHaveBeenCalled(); expect(updateHistory).not.toHaveBeenCalled(); expect(fetchDashboardData).not.toHaveBeenCalled(); diff --git a/spec/frontend/monitoring/mock_data.js b/spec/frontend/monitoring/mock_data.js index a8443c08b00..4611e6f1b18 100644 --- a/spec/frontend/monitoring/mock_data.js +++ b/spec/frontend/monitoring/mock_data.js @@ -642,7 +642,7 @@ const generateMockTemplatingData = data => { const responseForSimpleTextVariable = { simpleText: { - label: 'var-simpleText', + label: 'simpleText', type: 'text', value: 'Simple text', }, @@ -650,7 +650,7 @@ const responseForSimpleTextVariable = { const responseForAdvTextVariable = { advText: { - label: 'var-Variable 4', + label: 'Variable 4', type: 'text', value: 'default', }, @@ -658,7 +658,8 @@ const responseForAdvTextVariable = { const responseForSimpleCustomVariable = { simpleCustom: { - label: 'var-simpleCustom', + label: 'simpleCustom', + value: 'value1', options: [ { default: false, @@ -682,7 +683,7 @@ const responseForSimpleCustomVariable = { const responseForAdvancedCustomVariableWithoutOptions = { advCustomWithoutOpts: { - label: 'var-advCustomWithoutOpts', + label: 'advCustomWithoutOpts', options: [], type: 'custom', }, @@ -690,7 +691,8 @@ const responseForAdvancedCustomVariableWithoutOptions = { const responseForAdvancedCustomVariableWithoutLabel = { advCustomWithoutLabel: { - label: 'var-advCustomWithoutLabel', + label: 'advCustomWithoutLabel', + value: 'value2', options: [ { default: false, @@ -710,7 +712,8 @@ const responseForAdvancedCustomVariableWithoutLabel = { const responseForAdvancedCustomVariable = { ...responseForSimpleCustomVariable, advCustomNormal: { - label: 'var-Advanced Var', + label: 'Advanced Var', + value: 'value2', options: [ { default: false, diff --git a/spec/frontend/monitoring/store/actions_spec.js b/spec/frontend/monitoring/store/actions_spec.js index 32ff03a53d7..8914f2e66ea 100644 --- a/spec/frontend/monitoring/store/actions_spec.js +++ b/spec/frontend/monitoring/store/actions_spec.js @@ -26,7 +26,7 @@ import { clearExpandedPanel, setGettingStartedEmptyState, duplicateSystemDashboard, - setVariableValues, + updateVariableValues, } from '~/monitoring/stores/actions'; import { gqClient, @@ -40,6 +40,7 @@ import { deploymentData, environmentData, annotationsData, + mockTemplatingData, dashboardGitResponse, mockDashboardsErrorResponse, } from '../mock_data'; @@ -442,14 +443,14 @@ describe('Monitoring store actions', () => { }); }); - describe('setVariableValues', () => { + describe('updateVariableValues', () => { let mockedState; beforeEach(() => { mockedState = storeState(); }); it('should commit UPDATE_VARIABLE_VALUES mutation', done => { testAction( - setVariableValues, + updateVariableValues, { pod: 'POD' }, mockedState, [ @@ -574,6 +575,33 @@ describe('Monitoring store actions', () => { ); expect(dispatch).toHaveBeenCalledWith('fetchDashboardData'); }); + + it('stores templating variables', () => { + const response = { + ...metricsDashboardResponse.dashboard, + ...mockTemplatingData.allVariableTypes.dashboard, + }; + + receiveMetricsDashboardSuccess( + { state, commit, dispatch }, + { + response: { + ...metricsDashboardResponse, + dashboard: { + ...metricsDashboardResponse.dashboard, + ...mockTemplatingData.allVariableTypes.dashboard, + }, + }, + }, + ); + + expect(commit).toHaveBeenCalledWith( + types.RECEIVE_METRICS_DASHBOARD_SUCCESS, + + response, + ); + }); + it('sets the dashboards loaded from the repository', () => { const params = {}; const response = metricsDashboardResponse; diff --git a/spec/frontend/monitoring/store/getters_spec.js b/spec/frontend/monitoring/store/getters_spec.js index 3577bebb336..365052e68e3 100644 --- a/spec/frontend/monitoring/store/getters_spec.js +++ b/spec/frontend/monitoring/store/getters_spec.js @@ -3,7 +3,12 @@ import * as getters from '~/monitoring/stores/getters'; import mutations from '~/monitoring/stores/mutations'; import * as types from '~/monitoring/stores/mutation_types'; import { metricStates } from '~/monitoring/constants'; -import { environmentData, metricsResult, dashboardGitResponse } from '../mock_data'; +import { + environmentData, + metricsResult, + dashboardGitResponse, + mockTemplatingDataResponses, +} from '../mock_data'; import { metricsDashboardPayload, metricResultStatus, @@ -326,10 +331,6 @@ describe('Monitoring store Getters', () => { describe('getCustomVariablesArray', () => { let state; - const sampleVariables = { - 'var-label1': 'pod', - 'var-label2': 'env', - }; beforeEach(() => { state = { @@ -337,11 +338,20 @@ describe('Monitoring store Getters', () => { }; }); - it('transforms the promVariables object to an array in the [variable, variable_value] format', () => { - mutations[types.SET_VARIABLES](state, sampleVariables); + it('transforms the promVariables object to an array in the [variable, variable_value] format for all variable types', () => { + mutations[types.SET_VARIABLES](state, mockTemplatingDataResponses.allVariableTypes); const variablesArray = getters.getCustomVariablesArray(state); - expect(variablesArray).toEqual(['label1', 'pod', 'label2', 'env']); + expect(variablesArray).toEqual([ + 'simpleText', + 'Simple text', + 'advText', + 'default', + 'simpleCustom', + 'value1', + 'advCustomNormal', + 'value2', + ]); }); it('transforms the promVariables object to an empty array when no keys are present', () => { diff --git a/spec/frontend/monitoring/store/mutations_spec.js b/spec/frontend/monitoring/store/mutations_spec.js index 6c9b0726c93..4306243689a 100644 --- a/spec/frontend/monitoring/store/mutations_spec.js +++ b/spec/frontend/monitoring/store/mutations_spec.js @@ -427,18 +427,11 @@ describe('Monitoring mutations', () => { mutations[types.SET_VARIABLES](stateCopy, {}); }); - it('ignores updates that are not already in promVariables', () => { - mutations[types.SET_VARIABLES](stateCopy, { environment: 'prod' }); - mutations[types.UPDATE_VARIABLE_VALUES](stateCopy, { pod: 'new pod' }); + it('updates only the value of the variable in promVariables', () => { + mutations[types.SET_VARIABLES](stateCopy, { environment: { value: 'prod', type: 'text' } }); + mutations[types.UPDATE_VARIABLE_VALUES](stateCopy, { key: 'environment', value: 'new prod' }); - expect(stateCopy.promVariables).toEqual({ environment: 'prod' }); - }); - - it('only updates existing variables', () => { - mutations[types.SET_VARIABLES](stateCopy, { pod: 'POD' }); - mutations[types.UPDATE_VARIABLE_VALUES](stateCopy, { pod: 'new pod' }); - - expect(stateCopy.promVariables).toEqual({ pod: 'new pod' }); + expect(stateCopy.promVariables).toEqual({ environment: { value: 'new prod', type: 'text' } }); }); }); }); diff --git a/spec/frontend/monitoring/store/utils_spec.js b/spec/frontend/monitoring/store/utils_spec.js index af040743ebb..fe5754e1216 100644 --- a/spec/frontend/monitoring/store/utils_spec.js +++ b/spec/frontend/monitoring/store/utils_spec.js @@ -5,7 +5,6 @@ import { parseAnnotationsResponse, removeLeadingSlash, mapToDashboardViewModel, - removePrefixFromLabels, } from '~/monitoring/stores/utils'; import { annotationsData } from '../mock_data'; import { NOT_IN_DB_PREFIX } from '~/monitoring/constants'; @@ -420,24 +419,3 @@ describe('removeLeadingSlash', () => { }); }); }); - -describe('removePrefixFromLabels', () => { - it.each` - input | expected - ${undefined} | ${''} - ${null} | ${''} - ${''} | ${''} - ${' '} | ${' '} - ${'pod-1'} | ${'pod-1'} - ${'pod-var-1'} | ${'pod-var-1'} - ${'pod-1-var'} | ${'pod-1-var'} - ${'podvar--1'} | ${'podvar--1'} - ${'povar-d-1'} | ${'povar-d-1'} - ${'var-pod-1'} | ${'pod-1'} - ${'var-var-pod-1'} | ${'var-pod-1'} - ${'varvar-pod-1'} | ${'varvar-pod-1'} - ${'var-pod-1-var-'} | ${'pod-1-var-'} - `('removePrefixFromLabels returns $expected with input $input', ({ input, expected }) => { - expect(removePrefixFromLabels(input)).toEqual(expected); - }); -}); diff --git a/spec/frontend/monitoring/utils_spec.js b/spec/frontend/monitoring/utils_spec.js index 52fd776e67e..e78c17dc392 100644 --- a/spec/frontend/monitoring/utils_spec.js +++ b/spec/frontend/monitoring/utils_spec.js @@ -169,8 +169,8 @@ describe('monitoring/utils', () => { }); }); - describe('promCustomVariablesFromUrl', () => { - const { promCustomVariablesFromUrl } = monitoringUtils; + describe('getPromCustomVariablesFromUrl', () => { + const { getPromCustomVariablesFromUrl } = monitoringUtils; beforeEach(() => { jest.spyOn(urlUtils, 'queryToObject'); @@ -195,7 +195,7 @@ describe('monitoring/utils', () => { 'var-pod': 'POD', }); - expect(promCustomVariablesFromUrl()).toEqual(expect.objectContaining({ 'var-pod': 'POD' })); + expect(getPromCustomVariablesFromUrl()).toEqual(expect.objectContaining({ pod: 'POD' })); }); it('returns an empty object when no custom variables are present', () => { @@ -203,7 +203,7 @@ describe('monitoring/utils', () => { dashboard: '.gitlab/dashboards/custom_dashboard.yml', }); - expect(promCustomVariablesFromUrl()).toStrictEqual({}); + expect(getPromCustomVariablesFromUrl()).toStrictEqual({}); }); }); @@ -398,4 +398,108 @@ describe('monitoring/utils', () => { }); }); }); + + describe('removePrefixFromLabel', () => { + it.each` + input | expected + ${undefined} | ${''} + ${null} | ${''} + ${''} | ${''} + ${' '} | ${' '} + ${'pod-1'} | ${'pod-1'} + ${'pod-var-1'} | ${'pod-var-1'} + ${'pod-1-var'} | ${'pod-1-var'} + ${'podvar--1'} | ${'podvar--1'} + ${'povar-d-1'} | ${'povar-d-1'} + ${'var-pod-1'} | ${'pod-1'} + ${'var-var-pod-1'} | ${'var-pod-1'} + ${'varvar-pod-1'} | ${'varvar-pod-1'} + ${'var-pod-1-var-'} | ${'pod-1-var-'} + `('removePrefixFromLabel returns $expected with input $input', ({ input, expected }) => { + expect(monitoringUtils.removePrefixFromLabel(input)).toEqual(expected); + }); + }); + + describe('mergeURLVariables', () => { + beforeEach(() => { + jest.spyOn(urlUtils, 'queryToObject'); + }); + + afterEach(() => { + urlUtils.queryToObject.mockRestore(); + }); + + it('returns empty object if variables are not defined in yml or URL', () => { + urlUtils.queryToObject.mockReturnValueOnce({}); + + expect(monitoringUtils.mergeURLVariables({})).toEqual({}); + }); + + it('returns empty object if variables are defined in URL but not in yml', () => { + urlUtils.queryToObject.mockReturnValueOnce({ + 'var-env': 'one', + 'var-instance': 'localhost', + }); + + expect(monitoringUtils.mergeURLVariables({})).toEqual({}); + }); + + it('returns yml variables if variables defined in yml but not in the URL', () => { + urlUtils.queryToObject.mockReturnValueOnce({}); + + const params = { + env: 'one', + instance: 'localhost', + }; + + expect(monitoringUtils.mergeURLVariables(params)).toEqual(params); + }); + + it('returns yml variables if variables defined in URL do not match with yml variables', () => { + const urlParams = { + 'var-env': 'one', + 'var-instance': 'localhost', + }; + const ymlParams = { + pod: { value: 'one' }, + service: { value: 'database' }, + }; + urlUtils.queryToObject.mockReturnValueOnce(urlParams); + + expect(monitoringUtils.mergeURLVariables(ymlParams)).toEqual(ymlParams); + }); + + it('returns merged yml and URL variables if there is some match', () => { + const urlParams = { + 'var-env': 'one', + 'var-instance': 'localhost:8080', + }; + const ymlParams = { + instance: { value: 'localhost' }, + service: { value: 'database' }, + }; + + const merged = { + instance: { value: 'localhost:8080' }, + service: { value: 'database' }, + }; + + urlUtils.queryToObject.mockReturnValueOnce(urlParams); + + expect(monitoringUtils.mergeURLVariables(ymlParams)).toEqual(merged); + }); + }); + + describe('convertVariablesForURL', () => { + it.each` + input | expected + ${undefined} | ${{}} + ${null} | ${{}} + ${{}} | ${{}} + ${{ env: { value: 'prod' } }} | ${{ 'var-env': 'prod' }} + ${{ 'var-env': { value: 'prod' } }} | ${{ 'var-var-env': 'prod' }} + `('convertVariablesForURL returns $expected with input $input', ({ input, expected }) => { + expect(monitoringUtils.convertVariablesForURL(input)).toEqual(expected); + }); + }); }); |