diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-17 11:59:07 +0000 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2020-12-17 11:59:07 +0000 |
commit | 8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca (patch) | |
tree | 544930fb309b30317ae9797a9683768705d664c4 /spec/frontend/projects | |
parent | 4b1de649d0168371549608993deac953eb692019 (diff) | |
download | gitlab-ce-8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca.tar.gz |
Add latest changes from gitlab-org/gitlab@13-7-stable-eev13.7.0-rc42
Diffstat (limited to 'spec/frontend/projects')
6 files changed, 492 insertions, 24 deletions
diff --git a/spec/frontend/projects/pipelines/charts/components/__snapshots__/statistics_list_spec.js.snap b/spec/frontend/projects/pipelines/charts/components/__snapshots__/statistics_list_spec.js.snap index ac87fe893b9..c7e760486c0 100644 --- a/spec/frontend/projects/pipelines/charts/components/__snapshots__/statistics_list_spec.js.snap +++ b/spec/frontend/projects/pipelines/charts/components/__snapshots__/statistics_list_spec.js.snap @@ -1,6 +1,6 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`StatisticsList matches the snapshot 1`] = ` +exports[`StatisticsList displays the counts data with labels 1`] = ` <ul> <li> <span> @@ -35,7 +35,7 @@ exports[`StatisticsList matches the snapshot 1`] = ` </span> <strong> - 50% + 50.00% </strong> </li> <li> diff --git a/spec/frontend/projects/pipelines/charts/components/app_legacy_spec.js b/spec/frontend/projects/pipelines/charts/components/app_legacy_spec.js new file mode 100644 index 00000000000..c03b571eb26 --- /dev/null +++ b/spec/frontend/projects/pipelines/charts/components/app_legacy_spec.js @@ -0,0 +1,72 @@ +import { shallowMount } from '@vue/test-utils'; +import { GlColumnChart } from '@gitlab/ui/dist/charts'; +import Component from '~/projects/pipelines/charts/components/app_legacy.vue'; +import StatisticsList from '~/projects/pipelines/charts/components/statistics_list.vue'; +import PipelinesAreaChart from '~/projects/pipelines/charts/components/pipelines_area_chart.vue'; +import { + counts, + timesChartData, + areaChartData as lastWeekChartData, + areaChartData as lastMonthChartData, + lastYearChartData, +} from '../mock_data'; + +describe('ProjectsPipelinesChartsApp', () => { + let wrapper; + + beforeEach(() => { + wrapper = shallowMount(Component, { + propsData: { + counts, + timesChartData, + lastWeekChartData, + lastMonthChartData, + lastYearChartData, + }, + }); + }); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + }); + + describe('overall statistics', () => { + it('displays the statistics list', () => { + const list = wrapper.find(StatisticsList); + + expect(list.exists()).toBeTruthy(); + expect(list.props('counts')).toBe(counts); + }); + + it('displays the commit duration chart', () => { + const chart = wrapper.find(GlColumnChart); + + expect(chart.exists()).toBeTruthy(); + expect(chart.props('yAxisTitle')).toBe('Minutes'); + expect(chart.props('xAxisTitle')).toBe('Commit'); + expect(chart.props('bars')).toBe(wrapper.vm.timesChartTransformedData); + expect(chart.props('option')).toBe(wrapper.vm.$options.timesChartOptions); + }); + }); + + describe('pipelines charts', () => { + it('displays 3 area charts', () => { + expect(wrapper.findAll(PipelinesAreaChart).length).toBe(3); + }); + + describe('displays individual correctly', () => { + it('renders with the correct data', () => { + const charts = wrapper.findAll(PipelinesAreaChart); + + for (let i = 0; i < charts.length; i += 1) { + const chart = charts.at(i); + + expect(chart.exists()).toBeTruthy(); + expect(chart.props('chartData')).toBe(wrapper.vm.areaCharts[i].data); + expect(chart.text()).toBe(wrapper.vm.areaCharts[i].title); + } + }); + }); + }); +}); diff --git a/spec/frontend/projects/pipelines/charts/components/app_spec.js b/spec/frontend/projects/pipelines/charts/components/app_spec.js index 0dd3407dbbc..f8737dda5f6 100644 --- a/spec/frontend/projects/pipelines/charts/components/app_spec.js +++ b/spec/frontend/projects/pipelines/charts/components/app_spec.js @@ -1,29 +1,45 @@ -import { shallowMount } from '@vue/test-utils'; +import { createLocalVue, shallowMount } from '@vue/test-utils'; +import VueApollo from 'vue-apollo'; +import createMockApollo from 'jest/helpers/mock_apollo_helper'; import { GlColumnChart } from '@gitlab/ui/dist/charts'; import Component from '~/projects/pipelines/charts/components/app.vue'; import StatisticsList from '~/projects/pipelines/charts/components/statistics_list.vue'; import PipelinesAreaChart from '~/projects/pipelines/charts/components/pipelines_area_chart.vue'; -import { - counts, - timesChartData, - areaChartData as lastWeekChartData, - areaChartData as lastMonthChartData, - lastYearChartData, -} from '../mock_data'; +import getPipelineCountByStatus from '~/projects/pipelines/charts/graphql/queries/get_pipeline_count_by_status.query.graphql'; +import getProjectPipelineStatistics from '~/projects/pipelines/charts/graphql/queries/get_project_pipeline_statistics.query.graphql'; +import { mockPipelineCount, mockPipelineStatistics } from '../mock_data'; + +const projectPath = 'gitlab-org/gitlab'; +const localVue = createLocalVue(); +localVue.use(VueApollo); describe('ProjectsPipelinesChartsApp', () => { let wrapper; - beforeEach(() => { - wrapper = shallowMount(Component, { - propsData: { - counts, - timesChartData, - lastWeekChartData, - lastMonthChartData, - lastYearChartData, + function createMockApolloProvider() { + const requestHandlers = [ + [getPipelineCountByStatus, jest.fn().mockResolvedValue(mockPipelineCount)], + [getProjectPipelineStatistics, jest.fn().mockResolvedValue(mockPipelineStatistics)], + ]; + + return createMockApollo(requestHandlers); + } + + function createComponent(options = {}) { + const { fakeApollo } = options; + + return shallowMount(Component, { + provide: { + projectPath, }, + localVue, + apolloProvider: fakeApollo, }); + } + + beforeEach(() => { + const fakeApollo = createMockApolloProvider(); + wrapper = createComponent({ fakeApollo }); }); afterEach(() => { @@ -35,14 +51,20 @@ describe('ProjectsPipelinesChartsApp', () => { it('displays the statistics list', () => { const list = wrapper.find(StatisticsList); - expect(list.exists()).toBeTruthy(); - expect(list.props('counts')).toBe(counts); + expect(list.exists()).toBe(true); + expect(list.props('counts')).toMatchObject({ + failed: 1, + success: 23, + total: 34, + successRatio: 95.83333333333334, + totalDuration: 2471, + }); }); it('displays the commit duration chart', () => { const chart = wrapper.find(GlColumnChart); - expect(chart.exists()).toBeTruthy(); + expect(chart.exists()).toBe(true); expect(chart.props('yAxisTitle')).toBe('Minutes'); expect(chart.props('xAxisTitle')).toBe('Commit'); expect(chart.props('bars')).toBe(wrapper.vm.timesChartTransformedData); @@ -52,7 +74,7 @@ describe('ProjectsPipelinesChartsApp', () => { describe('pipelines charts', () => { it('displays 3 area charts', () => { - expect(wrapper.findAll(PipelinesAreaChart).length).toBe(3); + expect(wrapper.findAll(PipelinesAreaChart)).toHaveLength(3); }); describe('displays individual correctly', () => { @@ -62,7 +84,9 @@ describe('ProjectsPipelinesChartsApp', () => { for (let i = 0; i < charts.length; i += 1) { const chart = charts.at(i); - expect(chart.exists()).toBeTruthy(); + expect(chart.exists()).toBe(true); + // TODO: Refactor this to use the mocked data instead of the vm data + // https://gitlab.com/gitlab-org/gitlab/-/issues/292085 expect(chart.props('chartData')).toBe(wrapper.vm.areaCharts[i].data); expect(chart.text()).toBe(wrapper.vm.areaCharts[i].title); } diff --git a/spec/frontend/projects/pipelines/charts/components/statistics_list_spec.js b/spec/frontend/projects/pipelines/charts/components/statistics_list_spec.js index f78608e9cb2..4e79f62ce81 100644 --- a/spec/frontend/projects/pipelines/charts/components/statistics_list_spec.js +++ b/spec/frontend/projects/pipelines/charts/components/statistics_list_spec.js @@ -18,7 +18,7 @@ describe('StatisticsList', () => { wrapper = null; }); - it('matches the snapshot', () => { + it('displays the counts data with labels', () => { expect(wrapper.element).toMatchSnapshot(); }); }); diff --git a/spec/frontend/projects/pipelines/charts/mock_data.js b/spec/frontend/projects/pipelines/charts/mock_data.js index 84e0ccb828a..da055536fcc 100644 --- a/spec/frontend/projects/pipelines/charts/mock_data.js +++ b/spec/frontend/projects/pipelines/charts/mock_data.js @@ -32,3 +32,218 @@ export const transformedAreaChartData = [ data: [['01 Jan', 3], ['02 Jan', 3], ['03 Jan', 3], ['04 Jan', 3], ['05 Jan', 5]], }, ]; + +export const mockPipelineCount = { + data: { + project: { + totalPipelines: { count: 34, __typename: 'PipelineConnection' }, + successfulPipelines: { count: 23, __typename: 'PipelineConnection' }, + failedPipelines: { count: 1, __typename: 'PipelineConnection' }, + totalPipelineDuration: 2471, + __typename: 'Project', + }, + }, +}; + +export const mockPipelineStatistics = { + data: { + project: { + pipelineAnalytics: { + weekPipelinesTotals: [0, 0, 0, 0, 0, 0, 0, 0], + weekPipelinesLabels: [ + '24 November', + '25 November', + '26 November', + '27 November', + '28 November', + '29 November', + '30 November', + '01 December', + ], + weekPipelinesSuccessful: [0, 0, 0, 0, 0, 0, 0, 0], + monthPipelinesLabels: [ + '01 November', + '02 November', + '03 November', + '04 November', + '05 November', + '06 November', + '07 November', + '08 November', + '09 November', + '10 November', + '11 November', + '12 November', + '13 November', + '14 November', + '15 November', + '16 November', + '17 November', + '18 November', + '19 November', + '20 November', + '21 November', + '22 November', + '23 November', + '24 November', + '25 November', + '26 November', + '27 November', + '28 November', + '29 November', + '30 November', + '01 December', + ], + monthPipelinesTotals: [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 2, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + monthPipelinesSuccessful: [ + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + ], + yearPipelinesLabels: [ + 'December 2019', + 'January 2020', + 'February 2020', + 'March 2020', + 'April 2020', + 'May 2020', + 'June 2020', + 'July 2020', + 'August 2020', + 'September 2020', + 'October 2020', + 'November 2020', + 'December 2020', + ], + yearPipelinesTotals: [0, 0, 0, 0, 0, 0, 0, 0, 23, 7, 2, 2, 0], + yearPipelinesSuccessful: [0, 0, 0, 0, 0, 0, 0, 0, 17, 5, 1, 0, 0], + pipelineTimesLabels: [ + 'b3781247', + 'b3781247', + 'a50ba059', + '8e414f3b', + 'b2964d50', + '7caa525b', + '761b164e', + 'd3eccd18', + 'e2750f63', + 'e2750f63', + '1dfb4b96', + 'b49d6f94', + '66fa2f80', + 'e2750f63', + 'fc82cf15', + '19fb20b2', + '25f03a24', + 'e054110f', + '0278b7b2', + '38478c16', + '38478c16', + '38478c16', + '1fb2103e', + '97b99fb5', + '8abc6e87', + 'c94e80e3', + '5d349a50', + '5d349a50', + '9c581037', + '02d95fb2', + ], + pipelineTimesValues: [ + 1, + 0, + 0, + 0, + 0, + 1, + 1, + 2, + 1, + 0, + 1, + 2, + 2, + 0, + 4, + 2, + 1, + 2, + 1, + 1, + 0, + 1, + 1, + 0, + 1, + 5, + 2, + 0, + 0, + 0, + ], + __typename: 'Analytics', + }, + __typename: 'Project', + }, + }, +}; diff --git a/spec/frontend/projects/settings/components/shared_runners_toggle_spec.js b/spec/frontend/projects/settings/components/shared_runners_toggle_spec.js new file mode 100644 index 00000000000..1fac3d07b16 --- /dev/null +++ b/spec/frontend/projects/settings/components/shared_runners_toggle_spec.js @@ -0,0 +1,157 @@ +import { GlAlert, GlToggle, GlTooltip } from '@gitlab/ui'; +import { shallowMount } from '@vue/test-utils'; +import MockAxiosAdapter from 'axios-mock-adapter'; +import waitForPromises from 'helpers/wait_for_promises'; +import SharedRunnersToggleComponent from '~/projects/settings/components/shared_runners_toggle.vue'; +import axios from '~/lib/utils/axios_utils'; + +const TEST_UPDATE_PATH = '/test/update_shared_runners'; + +jest.mock('~/flash'); + +describe('projects/settings/components/shared_runners', () => { + let wrapper; + let mockAxios; + + const createComponent = (props = {}) => { + wrapper = shallowMount(SharedRunnersToggleComponent, { + propsData: { + isEnabled: false, + isDisabledAndUnoverridable: false, + isLoading: false, + updatePath: TEST_UPDATE_PATH, + ...props, + }, + }); + }; + + const findErrorAlert = () => wrapper.find(GlAlert); + const findSharedRunnersToggle = () => wrapper.find(GlToggle); + const findToggleTooltip = () => wrapper.find(GlTooltip); + const getToggleValue = () => findSharedRunnersToggle().props('value'); + const isToggleLoading = () => findSharedRunnersToggle().props('isLoading'); + const isToggleDisabled = () => findSharedRunnersToggle().props('disabled'); + + beforeEach(() => { + mockAxios = new MockAxiosAdapter(axios); + mockAxios.onPost(TEST_UPDATE_PATH).reply(200); + }); + + afterEach(() => { + wrapper.destroy(); + wrapper = null; + mockAxios.restore(); + }); + + describe('with group share settings DISABLED', () => { + beforeEach(() => { + createComponent({ + isDisabledAndUnoverridable: true, + }); + }); + + it('toggle should be disabled', () => { + expect(isToggleDisabled()).toBe(true); + }); + + it('tooltip should exist explaining why the toggle is disabled', () => { + expect(findToggleTooltip().exists()).toBe(true); + }); + }); + + describe('with group share settings ENABLED', () => { + beforeEach(() => { + createComponent(); + }); + + it('toggle should be enabled', () => { + expect(isToggleDisabled()).toBe(false); + }); + + it('loading icon, error message, and tooltip should not exist', () => { + expect(isToggleLoading()).toBe(false); + expect(findErrorAlert().exists()).toBe(false); + expect(findToggleTooltip().exists()).toBe(false); + }); + + describe('with shared runners DISABLED', () => { + beforeEach(() => { + createComponent(); + }); + + it('toggle should be turned off', () => { + expect(getToggleValue()).toBe(false); + }); + + it('can enable toggle', async () => { + findSharedRunnersToggle().vm.$emit('change', true); + await waitForPromises(); + + expect(mockAxios.history.post[0].data).toEqual(undefined); + expect(mockAxios.history.post).toHaveLength(1); + expect(findErrorAlert().exists()).toBe(false); + expect(getToggleValue()).toBe(true); + }); + }); + + describe('with shared runners ENABLED', () => { + beforeEach(() => { + createComponent({ isEnabled: true }); + }); + + it('toggle should be turned on', () => { + expect(getToggleValue()).toBe(true); + }); + + it('can disable toggle', async () => { + findSharedRunnersToggle().vm.$emit('change', true); + await waitForPromises(); + + expect(mockAxios.history.post[0].data).toEqual(undefined); + expect(mockAxios.history.post).toHaveLength(1); + expect(findErrorAlert().exists()).toBe(false); + expect(getToggleValue()).toBe(false); + }); + }); + + describe('loading icon', () => { + it('should show and hide on request', async () => { + createComponent(); + expect(isToggleLoading()).toBe(false); + + findSharedRunnersToggle().vm.$emit('change', true); + await wrapper.vm.$nextTick(); + expect(isToggleLoading()).toBe(true); + + await waitForPromises(); + expect(isToggleLoading()).toBe(false); + }); + }); + + describe('when request encounters an error', () => { + it('should show custom error message from API if it exists', async () => { + mockAxios.onPost(TEST_UPDATE_PATH).reply(401, { error: 'Custom API Error message' }); + createComponent(); + expect(getToggleValue()).toBe(false); + + findSharedRunnersToggle().vm.$emit('change', true); + await waitForPromises(); + + expect(findErrorAlert().text()).toBe('Custom API Error message'); + expect(getToggleValue()).toBe(false); // toggle value should not change + }); + + it('should show default error message if API does not return a custom error message', async () => { + mockAxios.onPost(TEST_UPDATE_PATH).reply(401); + createComponent(); + expect(getToggleValue()).toBe(false); + + findSharedRunnersToggle().vm.$emit('change', true); + await waitForPromises(); + + expect(findErrorAlert().text()).toBe('An error occurred while updating the configuration.'); + expect(getToggleValue()).toBe(false); // toggle value should not change + }); + }); + }); +}); |