summaryrefslogtreecommitdiff
path: root/spec/frontend/runner/components
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/runner/components')
-rw-r--r--spec/frontend/runner/components/cells/runner_actions_cell_spec.js223
-rw-r--r--spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js2
-rw-r--r--spec/frontend/runner/components/runner_delete_button_spec.js233
-rw-r--r--spec/frontend/runner/components/runner_jobs_spec.js4
-rw-r--r--spec/frontend/runner/components/runner_list_spec.js40
-rw-r--r--spec/frontend/runner/components/runner_pagination_spec.js18
-rw-r--r--spec/frontend/runner/components/runner_pause_button_spec.js24
-rw-r--r--spec/frontend/runner/components/runner_projects_spec.js4
-rw-r--r--spec/frontend/runner/components/runner_update_form_spec.js2
9 files changed, 321 insertions, 229 deletions
diff --git a/spec/frontend/runner/components/cells/runner_actions_cell_spec.js b/spec/frontend/runner/components/cells/runner_actions_cell_spec.js
index dcb0af67784..0d579106860 100644
--- a/spec/frontend/runner/components/cells/runner_actions_cell_spec.js
+++ b/spec/frontend/runner/components/cells/runner_actions_cell_spec.js
@@ -1,84 +1,37 @@
-import Vue from 'vue';
-import VueApollo from 'vue-apollo';
-import createMockApollo from 'helpers/mock_apollo_helper';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import waitForPromises from 'helpers/wait_for_promises';
-import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
-import { createAlert } from '~/flash';
-import { getIdFromGraphQLId } from '~/graphql_shared/utils';
-import { captureException } from '~/runner/sentry_utils';
-import RunnerActionCell from '~/runner/components/cells/runner_actions_cell.vue';
+import RunnerActionsCell from '~/runner/components/cells/runner_actions_cell.vue';
import RunnerPauseButton from '~/runner/components/runner_pause_button.vue';
import RunnerEditButton from '~/runner/components/runner_edit_button.vue';
-import RunnerDeleteModal from '~/runner/components/runner_delete_modal.vue';
-import getGroupRunnersQuery from '~/runner/graphql/get_group_runners.query.graphql';
-import getRunnersQuery from '~/runner/graphql/get_runners.query.graphql';
-import runnerDeleteMutation from '~/runner/graphql/runner_delete.mutation.graphql';
+import RunnerDeleteButton from '~/runner/components/runner_delete_button.vue';
import { runnersData } from '../../mock_data';
const mockRunner = runnersData.data.runners.nodes[0];
-const getRunnersQueryName = getRunnersQuery.definitions[0].name.value;
-const getGroupRunnersQueryName = getGroupRunnersQuery.definitions[0].name.value;
-
-Vue.use(VueApollo);
-
-jest.mock('~/flash');
-jest.mock('~/runner/sentry_utils');
-
-describe('RunnerTypeCell', () => {
+describe('RunnerActionsCell', () => {
let wrapper;
- const mockToastShow = jest.fn();
- const runnerDeleteMutationHandler = jest.fn();
-
const findEditBtn = () => wrapper.findComponent(RunnerEditButton);
const findRunnerPauseBtn = () => wrapper.findComponent(RunnerPauseButton);
- const findRunnerDeleteModal = () => wrapper.findComponent(RunnerDeleteModal);
- const findDeleteBtn = () => wrapper.findByTestId('delete-runner');
- const getTooltip = (w) => getBinding(w.element, 'gl-tooltip')?.value;
+ const findDeleteBtn = () => wrapper.findComponent(RunnerDeleteButton);
- const createComponent = (runner = {}, options) => {
- wrapper = shallowMountExtended(RunnerActionCell, {
+ const createComponent = ({ runner = {}, ...props } = {}) => {
+ wrapper = shallowMountExtended(RunnerActionsCell, {
propsData: {
+ editUrl: mockRunner.editAdminUrl,
runner: {
id: mockRunner.id,
shortSha: mockRunner.shortSha,
editAdminUrl: mockRunner.editAdminUrl,
userPermissions: mockRunner.userPermissions,
- active: mockRunner.active,
...runner,
},
+ ...props,
},
- apolloProvider: createMockApollo([[runnerDeleteMutation, runnerDeleteMutationHandler]]),
- directives: {
- GlTooltip: createMockDirective(),
- GlModal: createMockDirective(),
- },
- mocks: {
- $toast: {
- show: mockToastShow,
- },
- },
- ...options,
});
};
- beforeEach(() => {
- runnerDeleteMutationHandler.mockResolvedValue({
- data: {
- runnerDelete: {
- errors: [],
- },
- },
- });
- });
-
afterEach(() => {
- mockToastShow.mockReset();
- runnerDeleteMutationHandler.mockReset();
-
wrapper.destroy();
});
@@ -91,18 +44,20 @@ describe('RunnerTypeCell', () => {
it('Does not render the runner edit link when user cannot update', () => {
createComponent({
- userPermissions: {
- ...mockRunner.userPermissions,
- updateRunner: false,
+ runner: {
+ userPermissions: {
+ ...mockRunner.userPermissions,
+ updateRunner: false,
+ },
},
});
expect(findEditBtn().exists()).toBe(false);
});
- it('Does not render the runner edit link when editAdminUrl is not provided', () => {
+ it('Does not render the runner edit link when editUrl is not provided', () => {
createComponent({
- editAdminUrl: null,
+ editUrl: null,
});
expect(findEditBtn().exists()).toBe(false);
@@ -118,9 +73,11 @@ describe('RunnerTypeCell', () => {
it('Does not render the runner pause button when user cannot update', () => {
createComponent({
- userPermissions: {
- ...mockRunner.userPermissions,
- updateRunner: false,
+ runner: {
+ userPermissions: {
+ ...mockRunner.userPermissions,
+ updateRunner: false,
+ },
},
});
@@ -129,147 +86,35 @@ describe('RunnerTypeCell', () => {
});
describe('Delete action', () => {
- beforeEach(() => {
- createComponent(
- {},
- {
- stubs: { RunnerDeleteModal },
- },
- );
- });
+ it('Renders a compact delete button', () => {
+ createComponent();
- it('Renders delete button', () => {
- expect(findDeleteBtn().exists()).toBe(true);
+ expect(findDeleteBtn().props('compact')).toBe(true);
});
- it('Delete button opens delete modal', () => {
- const modalId = getBinding(findDeleteBtn().element, 'gl-modal').value;
+ it('Emits delete events', () => {
+ const value = { name: 'Runner' };
- expect(findRunnerDeleteModal().attributes('modal-id')).toBeDefined();
- expect(findRunnerDeleteModal().attributes('modal-id')).toBe(modalId);
- });
-
- it('Delete modal shows the runner name', () => {
- expect(findRunnerDeleteModal().props('runnerName')).toBe(
- `#${getIdFromGraphQLId(mockRunner.id)} (${mockRunner.shortSha})`,
- );
- });
- it('The delete button does not have a loading icon', () => {
- expect(findDeleteBtn().props('loading')).toBe(false);
- expect(getTooltip(findDeleteBtn())).toBe('Delete runner');
- });
+ createComponent();
- it('When delete mutation is called, current runners are refetched', () => {
- jest.spyOn(wrapper.vm.$apollo, 'mutate');
+ expect(wrapper.emitted('deleted')).toBe(undefined);
- findRunnerDeleteModal().vm.$emit('primary');
+ findDeleteBtn().vm.$emit('deleted', value);
- expect(wrapper.vm.$apollo.mutate).toHaveBeenCalledWith({
- mutation: runnerDeleteMutation,
- variables: {
- input: {
- id: mockRunner.id,
- },
- },
- awaitRefetchQueries: true,
- refetchQueries: [getRunnersQueryName, getGroupRunnersQueryName],
- });
+ expect(wrapper.emitted('deleted')).toEqual([[value]]);
});
it('Does not render the runner delete button when user cannot delete', () => {
createComponent({
- userPermissions: {
- ...mockRunner.userPermissions,
- deleteRunner: false,
+ runner: {
+ userPermissions: {
+ ...mockRunner.userPermissions,
+ deleteRunner: false,
+ },
},
});
expect(findDeleteBtn().exists()).toBe(false);
- expect(findRunnerDeleteModal().exists()).toBe(false);
- });
-
- describe('When delete is clicked', () => {
- beforeEach(async () => {
- findRunnerDeleteModal().vm.$emit('primary');
- await waitForPromises();
- });
-
- it('The delete mutation is called correctly', () => {
- expect(runnerDeleteMutationHandler).toHaveBeenCalledTimes(1);
- expect(runnerDeleteMutationHandler).toHaveBeenCalledWith({
- input: { id: mockRunner.id },
- });
- });
-
- it('The delete button has a loading icon', () => {
- expect(findDeleteBtn().props('loading')).toBe(true);
- expect(getTooltip(findDeleteBtn())).toBe('');
- });
-
- it('The toast notification is shown', async () => {
- await waitForPromises();
- expect(mockToastShow).toHaveBeenCalledTimes(1);
- expect(mockToastShow).toHaveBeenCalledWith(
- expect.stringContaining(`#${getIdFromGraphQLId(mockRunner.id)} (${mockRunner.shortSha})`),
- );
- });
- });
-
- describe('When delete fails', () => {
- describe('On a network error', () => {
- const mockErrorMsg = 'Delete error!';
-
- beforeEach(async () => {
- runnerDeleteMutationHandler.mockRejectedValueOnce(new Error(mockErrorMsg));
-
- findRunnerDeleteModal().vm.$emit('primary');
- await waitForPromises();
- });
-
- it('error is reported to sentry', () => {
- expect(captureException).toHaveBeenCalledWith({
- error: new Error(mockErrorMsg),
- component: 'RunnerActionsCell',
- });
- });
-
- it('error is shown to the user', () => {
- expect(createAlert).toHaveBeenCalledTimes(1);
- });
-
- it('toast notification is not shown', () => {
- expect(mockToastShow).not.toHaveBeenCalled();
- });
- });
-
- describe('On a validation error', () => {
- const mockErrorMsg = 'Runner not found!';
- const mockErrorMsg2 = 'User not allowed!';
-
- beforeEach(async () => {
- runnerDeleteMutationHandler.mockResolvedValue({
- data: {
- runnerDelete: {
- errors: [mockErrorMsg, mockErrorMsg2],
- },
- },
- });
-
- findRunnerDeleteModal().vm.$emit('primary');
- await waitForPromises();
- });
-
- it('error is reported to sentry', () => {
- expect(captureException).toHaveBeenCalledWith({
- error: new Error(`${mockErrorMsg} ${mockErrorMsg2}`),
- component: 'RunnerActionsCell',
- });
- });
-
- it('error is shown to the user', () => {
- expect(createAlert).toHaveBeenCalledTimes(1);
- });
- });
});
});
});
diff --git a/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js b/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
index d2deb49a5f7..2510aaf0334 100644
--- a/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
+++ b/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
@@ -8,7 +8,7 @@ import waitForPromises from 'helpers/wait_for_promises';
import { createAlert } from '~/flash';
import RegistrationTokenResetDropdownItem from '~/runner/components/registration/registration_token_reset_dropdown_item.vue';
import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '~/runner/constants';
-import runnersRegistrationTokenResetMutation from '~/runner/graphql/runners_registration_token_reset.mutation.graphql';
+import runnersRegistrationTokenResetMutation from '~/runner/graphql/list/runners_registration_token_reset.mutation.graphql';
import { captureException } from '~/runner/sentry_utils';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
diff --git a/spec/frontend/runner/components/runner_delete_button_spec.js b/spec/frontend/runner/components/runner_delete_button_spec.js
new file mode 100644
index 00000000000..81c870f23cf
--- /dev/null
+++ b/spec/frontend/runner/components/runner_delete_button_spec.js
@@ -0,0 +1,233 @@
+import Vue from 'vue';
+import { GlButton } from '@gitlab/ui';
+import VueApollo from 'vue-apollo';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
+import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
+import runnerDeleteMutation from '~/runner/graphql/shared/runner_delete.mutation.graphql';
+import waitForPromises from 'helpers/wait_for_promises';
+import { captureException } from '~/runner/sentry_utils';
+import { getIdFromGraphQLId } from '~/graphql_shared/utils';
+import { createAlert } from '~/flash';
+import { I18N_DELETE_RUNNER } from '~/runner/constants';
+
+import RunnerDeleteButton from '~/runner/components/runner_delete_button.vue';
+import RunnerDeleteModal from '~/runner/components/runner_delete_modal.vue';
+import { runnersData } from '../mock_data';
+
+const mockRunner = runnersData.data.runners.nodes[0];
+const mockRunnerId = getIdFromGraphQLId(mockRunner.id);
+
+Vue.use(VueApollo);
+
+jest.mock('~/flash');
+jest.mock('~/runner/sentry_utils');
+
+describe('RunnerDeleteButton', () => {
+ let wrapper;
+ let runnerDeleteHandler;
+
+ const getTooltip = () => getBinding(wrapper.element, 'gl-tooltip').value;
+ const getModal = () => getBinding(wrapper.element, 'gl-modal').value;
+ const findBtn = () => wrapper.findComponent(GlButton);
+ const findModal = () => wrapper.findComponent(RunnerDeleteModal);
+
+ const createComponent = ({ props = {}, mountFn = shallowMountExtended } = {}) => {
+ const { runner, ...propsData } = props;
+
+ wrapper = mountFn(RunnerDeleteButton, {
+ propsData: {
+ runner: {
+ id: mockRunner.id,
+ shortSha: mockRunner.shortSha,
+ ...runner,
+ },
+ ...propsData,
+ },
+ apolloProvider: createMockApollo([[runnerDeleteMutation, runnerDeleteHandler]]),
+ directives: {
+ GlTooltip: createMockDirective(),
+ GlModal: createMockDirective(),
+ },
+ });
+ };
+
+ const clickOkAndWait = async () => {
+ findModal().vm.$emit('primary');
+ await waitForPromises();
+ };
+
+ beforeEach(() => {
+ runnerDeleteHandler = jest.fn().mockImplementation(() => {
+ return Promise.resolve({
+ data: {
+ runnerDelete: {
+ errors: [],
+ },
+ },
+ });
+ });
+
+ createComponent();
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it('Displays a delete button without an icon', () => {
+ expect(findBtn().props()).toMatchObject({
+ loading: false,
+ icon: '',
+ });
+ expect(findBtn().classes('btn-icon')).toBe(false);
+ expect(findBtn().text()).toBe(I18N_DELETE_RUNNER);
+ });
+
+ it('Displays a modal with the runner name', () => {
+ expect(findModal().props('runnerName')).toBe(`#${mockRunnerId} (${mockRunner.shortSha})`);
+ });
+
+ it('Displays a modal when clicked', () => {
+ const modalId = `delete-runner-modal-${mockRunnerId}`;
+
+ expect(getModal()).toBe(modalId);
+ expect(findModal().attributes('modal-id')).toBe(modalId);
+ });
+
+ it('Does not display redundant text for screen readers', () => {
+ expect(findBtn().attributes('aria-label')).toBe(undefined);
+ });
+
+ describe(`Before the delete button is clicked`, () => {
+ it('The mutation has not been called', () => {
+ expect(runnerDeleteHandler).toHaveBeenCalledTimes(0);
+ });
+ });
+
+ describe('Immediately after the delete button is clicked', () => {
+ beforeEach(async () => {
+ findModal().vm.$emit('primary');
+ });
+
+ it('The button has a loading state', async () => {
+ expect(findBtn().props('loading')).toBe(true);
+ });
+
+ it('The stale tooltip is removed', async () => {
+ expect(getTooltip()).toBe('');
+ });
+ });
+
+ describe('After clicking on the delete button', () => {
+ beforeEach(async () => {
+ await clickOkAndWait();
+ });
+
+ it('The mutation to delete is called', () => {
+ expect(runnerDeleteHandler).toHaveBeenCalledTimes(1);
+ expect(runnerDeleteHandler).toHaveBeenCalledWith({
+ input: {
+ id: mockRunner.id,
+ },
+ });
+ });
+
+ it('The user can be notified with an event', () => {
+ const deleted = wrapper.emitted('deleted');
+
+ expect(deleted).toHaveLength(1);
+ expect(deleted[0][0].message).toMatch(`#${mockRunnerId}`);
+ expect(deleted[0][0].message).toMatch(`${mockRunner.shortSha}`);
+ });
+ });
+
+ describe('When update fails', () => {
+ describe('On a network error', () => {
+ const mockErrorMsg = 'Update error!';
+
+ beforeEach(async () => {
+ runnerDeleteHandler.mockRejectedValueOnce(new Error(mockErrorMsg));
+
+ await clickOkAndWait();
+ });
+
+ it('error is reported to sentry', () => {
+ expect(captureException).toHaveBeenCalledWith({
+ error: new Error(mockErrorMsg),
+ component: 'RunnerDeleteButton',
+ });
+ });
+
+ it('error is shown to the user', () => {
+ expect(createAlert).toHaveBeenCalledTimes(1);
+ });
+ });
+
+ describe('On a validation error', () => {
+ const mockErrorMsg = 'Runner not found!';
+ const mockErrorMsg2 = 'User not allowed!';
+
+ beforeEach(async () => {
+ runnerDeleteHandler.mockResolvedValueOnce({
+ data: {
+ runnerDelete: {
+ errors: [mockErrorMsg, mockErrorMsg2],
+ },
+ },
+ });
+
+ await clickOkAndWait();
+ });
+
+ it('error is reported to sentry', () => {
+ expect(captureException).toHaveBeenCalledWith({
+ error: new Error(`${mockErrorMsg} ${mockErrorMsg2}`),
+ component: 'RunnerDeleteButton',
+ });
+ });
+
+ it('error is shown to the user', () => {
+ expect(createAlert).toHaveBeenCalledTimes(1);
+ });
+ });
+ });
+
+ describe('When displaying a compact button for an active runner', () => {
+ beforeEach(() => {
+ createComponent({
+ props: {
+ runner: {
+ active: true,
+ },
+ compact: true,
+ },
+ mountFn: mountExtended,
+ });
+ });
+
+ it('Displays no text', () => {
+ expect(findBtn().text()).toBe('');
+ expect(findBtn().classes('btn-icon')).toBe(true);
+ });
+
+ it('Display correctly for screen readers', () => {
+ expect(findBtn().attributes('aria-label')).toBe(I18N_DELETE_RUNNER);
+ expect(getTooltip()).toBe(I18N_DELETE_RUNNER);
+ });
+
+ describe('Immediately after the button is clicked', () => {
+ beforeEach(async () => {
+ findModal().vm.$emit('primary');
+ });
+
+ it('The button has a loading state', async () => {
+ expect(findBtn().props('loading')).toBe(true);
+ });
+
+ it('The stale tooltip is removed', async () => {
+ expect(getTooltip()).toBe('');
+ });
+ });
+ });
+});
diff --git a/spec/frontend/runner/components/runner_jobs_spec.js b/spec/frontend/runner/components/runner_jobs_spec.js
index 97339056370..9abb2861005 100644
--- a/spec/frontend/runner/components/runner_jobs_spec.js
+++ b/spec/frontend/runner/components/runner_jobs_spec.js
@@ -11,7 +11,7 @@ import RunnerPagination from '~/runner/components/runner_pagination.vue';
import { captureException } from '~/runner/sentry_utils';
import { I18N_NO_JOBS_FOUND, RUNNER_DETAILS_JOBS_PAGE_SIZE } from '~/runner/constants';
-import getRunnerJobsQuery from '~/runner/graphql/get_runner_jobs.query.graphql';
+import runnerJobsQuery from '~/runner/graphql/details/runner_jobs.query.graphql';
import { runnerData, runnerJobsData } from '../mock_data';
@@ -34,7 +34,7 @@ describe('RunnerJobs', () => {
const createComponent = ({ mountFn = shallowMountExtended } = {}) => {
wrapper = mountFn(RunnerJobs, {
- apolloProvider: createMockApollo([[getRunnerJobsQuery, mockRunnerJobsQuery]]),
+ apolloProvider: createMockApollo([[runnerJobsQuery, mockRunnerJobsQuery]]),
propsData: {
runner: mockRunner,
},
diff --git a/spec/frontend/runner/components/runner_list_spec.js b/spec/frontend/runner/components/runner_list_spec.js
index 42d6ecca09e..a0f42738d2c 100644
--- a/spec/frontend/runner/components/runner_list_spec.js
+++ b/spec/frontend/runner/components/runner_list_spec.js
@@ -1,4 +1,4 @@
-import { GlTable, GlSkeletonLoader } from '@gitlab/ui';
+import { GlTableLite, GlSkeletonLoader } from '@gitlab/ui';
import {
extendedWrapper,
shallowMountExtended,
@@ -6,8 +6,6 @@ import {
} from 'helpers/vue_test_utils_helper';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import RunnerList from '~/runner/components/runner_list.vue';
-import RunnerEditButton from '~/runner/components/runner_edit_button.vue';
-import RunnerPauseButton from '~/runner/components/runner_pause_button.vue';
import { runnersData } from '../mock_data';
const mockRunners = runnersData.data.runners.nodes;
@@ -17,19 +15,20 @@ describe('RunnerList', () => {
let wrapper;
const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
- const findTable = () => wrapper.findComponent(GlTable);
+ const findTable = () => wrapper.findComponent(GlTableLite);
const findHeaders = () => wrapper.findAll('th');
const findRows = () => wrapper.findAll('[data-testid^="runner-row-"]');
const findCell = ({ row = 0, fieldKey }) =>
extendedWrapper(findRows().at(row).find(`[data-testid="td-${fieldKey}"]`));
- const createComponent = ({ props = {} } = {}, mountFn = shallowMountExtended) => {
+ const createComponent = ({ props = {}, ...options } = {}, mountFn = shallowMountExtended) => {
wrapper = mountFn(RunnerList, {
propsData: {
runners: mockRunners,
activeRunnersCount: mockActiveRunnersCount,
...props,
},
+ ...options,
});
};
@@ -90,11 +89,31 @@ describe('RunnerList', () => {
expect(findCell({ fieldKey: 'contactedAt' }).text()).toEqual(expect.any(String));
// Actions
- const actions = findCell({ fieldKey: 'actions' });
+ expect(findCell({ fieldKey: 'actions' }).exists()).toBe(true);
+ });
+
+ describe('Scoped cell slots', () => {
+ it('Render #runner-name slot in "summary" cell', () => {
+ createComponent(
+ {
+ scopedSlots: { 'runner-name': ({ runner }) => `Summary: ${runner.id}` },
+ },
+ mountExtended,
+ );
+
+ expect(findCell({ fieldKey: 'summary' }).text()).toContain(`Summary: ${mockRunners[0].id}`);
+ });
- expect(actions.findComponent(RunnerEditButton).exists()).toBe(true);
- expect(actions.findComponent(RunnerPauseButton).exists()).toBe(true);
- expect(actions.findByTestId('delete-runner').exists()).toBe(true);
+ it('Render #runner-actions-cell slot in "actions" cell', () => {
+ createComponent(
+ {
+ scopedSlots: { 'runner-actions-cell': ({ runner }) => `Actions: ${runner.id}` },
+ },
+ mountExtended,
+ );
+
+ expect(findCell({ fieldKey: 'actions' }).text()).toBe(`Actions: ${mockRunners[0].id}`);
+ });
});
describe('Table data formatting', () => {
@@ -143,7 +162,8 @@ describe('RunnerList', () => {
describe('When data is loading', () => {
it('shows a busy state', () => {
createComponent({ props: { runners: [], loading: true } });
- expect(findTable().attributes('busy')).toBeTruthy();
+
+ expect(findTable().classes('gl-opacity-6')).toBe(true);
});
it('when there are no runners, shows an skeleton loader', () => {
diff --git a/spec/frontend/runner/components/runner_pagination_spec.js b/spec/frontend/runner/components/runner_pagination_spec.js
index ecd6e6bd7f9..e144b52ceb3 100644
--- a/spec/frontend/runner/components/runner_pagination_spec.js
+++ b/spec/frontend/runner/components/runner_pagination_spec.js
@@ -45,14 +45,6 @@ describe('RunnerPagination', () => {
expect(findPagination().props('nextPage')).toBe(2);
});
- it('Shows prev page disabled', () => {
- expect(findPagination().find('[aria-disabled]').text()).toBe('Prev');
- });
-
- it('Shows next page link', () => {
- expect(findPagination().find('a').text()).toBe('Next');
- });
-
it('Goes to the second page', () => {
findPagination().vm.$emit('input', 2);
@@ -84,7 +76,7 @@ describe('RunnerPagination', () => {
const links = findPagination().findAll('a');
expect(links).toHaveLength(2);
- expect(links.at(0).text()).toBe('Prev');
+ expect(links.at(0).text()).toBe('Previous');
expect(links.at(1).text()).toBe('Next');
});
@@ -124,14 +116,6 @@ describe('RunnerPagination', () => {
expect(findPagination().props('prevPage')).toBe(2);
expect(findPagination().props('nextPage')).toBe(null);
});
-
- it('Shows next page link', () => {
- expect(findPagination().find('a').text()).toBe('Prev');
- });
-
- it('Shows next page disabled', () => {
- expect(findPagination().find('[aria-disabled]').text()).toBe('Next');
- });
});
describe('When only one page', () => {
diff --git a/spec/frontend/runner/components/runner_pause_button_spec.js b/spec/frontend/runner/components/runner_pause_button_spec.js
index 278f3dec2ee..3d9df03977e 100644
--- a/spec/frontend/runner/components/runner_pause_button_spec.js
+++ b/spec/frontend/runner/components/runner_pause_button_spec.js
@@ -4,10 +4,16 @@ import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
import { shallowMountExtended, mountExtended } from 'helpers/vue_test_utils_helper';
-import runnerToggleActiveMutation from '~/runner/graphql/runner_toggle_active.mutation.graphql';
+import runnerToggleActiveMutation from '~/runner/graphql/shared/runner_toggle_active.mutation.graphql';
import waitForPromises from 'helpers/wait_for_promises';
import { captureException } from '~/runner/sentry_utils';
import { createAlert } from '~/flash';
+import {
+ I18N_PAUSE,
+ I18N_PAUSE_TOOLTIP,
+ I18N_RESUME,
+ I18N_RESUME_TOOLTIP,
+} from '~/runner/constants';
import RunnerPauseButton from '~/runner/components/runner_pause_button.vue';
import { runnersData } from '../mock_data';
@@ -74,10 +80,10 @@ describe('RunnerPauseButton', () => {
describe('Pause/Resume action', () => {
describe.each`
- runnerState | icon | content | isActive | newActiveValue
- ${'paused'} | ${'play'} | ${'Resume'} | ${false} | ${true}
- ${'active'} | ${'pause'} | ${'Pause'} | ${true} | ${false}
- `('When the runner is $runnerState', ({ icon, content, isActive, newActiveValue }) => {
+ runnerState | icon | content | tooltip | isActive | newActiveValue
+ ${'paused'} | ${'play'} | ${I18N_RESUME} | ${I18N_RESUME_TOOLTIP} | ${false} | ${true}
+ ${'active'} | ${'pause'} | ${I18N_PAUSE} | ${I18N_PAUSE_TOOLTIP} | ${true} | ${false}
+ `('When the runner is $runnerState', ({ icon, content, tooltip, isActive, newActiveValue }) => {
beforeEach(() => {
createComponent({
props: {
@@ -91,7 +97,11 @@ describe('RunnerPauseButton', () => {
it(`Displays a ${icon} button`, () => {
expect(findBtn().props('loading')).toBe(false);
expect(findBtn().props('icon')).toBe(icon);
+ });
+
+ it('Displays button content', () => {
expect(findBtn().text()).toBe(content);
+ expect(getTooltip()).toBe(tooltip);
});
it('Does not display redundant text for screen readers', () => {
@@ -218,8 +228,8 @@ describe('RunnerPauseButton', () => {
});
it('Display correctly for screen readers', () => {
- expect(findBtn().attributes('aria-label')).toBe('Pause');
- expect(getTooltip()).toBe('Pause');
+ expect(findBtn().attributes('aria-label')).toBe(I18N_PAUSE);
+ expect(getTooltip()).toBe(I18N_PAUSE_TOOLTIP);
});
describe('Immediately after the button is clicked', () => {
diff --git a/spec/frontend/runner/components/runner_projects_spec.js b/spec/frontend/runner/components/runner_projects_spec.js
index 68a2130d6d9..96de8d11bca 100644
--- a/spec/frontend/runner/components/runner_projects_spec.js
+++ b/spec/frontend/runner/components/runner_projects_spec.js
@@ -16,7 +16,7 @@ import RunnerAssignedItem from '~/runner/components/runner_assigned_item.vue';
import RunnerPagination from '~/runner/components/runner_pagination.vue';
import { captureException } from '~/runner/sentry_utils';
-import getRunnerProjectsQuery from '~/runner/graphql/get_runner_projects.query.graphql';
+import runnerProjectsQuery from '~/runner/graphql/details/runner_projects.query.graphql';
import { runnerData, runnerProjectsData } from '../mock_data';
@@ -40,7 +40,7 @@ describe('RunnerProjects', () => {
const createComponent = ({ mountFn = shallowMountExtended } = {}) => {
wrapper = mountFn(RunnerProjects, {
- apolloProvider: createMockApollo([[getRunnerProjectsQuery, mockRunnerProjectsQuery]]),
+ apolloProvider: createMockApollo([[runnerProjectsQuery, mockRunnerProjectsQuery]]),
propsData: {
runner: mockRunner,
},
diff --git a/spec/frontend/runner/components/runner_update_form_spec.js b/spec/frontend/runner/components/runner_update_form_spec.js
index 8b76be396ef..b071791e39f 100644
--- a/spec/frontend/runner/components/runner_update_form_spec.js
+++ b/spec/frontend/runner/components/runner_update_form_spec.js
@@ -13,7 +13,7 @@ import {
ACCESS_LEVEL_REF_PROTECTED,
ACCESS_LEVEL_NOT_PROTECTED,
} from '~/runner/constants';
-import runnerUpdateMutation from '~/runner/graphql/runner_update.mutation.graphql';
+import runnerUpdateMutation from '~/runner/graphql/details/runner_update.mutation.graphql';
import { captureException } from '~/runner/sentry_utils';
import { runnerData } from '../mock_data';