Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-11-04 00:09:24 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-11-04 00:09:24 +0300
commit9432ed811233643af1cb5ad78e2cd9755ed989a9 (patch)
treea6f4d254ebd818a58017b3bfb0911f4aae169fcf /spec/frontend/pipeline_schedules/components
parent44434461b3c58336624125b5ab002e7200e4a208 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend/pipeline_schedules/components')
-rw-r--r--spec/frontend/pipeline_schedules/components/delete_pipeline_schedule_modal_spec.js38
-rw-r--r--spec/frontend/pipeline_schedules/components/pipeline_schedules_spec.js233
-rw-r--r--spec/frontend/pipeline_schedules/components/table/cells/pipeline_schedule_actions_spec.js17
-rw-r--r--spec/frontend/pipeline_schedules/components/take_ownership_modal_legacy_spec.js44
-rw-r--r--spec/frontend/pipeline_schedules/components/take_ownership_modal_spec.js38
5 files changed, 265 insertions, 105 deletions
diff --git a/spec/frontend/pipeline_schedules/components/delete_pipeline_schedule_modal_spec.js b/spec/frontend/pipeline_schedules/components/delete_pipeline_schedule_modal_spec.js
new file mode 100644
index 00000000000..2b1770142b5
--- /dev/null
+++ b/spec/frontend/pipeline_schedules/components/delete_pipeline_schedule_modal_spec.js
@@ -0,0 +1,38 @@
+import { shallowMount } from '@vue/test-utils';
+import { GlModal } from '@gitlab/ui';
+import DeletePipelineScheduleModal from '~/pipeline_schedules/components/delete_pipeline_schedule_modal.vue';
+
+describe('Delete pipeline schedule modal', () => {
+ let wrapper;
+
+ const createComponent = (props = {}) => {
+ wrapper = shallowMount(DeletePipelineScheduleModal, {
+ propsData: {
+ visible: true,
+ ...props,
+ },
+ });
+ };
+
+ const findModal = () => wrapper.findComponent(GlModal);
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('emits the deleteSchedule event', async () => {
+ findModal().vm.$emit('primary');
+
+ expect(wrapper.emitted()).toEqual({ deleteSchedule: [[]] });
+ });
+
+ it('emits the hideModal event', async () => {
+ findModal().vm.$emit('hide');
+
+ expect(wrapper.emitted()).toEqual({ hideModal: [[]] });
+ });
+});
diff --git a/spec/frontend/pipeline_schedules/components/pipeline_schedules_spec.js b/spec/frontend/pipeline_schedules/components/pipeline_schedules_spec.js
index 2a7ccce1092..caee284f6d6 100644
--- a/spec/frontend/pipeline_schedules/components/pipeline_schedules_spec.js
+++ b/spec/frontend/pipeline_schedules/components/pipeline_schedules_spec.js
@@ -1,4 +1,4 @@
-import { GlAlert, GlLoadingIcon, GlModal, GlTabs } from '@gitlab/ui';
+import { GlAlert, GlLoadingIcon, GlTabs } from '@gitlab/ui';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import { trimText } from 'helpers/text_helper';
@@ -6,17 +6,25 @@ import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import { mountExtended } from 'helpers/vue_test_utils_helper';
import PipelineSchedules from '~/pipeline_schedules/components/pipeline_schedules.vue';
+import DeletePipelineScheduleModal from '~/pipeline_schedules/components/delete_pipeline_schedule_modal.vue';
+import TakeOwnershipModal from '~/pipeline_schedules/components/take_ownership_modal.vue';
import PipelineSchedulesTable from '~/pipeline_schedules/components/table/pipeline_schedules_table.vue';
import deletePipelineScheduleMutation from '~/pipeline_schedules/graphql/mutations/delete_pipeline_schedule.mutation.graphql';
+import takeOwnershipMutation from '~/pipeline_schedules/graphql/mutations/take_ownership.mutation.graphql';
import getPipelineSchedulesQuery from '~/pipeline_schedules/graphql/queries/get_pipeline_schedules.query.graphql';
import {
mockGetPipelineSchedulesGraphQLResponse,
mockPipelineScheduleNodes,
deleteMutationResponse,
+ takeOwnershipMutationResponse,
} from '../mock_data';
Vue.use(VueApollo);
+const $toast = {
+ show: jest.fn(),
+};
+
describe('Pipeline schedules app', () => {
let wrapper;
@@ -25,6 +33,12 @@ describe('Pipeline schedules app', () => {
const deleteMutationHandlerSuccess = jest.fn().mockResolvedValue(deleteMutationResponse);
const deleteMutationHandlerFailed = jest.fn().mockRejectedValue(new Error('GraphQL error'));
+ const takeOwnershipMutationHandlerSuccess = jest
+ .fn()
+ .mockResolvedValue(takeOwnershipMutationResponse);
+ const takeOwnershipMutationHandlerFailed = jest
+ .fn()
+ .mockRejectedValue(new Error('GraphQL error'));
const createMockApolloProvider = (
requestHandlers = [[getPipelineSchedulesQuery, successHandler]],
@@ -37,6 +51,9 @@ describe('Pipeline schedules app', () => {
provide: {
fullPath: 'gitlab-org/gitlab',
},
+ mocks: {
+ $toast,
+ },
apolloProvider: createMockApolloProvider(requestHandlers),
});
};
@@ -44,7 +61,8 @@ describe('Pipeline schedules app', () => {
const findTable = () => wrapper.findComponent(PipelineSchedulesTable);
const findAlert = () => wrapper.findComponent(GlAlert);
const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
- const findModal = () => wrapper.findComponent(GlModal);
+ const findDeleteModal = () => wrapper.findComponent(DeletePipelineScheduleModal);
+ const findTakeOwnershipModal = () => wrapper.findComponent(TakeOwnershipModal);
const findTabs = () => wrapper.findComponent(GlTabs);
const findNewButton = () => wrapper.findByTestId('new-schedule-button');
const findAllTab = () => wrapper.findByTestId('pipeline-schedules-all-tab');
@@ -55,119 +73,182 @@ describe('Pipeline schedules app', () => {
wrapper.destroy();
});
- it('displays table, tabs and new button', async () => {
- createComponent();
+ describe('default', () => {
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('displays table, tabs and new button', async () => {
+ await waitForPromises();
+
+ expect(findTable().exists()).toBe(true);
+ expect(findNewButton().exists()).toBe(true);
+ expect(findTabs().exists()).toBe(true);
+ expect(findAlert().exists()).toBe(false);
+ });
+
+ it('handles loading state', async () => {
+ expect(findLoadingIcon().exists()).toBe(true);
- await waitForPromises();
+ await waitForPromises();
- expect(findTable().exists()).toBe(true);
- expect(findNewButton().exists()).toBe(true);
- expect(findTabs().exists()).toBe(true);
- expect(findAlert().exists()).toBe(false);
+ expect(findLoadingIcon().exists()).toBe(false);
+ });
});
- it('fetches query and passes an array of pipeline schedules', async () => {
- createComponent();
+ describe('fetching pipeline schedules', () => {
+ it('fetches query and passes an array of pipeline schedules', async () => {
+ createComponent();
+
+ expect(successHandler).toHaveBeenCalled();
+
+ await waitForPromises();
+
+ expect(findTable().props('schedules')).toEqual(mockPipelineScheduleNodes);
+ });
- expect(successHandler).toHaveBeenCalled();
+ it('shows query error alert', async () => {
+ createComponent([[getPipelineSchedulesQuery, failedHandler]]);
- await waitForPromises();
+ await waitForPromises();
- expect(findTable().props('schedules')).toEqual(mockPipelineScheduleNodes);
+ expect(findAlert().text()).toBe('There was a problem fetching pipeline schedules.');
+ });
});
- it('handles loading state', async () => {
- createComponent();
+ describe('deleting a pipeline schedule', () => {
+ it('shows delete mutation error alert', async () => {
+ createComponent([
+ [getPipelineSchedulesQuery, successHandler],
+ [deletePipelineScheduleMutation, deleteMutationHandlerFailed],
+ ]);
- expect(findLoadingIcon().exists()).toBe(true);
+ await waitForPromises();
- await waitForPromises();
+ findDeleteModal().vm.$emit('deleteSchedule');
- expect(findLoadingIcon().exists()).toBe(false);
- });
+ await waitForPromises();
- it('shows query error alert', async () => {
- createComponent([[getPipelineSchedulesQuery, failedHandler]]);
+ expect(findAlert().text()).toBe('There was a problem deleting the pipeline schedule.');
+ });
- await waitForPromises();
+ it('deletes pipeline schedule and refetches query', async () => {
+ createComponent([
+ [getPipelineSchedulesQuery, successHandler],
+ [deletePipelineScheduleMutation, deleteMutationHandlerSuccess],
+ ]);
- expect(findAlert().text()).toBe('There was a problem fetching pipeline schedules.');
- });
+ jest.spyOn(wrapper.vm.$apollo.queries.schedules, 'refetch');
- it('shows delete mutation error alert', async () => {
- createComponent([
- [getPipelineSchedulesQuery, successHandler],
- [deletePipelineScheduleMutation, deleteMutationHandlerFailed],
- ]);
+ await waitForPromises();
- await waitForPromises();
+ const scheduleId = mockPipelineScheduleNodes[0].id;
- findModal().vm.$emit('primary');
+ findTable().vm.$emit('showDeleteModal', scheduleId);
- await waitForPromises();
+ expect(wrapper.vm.$apollo.queries.schedules.refetch).not.toHaveBeenCalled();
- expect(findAlert().text()).toBe('There was a problem deleting the pipeline schedule.');
- });
+ findDeleteModal().vm.$emit('deleteSchedule');
- it('deletes pipeline schedule and refetches query', async () => {
- createComponent([
- [getPipelineSchedulesQuery, successHandler],
- [deletePipelineScheduleMutation, deleteMutationHandlerSuccess],
- ]);
+ await waitForPromises();
- jest.spyOn(wrapper.vm.$apollo.queries.schedules, 'refetch');
+ expect(deleteMutationHandlerSuccess).toHaveBeenCalledWith({
+ id: scheduleId,
+ });
+ expect(wrapper.vm.$apollo.queries.schedules.refetch).toHaveBeenCalled();
+ expect($toast.show).toHaveBeenCalledWith('Pipeline schedule successfully deleted.');
+ });
- await waitForPromises();
+ it('handles delete modal visibility correctly', async () => {
+ createComponent();
+
+ await waitForPromises();
+
+ expect(findDeleteModal().props('visible')).toBe(false);
- const scheduleId = mockPipelineScheduleNodes[0].id;
+ findTable().vm.$emit('showDeleteModal', mockPipelineScheduleNodes[0].id);
- findTable().vm.$emit('showDeleteModal', scheduleId);
+ await nextTick();
- expect(wrapper.vm.$apollo.queries.schedules.refetch).not.toHaveBeenCalled();
+ expect(findDeleteModal().props('visible')).toBe(true);
+ expect(findTakeOwnershipModal().props('visible')).toBe(false);
- findModal().vm.$emit('primary');
+ findDeleteModal().vm.$emit('hideModal');
- await waitForPromises();
+ await nextTick();
- expect(deleteMutationHandlerSuccess).toHaveBeenCalledWith({
- id: scheduleId,
+ expect(findDeleteModal().props('visible')).toBe(false);
});
- expect(wrapper.vm.$apollo.queries.schedules.refetch).toHaveBeenCalled();
});
- it('modal should be visible after event', async () => {
- createComponent();
+ describe('taking ownership of a pipeline schedule', () => {
+ it('shows take ownership mutation error alert', async () => {
+ createComponent([
+ [getPipelineSchedulesQuery, successHandler],
+ [takeOwnershipMutation, takeOwnershipMutationHandlerFailed],
+ ]);
+
+ await waitForPromises();
+
+ findTakeOwnershipModal().vm.$emit('takeOwnership');
- await waitForPromises();
+ await waitForPromises();
- expect(findModal().props('visible')).toBe(false);
+ expect(findAlert().text()).toBe(
+ 'There was a problem taking ownership of the pipeline schedule.',
+ );
+ });
- findTable().vm.$emit('showDeleteModal', mockPipelineScheduleNodes[0].id);
+ it('takes ownership of pipeline schedule and refetches query', async () => {
+ createComponent([
+ [getPipelineSchedulesQuery, successHandler],
+ [takeOwnershipMutation, takeOwnershipMutationHandlerSuccess],
+ ]);
- await nextTick();
+ jest.spyOn(wrapper.vm.$apollo.queries.schedules, 'refetch');
- expect(findModal().props('visible')).toBe(true);
- });
+ await waitForPromises();
- it('modal should be hidden', async () => {
- createComponent();
+ const scheduleId = mockPipelineScheduleNodes[1].id;
- await waitForPromises();
+ findTable().vm.$emit('showTakeOwnershipModal', scheduleId);
- findTable().vm.$emit('showDeleteModal', mockPipelineScheduleNodes[0].id);
+ expect(wrapper.vm.$apollo.queries.schedules.refetch).not.toHaveBeenCalled();
- await nextTick();
+ findTakeOwnershipModal().vm.$emit('takeOwnership');
- expect(findModal().props('visible')).toBe(true);
+ await waitForPromises();
- findModal().vm.$emit('hide');
+ expect(takeOwnershipMutationHandlerSuccess).toHaveBeenCalledWith({
+ id: scheduleId,
+ });
+ expect(wrapper.vm.$apollo.queries.schedules.refetch).toHaveBeenCalled();
+ expect($toast.show).toHaveBeenCalledWith('Successfully taken ownership from Admin.');
+ });
- await nextTick();
+ it('handles take ownership modal visibility correctly', async () => {
+ createComponent();
- expect(findModal().props('visible')).toBe(false);
+ await waitForPromises();
+
+ expect(findTakeOwnershipModal().props('visible')).toBe(false);
+
+ findTable().vm.$emit('showTakeOwnershipModal', mockPipelineScheduleNodes[0].id);
+
+ await nextTick();
+
+ expect(findTakeOwnershipModal().props('visible')).toBe(true);
+ expect(findDeleteModal().props('visible')).toBe(false);
+
+ findTakeOwnershipModal().vm.$emit('hideModal');
+
+ await nextTick();
+
+ expect(findTakeOwnershipModal().props('visible')).toBe(false);
+ });
});
- describe('tabs', () => {
+ describe('pipeline schedule tabs', () => {
beforeEach(async () => {
createComponent();
@@ -185,19 +266,15 @@ describe('Pipeline schedules app', () => {
it('displays Inactive tab with no count', () => {
expect(findInactiveTab().text()).toBe('Inactive');
});
- });
- it('should refetch the schedules query on a tab click', async () => {
- createComponent();
+ it('should refetch the schedules query on a tab click', async () => {
+ jest.spyOn(wrapper.vm.$apollo.queries.schedules, 'refetch').mockImplementation(jest.fn());
- await waitForPromises();
+ expect(wrapper.vm.$apollo.queries.schedules.refetch).toHaveBeenCalledTimes(0);
- jest.spyOn(wrapper.vm.$apollo.queries.schedules, 'refetch').mockImplementation(jest.fn());
+ await findAllTab().trigger('click');
- expect(wrapper.vm.$apollo.queries.schedules.refetch).toHaveBeenCalledTimes(0);
-
- await findAllTab().trigger('click');
-
- expect(wrapper.vm.$apollo.queries.schedules.refetch).toHaveBeenCalledTimes(1);
+ expect(wrapper.vm.$apollo.queries.schedules.refetch).toHaveBeenCalledTimes(1);
+ });
});
});
diff --git a/spec/frontend/pipeline_schedules/components/table/cells/pipeline_schedule_actions_spec.js b/spec/frontend/pipeline_schedules/components/table/cells/pipeline_schedule_actions_spec.js
index ecc1bdeb679..a7e831e44f4 100644
--- a/spec/frontend/pipeline_schedules/components/table/cells/pipeline_schedule_actions_spec.js
+++ b/spec/frontend/pipeline_schedules/components/table/cells/pipeline_schedule_actions_spec.js
@@ -1,7 +1,11 @@
import { GlButton } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import PipelineScheduleActions from '~/pipeline_schedules/components/table/cells/pipeline_schedule_actions.vue';
-import { mockPipelineScheduleNodes, mockPipelineScheduleAsGuestNodes } from '../../../mock_data';
+import {
+ mockPipelineScheduleNodes,
+ mockPipelineScheduleAsGuestNodes,
+ mockTakeOwnershipNodes,
+} from '../../../mock_data';
describe('Pipeline schedule actions', () => {
let wrapper;
@@ -20,6 +24,7 @@ describe('Pipeline schedule actions', () => {
const findAllButtons = () => wrapper.findAllComponents(GlButton);
const findDeleteBtn = () => wrapper.findByTestId('delete-pipeline-schedule-btn');
+ const findTakeOwnershipBtn = () => wrapper.findByTestId('take-ownership-pipeline-schedule-btn');
afterEach(() => {
wrapper.destroy();
@@ -46,4 +51,14 @@ describe('Pipeline schedule actions', () => {
showDeleteModal: [[mockPipelineScheduleNodes[0].id]],
});
});
+
+ it('take ownership button emits showTakeOwnershipModal event and schedule id', () => {
+ createComponent({ schedule: mockTakeOwnershipNodes[0] });
+
+ findTakeOwnershipBtn().vm.$emit('click');
+
+ expect(wrapper.emitted()).toEqual({
+ showTakeOwnershipModal: [[mockTakeOwnershipNodes[0].id]],
+ });
+ });
});
diff --git a/spec/frontend/pipeline_schedules/components/take_ownership_modal_legacy_spec.js b/spec/frontend/pipeline_schedules/components/take_ownership_modal_legacy_spec.js
new file mode 100644
index 00000000000..e453b5e70c0
--- /dev/null
+++ b/spec/frontend/pipeline_schedules/components/take_ownership_modal_legacy_spec.js
@@ -0,0 +1,44 @@
+import { GlModal } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import TakeOwnershipModalLegacy from '~/pipeline_schedules/components/take_ownership_modal_legacy.vue';
+
+describe('Take ownership modal', () => {
+ let wrapper;
+ const url = `/root/job-log-tester/-/pipeline_schedules/3/take_ownership`;
+
+ const createComponent = (props = {}) => {
+ wrapper = shallowMountExtended(TakeOwnershipModalLegacy, {
+ propsData: {
+ ownershipUrl: url,
+ ...props,
+ },
+ });
+ };
+
+ const findModal = () => wrapper.findComponent(GlModal);
+
+ beforeEach(() => {
+ createComponent();
+ });
+
+ it('has a primary action set to a url and a post data-method', () => {
+ const actionPrimary = findModal().props('actionPrimary');
+
+ expect(actionPrimary.attributes).toEqual(
+ expect.objectContaining([
+ {
+ category: 'primary',
+ variant: 'confirm',
+ href: url,
+ 'data-method': 'post',
+ },
+ ]),
+ );
+ });
+
+ it('shows a take ownership message', () => {
+ expect(findModal().text()).toBe(
+ 'Only the owner of a pipeline schedule can make changes to it. Do you want to take ownership of this schedule?',
+ );
+ });
+});
diff --git a/spec/frontend/pipeline_schedules/components/take_ownership_modal_spec.js b/spec/frontend/pipeline_schedules/components/take_ownership_modal_spec.js
index d787611fe8f..9812ae3b6c8 100644
--- a/spec/frontend/pipeline_schedules/components/take_ownership_modal_spec.js
+++ b/spec/frontend/pipeline_schedules/components/take_ownership_modal_spec.js
@@ -1,15 +1,14 @@
+import { shallowMount } from '@vue/test-utils';
import { GlModal } from '@gitlab/ui';
-import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import TakeOwnershipModal from '~/pipeline_schedules/components/take_ownership_modal.vue';
describe('Take ownership modal', () => {
let wrapper;
- const url = `/root/job-log-tester/-/pipeline_schedules/3/take_ownership`;
const createComponent = (props = {}) => {
- wrapper = shallowMountExtended(TakeOwnershipModal, {
+ wrapper = shallowMount(TakeOwnershipModal, {
propsData: {
- ownershipUrl: url,
+ visible: true,
...props,
},
});
@@ -21,34 +20,21 @@ describe('Take ownership modal', () => {
createComponent();
});
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('has a primary action set to a url and a post data-method', () => {
- const actionPrimary = findModal().props('actionPrimary');
-
- expect(actionPrimary.attributes).toEqual(
- expect.objectContaining([
- {
- category: 'primary',
- variant: 'confirm',
- href: url,
- 'data-method': 'post',
- },
- ]),
- );
- });
-
it('shows a take ownership message', () => {
expect(findModal().text()).toBe(
'Only the owner of a pipeline schedule can make changes to it. Do you want to take ownership of this schedule?',
);
});
- it('emits the cancel event when clicking on cancel', async () => {
- findModal().vm.$emit('cancel');
+ it('emits the takeOwnership event', async () => {
+ findModal().vm.$emit('primary');
+
+ expect(wrapper.emitted()).toEqual({ takeOwnership: [[]] });
+ });
+
+ it('emits the hideModal event', async () => {
+ findModal().vm.$emit('hide');
- expect(findModal().emitted('cancel')).toHaveLength(1);
+ expect(wrapper.emitted()).toEqual({ hideModal: [[]] });
});
});