summaryrefslogtreecommitdiff
path: root/spec/frontend/projects
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-12-17 11:59:07 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2020-12-17 11:59:07 +0000
commit8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca (patch)
tree544930fb309b30317ae9797a9683768705d664c4 /spec/frontend/projects
parent4b1de649d0168371549608993deac953eb692019 (diff)
downloadgitlab-ce-8b573c94895dc0ac0e1d9d59cf3e8745e8b539ca.tar.gz
Add latest changes from gitlab-org/gitlab@13-7-stable-eev13.7.0-rc42
Diffstat (limited to 'spec/frontend/projects')
-rw-r--r--spec/frontend/projects/pipelines/charts/components/__snapshots__/statistics_list_spec.js.snap4
-rw-r--r--spec/frontend/projects/pipelines/charts/components/app_legacy_spec.js72
-rw-r--r--spec/frontend/projects/pipelines/charts/components/app_spec.js66
-rw-r--r--spec/frontend/projects/pipelines/charts/components/statistics_list_spec.js2
-rw-r--r--spec/frontend/projects/pipelines/charts/mock_data.js215
-rw-r--r--spec/frontend/projects/settings/components/shared_runners_toggle_spec.js157
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
+ });
+ });
+ });
+});