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:
Diffstat (limited to 'spec/frontend/jobs/components/job')
-rw-r--r--spec/frontend/jobs/components/job/artifacts_block_spec.js193
-rw-r--r--spec/frontend/jobs/components/job/commit_block_spec.js66
-rw-r--r--spec/frontend/jobs/components/job/empty_state_spec.js140
-rw-r--r--spec/frontend/jobs/components/job/environments_block_spec.js260
-rw-r--r--spec/frontend/jobs/components/job/erased_block_spec.js59
-rw-r--r--spec/frontend/jobs/components/job/job_app_spec.js343
-rw-r--r--spec/frontend/jobs/components/job/job_container_item_spec.js87
-rw-r--r--spec/frontend/jobs/components/job/job_log_controllers_spec.js323
-rw-r--r--spec/frontend/jobs/components/job/job_retry_forward_deployment_modal_spec.js67
-rw-r--r--spec/frontend/jobs/components/job/job_sidebar_details_container_spec.js133
-rw-r--r--spec/frontend/jobs/components/job/job_sidebar_retry_button_spec.js64
-rw-r--r--spec/frontend/jobs/components/job/jobs_container_spec.js143
-rw-r--r--spec/frontend/jobs/components/job/manual_variables_form_spec.js364
-rw-r--r--spec/frontend/jobs/components/job/mock_data.js123
-rw-r--r--spec/frontend/jobs/components/job/sidebar_detail_row_spec.js68
-rw-r--r--spec/frontend/jobs/components/job/sidebar_header_spec.js87
-rw-r--r--spec/frontend/jobs/components/job/sidebar_spec.js216
-rw-r--r--spec/frontend/jobs/components/job/stages_dropdown_spec.js191
-rw-r--r--spec/frontend/jobs/components/job/stuck_block_spec.js94
-rw-r--r--spec/frontend/jobs/components/job/trigger_block_spec.js81
-rw-r--r--spec/frontend/jobs/components/job/unmet_prerequisites_block_spec.js37
21 files changed, 0 insertions, 3139 deletions
diff --git a/spec/frontend/jobs/components/job/artifacts_block_spec.js b/spec/frontend/jobs/components/job/artifacts_block_spec.js
deleted file mode 100644
index f9e52a5ae43..00000000000
--- a/spec/frontend/jobs/components/job/artifacts_block_spec.js
+++ /dev/null
@@ -1,193 +0,0 @@
-import { GlPopover } from '@gitlab/ui';
-import { mountExtended } from 'helpers/vue_test_utils_helper';
-import { trimText } from 'helpers/text_helper';
-import ArtifactsBlock from '~/jobs/components/job/sidebar/artifacts_block.vue';
-import { getTimeago } from '~/lib/utils/datetime_utility';
-
-describe('Artifacts block', () => {
- let wrapper;
-
- const createWrapper = (propsData) =>
- mountExtended(ArtifactsBlock, {
- propsData: {
- helpUrl: 'help-url',
- ...propsData,
- },
- });
-
- const findArtifactRemoveElt = () => wrapper.findByTestId('artifacts-remove-timeline');
- const findJobLockedElt = () => wrapper.findByTestId('job-locked-message');
- const findKeepBtn = () => wrapper.findByTestId('keep-artifacts');
- const findDownloadBtn = () => wrapper.findByTestId('download-artifacts');
- const findBrowseBtn = () => wrapper.findByTestId('browse-artifacts');
- const findArtifactsHelpLink = () => wrapper.findByTestId('artifacts-help-link');
- const findPopover = () => wrapper.findComponent(GlPopover);
-
- const expireAt = '2018-08-14T09:38:49.157Z';
- const timeago = getTimeago();
- const formattedDate = timeago.format(expireAt);
- const lockedText =
- 'These artifacts are the latest. They will not be deleted (even if expired) until newer artifacts are available.';
-
- const expiredArtifact = {
- expire_at: expireAt,
- expired: true,
- locked: false,
- };
-
- const nonExpiredArtifact = {
- download_path: '/gitlab-org/gitlab-foss/-/jobs/98314558/artifacts/download',
- browse_path: '/gitlab-org/gitlab-foss/-/jobs/98314558/artifacts/browse',
- keep_path: '/gitlab-org/gitlab-foss/-/jobs/98314558/artifacts/keep',
- expire_at: expireAt,
- expired: false,
- locked: false,
- };
-
- const lockedExpiredArtifact = {
- ...expiredArtifact,
- download_path: '/gitlab-org/gitlab-foss/-/jobs/98314558/artifacts/download',
- browse_path: '/gitlab-org/gitlab-foss/-/jobs/98314558/artifacts/browse',
- expired: true,
- locked: true,
- };
-
- const lockedNonExpiredArtifact = {
- ...nonExpiredArtifact,
- keep_path: undefined,
- locked: true,
- };
-
- describe('with expired artifacts that are not locked', () => {
- beforeEach(() => {
- wrapper = createWrapper({
- artifact: expiredArtifact,
- });
- });
-
- it('renders expired artifact date and info', () => {
- expect(trimText(findArtifactRemoveElt().text())).toBe(
- `The artifacts were removed ${formattedDate}`,
- );
-
- expect(
- findArtifactRemoveElt()
- .find('[data-testid="artifact-expired-help-link"]')
- .attributes('href'),
- ).toBe('help-url');
- });
-
- it('does not show the keep button', () => {
- expect(findKeepBtn().exists()).toBe(false);
- });
-
- it('does not show the download button', () => {
- expect(findDownloadBtn().exists()).toBe(false);
- });
-
- it('does not show the browse button', () => {
- expect(findBrowseBtn().exists()).toBe(false);
- });
- });
-
- describe('with artifacts that will expire', () => {
- beforeEach(() => {
- wrapper = createWrapper({
- artifact: nonExpiredArtifact,
- });
- });
-
- it('renders will expire artifact date and info', () => {
- expect(trimText(findArtifactRemoveElt().text())).toBe(
- `The artifacts will be removed ${formattedDate}`,
- );
-
- expect(
- findArtifactRemoveElt()
- .find('[data-testid="artifact-expired-help-link"]')
- .attributes('href'),
- ).toBe('help-url');
- });
-
- it('renders the keep button', () => {
- expect(findKeepBtn().exists()).toBe(true);
- });
-
- it('renders the download button', () => {
- expect(findDownloadBtn().exists()).toBe(true);
- });
-
- it('renders the browse button', () => {
- expect(findBrowseBtn().exists()).toBe(true);
- });
- });
-
- describe('with expired locked artifacts', () => {
- beforeEach(() => {
- wrapper = createWrapper({
- artifact: lockedExpiredArtifact,
- });
- });
-
- it('renders the information that the artefacts are locked', () => {
- expect(findArtifactRemoveElt().exists()).toBe(false);
- expect(trimText(findJobLockedElt().text())).toBe(lockedText);
- });
-
- it('does not render the keep button', () => {
- expect(findKeepBtn().exists()).toBe(false);
- });
-
- it('renders the download button', () => {
- expect(findDownloadBtn().exists()).toBe(true);
- });
-
- it('renders the browse button', () => {
- expect(findBrowseBtn().exists()).toBe(true);
- });
- });
-
- describe('with non expired locked artifacts', () => {
- beforeEach(() => {
- wrapper = createWrapper({
- artifact: lockedNonExpiredArtifact,
- });
- });
-
- it('renders the information that the artefacts are locked', () => {
- expect(findArtifactRemoveElt().exists()).toBe(false);
- expect(trimText(findJobLockedElt().text())).toBe(lockedText);
- });
-
- it('does not render the keep button', () => {
- expect(findKeepBtn().exists()).toBe(false);
- });
-
- it('renders the download button', () => {
- expect(findDownloadBtn().exists()).toBe(true);
- });
-
- it('renders the browse button', () => {
- expect(findBrowseBtn().exists()).toBe(true);
- });
- });
-
- describe('artifacts help text', () => {
- beforeEach(() => {
- wrapper = createWrapper({
- artifact: lockedNonExpiredArtifact,
- });
- });
-
- it('displays help text', () => {
- const expectedHelpText =
- 'Job artifacts are files that are configured to be uploaded when a job finishes execution. Artifacts could be compiled files, unit tests or scanning reports, or any other files generated by a job.';
-
- expect(findPopover().text()).toBe(expectedHelpText);
- });
-
- it('links to artifacts help page', () => {
- expect(findArtifactsHelpLink().attributes('href')).toBe('/help/ci/jobs/job_artifacts');
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/commit_block_spec.js b/spec/frontend/jobs/components/job/commit_block_spec.js
deleted file mode 100644
index 1c28b5079d7..00000000000
--- a/spec/frontend/jobs/components/job/commit_block_spec.js
+++ /dev/null
@@ -1,66 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import { extendedWrapper } from 'helpers/vue_test_utils_helper';
-import CommitBlock from '~/jobs/components/job/sidebar/commit_block.vue';
-import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
-
-describe('Commit block', () => {
- let wrapper;
-
- const commit = {
- short_id: '1f0fb84f',
- id: '1f0fb84fb6770d74d97eee58118fd3909cd4f48c',
- commit_path: 'commit/1f0fb84fb6770d74d97eee58118fd3909cd4f48c',
- title: 'Update README.md',
- };
-
- const mergeRequest = {
- iid: '!21244',
- path: 'merge_requests/21244',
- };
-
- const findCommitSha = () => wrapper.findByTestId('commit-sha');
- const findLinkSha = () => wrapper.findByTestId('link-commit');
-
- const mountComponent = (props) => {
- wrapper = extendedWrapper(
- shallowMount(CommitBlock, {
- propsData: {
- commit,
- ...props,
- },
- }),
- );
- };
-
- describe('without merge request', () => {
- beforeEach(() => {
- mountComponent();
- });
-
- it('renders pipeline short sha link', () => {
- expect(findCommitSha().attributes('href')).toBe(commit.commit_path);
- expect(findCommitSha().text()).toBe(commit.short_id);
- });
-
- it('renders clipboard button', () => {
- expect(wrapper.findComponent(ClipboardButton).attributes('text')).toBe(commit.id);
- });
-
- it('renders git commit title', () => {
- expect(wrapper.text()).toContain(commit.title);
- });
-
- it('does not render merge request', () => {
- expect(findLinkSha().exists()).toBe(false);
- });
- });
-
- describe('with merge request', () => {
- it('renders merge request link and reference', () => {
- mountComponent({ mergeRequest });
-
- expect(findLinkSha().attributes('href')).toBe(mergeRequest.path);
- expect(findLinkSha().text()).toBe(`!${mergeRequest.iid}`);
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/empty_state_spec.js b/spec/frontend/jobs/components/job/empty_state_spec.js
deleted file mode 100644
index 970c2591795..00000000000
--- a/spec/frontend/jobs/components/job/empty_state_spec.js
+++ /dev/null
@@ -1,140 +0,0 @@
-import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import EmptyState from '~/jobs/components/job/empty_state.vue';
-import ManualVariablesForm from '~/jobs/components/job/manual_variables_form.vue';
-import { mockFullPath, mockId } from './mock_data';
-
-describe('Empty State', () => {
- let wrapper;
-
- const defaultProps = {
- illustrationPath: 'illustrations/pending_job_empty.svg',
- illustrationSizeClass: 'svg-430',
- jobId: mockId,
- title: 'This job has not started yet',
- playable: false,
- isRetryable: true,
- };
-
- const createWrapper = (props) => {
- wrapper = shallowMountExtended(EmptyState, {
- propsData: {
- ...defaultProps,
- ...props,
- },
- provide: {
- projectPath: mockFullPath,
- },
- });
- };
-
- const content = 'This job is in pending state and is waiting to be picked by a runner';
-
- const findEmptyStateImage = () => wrapper.find('img');
- const findTitle = () => wrapper.findByTestId('job-empty-state-title');
- const findContent = () => wrapper.findByTestId('job-empty-state-content');
- const findAction = () => wrapper.findByTestId('job-empty-state-action');
- const findManualVarsForm = () => wrapper.findComponent(ManualVariablesForm);
-
- describe('renders image and title', () => {
- beforeEach(() => {
- createWrapper();
- });
-
- it('renders empty state image', () => {
- expect(findEmptyStateImage().exists()).toBe(true);
- });
-
- it('renders provided title', () => {
- expect(findTitle().text().trim()).toBe(defaultProps.title);
- });
- });
-
- describe('with content', () => {
- beforeEach(() => {
- createWrapper({ content });
- });
-
- it('renders content', () => {
- expect(findContent().text().trim()).toBe(content);
- });
- });
-
- describe('without content', () => {
- beforeEach(() => {
- createWrapper();
- });
-
- it('does not render content', () => {
- expect(findContent().exists()).toBe(false);
- });
- });
-
- describe('with action', () => {
- beforeEach(() => {
- createWrapper({
- action: {
- path: 'runner',
- button_title: 'Check runner',
- method: 'post',
- },
- });
- });
-
- it('renders action', () => {
- expect(findAction().attributes('href')).toBe('runner');
- });
- });
-
- describe('without action', () => {
- beforeEach(() => {
- createWrapper({
- action: null,
- });
- });
-
- it('does not render action', () => {
- expect(findAction().exists()).toBe(false);
- });
-
- it('does not render manual variables form', () => {
- expect(findManualVarsForm().exists()).toBe(false);
- });
- });
-
- describe('with playable action and not scheduled job', () => {
- beforeEach(() => {
- createWrapper({
- content,
- playable: true,
- scheduled: false,
- action: {
- path: 'runner',
- button_title: 'Check runner',
- method: 'post',
- },
- });
- });
-
- it('renders manual variables form', () => {
- expect(findManualVarsForm().exists()).toBe(true);
- });
-
- it('does not render the empty state action', () => {
- expect(findAction().exists()).toBe(false);
- });
- });
-
- describe('with playable action and scheduled job', () => {
- beforeEach(() => {
- createWrapper({
- playable: true,
- scheduled: true,
- content,
- });
- });
-
- it('does not render manual variables form', () => {
- expect(findManualVarsForm().exists()).toBe(false);
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/environments_block_spec.js b/spec/frontend/jobs/components/job/environments_block_spec.js
deleted file mode 100644
index ab36f79ea5e..00000000000
--- a/spec/frontend/jobs/components/job/environments_block_spec.js
+++ /dev/null
@@ -1,260 +0,0 @@
-import { mount } from '@vue/test-utils';
-import EnvironmentsBlock from '~/jobs/components/job/environments_block.vue';
-
-const TEST_CLUSTER_NAME = 'test_cluster';
-const TEST_CLUSTER_PATH = 'path/to/test_cluster';
-const TEST_KUBERNETES_NAMESPACE = 'this-is-a-kubernetes-namespace';
-
-describe('Environments block', () => {
- let wrapper;
-
- const status = {
- group: 'success',
- icon: 'status_success',
- label: 'passed',
- text: 'passed',
- tooltip: 'passed',
- };
-
- const environment = {
- environment_path: '/environment',
- name: 'environment',
- };
-
- const lastDeployment = { iid: 'deployment', deployable: { build_path: 'bar' } };
-
- const createEnvironmentWithLastDeployment = () => ({
- ...environment,
- last_deployment: { ...lastDeployment },
- });
-
- const createDeploymentWithCluster = () => ({ name: TEST_CLUSTER_NAME, path: TEST_CLUSTER_PATH });
-
- const createDeploymentWithClusterAndKubernetesNamespace = () => ({
- name: TEST_CLUSTER_NAME,
- path: TEST_CLUSTER_PATH,
- kubernetes_namespace: TEST_KUBERNETES_NAMESPACE,
- });
-
- const createComponent = (deploymentStatus = {}, deploymentCluster = {}) => {
- wrapper = mount(EnvironmentsBlock, {
- propsData: {
- deploymentStatus,
- deploymentCluster,
- iconStatus: status,
- },
- });
- };
-
- const findText = () => wrapper.findComponent(EnvironmentsBlock).text();
- const findJobDeploymentLink = () => wrapper.find('[data-testid="job-deployment-link"]');
- const findEnvironmentLink = () => wrapper.find('[data-testid="job-environment-link"]');
- const findClusterLink = () => wrapper.find('[data-testid="job-cluster-link"]');
-
- describe('with last deployment', () => {
- it('renders info for most recent deployment', () => {
- createComponent({
- status: 'last',
- environment,
- });
-
- expect(findText()).toBe('This job is deployed to environment.');
- });
-
- describe('when there is a cluster', () => {
- it('renders info with cluster', () => {
- createComponent(
- {
- status: 'last',
- environment: createEnvironmentWithLastDeployment(),
- },
- createDeploymentWithCluster(),
- );
-
- expect(findText()).toBe(
- `This job is deployed to environment using cluster ${TEST_CLUSTER_NAME}.`,
- );
- });
-
- describe('when there is a kubernetes namespace', () => {
- it('renders info with cluster', () => {
- createComponent(
- {
- status: 'last',
- environment: createEnvironmentWithLastDeployment(),
- },
- createDeploymentWithClusterAndKubernetesNamespace(),
- );
-
- expect(findText()).toBe(
- `This job is deployed to environment using cluster ${TEST_CLUSTER_NAME} and namespace ${TEST_KUBERNETES_NAMESPACE}.`,
- );
- });
- });
- });
- });
-
- describe('with out of date deployment', () => {
- describe('with last deployment', () => {
- it('renders info for out date and most recent', () => {
- createComponent({
- status: 'out_of_date',
- environment: createEnvironmentWithLastDeployment(),
- });
-
- expect(findText()).toBe(
- 'This job is an out-of-date deployment to environment. View the most recent deployment.',
- );
-
- expect(findJobDeploymentLink().attributes('href')).toBe('bar');
- });
-
- describe('when there is a cluster', () => {
- it('renders info with cluster', () => {
- createComponent(
- {
- status: 'out_of_date',
- environment: createEnvironmentWithLastDeployment(),
- },
- createDeploymentWithCluster(),
- );
-
- expect(findText()).toBe(
- `This job is an out-of-date deployment to environment using cluster ${TEST_CLUSTER_NAME}. View the most recent deployment.`,
- );
- });
-
- describe('when there is a kubernetes namespace', () => {
- it('renders info with cluster', () => {
- createComponent(
- {
- status: 'out_of_date',
- environment: createEnvironmentWithLastDeployment(),
- },
- createDeploymentWithClusterAndKubernetesNamespace(),
- );
-
- expect(findText()).toBe(
- `This job is an out-of-date deployment to environment using cluster ${TEST_CLUSTER_NAME} and namespace ${TEST_KUBERNETES_NAMESPACE}. View the most recent deployment.`,
- );
- });
- });
- });
- });
-
- describe('without last deployment', () => {
- it('renders info about out of date deployment', () => {
- createComponent({
- status: 'out_of_date',
- environment,
- });
-
- expect(findText()).toBe('This job is an out-of-date deployment to environment.');
- });
- });
- });
-
- describe('with failed deployment', () => {
- it('renders info about failed deployment', () => {
- createComponent({
- status: 'failed',
- environment,
- });
-
- expect(findText()).toBe('The deployment of this job to environment did not succeed.');
- });
- });
-
- describe('creating deployment', () => {
- describe('with last deployment', () => {
- it('renders info about creating deployment and overriding latest deployment', () => {
- createComponent({
- status: 'creating',
- environment: createEnvironmentWithLastDeployment(),
- });
-
- expect(findText()).toBe(
- 'This job is creating a deployment to environment. This will overwrite the latest deployment.',
- );
-
- expect(findEnvironmentLink().attributes('href')).toBe(environment.environment_path);
-
- expect(findJobDeploymentLink().attributes('href')).toBe('bar');
-
- expect(findClusterLink().exists()).toBe(false);
- });
- });
-
- describe('without last deployment', () => {
- it('renders info about deployment being created', () => {
- createComponent({
- status: 'creating',
- environment,
- });
-
- expect(findText()).toBe('This job is creating a deployment to environment.');
- });
-
- describe('when there is a cluster', () => {
- it('inclues information about the cluster', () => {
- createComponent(
- {
- status: 'creating',
- environment,
- },
- createDeploymentWithCluster(),
- );
-
- expect(findText()).toBe(
- `This job is creating a deployment to environment using cluster ${TEST_CLUSTER_NAME}.`,
- );
- });
- });
- });
-
- describe('without environment', () => {
- it('does not render environment link', () => {
- createComponent({
- status: 'creating',
- environment: null,
- });
-
- expect(findEnvironmentLink().exists()).toBe(false);
- });
- });
- });
-
- describe('with a cluster', () => {
- it('renders the cluster link', () => {
- createComponent(
- {
- status: 'last',
- environment: createEnvironmentWithLastDeployment(),
- },
- createDeploymentWithCluster(),
- );
-
- expect(findText()).toBe(
- `This job is deployed to environment using cluster ${TEST_CLUSTER_NAME}.`,
- );
-
- expect(findClusterLink().attributes('href')).toBe(TEST_CLUSTER_PATH);
- });
-
- describe('when the cluster is missing the path', () => {
- it('renders the name without a link', () => {
- createComponent(
- {
- status: 'last',
- environment: createEnvironmentWithLastDeployment(),
- },
- { name: 'the-cluster' },
- );
-
- expect(findText()).toContain('using cluster the-cluster.');
-
- expect(findClusterLink().exists()).toBe(false);
- });
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/erased_block_spec.js b/spec/frontend/jobs/components/job/erased_block_spec.js
deleted file mode 100644
index aeab676fc7e..00000000000
--- a/spec/frontend/jobs/components/job/erased_block_spec.js
+++ /dev/null
@@ -1,59 +0,0 @@
-import { GlLink } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import ErasedBlock from '~/jobs/components/job/erased_block.vue';
-import { getTimeago } from '~/lib/utils/datetime_utility';
-
-describe('Erased block', () => {
- let wrapper;
-
- const erasedAt = '2016-11-07T11:11:16.525Z';
- const timeago = getTimeago();
- const formattedDate = timeago.format(erasedAt);
-
- const findLink = () => wrapper.findComponent(GlLink);
-
- const createComponent = (props) => {
- wrapper = mount(ErasedBlock, {
- propsData: props,
- });
- };
-
- describe('with job erased by user', () => {
- beforeEach(() => {
- createComponent({
- user: {
- username: 'root',
- web_url: 'gitlab.com/root',
- },
- erasedAt,
- });
- });
-
- it('renders username and link', () => {
- expect(findLink().attributes('href')).toEqual('gitlab.com/root');
-
- expect(wrapper.text().trim()).toContain('Job has been erased by');
- expect(wrapper.text().trim()).toContain('root');
- });
-
- it('renders erasedAt', () => {
- expect(wrapper.text().trim()).toContain(formattedDate);
- });
- });
-
- describe('with erased job', () => {
- beforeEach(() => {
- createComponent({
- erasedAt,
- });
- });
-
- it('renders username and link', () => {
- expect(wrapper.text().trim()).toContain('Job has been erased');
- });
-
- it('renders erasedAt', () => {
- expect(wrapper.text().trim()).toContain(formattedDate);
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/job_app_spec.js b/spec/frontend/jobs/components/job/job_app_spec.js
deleted file mode 100644
index 8f5700ee22d..00000000000
--- a/spec/frontend/jobs/components/job/job_app_spec.js
+++ /dev/null
@@ -1,343 +0,0 @@
-import Vue, { nextTick } from 'vue';
-// eslint-disable-next-line no-restricted-imports
-import Vuex from 'vuex';
-import { GlLoadingIcon } from '@gitlab/ui';
-import MockAdapter from 'axios-mock-adapter';
-import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import { TEST_HOST } from 'helpers/test_constants';
-import EmptyState from '~/jobs/components/job/empty_state.vue';
-import EnvironmentsBlock from '~/jobs/components/job/environments_block.vue';
-import ErasedBlock from '~/jobs/components/job/erased_block.vue';
-import JobApp from '~/jobs/components/job/job_app.vue';
-import JobLog from '~/jobs/components/log/log.vue';
-import JobLogTopBar from 'ee_else_ce/jobs/components/job/job_log_controllers.vue';
-import Sidebar from '~/jobs/components/job/sidebar/sidebar.vue';
-import StuckBlock from '~/jobs/components/job/stuck_block.vue';
-import UnmetPrerequisitesBlock from '~/jobs/components/job/unmet_prerequisites_block.vue';
-import createStore from '~/jobs/store';
-import axios from '~/lib/utils/axios_utils';
-import { HTTP_STATUS_OK } from '~/lib/utils/http_status';
-import { MANUAL_STATUS } from '~/jobs/constants';
-import job from '../../mock_data';
-import { mockPendingJobData } from './mock_data';
-
-describe('Job App', () => {
- Vue.use(Vuex);
-
- let store;
- let wrapper;
- let mock;
-
- const initSettings = {
- endpoint: `${TEST_HOST}jobs/123.json`,
- pagePath: `${TEST_HOST}jobs/123`,
- logState:
- 'eyJvZmZzZXQiOjE3NDUxLCJuX29wZW5fdGFncyI6MCwiZmdfY29sb3IiOm51bGwsImJnX2NvbG9yIjpudWxsLCJzdHlsZV9tYXNrIjowfQ%3D%3D',
- };
-
- const props = {
- artifactHelpUrl: 'help/artifact',
- deploymentHelpUrl: 'help/deployment',
- runnerSettingsUrl: 'settings/ci-cd/runners',
- terminalPath: 'jobs/123/terminal',
- projectPath: 'user-name/project-name',
- subscriptionsMoreMinutesUrl: 'https://customers.gitlab.com/buy_pipeline_minutes',
- };
-
- const createComponent = () => {
- wrapper = shallowMountExtended(JobApp, {
- propsData: { ...props },
- store,
- });
- };
-
- const setupAndMount = async ({ jobData = {}, jobLogData = {} } = {}) => {
- mock.onGet(initSettings.endpoint).replyOnce(HTTP_STATUS_OK, { ...job, ...jobData });
- mock.onGet(`${initSettings.pagePath}/trace.json`).reply(HTTP_STATUS_OK, jobLogData);
-
- const asyncInit = store.dispatch('init', initSettings);
-
- createComponent();
-
- await asyncInit;
- jest.runOnlyPendingTimers();
- await axios.waitForAll();
- await nextTick();
- };
-
- const findLoadingComponent = () => wrapper.findComponent(GlLoadingIcon);
- const findSidebar = () => wrapper.findComponent(Sidebar);
- const findStuckBlockComponent = () => wrapper.findComponent(StuckBlock);
- const findFailedJobComponent = () => wrapper.findComponent(UnmetPrerequisitesBlock);
- const findEnvironmentsBlockComponent = () => wrapper.findComponent(EnvironmentsBlock);
- const findErasedBlock = () => wrapper.findComponent(ErasedBlock);
- const findEmptyState = () => wrapper.findComponent(EmptyState);
- const findJobLog = () => wrapper.findComponent(JobLog);
- const findJobLogTopBar = () => wrapper.findComponent(JobLogTopBar);
-
- const findJobContent = () => wrapper.findByTestId('job-content');
- const findArchivedJob = () => wrapper.findByTestId('archived-job');
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- store = createStore();
- });
-
- afterEach(() => {
- mock.restore();
- // eslint-disable-next-line @gitlab/vtu-no-explicit-wrapper-destroy
- wrapper.destroy();
- });
-
- describe('while loading', () => {
- beforeEach(() => {
- store.state.isLoading = true;
- createComponent();
- });
-
- it('renders loading icon', () => {
- expect(findLoadingComponent().exists()).toBe(true);
- expect(findSidebar().exists()).toBe(false);
- expect(findJobContent().exists()).toBe(false);
- });
- });
-
- describe('with successful request', () => {
- describe('Header section', () => {
- describe('job callout message', () => {
- it('should not render the reason when reason is absent', () =>
- setupAndMount().then(() => {
- expect(wrapper.vm.shouldRenderCalloutMessage).toBe(false);
- }));
-
- it('should render the reason when reason is present', () =>
- setupAndMount({
- jobData: {
- callout_message: 'There is an unkown failure, please try again',
- },
- }).then(() => {
- expect(wrapper.vm.shouldRenderCalloutMessage).toBe(true);
- }));
- });
- });
-
- describe('stuck block', () => {
- describe('without active runners available', () => {
- it('renders stuck block when there are no runners', () =>
- setupAndMount({
- jobData: {
- status: {
- group: 'pending',
- icon: 'status_pending',
- label: 'pending',
- text: 'pending',
- details_path: 'path',
- },
- stuck: true,
- runners: {
- available: false,
- online: false,
- },
- tags: [],
- },
- }).then(() => {
- expect(findStuckBlockComponent().exists()).toBe(true);
- }));
- });
-
- it('does not render stuck block when there are runners', () =>
- setupAndMount({
- jobData: {
- runners: { available: true },
- },
- }).then(() => {
- expect(findStuckBlockComponent().exists()).toBe(false);
- }));
- });
-
- describe('unmet prerequisites block', () => {
- it('renders unmet prerequisites block when there is an unmet prerequisites failure', () =>
- setupAndMount({
- jobData: {
- status: {
- group: 'failed',
- icon: 'status_failed',
- label: 'failed',
- text: 'failed',
- details_path: 'path',
- illustration: {
- content: 'Retry this job in order to create the necessary resources.',
- image: 'path',
- size: 'svg-430',
- title: 'Failed to create resources',
- },
- },
- failure_reason: 'unmet_prerequisites',
- has_trace: false,
- runners: {
- available: true,
- },
- tags: [],
- },
- }).then(() => {
- expect(findFailedJobComponent().exists()).toBe(true);
- }));
- });
-
- describe('environments block', () => {
- it('renders environment block when job has environment', () =>
- setupAndMount({
- jobData: {
- deployment_status: {
- environment: {
- environment_path: '/path',
- name: 'foo',
- },
- },
- },
- }).then(() => {
- expect(findEnvironmentsBlockComponent().exists()).toBe(true);
- }));
-
- it('does not render environment block when job has environment', () =>
- setupAndMount().then(() => {
- expect(findEnvironmentsBlockComponent().exists()).toBe(false);
- }));
- });
-
- describe('erased block', () => {
- it('renders erased block when `erased` is true', () =>
- setupAndMount({
- jobData: {
- erased_by: {
- username: 'root',
- web_url: 'gitlab.com/root',
- },
- erased_at: '2016-11-07T11:11:16.525Z',
- },
- }).then(() => {
- expect(findErasedBlock().exists()).toBe(true);
- }));
-
- it('does not render erased block when `erased` is false', () =>
- setupAndMount({
- jobData: {
- erased_at: null,
- },
- }).then(() => {
- expect(findErasedBlock().exists()).toBe(false);
- }));
- });
-
- describe('empty states block', () => {
- it('renders empty state when job does not have log and is not running', () =>
- setupAndMount({
- jobData: {
- has_trace: false,
- status: {
- group: 'pending',
- icon: 'status_pending',
- label: 'pending',
- text: 'pending',
- details_path: 'path',
- illustration: {
- image: 'path',
- size: '340',
- title: 'Empty State',
- content: 'This is an empty state',
- },
- action: {
- button_title: 'Retry job',
- method: 'post',
- path: '/path',
- },
- },
- },
- }).then(() => {
- expect(findEmptyState().exists()).toBe(true);
- }));
-
- it('does not render empty state when job does not have log but it is running', () =>
- setupAndMount({
- jobData: {
- has_trace: false,
- status: {
- group: 'running',
- icon: 'status_running',
- label: 'running',
- text: 'running',
- details_path: 'path',
- },
- },
- }).then(() => {
- expect(findEmptyState().exists()).toBe(false);
- }));
-
- it('does not render empty state when job has log but it is not running', () =>
- setupAndMount({ jobData: { has_trace: true } }).then(() => {
- expect(findEmptyState().exists()).toBe(false);
- }));
- });
-
- describe('sidebar', () => {
- it('renders sidebar', async () => {
- await setupAndMount();
-
- expect(findSidebar().exists()).toBe(true);
- });
- });
- });
-
- describe('archived job', () => {
- beforeEach(() => setupAndMount({ jobData: { archived: true } }));
-
- it('renders warning about job being archived', () => {
- expect(findArchivedJob().exists()).toBe(true);
- });
- });
-
- describe('non-archived job', () => {
- beforeEach(() => setupAndMount());
-
- it('does not warning about job being archived', () => {
- expect(findArchivedJob().exists()).toBe(false);
- });
- });
-
- describe('job log', () => {
- beforeEach(() => setupAndMount());
-
- it('should render job log header', () => {
- expect(findJobLogTopBar().exists()).toBe(true);
- });
-
- it('should render job log', () => {
- expect(findJobLog().exists()).toBe(true);
- });
- });
-
- describe('job log polling', () => {
- beforeEach(() => {
- jest.spyOn(store, 'dispatch');
- });
-
- it('should poll job log by default', async () => {
- await setupAndMount({
- jobData: mockPendingJobData,
- });
-
- expect(store.dispatch).toHaveBeenCalledWith('fetchJobLog');
- });
-
- it('should NOT poll job log for manual variables form empty state', async () => {
- const manualPendingJobData = mockPendingJobData;
- manualPendingJobData.status.group = MANUAL_STATUS;
-
- await setupAndMount({
- jobData: manualPendingJobData,
- });
-
- expect(store.dispatch).not.toHaveBeenCalledWith('fetchJobLog');
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/job_container_item_spec.js b/spec/frontend/jobs/components/job/job_container_item_spec.js
deleted file mode 100644
index 39782130d38..00000000000
--- a/spec/frontend/jobs/components/job/job_container_item_spec.js
+++ /dev/null
@@ -1,87 +0,0 @@
-import { GlIcon, GlLink } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import { nextTick } from 'vue';
-import delayedJobFixture from 'test_fixtures/jobs/delayed.json';
-import JobContainerItem from '~/jobs/components/job/sidebar/job_container_item.vue';
-import CiIcon from '~/vue_shared/components/ci_icon.vue';
-import job from '../../mock_data';
-
-describe('JobContainerItem', () => {
- let wrapper;
-
- const findCiIcon = () => wrapper.findComponent(CiIcon);
- const findGlIcon = () => wrapper.findComponent(GlIcon);
-
- function createComponent(jobData = {}, props = { isActive: false, retried: false }) {
- wrapper = shallowMount(JobContainerItem, {
- propsData: {
- job: {
- ...jobData,
- retried: props.retried,
- },
- isActive: props.isActive,
- },
- });
- }
-
- describe('when a job is not active and not retried', () => {
- beforeEach(() => {
- createComponent(job);
- });
-
- it('displays a status icon', () => {
- expect(findCiIcon().props('status')).toBe(job.status);
- });
-
- it('displays the job name', () => {
- expect(wrapper.text()).toContain(job.name);
- });
-
- it('displays a link to the job', () => {
- const link = wrapper.findComponent(GlLink);
-
- expect(link.attributes('href')).toBe(job.status.details_path);
- });
- });
-
- describe('when a job is active', () => {
- beforeEach(() => {
- createComponent(job, { isActive: true });
- });
-
- it('displays an arrow sprite icon', () => {
- expect(findGlIcon().props('name')).toBe('arrow-right');
- });
- });
-
- describe('when a job is retried', () => {
- beforeEach(() => {
- createComponent(job, { isActive: false, retried: true });
- });
-
- it('displays a retry icon', () => {
- expect(findGlIcon().props('name')).toBe('retry');
- });
- });
-
- describe('for a delayed job', () => {
- beforeEach(() => {
- const remainingMilliseconds = 1337000;
- jest
- .spyOn(Date, 'now')
- .mockImplementation(
- () => new Date(delayedJobFixture.scheduled_at).getTime() - remainingMilliseconds,
- );
-
- createComponent(delayedJobFixture);
- });
-
- it('displays remaining time in tooltip', async () => {
- await nextTick();
-
- const link = wrapper.findComponent(GlLink);
-
- expect(link.attributes('title')).toMatch('delayed job - delayed manual action (00:22:17)');
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/job_log_controllers_spec.js b/spec/frontend/jobs/components/job/job_log_controllers_spec.js
deleted file mode 100644
index 7b6d58f63d1..00000000000
--- a/spec/frontend/jobs/components/job/job_log_controllers_spec.js
+++ /dev/null
@@ -1,323 +0,0 @@
-import { GlSearchBoxByClick } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import JobLogControllers from '~/jobs/components/job/job_log_controllers.vue';
-import HelpPopover from '~/vue_shared/components/help_popover.vue';
-import { backoffMockImplementation } from 'helpers/backoff_helper';
-import * as commonUtils from '~/lib/utils/common_utils';
-import { mockJobLog } from '../../mock_data';
-
-const mockToastShow = jest.fn();
-
-describe('Job log controllers', () => {
- let wrapper;
-
- beforeEach(() => {
- jest.spyOn(commonUtils, 'backOff').mockImplementation(backoffMockImplementation);
- });
-
- afterEach(() => {
- commonUtils.backOff.mockReset();
- });
-
- const defaultProps = {
- rawPath: '/raw',
- size: 511952,
- isScrollTopDisabled: false,
- isScrollBottomDisabled: false,
- isScrollingDown: true,
- isJobLogSizeVisible: true,
- isComplete: true,
- jobLog: mockJobLog,
- };
-
- const createWrapper = (props, { jobLogJumpToFailures = false } = {}) => {
- wrapper = mount(JobLogControllers, {
- propsData: {
- ...defaultProps,
- ...props,
- },
- provide: {
- glFeatures: {
- jobLogJumpToFailures,
- },
- },
- data() {
- return {
- searchTerm: '82',
- };
- },
- mocks: {
- $toast: {
- show: mockToastShow,
- },
- },
- });
- };
-
- const findTruncatedInfo = () => wrapper.find('[data-testid="log-truncated-info"]');
- const findRawLink = () => wrapper.find('[data-testid="raw-link"]');
- const findRawLinkController = () => wrapper.find('[data-testid="job-raw-link-controller"]');
- const findScrollTop = () => wrapper.find('[data-testid="job-controller-scroll-top"]');
- const findScrollBottom = () => wrapper.find('[data-testid="job-controller-scroll-bottom"]');
- const findJobLogSearch = () => wrapper.findComponent(GlSearchBoxByClick);
- const findSearchHelp = () => wrapper.findComponent(HelpPopover);
- const findScrollFailure = () => wrapper.find('[data-testid="job-controller-scroll-to-failure"]');
-
- describe('Truncate information', () => {
- describe('with isJobLogSizeVisible', () => {
- beforeEach(() => {
- createWrapper();
- });
-
- it('renders size information', () => {
- expect(findTruncatedInfo().text()).toMatch('499.95 KiB');
- });
-
- it('renders link to raw job log', () => {
- expect(findRawLink().attributes('href')).toBe(defaultProps.rawPath);
- });
- });
- });
-
- describe('links section', () => {
- describe('with raw job log path', () => {
- beforeEach(() => {
- createWrapper();
- });
-
- it('renders raw job log link', () => {
- expect(findRawLinkController().attributes('href')).toBe(defaultProps.rawPath);
- });
- });
-
- describe('without raw job log path', () => {
- beforeEach(() => {
- createWrapper({
- rawPath: null,
- });
- });
-
- it('does not render raw job log link', () => {
- expect(findRawLinkController().exists()).toBe(false);
- });
- });
- });
-
- describe('scroll buttons', () => {
- describe('scroll top button', () => {
- describe('when user can scroll top', () => {
- beforeEach(() => {
- createWrapper({
- isScrollTopDisabled: false,
- });
- });
-
- it('emits scrollJobLogTop event on click', async () => {
- await findScrollTop().trigger('click');
-
- expect(wrapper.emitted().scrollJobLogTop).toHaveLength(1);
- });
- });
-
- describe('when user can not scroll top', () => {
- beforeEach(() => {
- createWrapper({
- isScrollTopDisabled: true,
- isScrollBottomDisabled: false,
- isScrollingDown: false,
- });
- });
-
- it('renders disabled scroll top button', () => {
- expect(findScrollTop().attributes('disabled')).toBeDefined();
- });
-
- it('does not emit scrollJobLogTop event on click', async () => {
- await findScrollTop().trigger('click');
-
- expect(wrapper.emitted().scrollJobLogTop).toBeUndefined();
- });
- });
- });
-
- describe('scroll bottom button', () => {
- describe('when user can scroll bottom', () => {
- beforeEach(() => {
- createWrapper();
- });
-
- it('emits scrollJobLogBottom event on click', async () => {
- await findScrollBottom().trigger('click');
-
- expect(wrapper.emitted().scrollJobLogBottom).toHaveLength(1);
- });
- });
-
- describe('when user can not scroll bottom', () => {
- beforeEach(() => {
- createWrapper({
- isScrollTopDisabled: false,
- isScrollBottomDisabled: true,
- isScrollingDown: false,
- });
- });
-
- it('renders disabled scroll bottom button', () => {
- expect(findScrollBottom().attributes('disabled')).toEqual('disabled');
- });
-
- it('does not emit scrollJobLogBottom event on click', async () => {
- await findScrollBottom().trigger('click');
-
- expect(wrapper.emitted().scrollJobLogBottom).toBeUndefined();
- });
- });
-
- describe('while isScrollingDown is true', () => {
- beforeEach(() => {
- createWrapper();
- });
-
- it('renders animate class for the scroll down button', () => {
- expect(findScrollBottom().classes()).toContain('animate');
- });
- });
-
- describe('while isScrollingDown is false', () => {
- beforeEach(() => {
- createWrapper({
- isScrollTopDisabled: true,
- isScrollBottomDisabled: false,
- isScrollingDown: false,
- });
- });
-
- it('does not render animate class for the scroll down button', () => {
- expect(findScrollBottom().classes()).not.toContain('animate');
- });
- });
- });
-
- describe('scroll to failure button', () => {
- describe('with feature flag disabled', () => {
- it('does not display button', () => {
- createWrapper();
-
- expect(findScrollFailure().exists()).toBe(false);
- });
- });
-
- describe('with red text failures on the page', () => {
- let firstFailure;
- let secondFailure;
-
- beforeEach(() => {
- jest.spyOn(document, 'querySelectorAll').mockReturnValueOnce(['mock-element']);
-
- createWrapper({}, { jobLogJumpToFailures: true });
-
- firstFailure = document.createElement('div');
- firstFailure.className = 'term-fg-l-red';
- document.body.appendChild(firstFailure);
-
- secondFailure = document.createElement('div');
- secondFailure.className = 'term-fg-l-red';
- document.body.appendChild(secondFailure);
- });
-
- afterEach(() => {
- if (firstFailure) {
- firstFailure.remove();
- firstFailure = null;
- }
-
- if (secondFailure) {
- secondFailure.remove();
- secondFailure = null;
- }
- });
-
- it('is enabled', () => {
- expect(findScrollFailure().props('disabled')).toBe(false);
- });
-
- it('scrolls to each failure', async () => {
- jest.spyOn(firstFailure, 'scrollIntoView');
-
- await findScrollFailure().trigger('click');
-
- expect(firstFailure.scrollIntoView).toHaveBeenCalled();
-
- await findScrollFailure().trigger('click');
-
- expect(secondFailure.scrollIntoView).toHaveBeenCalled();
-
- await findScrollFailure().trigger('click');
-
- expect(firstFailure.scrollIntoView).toHaveBeenCalled();
- });
- });
-
- describe('with no red text failures on the page', () => {
- beforeEach(() => {
- jest.spyOn(document, 'querySelectorAll').mockReturnValueOnce([]);
-
- createWrapper({}, { jobLogJumpToFailures: true });
- });
-
- it('is disabled', () => {
- expect(findScrollFailure().props('disabled')).toBe(true);
- });
- });
-
- describe('when the job log is not complete', () => {
- beforeEach(() => {
- jest.spyOn(document, 'querySelectorAll').mockReturnValueOnce(['mock-element']);
-
- createWrapper({ isComplete: false }, { jobLogJumpToFailures: true });
- });
-
- it('is enabled', () => {
- expect(findScrollFailure().props('disabled')).toBe(false);
- });
- });
-
- describe('on error', () => {
- beforeEach(() => {
- jest.spyOn(commonUtils, 'backOff').mockRejectedValueOnce();
-
- createWrapper({}, { jobLogJumpToFailures: true });
- });
-
- it('stays disabled', () => {
- expect(findScrollFailure().props('disabled')).toBe(true);
- });
- });
- });
- });
-
- describe('Job log search', () => {
- beforeEach(() => {
- createWrapper();
- });
-
- it('displays job log search', () => {
- expect(findJobLogSearch().exists()).toBe(true);
- expect(findSearchHelp().exists()).toBe(true);
- });
-
- it('emits search results', () => {
- const expectedSearchResults = [[[mockJobLog[6].lines[1], mockJobLog[6].lines[2]]]];
-
- findJobLogSearch().vm.$emit('submit');
-
- expect(wrapper.emitted('searchResults')).toEqual(expectedSearchResults);
- });
-
- it('clears search results', () => {
- findJobLogSearch().vm.$emit('clear');
-
- expect(wrapper.emitted('searchResults')).toEqual([[[]]]);
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/job_retry_forward_deployment_modal_spec.js b/spec/frontend/jobs/components/job/job_retry_forward_deployment_modal_spec.js
deleted file mode 100644
index a44a13259aa..00000000000
--- a/spec/frontend/jobs/components/job/job_retry_forward_deployment_modal_spec.js
+++ /dev/null
@@ -1,67 +0,0 @@
-import { GlLink, GlModal } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import JobRetryForwardDeploymentModal from '~/jobs/components/job/sidebar/job_retry_forward_deployment_modal.vue';
-import { JOB_RETRY_FORWARD_DEPLOYMENT_MODAL } from '~/jobs/constants';
-import createStore from '~/jobs/store';
-import job from '../../mock_data';
-
-describe('Job Retry Forward Deployment Modal', () => {
- let store;
- let wrapper;
-
- const retryOutdatedJobDocsUrl = 'url-to-docs';
- const findLink = () => wrapper.findComponent(GlLink);
- const findModal = () => wrapper.findComponent(GlModal);
-
- const createWrapper = ({ props = {}, provide = {}, stubs = {} } = {}) => {
- store = createStore();
- wrapper = shallowMount(JobRetryForwardDeploymentModal, {
- propsData: {
- modalId: 'modal-id',
- href: job.retry_path,
- ...props,
- },
- provide,
- store,
- stubs,
- });
- };
-
- beforeEach(createWrapper);
-
- describe('Modal configuration', () => {
- it('should display the correct messages', () => {
- const modal = findModal();
- expect(modal.attributes('title')).toMatch(JOB_RETRY_FORWARD_DEPLOYMENT_MODAL.title);
- expect(modal.text()).toMatch(JOB_RETRY_FORWARD_DEPLOYMENT_MODAL.info);
- expect(modal.text()).toMatch(JOB_RETRY_FORWARD_DEPLOYMENT_MODAL.areYouSure);
- });
- });
-
- describe('Modal docs help link', () => {
- it('should not display an info link when none is provided', () => {
- createWrapper();
-
- expect(findLink().exists()).toBe(false);
- });
-
- it('should display an info link when one is provided', () => {
- createWrapper({ provide: { retryOutdatedJobDocsUrl } });
-
- expect(findLink().attributes('href')).toBe(retryOutdatedJobDocsUrl);
- expect(findLink().text()).toMatch(JOB_RETRY_FORWARD_DEPLOYMENT_MODAL.moreInfo);
- });
- });
-
- describe('Modal actions', () => {
- beforeEach(createWrapper);
-
- it('should correctly configure the primary action', () => {
- expect(findModal().props('actionPrimary').attributes).toMatchObject({
- 'data-method': 'post',
- href: job.retry_path,
- variant: 'danger',
- });
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/job_sidebar_details_container_spec.js b/spec/frontend/jobs/components/job/job_sidebar_details_container_spec.js
deleted file mode 100644
index c1028f3929d..00000000000
--- a/spec/frontend/jobs/components/job/job_sidebar_details_container_spec.js
+++ /dev/null
@@ -1,133 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import { extendedWrapper } from 'helpers/vue_test_utils_helper';
-import DetailRow from '~/jobs/components/job/sidebar/sidebar_detail_row.vue';
-import SidebarJobDetailsContainer from '~/jobs/components/job/sidebar/sidebar_job_details_container.vue';
-import createStore from '~/jobs/store';
-import job from '../../mock_data';
-
-describe('Job Sidebar Details Container', () => {
- let store;
- let wrapper;
-
- const findJobTimeout = () => wrapper.findByTestId('job-timeout');
- const findJobTags = () => wrapper.findByTestId('job-tags');
- const findAllDetailsRow = () => wrapper.findAllComponents(DetailRow);
-
- const createWrapper = ({ props = {} } = {}) => {
- store = createStore();
- wrapper = extendedWrapper(
- shallowMount(SidebarJobDetailsContainer, {
- propsData: props,
- store,
- stubs: {
- DetailRow,
- },
- }),
- );
- };
-
- describe('when no details are available', () => {
- beforeEach(() => {
- createWrapper();
- });
-
- it('should render an empty container', () => {
- expect(wrapper.html()).toBe('');
- });
-
- it.each(['duration', 'erased_at', 'finished_at', 'queued_at', 'runner', 'coverage'])(
- 'should not render %s details when missing',
- async (detail) => {
- await store.dispatch('receiveJobSuccess', { [detail]: undefined });
-
- expect(findAllDetailsRow()).toHaveLength(0);
- },
- );
- });
-
- describe('when some of the details are available', () => {
- beforeEach(createWrapper);
-
- it.each([
- ['duration', 'Elapsed time: 6 seconds'],
- ['erased_at', 'Erased: 3 weeks ago'],
- ['finished_at', 'Finished: 3 weeks ago'],
- ['queued_duration', 'Queued: 9 seconds'],
- ['runner', 'Runner: #1 (ABCDEFGH) local ci runner'],
- ['coverage', 'Coverage: 20%'],
- ])('uses %s to render job-%s', async (detail, value) => {
- await store.dispatch('receiveJobSuccess', { [detail]: job[detail] });
- const detailsRow = findAllDetailsRow();
-
- expect(detailsRow).toHaveLength(1);
- expect(detailsRow.at(0).text()).toBe(value);
- });
-
- it('only renders tags', async () => {
- const { tags } = job;
- await store.dispatch('receiveJobSuccess', { tags });
- const tagsComponent = findJobTags();
-
- expect(tagsComponent.text()).toBe('Tags: tag');
- });
- });
-
- describe('when all the info are available', () => {
- it('renders all the details components', async () => {
- createWrapper();
- await store.dispatch('receiveJobSuccess', job);
-
- expect(findAllDetailsRow()).toHaveLength(7);
- });
-
- describe('duration row', () => {
- it('renders all the details components', async () => {
- createWrapper();
- await store.dispatch('receiveJobSuccess', job);
-
- expect(findAllDetailsRow().at(0).text()).toBe('Duration: 6 seconds');
- });
- });
- });
-
- describe('timeout', () => {
- const {
- metadata: { timeout_human_readable, timeout_source },
- } = job;
-
- beforeEach(createWrapper);
-
- it('does not render if metadata is empty', async () => {
- const metadata = {};
- await store.dispatch('receiveJobSuccess', { metadata });
- const detailsRow = findAllDetailsRow();
-
- expect(wrapper.html()).toBe('');
- expect(detailsRow.exists()).toBe(false);
- });
-
- it('uses metadata to render timeout', async () => {
- const metadata = { timeout_human_readable };
- await store.dispatch('receiveJobSuccess', { metadata });
- const detailsRow = findAllDetailsRow();
-
- expect(detailsRow).toHaveLength(1);
- expect(detailsRow.at(0).text()).toBe('Timeout: 1m 40s');
- });
-
- it('uses metadata to render timeout and the source', async () => {
- const metadata = { timeout_human_readable, timeout_source };
- await store.dispatch('receiveJobSuccess', { metadata });
- const detailsRow = findAllDetailsRow();
-
- expect(detailsRow.at(0).text()).toBe('Timeout: 1m 40s (from runner)');
- });
-
- it('should not render when no time is provided', async () => {
- const metadata = { timeout_source };
- await store.dispatch('receiveJobSuccess', { metadata });
-
- expect(findJobTimeout().exists()).toBe(false);
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/job_sidebar_retry_button_spec.js b/spec/frontend/jobs/components/job/job_sidebar_retry_button_spec.js
deleted file mode 100644
index 8a63bfdc3d6..00000000000
--- a/spec/frontend/jobs/components/job/job_sidebar_retry_button_spec.js
+++ /dev/null
@@ -1,64 +0,0 @@
-import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import JobsSidebarRetryButton from '~/jobs/components/job/sidebar/job_sidebar_retry_button.vue';
-import createStore from '~/jobs/store';
-import job from '../../mock_data';
-
-describe('Job Sidebar Retry Button', () => {
- let store;
- let wrapper;
-
- const forwardDeploymentFailure = 'forward_deployment_failure';
- const findRetryButton = () => wrapper.findByTestId('retry-job-button');
- const findRetryLink = () => wrapper.findByTestId('retry-job-link');
-
- const createWrapper = ({ props = {} } = {}) => {
- store = createStore();
- wrapper = shallowMountExtended(JobsSidebarRetryButton, {
- propsData: {
- href: job.retry_path,
- isManualJob: false,
- modalId: 'modal-id',
- ...props,
- },
- store,
- });
- };
-
- beforeEach(createWrapper);
-
- it.each([
- [null, false, true],
- ['unmet_prerequisites', false, true],
- [forwardDeploymentFailure, true, false],
- ])(
- 'when error is: %s, should render button: %s | should render link: %s',
- async (failureReason, buttonExists, linkExists) => {
- await store.dispatch('receiveJobSuccess', { ...job, failure_reason: failureReason });
-
- expect(findRetryButton().exists()).toBe(buttonExists);
- expect(findRetryLink().exists()).toBe(linkExists);
- },
- );
-
- describe('Button', () => {
- it('should have the correct configuration', async () => {
- await store.dispatch('receiveJobSuccess', { failure_reason: forwardDeploymentFailure });
-
- expect(findRetryButton().attributes()).toMatchObject({
- category: 'primary',
- variant: 'confirm',
- icon: 'retry',
- });
- });
- });
-
- describe('Link', () => {
- it('should have the correct configuration', () => {
- expect(findRetryLink().attributes()).toMatchObject({
- 'data-method': 'post',
- href: job.retry_path,
- icon: 'retry',
- });
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/jobs_container_spec.js b/spec/frontend/jobs/components/job/jobs_container_spec.js
deleted file mode 100644
index 05660880751..00000000000
--- a/spec/frontend/jobs/components/job/jobs_container_spec.js
+++ /dev/null
@@ -1,143 +0,0 @@
-import { GlLink } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import { extendedWrapper } from 'helpers/vue_test_utils_helper';
-import JobsContainer from '~/jobs/components/job/sidebar/jobs_container.vue';
-
-describe('Jobs List block', () => {
- let wrapper;
-
- const retried = {
- status: {
- details_path: '/gitlab-org/gitlab-foss/pipelines/28029444',
- group: 'success',
- has_details: true,
- icon: 'status_success',
- label: 'passed',
- text: 'passed',
- tooltip: 'passed',
- },
- id: 233432756,
- tooltip: 'build - passed',
- retried: true,
- };
-
- const active = {
- name: 'test',
- status: {
- details_path: '/gitlab-org/gitlab-foss/pipelines/28029444',
- group: 'success',
- has_details: true,
- icon: 'status_success',
- label: 'passed',
- text: 'passed',
- tooltip: 'passed',
- },
- id: 2322756,
- tooltip: 'build - passed',
- active: true,
- };
-
- const job = {
- name: 'build',
- status: {
- details_path: '/gitlab-org/gitlab-foss/pipelines/28029444',
- group: 'success',
- has_details: true,
- icon: 'status_success',
- label: 'passed',
- text: 'passed',
- tooltip: 'passed',
- },
- id: 232153,
- tooltip: 'build - passed',
- };
-
- const findAllJobs = () => wrapper.findAllComponents(GlLink);
- const findJob = () => findAllJobs().at(0);
-
- const findArrowIcon = () => wrapper.findByTestId('arrow-right-icon');
- const findRetryIcon = () => wrapper.findByTestId('retry-icon');
-
- const createComponent = (props) => {
- wrapper = extendedWrapper(
- mount(JobsContainer, {
- propsData: {
- ...props,
- },
- }),
- );
- };
-
- it('renders a list of jobs', () => {
- createComponent({
- jobs: [job, retried, active],
- jobId: 12313,
- });
-
- expect(findAllJobs()).toHaveLength(3);
- });
-
- it('renders the arrow right icon when job id matches `jobId`', () => {
- createComponent({
- jobs: [active],
- jobId: active.id,
- });
-
- expect(findArrowIcon().exists()).toBe(true);
- });
-
- it('does not render the arrow right icon when the job is not active', () => {
- createComponent({
- jobs: [job],
- jobId: active.id,
- });
-
- expect(findArrowIcon().exists()).toBe(false);
- });
-
- it('renders the job name when present', () => {
- createComponent({
- jobs: [job],
- jobId: active.id,
- });
-
- expect(findJob().text()).toBe(job.name);
- expect(findJob().text()).not.toContain(job.id.toString());
- });
-
- it('renders job id when job name is not available', () => {
- createComponent({
- jobs: [retried],
- jobId: active.id,
- });
-
- expect(findJob().text()).toBe(retried.id.toString());
- });
-
- it('links to the job page', () => {
- createComponent({
- jobs: [job],
- jobId: active.id,
- });
-
- expect(findJob().attributes('href')).toBe(job.status.details_path);
- });
-
- it('renders retry icon when job was retried', () => {
- createComponent({
- jobs: [retried],
- jobId: active.id,
- });
-
- expect(findRetryIcon().exists()).toBe(true);
- });
-
- it('does not render retry icon when job was not retried', () => {
- createComponent({
- jobs: [job],
- jobId: active.id,
- });
-
- expect(findRetryIcon().exists()).toBe(false);
- });
-});
diff --git a/spec/frontend/jobs/components/job/manual_variables_form_spec.js b/spec/frontend/jobs/components/job/manual_variables_form_spec.js
deleted file mode 100644
index 989fe5c11e9..00000000000
--- a/spec/frontend/jobs/components/job/manual_variables_form_spec.js
+++ /dev/null
@@ -1,364 +0,0 @@
-import { GlSprintf, GlLink } from '@gitlab/ui';
-import { createLocalVue } from '@vue/test-utils';
-import VueApollo from 'vue-apollo';
-import { nextTick } from 'vue';
-import { createAlert } from '~/alert';
-import { mountExtended } from 'helpers/vue_test_utils_helper';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import { TYPENAME_CI_BUILD } from '~/graphql_shared/constants';
-import { JOB_GRAPHQL_ERRORS } from '~/jobs/constants';
-import { convertToGraphQLId } from '~/graphql_shared/utils';
-import waitForPromises from 'helpers/wait_for_promises';
-import { redirectTo } from '~/lib/utils/url_utility'; // eslint-disable-line import/no-deprecated
-import ManualVariablesForm from '~/jobs/components/job/manual_variables_form.vue';
-import getJobQuery from '~/jobs/components/job/graphql/queries/get_job.query.graphql';
-import playJobMutation from '~/jobs/components/job/graphql/mutations/job_play_with_variables.mutation.graphql';
-import retryJobMutation from '~/jobs/components/job/graphql/mutations/job_retry_with_variables.mutation.graphql';
-
-import {
- mockFullPath,
- mockId,
- mockJobResponse,
- mockJobWithVariablesResponse,
- mockJobPlayMutationData,
- mockJobRetryMutationData,
-} from './mock_data';
-
-const localVue = createLocalVue();
-jest.mock('~/alert');
-localVue.use(VueApollo);
-
-jest.mock('~/lib/utils/url_utility', () => ({
- ...jest.requireActual('~/lib/utils/url_utility'),
- redirectTo: jest.fn(),
-}));
-
-const defaultProvide = {
- projectPath: mockFullPath,
-};
-
-describe('Manual Variables Form', () => {
- let wrapper;
- let mockApollo;
- let requestHandlers;
-
- const getJobQueryResponseHandlerWithVariables = jest.fn().mockResolvedValue(mockJobResponse);
- const playJobMutationHandler = jest.fn().mockResolvedValue({});
- const retryJobMutationHandler = jest.fn().mockResolvedValue({});
-
- const defaultHandlers = {
- getJobQueryResponseHandlerWithVariables,
- playJobMutationHandler,
- retryJobMutationHandler,
- };
-
- const createComponent = ({ props = {}, handlers = defaultHandlers } = {}) => {
- requestHandlers = handlers;
-
- mockApollo = createMockApollo([
- [getJobQuery, handlers.getJobQueryResponseHandlerWithVariables],
- [playJobMutation, handlers.playJobMutationHandler],
- [retryJobMutation, handlers.retryJobMutationHandler],
- ]);
-
- const options = {
- localVue,
- apolloProvider: mockApollo,
- };
-
- wrapper = mountExtended(ManualVariablesForm, {
- propsData: {
- jobId: mockId,
- isRetryable: false,
- ...props,
- },
- provide: {
- ...defaultProvide,
- },
- ...options,
- });
-
- return waitForPromises();
- };
-
- const findHelpText = () => wrapper.findComponent(GlSprintf);
- const findHelpLink = () => wrapper.findComponent(GlLink);
- const findCancelBtn = () => wrapper.findByTestId('cancel-btn');
- const findRunBtn = () => wrapper.findByTestId('run-manual-job-btn');
- const findDeleteVarBtn = () => wrapper.findByTestId('delete-variable-btn');
- const findAllDeleteVarBtns = () => wrapper.findAllByTestId('delete-variable-btn');
- const findDeleteVarBtnPlaceholder = () => wrapper.findByTestId('delete-variable-btn-placeholder');
- const findCiVariableKey = () => wrapper.findByTestId('ci-variable-key');
- const findAllCiVariableKeys = () => wrapper.findAllByTestId('ci-variable-key');
- const findCiVariableValue = () => wrapper.findByTestId('ci-variable-value');
- const findAllVariables = () => wrapper.findAllByTestId('ci-variable-row');
-
- const setCiVariableKey = () => {
- findCiVariableKey().setValue('new key');
- findCiVariableKey().vm.$emit('change');
- nextTick();
- };
-
- const setCiVariableKeyByPosition = (position, value) => {
- findAllCiVariableKeys().at(position).setValue(value);
- findAllCiVariableKeys().at(position).vm.$emit('change');
- nextTick();
- };
-
- afterEach(() => {
- createAlert.mockClear();
- });
-
- describe('when page renders', () => {
- beforeEach(async () => {
- await createComponent();
- });
-
- it('renders help text with provided link', () => {
- expect(findHelpText().exists()).toBe(true);
- expect(findHelpLink().attributes('href')).toBe(
- '/help/ci/variables/index#add-a-cicd-variable-to-a-project',
- );
- });
- });
-
- describe('when query is unsuccessful', () => {
- beforeEach(async () => {
- await createComponent({
- handlers: {
- getJobQueryResponseHandlerWithVariables: jest.fn().mockRejectedValue({}),
- },
- });
- });
-
- it('shows an alert with error', () => {
- expect(createAlert).toHaveBeenCalledWith({
- message: JOB_GRAPHQL_ERRORS.jobQueryErrorText,
- });
- });
- });
-
- describe('when job has not been retried', () => {
- beforeEach(async () => {
- await createComponent({
- handlers: {
- getJobQueryResponseHandlerWithVariables: jest
- .fn()
- .mockResolvedValue(mockJobWithVariablesResponse),
- },
- });
- });
-
- it('does not render the cancel button', () => {
- expect(findCancelBtn().exists()).toBe(false);
- expect(findRunBtn().exists()).toBe(true);
- });
- });
-
- describe('when job has variables', () => {
- beforeEach(async () => {
- await createComponent({
- handlers: {
- getJobQueryResponseHandlerWithVariables: jest
- .fn()
- .mockResolvedValue(mockJobWithVariablesResponse),
- },
- });
- });
-
- it('sets manual job variables', () => {
- const queryKey = mockJobWithVariablesResponse.data.project.job.manualVariables.nodes[0].key;
- const queryValue =
- mockJobWithVariablesResponse.data.project.job.manualVariables.nodes[0].value;
-
- expect(findCiVariableKey().element.value).toBe(queryKey);
- expect(findCiVariableValue().element.value).toBe(queryValue);
- });
- });
-
- describe('when play mutation fires', () => {
- beforeEach(async () => {
- await createComponent({
- handlers: {
- playJobMutationHandler: jest.fn().mockResolvedValue(mockJobPlayMutationData),
- },
- });
- });
-
- it('passes variables in correct format', async () => {
- await setCiVariableKey();
-
- await findCiVariableValue().setValue('new value');
-
- await findRunBtn().vm.$emit('click');
-
- expect(requestHandlers.playJobMutationHandler).toHaveBeenCalledTimes(1);
- expect(requestHandlers.playJobMutationHandler).toHaveBeenCalledWith({
- id: convertToGraphQLId(TYPENAME_CI_BUILD, mockId),
- variables: [
- {
- key: 'new key',
- value: 'new value',
- },
- ],
- });
- });
-
- it('redirects to job properly after job is run', async () => {
- findRunBtn().vm.$emit('click');
- await waitForPromises();
-
- expect(requestHandlers.playJobMutationHandler).toHaveBeenCalledTimes(1);
- expect(redirectTo).toHaveBeenCalledWith(mockJobPlayMutationData.data.jobPlay.job.webPath); // eslint-disable-line import/no-deprecated
- });
- });
-
- describe('when play mutation is unsuccessful', () => {
- beforeEach(async () => {
- await createComponent({
- handlers: {
- playJobMutationHandler: jest.fn().mockRejectedValue({}),
- },
- });
- });
-
- it('shows an alert with error', async () => {
- findRunBtn().vm.$emit('click');
- await waitForPromises();
-
- expect(createAlert).toHaveBeenCalledWith({
- message: JOB_GRAPHQL_ERRORS.jobMutationErrorText,
- });
- });
- });
-
- describe('when job is retryable', () => {
- beforeEach(async () => {
- await createComponent({
- props: { isRetryable: true },
- handlers: {
- retryJobMutationHandler: jest.fn().mockResolvedValue(mockJobRetryMutationData),
- },
- });
- });
-
- it('renders cancel button', () => {
- expect(findCancelBtn().exists()).toBe(true);
- });
-
- it('redirects to job properly after rerun', async () => {
- findRunBtn().vm.$emit('click');
- await waitForPromises();
-
- expect(requestHandlers.retryJobMutationHandler).toHaveBeenCalledTimes(1);
- expect(redirectTo).toHaveBeenCalledWith(mockJobRetryMutationData.data.jobRetry.job.webPath); // eslint-disable-line import/no-deprecated
- });
- });
-
- describe('when retry mutation is unsuccessful', () => {
- beforeEach(async () => {
- await createComponent({
- props: { isRetryable: true },
- handlers: {
- retryJobMutationHandler: jest.fn().mockRejectedValue({}),
- },
- });
- });
-
- it('shows an alert with error', async () => {
- findRunBtn().vm.$emit('click');
- await waitForPromises();
-
- expect(createAlert).toHaveBeenCalledWith({
- message: JOB_GRAPHQL_ERRORS.jobMutationErrorText,
- });
- });
- });
-
- describe('updating variables in UI', () => {
- beforeEach(async () => {
- await createComponent({
- handlers: {
- getJobQueryResponseHandlerWithVariables: jest.fn().mockResolvedValue(mockJobResponse),
- },
- });
- });
-
- it('creates a new variable when user enters a new key value', async () => {
- expect(findAllVariables()).toHaveLength(1);
-
- await setCiVariableKey();
-
- expect(findAllVariables()).toHaveLength(2);
- });
-
- it('does not create extra empty variables', async () => {
- expect(findAllVariables()).toHaveLength(1);
-
- await setCiVariableKey();
-
- expect(findAllVariables()).toHaveLength(2);
-
- await setCiVariableKey();
-
- expect(findAllVariables()).toHaveLength(2);
- });
-
- it('removes the correct variable row', async () => {
- const variableKeyNameOne = 'key-one';
- const variableKeyNameThree = 'key-three';
-
- await setCiVariableKeyByPosition(0, variableKeyNameOne);
-
- await setCiVariableKeyByPosition(1, 'key-two');
-
- await setCiVariableKeyByPosition(2, variableKeyNameThree);
-
- expect(findAllVariables()).toHaveLength(4);
-
- await findAllDeleteVarBtns().at(1).trigger('click');
-
- expect(findAllVariables()).toHaveLength(3);
-
- expect(findAllCiVariableKeys().at(0).element.value).toBe(variableKeyNameOne);
- expect(findAllCiVariableKeys().at(1).element.value).toBe(variableKeyNameThree);
- expect(findAllCiVariableKeys().at(2).element.value).toBe('');
- });
-
- it('delete variable button should only show when there is more than one variable', async () => {
- expect(findDeleteVarBtn().exists()).toBe(false);
-
- await setCiVariableKey();
-
- expect(findDeleteVarBtn().exists()).toBe(true);
- });
- });
-
- describe('variable delete button placeholder', () => {
- beforeEach(async () => {
- await createComponent({
- handlers: {
- getJobQueryResponseHandlerWithVariables: jest.fn().mockResolvedValue(mockJobResponse),
- },
- });
- });
-
- it('delete variable button placeholder should only exist when a user cannot remove', () => {
- expect(findDeleteVarBtnPlaceholder().exists()).toBe(true);
- });
-
- it('does not show the placeholder button', () => {
- expect(findDeleteVarBtnPlaceholder().classes('gl-opacity-0')).toBe(true);
- });
-
- it('placeholder button will not delete the row on click', async () => {
- expect(findAllCiVariableKeys()).toHaveLength(1);
- expect(findDeleteVarBtnPlaceholder().exists()).toBe(true);
-
- await findDeleteVarBtnPlaceholder().trigger('click');
-
- expect(findAllCiVariableKeys()).toHaveLength(1);
- expect(findDeleteVarBtnPlaceholder().exists()).toBe(true);
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/mock_data.js b/spec/frontend/jobs/components/job/mock_data.js
deleted file mode 100644
index fb3a361c9c9..00000000000
--- a/spec/frontend/jobs/components/job/mock_data.js
+++ /dev/null
@@ -1,123 +0,0 @@
-export const mockFullPath = 'Commit451/lab-coat';
-export const mockId = 401;
-
-export const mockJobResponse = {
- data: {
- project: {
- id: 'gid://gitlab/Project/4',
- job: {
- id: 'gid://gitlab/Ci::Build/401',
- manualJob: true,
- manualVariables: {
- nodes: [],
- __typename: 'CiManualVariableConnection',
- },
- name: 'manual_job',
- retryable: true,
- status: 'SUCCESS',
- __typename: 'CiJob',
- },
- __typename: 'Project',
- },
- },
-};
-
-export const mockJobWithVariablesResponse = {
- data: {
- project: {
- id: 'gid://gitlab/Project/4',
- job: {
- id: 'gid://gitlab/Ci::Build/401',
- manualJob: true,
- manualVariables: {
- nodes: [
- {
- id: 'gid://gitlab/Ci::JobVariable/150',
- key: 'new key',
- value: 'new value',
- __typename: 'CiManualVariable',
- },
- ],
- __typename: 'CiManualVariableConnection',
- },
- name: 'manual_job',
- retryable: true,
- status: 'SUCCESS',
- __typename: 'CiJob',
- },
- __typename: 'Project',
- },
- },
-};
-
-export const mockJobPlayMutationData = {
- data: {
- jobPlay: {
- job: {
- id: 'gid://gitlab/Ci::Build/401',
- manualVariables: {
- nodes: [
- {
- id: 'gid://gitlab/Ci::JobVariable/151',
- key: 'new key',
- value: 'new value',
- __typename: 'CiManualVariable',
- },
- ],
- __typename: 'CiManualVariableConnection',
- },
- webPath: '/Commit451/lab-coat/-/jobs/401',
- __typename: 'CiJob',
- },
- errors: [],
- __typename: 'JobPlayPayload',
- },
- },
-};
-
-export const mockJobRetryMutationData = {
- data: {
- jobRetry: {
- job: {
- id: 'gid://gitlab/Ci::Build/401',
- manualVariables: {
- nodes: [
- {
- id: 'gid://gitlab/Ci::JobVariable/151',
- key: 'new key',
- value: 'new value',
- __typename: 'CiManualVariable',
- },
- ],
- __typename: 'CiManualVariableConnection',
- },
- webPath: '/Commit451/lab-coat/-/jobs/401',
- __typename: 'CiJob',
- },
- errors: [],
- __typename: 'JobRetryPayload',
- },
- },
-};
-
-export const mockPendingJobData = {
- has_trace: false,
- status: {
- group: 'pending',
- icon: 'status_pending',
- label: 'pending',
- text: 'pending',
- details_path: 'path',
- illustration: {
- image: 'path',
- size: '340',
- title: '',
- content: '',
- },
- action: {
- button_title: 'Retry job',
- method: 'post',
- path: '/path',
- },
- },
-};
diff --git a/spec/frontend/jobs/components/job/sidebar_detail_row_spec.js b/spec/frontend/jobs/components/job/sidebar_detail_row_spec.js
deleted file mode 100644
index 546f5392caf..00000000000
--- a/spec/frontend/jobs/components/job/sidebar_detail_row_spec.js
+++ /dev/null
@@ -1,68 +0,0 @@
-import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import SidebarDetailRow from '~/jobs/components/job/sidebar/sidebar_detail_row.vue';
-import { DOCS_URL } from 'jh_else_ce/lib/utils/url_utility';
-
-describe('Sidebar detail row', () => {
- let wrapper;
-
- const title = 'this is the title';
- const value = 'this is the value';
- const helpUrl = `${DOCS_URL}/runner/register/index.html`;
- const path = 'path/to/value';
-
- const findHelpLink = () => wrapper.findByTestId('job-sidebar-help-link');
- const findValueLink = () => wrapper.findByTestId('job-sidebar-value-link');
-
- const createComponent = (props) => {
- wrapper = shallowMountExtended(SidebarDetailRow, {
- propsData: {
- ...props,
- },
- });
- };
-
- describe('with title/value and without helpUrl/path', () => {
- beforeEach(() => {
- createComponent({ title, value });
- });
-
- it('should render the provided title and value', () => {
- expect(wrapper.text()).toBe(`${title}: ${value}`);
- });
-
- it('should not render the help link', () => {
- expect(findHelpLink().exists()).toBe(false);
- });
-
- it('should not render the value link', () => {
- expect(findValueLink().exists()).toBe(false);
- });
- });
-
- describe('when helpUrl provided', () => {
- beforeEach(() => {
- createComponent({
- helpUrl,
- title,
- value,
- });
- });
-
- it('should render the help link', () => {
- expect(findHelpLink().exists()).toBe(true);
- expect(findHelpLink().attributes('href')).toBe(helpUrl);
- });
- });
-
- describe('when path is provided', () => {
- it('should render link to value', () => {
- createComponent({
- path,
- title,
- value,
- });
-
- expect(findValueLink().attributes('href')).toBe(path);
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/sidebar_header_spec.js b/spec/frontend/jobs/components/job/sidebar_header_spec.js
deleted file mode 100644
index cf182330578..00000000000
--- a/spec/frontend/jobs/components/job/sidebar_header_spec.js
+++ /dev/null
@@ -1,87 +0,0 @@
-import Vue from 'vue';
-import VueApollo from 'vue-apollo';
-import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import waitForPromises from 'helpers/wait_for_promises';
-import SidebarHeader from '~/jobs/components/job/sidebar/sidebar_header.vue';
-import JobRetryButton from '~/jobs/components/job/sidebar/job_sidebar_retry_button.vue';
-import getJobQuery from '~/jobs/components/job/graphql/queries/get_job.query.graphql';
-import { mockFullPath, mockId, mockJobResponse } from './mock_data';
-
-Vue.use(VueApollo);
-
-const defaultProvide = {
- projectPath: mockFullPath,
-};
-
-describe('Sidebar Header', () => {
- let wrapper;
-
- const createComponent = ({ options = {}, props = {}, restJob = {} } = {}) => {
- wrapper = shallowMountExtended(SidebarHeader, {
- propsData: {
- ...props,
- jobId: mockId,
- restJob,
- },
- provide: {
- ...defaultProvide,
- },
- ...options,
- });
- };
-
- const createComponentWithApollo = ({ props = {}, restJob = {} } = {}) => {
- const getJobQueryResponse = jest.fn().mockResolvedValue(mockJobResponse);
-
- const requestHandlers = [[getJobQuery, getJobQueryResponse]];
-
- const apolloProvider = createMockApollo(requestHandlers);
-
- const options = {
- apolloProvider,
- };
-
- createComponent({
- props,
- restJob,
- options,
- });
-
- return waitForPromises();
- };
-
- const findCancelButton = () => wrapper.findByTestId('cancel-button');
- const findEraseButton = () => wrapper.findByTestId('job-log-erase-link');
- const findJobName = () => wrapper.findByTestId('job-name');
- const findRetryButton = () => wrapper.findComponent(JobRetryButton);
-
- describe('when rendering contents', () => {
- it('renders the correct job name', async () => {
- await createComponentWithApollo();
- expect(findJobName().text()).toBe(mockJobResponse.data.project.job.name);
- });
-
- it('does not render buttons with no paths', async () => {
- await createComponentWithApollo();
- expect(findCancelButton().exists()).toBe(false);
- expect(findEraseButton().exists()).toBe(false);
- expect(findRetryButton().exists()).toBe(false);
- });
-
- it('renders a retry button with a path', async () => {
- await createComponentWithApollo({ restJob: { retry_path: 'retry/path' } });
- expect(findRetryButton().exists()).toBe(true);
- });
-
- it('renders a cancel button with a path', async () => {
- await createComponentWithApollo({ restJob: { cancel_path: 'cancel/path' } });
- expect(findCancelButton().exists()).toBe(true);
- });
-
- it('renders an erase button with a path', async () => {
- await createComponentWithApollo({ restJob: { erase_path: 'erase/path' } });
- expect(findEraseButton().exists()).toBe(true);
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/sidebar_spec.js b/spec/frontend/jobs/components/job/sidebar_spec.js
deleted file mode 100644
index fbff64b4d78..00000000000
--- a/spec/frontend/jobs/components/job/sidebar_spec.js
+++ /dev/null
@@ -1,216 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import { nextTick } from 'vue';
-import MockAdapter from 'axios-mock-adapter';
-import { extendedWrapper } from 'helpers/vue_test_utils_helper';
-import axios from '~/lib/utils/axios_utils';
-import { HTTP_STATUS_OK } from '~/lib/utils/http_status';
-import ArtifactsBlock from '~/jobs/components/job/sidebar/artifacts_block.vue';
-import JobRetryForwardDeploymentModal from '~/jobs/components/job/sidebar/job_retry_forward_deployment_modal.vue';
-import JobsContainer from '~/jobs/components/job/sidebar/jobs_container.vue';
-import Sidebar from '~/jobs/components/job/sidebar/sidebar.vue';
-import StagesDropdown from '~/jobs/components/job/sidebar/stages_dropdown.vue';
-import createStore from '~/jobs/store';
-import job, { jobsInStage } from '../../mock_data';
-
-describe('Sidebar details block', () => {
- let mock;
- let store;
- let wrapper;
-
- const forwardDeploymentFailure = 'forward_deployment_failure';
- const findModal = () => wrapper.findComponent(JobRetryForwardDeploymentModal);
- const findArtifactsBlock = () => wrapper.findComponent(ArtifactsBlock);
- const findNewIssueButton = () => wrapper.findByTestId('job-new-issue');
- const findTerminalLink = () => wrapper.findByTestId('terminal-link');
- const findJobStagesDropdown = () => wrapper.findComponent(StagesDropdown);
- const findJobsContainer = () => wrapper.findComponent(JobsContainer);
-
- const createWrapper = (props) => {
- store = createStore();
-
- store.state.job = job;
-
- wrapper = extendedWrapper(
- shallowMount(Sidebar, {
- propsData: {
- ...props,
- },
-
- store,
- }),
- );
- };
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
- mock.onGet().reply(HTTP_STATUS_OK, {
- name: job.stage,
- });
- });
-
- describe('without terminal path', () => {
- it('does not render terminal link', async () => {
- createWrapper();
- await store.dispatch('receiveJobSuccess', job);
-
- expect(findTerminalLink().exists()).toBe(false);
- });
- });
-
- describe('with terminal path', () => {
- it('renders terminal link', async () => {
- createWrapper();
- await store.dispatch('receiveJobSuccess', { ...job, terminal_path: 'job/43123/terminal' });
-
- expect(findTerminalLink().exists()).toBe(true);
- });
- });
-
- describe('actions', () => {
- beforeEach(() => {
- createWrapper();
- return store.dispatch('receiveJobSuccess', job);
- });
-
- it('should render link to new issue', () => {
- expect(findNewIssueButton().attributes('href')).toBe(job.new_issue_path);
- expect(findNewIssueButton().text()).toBe('New issue');
- });
- });
-
- describe('forward deployment failure', () => {
- describe('when the relevant data is missing', () => {
- it.each`
- retryPath | failureReason
- ${null} | ${null}
- ${''} | ${''}
- ${job.retry_path} | ${''}
- ${''} | ${forwardDeploymentFailure}
- ${job.retry_path} | ${'unmet_prerequisites'}
- `(
- 'should not render the modal when path and failure are $retryPath, $failureReason',
- async ({ retryPath, failureReason }) => {
- createWrapper();
- await store.dispatch('receiveJobSuccess', {
- ...job,
- failure_reason: failureReason,
- retry_path: retryPath,
- });
- expect(findModal().exists()).toBe(false);
- },
- );
- });
-
- describe('when there is the relevant error', () => {
- beforeEach(() => {
- createWrapper();
- return store.dispatch('receiveJobSuccess', {
- ...job,
- failure_reason: forwardDeploymentFailure,
- });
- });
-
- it('should render the modal', () => {
- expect(findModal().exists()).toBe(true);
- });
- });
- });
-
- describe('stages dropdown', () => {
- beforeEach(() => {
- createWrapper();
- return store.dispatch('receiveJobSuccess', job);
- });
-
- describe('with stages', () => {
- it('renders value provided as selectedStage as selected', () => {
- expect(findJobStagesDropdown().props('selectedStage')).toBe(job.stage);
- });
- });
-
- describe('without jobs for stages', () => {
- it('does not render jobs container', () => {
- expect(findJobsContainer().exists()).toBe(false);
- });
- });
-
- describe('with jobs for stages', () => {
- beforeEach(() => {
- return store.dispatch('receiveJobsForStageSuccess', jobsInStage.latest_statuses);
- });
-
- it('renders list of jobs', () => {
- expect(findJobsContainer().exists()).toBe(true);
- });
- });
-
- describe('when job data changes', () => {
- const stageArg = job.pipeline.details.stages.find((stage) => stage.name === job.stage);
-
- beforeEach(() => {
- jest.spyOn(store, 'dispatch');
- });
-
- describe('and the job stage is currently selected', () => {
- describe('when the status changed', () => {
- it('refetch the jobs list for the stage', async () => {
- await store.dispatch('receiveJobSuccess', { ...job, status: 'new' });
-
- expect(store.dispatch).toHaveBeenNthCalledWith(2, 'fetchJobsForStage', { ...stageArg });
- });
- });
-
- describe('when the status did not change', () => {
- it('does not refetch the jobs list for the stage', async () => {
- await store.dispatch('receiveJobSuccess', { ...job });
-
- expect(store.dispatch).toHaveBeenCalledTimes(1);
- expect(store.dispatch).toHaveBeenNthCalledWith(1, 'receiveJobSuccess', {
- ...job,
- });
- });
- });
- });
-
- describe('and the job stage is not currently selected', () => {
- it('does not refetch the jobs list for the stage', async () => {
- // Setting stage to `random` on the job means that we are looking
- // at `build` stage currently, but the job we are seeing in the logs
- // belong to `random`, so we shouldn't have to refetch
- await store.dispatch('receiveJobSuccess', { ...job, stage: 'random' });
-
- expect(store.dispatch).toHaveBeenCalledTimes(1);
- expect(store.dispatch).toHaveBeenNthCalledWith(1, 'receiveJobSuccess', {
- ...job,
- stage: 'random',
- });
- });
- });
- });
- });
-
- describe('artifacts', () => {
- beforeEach(() => {
- createWrapper();
- });
-
- it('artifacts are not shown if there are no properties other than locked', () => {
- expect(findArtifactsBlock().exists()).toBe(false);
- });
-
- it('artifacts are shown if present', async () => {
- store.state.job.artifact = {
- download_path: '/root/ci-project/-/jobs/1960/artifacts/download',
- browse_path: '/root/ci-project/-/jobs/1960/artifacts/browse',
- keep_path: '/root/ci-project/-/jobs/1960/artifacts/keep',
- expire_at: '2021-03-23T17:57:11.211Z',
- expired: false,
- locked: false,
- };
-
- await nextTick();
-
- expect(findArtifactsBlock().exists()).toBe(true);
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/stages_dropdown_spec.js b/spec/frontend/jobs/components/job/stages_dropdown_spec.js
deleted file mode 100644
index c42edc62183..00000000000
--- a/spec/frontend/jobs/components/job/stages_dropdown_spec.js
+++ /dev/null
@@ -1,191 +0,0 @@
-import { GlDisclosureDropdown, GlLink, GlSprintf } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import { Mousetrap } from '~/lib/mousetrap';
-import { extendedWrapper } from 'helpers/vue_test_utils_helper';
-import StagesDropdown from '~/jobs/components/job/sidebar/stages_dropdown.vue';
-import CiIcon from '~/vue_shared/components/ci_icon.vue';
-import * as copyToClipboard from '~/behaviors/copy_to_clipboard';
-import {
- mockPipelineWithoutRef,
- mockPipelineWithoutMR,
- mockPipelineWithAttachedMR,
- mockPipelineDetached,
-} from '../../mock_data';
-
-describe('Stages Dropdown', () => {
- let wrapper;
-
- const findStatus = () => wrapper.findComponent(CiIcon);
- const findDropdown = () => wrapper.findComponent(GlDisclosureDropdown);
- const findSelectedStageText = () => findDropdown().props('toggleText');
-
- const findPipelineInfoText = () => wrapper.findByTestId('pipeline-info').text();
-
- const createComponent = (props) => {
- wrapper = extendedWrapper(
- shallowMount(StagesDropdown, {
- propsData: {
- stages: [],
- selectedStage: 'deploy',
- ...props,
- },
- stubs: {
- GlSprintf,
- GlLink,
- },
- }),
- );
- };
-
- describe('without a merge request pipeline', () => {
- beforeEach(() => {
- createComponent({
- pipeline: mockPipelineWithoutMR,
- stages: [{ name: 'build' }, { name: 'test' }],
- });
- });
-
- it('renders pipeline status', () => {
- expect(findStatus().exists()).toBe(true);
- });
-
- it('renders dropdown with stages', () => {
- expect(findDropdown().props('items')).toEqual([
- expect.objectContaining({ text: 'build' }),
- expect.objectContaining({ text: 'test' }),
- ]);
- });
-
- it('renders selected stage', () => {
- expect(findSelectedStageText()).toBe('deploy');
- });
- });
-
- describe('pipelineInfo', () => {
- const allElements = [
- 'pipeline-path',
- 'mr-link',
- 'source-ref-link',
- 'copy-source-ref-link',
- 'source-branch-link',
- 'copy-source-branch-link',
- 'target-branch-link',
- 'copy-target-branch-link',
- ];
- describe.each([
- [
- 'does not have a ref',
- {
- pipeline: mockPipelineWithoutRef,
- text: `Pipeline #${mockPipelineWithoutRef.id}`,
- foundElements: [
- { testId: 'pipeline-path', props: [{ href: mockPipelineWithoutRef.path }] },
- ],
- },
- ],
- [
- 'hasRef but not triggered by MR',
- {
- pipeline: mockPipelineWithoutMR,
- text: `Pipeline #${mockPipelineWithoutMR.id} for ${mockPipelineWithoutMR.ref.name}`,
- foundElements: [
- { testId: 'pipeline-path', props: [{ href: mockPipelineWithoutMR.path }] },
- { testId: 'source-ref-link', props: [{ href: mockPipelineWithoutMR.ref.path }] },
- { testId: 'copy-source-ref-link', props: [{ text: mockPipelineWithoutMR.ref.name }] },
- ],
- },
- ],
- [
- 'hasRef and MR but not MR pipeline',
- {
- pipeline: mockPipelineDetached,
- text: `Pipeline #${mockPipelineDetached.id} for !${mockPipelineDetached.merge_request.iid} with ${mockPipelineDetached.merge_request.source_branch}`,
- foundElements: [
- { testId: 'pipeline-path', props: [{ href: mockPipelineDetached.path }] },
- { testId: 'mr-link', props: [{ href: mockPipelineDetached.merge_request.path }] },
- {
- testId: 'source-branch-link',
- props: [{ href: mockPipelineDetached.merge_request.source_branch_path }],
- },
- {
- testId: 'copy-source-branch-link',
- props: [{ text: mockPipelineDetached.merge_request.source_branch }],
- },
- ],
- },
- ],
- [
- 'hasRef and MR and MR pipeline',
- {
- pipeline: mockPipelineWithAttachedMR,
- text: `Pipeline #${mockPipelineWithAttachedMR.id} for !${mockPipelineWithAttachedMR.merge_request.iid} with ${mockPipelineWithAttachedMR.merge_request.source_branch} into ${mockPipelineWithAttachedMR.merge_request.target_branch}`,
- foundElements: [
- { testId: 'pipeline-path', props: [{ href: mockPipelineWithAttachedMR.path }] },
- { testId: 'mr-link', props: [{ href: mockPipelineWithAttachedMR.merge_request.path }] },
- {
- testId: 'source-branch-link',
- props: [{ href: mockPipelineWithAttachedMR.merge_request.source_branch_path }],
- },
- {
- testId: 'copy-source-branch-link',
- props: [{ text: mockPipelineWithAttachedMR.merge_request.source_branch }],
- },
- {
- testId: 'target-branch-link',
- props: [{ href: mockPipelineWithAttachedMR.merge_request.target_branch_path }],
- },
- {
- testId: 'copy-target-branch-link',
- props: [{ text: mockPipelineWithAttachedMR.merge_request.target_branch }],
- },
- ],
- },
- ],
- ])('%s', (_, { pipeline, text, foundElements }) => {
- beforeEach(() => {
- createComponent({
- pipeline,
- });
- });
-
- it('should render the text', () => {
- expect(findPipelineInfoText()).toMatchInterpolatedText(text);
- });
-
- it('should find components with props', () => {
- foundElements.forEach((element) => {
- element.props.forEach((prop) => {
- const key = Object.keys(prop)[0];
- expect(wrapper.findByTestId(element.testId).attributes(key)).toBe(prop[key]);
- });
- });
- });
-
- it('should not find components', () => {
- const foundTestIds = foundElements.map((element) => element.testId);
- allElements
- .filter((testId) => !foundTestIds.includes(testId))
- .forEach((testId) => {
- expect(wrapper.findByTestId(testId).exists()).toBe(false);
- });
- });
- });
- });
-
- describe('mousetrap', () => {
- it.each([
- ['copy-source-ref-link', mockPipelineWithoutMR],
- ['copy-source-branch-link', mockPipelineWithAttachedMR],
- ])(
- 'calls clickCopyToClipboardButton with `%s` button when `b` is pressed',
- (button, pipeline) => {
- const copyToClipboardMock = jest.spyOn(copyToClipboard, 'clickCopyToClipboardButton');
- createComponent({ pipeline });
-
- Mousetrap.trigger('b');
-
- expect(copyToClipboardMock).toHaveBeenCalledWith(wrapper.findByTestId(button).element);
- },
- );
- });
-});
diff --git a/spec/frontend/jobs/components/job/stuck_block_spec.js b/spec/frontend/jobs/components/job/stuck_block_spec.js
deleted file mode 100644
index 0f014a9222b..00000000000
--- a/spec/frontend/jobs/components/job/stuck_block_spec.js
+++ /dev/null
@@ -1,94 +0,0 @@
-import { GlBadge, GlLink } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import StuckBlock from '~/jobs/components/job/stuck_block.vue';
-
-describe('Stuck Block Job component', () => {
- let wrapper;
-
- const createWrapper = (props) => {
- wrapper = shallowMount(StuckBlock, {
- propsData: {
- ...props,
- },
- });
- };
-
- const tags = ['docker', 'gitlab-org'];
-
- const findStuckNoActiveRunners = () =>
- wrapper.find('[data-testid="job-stuck-no-active-runners"]');
- const findStuckNoRunners = () => wrapper.find('[data-testid="job-stuck-no-runners"]');
- const findStuckWithTags = () => wrapper.find('[data-testid="job-stuck-with-tags"]');
- const findRunnerPathLink = () => wrapper.findComponent(GlLink);
- const findAllBadges = () => wrapper.findAllComponents(GlBadge);
-
- describe('with no runners for project', () => {
- beforeEach(() => {
- createWrapper({
- hasOfflineRunnersForProject: true,
- runnersPath: '/root/project/runners#js-runners-settings',
- });
- });
-
- it('renders only information about project not having runners', () => {
- expect(findStuckNoRunners().exists()).toBe(true);
- expect(findStuckWithTags().exists()).toBe(false);
- expect(findStuckNoActiveRunners().exists()).toBe(false);
- });
-
- it('renders link to runners page', () => {
- expect(findRunnerPathLink().attributes('href')).toBe(
- '/root/project/runners#js-runners-settings',
- );
- });
- });
-
- describe('with tags', () => {
- beforeEach(() => {
- createWrapper({
- hasOfflineRunnersForProject: false,
- tags,
- runnersPath: '/root/project/runners#js-runners-settings',
- });
- });
-
- it('renders information about the tags not being set', () => {
- expect(findStuckWithTags().exists()).toBe(true);
- expect(findStuckNoActiveRunners().exists()).toBe(false);
- expect(findStuckNoRunners().exists()).toBe(false);
- });
-
- it('renders tags', () => {
- findAllBadges().wrappers.forEach((badgeElt, index) => {
- return expect(badgeElt.text()).toBe(tags[index]);
- });
- });
-
- it('renders link to runners page', () => {
- expect(findRunnerPathLink().attributes('href')).toBe(
- '/root/project/runners#js-runners-settings',
- );
- });
- });
-
- describe('without active runners', () => {
- beforeEach(() => {
- createWrapper({
- hasOfflineRunnersForProject: false,
- runnersPath: '/root/project/runners#js-runners-settings',
- });
- });
-
- it('renders information about project not having runners', () => {
- expect(findStuckNoActiveRunners().exists()).toBe(true);
- expect(findStuckNoRunners().exists()).toBe(false);
- expect(findStuckWithTags().exists()).toBe(false);
- });
-
- it('renders link to runners page', () => {
- expect(findRunnerPathLink().attributes('href')).toBe(
- '/root/project/runners#js-runners-settings',
- );
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/trigger_block_spec.js b/spec/frontend/jobs/components/job/trigger_block_spec.js
deleted file mode 100644
index 8bb2c1f3ad8..00000000000
--- a/spec/frontend/jobs/components/job/trigger_block_spec.js
+++ /dev/null
@@ -1,81 +0,0 @@
-import { GlButton, GlTableLite } from '@gitlab/ui';
-import { mount } from '@vue/test-utils';
-import TriggerBlock from '~/jobs/components/job/sidebar/trigger_block.vue';
-
-describe('Trigger block', () => {
- let wrapper;
-
- const findRevealButton = () => wrapper.findComponent(GlButton);
- const findVariableTable = () => wrapper.findComponent(GlTableLite);
- const findShortToken = () => wrapper.find('[data-testid="trigger-short-token"]');
- const findVariableValue = (index) =>
- wrapper.findAll('[data-testid="trigger-build-value"]').at(index);
- const findVariableKey = (index) => wrapper.findAll('[data-testid="trigger-build-key"]').at(index);
-
- const createComponent = (props) => {
- wrapper = mount(TriggerBlock, {
- propsData: {
- ...props,
- },
- });
- };
-
- describe('with short token and no variables', () => {
- it('renders short token', () => {
- createComponent({
- trigger: {
- short_token: '0a666b2',
- variables: [],
- },
- });
-
- expect(findShortToken().text()).toContain('0a666b2');
- });
- });
-
- describe('without variables or short token', () => {
- beforeEach(() => {
- createComponent({ trigger: { variables: [] } });
- });
-
- it('does not render short token', () => {
- expect(findShortToken().exists()).toBe(false);
- });
-
- it('does not render variables', () => {
- expect(findRevealButton().exists()).toBe(false);
- expect(findVariableTable().exists()).toBe(false);
- });
- });
-
- describe('with variables', () => {
- describe('hide/reveal variables', () => {
- it('should toggle variables on click', async () => {
- const hiddenValue = '••••••';
- const gcsVar = { key: 'UPLOAD_TO_GCS', value: 'false', public: false };
- const s3Var = { key: 'UPLOAD_TO_S3', value: 'true', public: false };
-
- createComponent({
- trigger: {
- variables: [gcsVar, s3Var],
- },
- });
-
- expect(findRevealButton().text()).toBe('Reveal values');
-
- expect(findVariableValue(0).text()).toBe(hiddenValue);
- expect(findVariableValue(1).text()).toBe(hiddenValue);
-
- expect(findVariableKey(0).text()).toBe(gcsVar.key);
- expect(findVariableKey(1).text()).toBe(s3Var.key);
-
- await findRevealButton().trigger('click');
-
- expect(findRevealButton().text()).toBe('Hide values');
-
- expect(findVariableValue(0).text()).toBe(gcsVar.value);
- expect(findVariableValue(1).text()).toBe(s3Var.value);
- });
- });
- });
-});
diff --git a/spec/frontend/jobs/components/job/unmet_prerequisites_block_spec.js b/spec/frontend/jobs/components/job/unmet_prerequisites_block_spec.js
deleted file mode 100644
index 1072cdd6781..00000000000
--- a/spec/frontend/jobs/components/job/unmet_prerequisites_block_spec.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import { GlAlert, GlLink } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import UnmetPrerequisitesBlock from '~/jobs/components/job/unmet_prerequisites_block.vue';
-
-describe('Unmet Prerequisites Block Job component', () => {
- let wrapper;
- const helpPath = '/user/project/clusters/index.html#troubleshooting-failed-deployment-jobs';
-
- const createComponent = () => {
- wrapper = shallowMount(UnmetPrerequisitesBlock, {
- propsData: {
- helpPath,
- },
- });
- };
-
- beforeEach(() => {
- createComponent();
- });
-
- it('renders an alert with the correct message', () => {
- const container = wrapper.findComponent(GlAlert);
- const alertMessage =
- 'This job failed because the necessary resources were not successfully created.';
-
- expect(container).not.toBeNull();
- expect(container.text()).toContain(alertMessage);
- });
-
- it('renders link to help page', () => {
- const helpLink = wrapper.findComponent(GlLink);
-
- expect(helpLink).not.toBeNull();
- expect(helpLink.text()).toContain('More information');
- expect(helpLink.attributes().href).toEqual(helpPath);
- });
-});