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')
-rw-r--r--spec/frontend/jobs/bridge/app_spec.js146
-rw-r--r--spec/frontend/jobs/bridge/components/empty_state_spec.js58
-rw-r--r--spec/frontend/jobs/bridge/components/sidebar_spec.js99
-rw-r--r--spec/frontend/jobs/bridge/mock_data.js102
-rw-r--r--spec/frontend/jobs/components/job_app_spec.js7
-rw-r--r--spec/frontend/jobs/components/job_log_controllers_spec.js61
-rw-r--r--spec/frontend/jobs/components/job_sidebar_details_container_spec.js4
-rw-r--r--spec/frontend/jobs/components/jobs_container_spec.js2
-rw-r--r--spec/frontend/jobs/components/log/collapsible_section_spec.js9
-rw-r--r--spec/frontend/jobs/components/log/line_spec.js42
-rw-r--r--spec/frontend/jobs/components/log/log_spec.js91
-rw-r--r--spec/frontend/jobs/components/log/mock_data.js74
-rw-r--r--spec/frontend/jobs/components/table/cells/actions_cell_spec.js41
-rw-r--r--spec/frontend/jobs/components/table/cells/job_cell_spec.js32
-rw-r--r--spec/frontend/jobs/components/table/job_table_app_spec.js43
-rw-r--r--spec/frontend/jobs/components/table/jobs_table_spec.js10
-rw-r--r--spec/frontend/jobs/mock_data.js772
-rw-r--r--spec/frontend/jobs/store/mutations_spec.js94
-rw-r--r--spec/frontend/jobs/store/utils_spec.js111
19 files changed, 357 insertions, 1441 deletions
diff --git a/spec/frontend/jobs/bridge/app_spec.js b/spec/frontend/jobs/bridge/app_spec.js
deleted file mode 100644
index 210dcfa364b..00000000000
--- a/spec/frontend/jobs/bridge/app_spec.js
+++ /dev/null
@@ -1,146 +0,0 @@
-import Vue, { nextTick } from 'vue';
-import { shallowMount } from '@vue/test-utils';
-
-import { GlBreakpointInstance } from '@gitlab/ui/dist/utils';
-import { GlLoadingIcon } from '@gitlab/ui';
-import VueApollo from 'vue-apollo';
-import createMockApollo from 'helpers/mock_apollo_helper';
-import getPipelineQuery from '~/jobs/bridge/graphql/queries/pipeline.query.graphql';
-import waitForPromises from 'helpers/wait_for_promises';
-import BridgeApp from '~/jobs/bridge/app.vue';
-import BridgeEmptyState from '~/jobs/bridge/components/empty_state.vue';
-import BridgeSidebar from '~/jobs/bridge/components/sidebar.vue';
-import CiHeader from '~/vue_shared/components/header_ci_component.vue';
-import {
- MOCK_BUILD_ID,
- MOCK_PIPELINE_IID,
- MOCK_PROJECT_FULL_PATH,
- mockPipelineQueryResponse,
-} from './mock_data';
-
-describe('Bridge Show Page', () => {
- let wrapper;
- let mockApollo;
- let mockPipelineQuery;
-
- const createComponent = (options) => {
- wrapper = shallowMount(BridgeApp, {
- provide: {
- buildId: MOCK_BUILD_ID,
- projectFullPath: MOCK_PROJECT_FULL_PATH,
- pipelineIid: MOCK_PIPELINE_IID,
- },
- mocks: {
- $apollo: {
- queries: {
- pipeline: {
- loading: true,
- },
- },
- },
- },
- ...options,
- });
- };
-
- const createComponentWithApollo = () => {
- const handlers = [[getPipelineQuery, mockPipelineQuery]];
- Vue.use(VueApollo);
- mockApollo = createMockApollo(handlers);
-
- createComponent({
- apolloProvider: mockApollo,
- mocks: {},
- });
- };
-
- const findCiHeader = () => wrapper.findComponent(CiHeader);
- const findEmptyState = () => wrapper.findComponent(BridgeEmptyState);
- const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
- const findSidebar = () => wrapper.findComponent(BridgeSidebar);
-
- beforeEach(() => {
- mockPipelineQuery = jest.fn();
- });
-
- afterEach(() => {
- mockPipelineQuery.mockReset();
- wrapper.destroy();
- });
-
- describe('while pipeline query is loading', () => {
- beforeEach(() => {
- createComponent();
- });
-
- it('renders loading icon', () => {
- expect(findLoadingIcon().exists()).toBe(true);
- });
- });
-
- describe('after pipeline query is loaded', () => {
- beforeEach(async () => {
- mockPipelineQuery.mockResolvedValue(mockPipelineQueryResponse);
- createComponentWithApollo();
- await waitForPromises();
- });
-
- it('query is called with correct variables', async () => {
- expect(mockPipelineQuery).toHaveBeenCalledTimes(1);
- expect(mockPipelineQuery).toHaveBeenCalledWith({
- fullPath: MOCK_PROJECT_FULL_PATH,
- iid: MOCK_PIPELINE_IID,
- });
- });
-
- it('renders CI header state', () => {
- expect(findCiHeader().exists()).toBe(true);
- });
-
- it('renders empty state', () => {
- expect(findEmptyState().exists()).toBe(true);
- });
-
- it('renders sidebar', () => {
- expect(findSidebar().exists()).toBe(true);
- });
- });
-
- describe('sidebar expansion', () => {
- beforeEach(async () => {
- mockPipelineQuery.mockResolvedValue(mockPipelineQueryResponse);
- createComponentWithApollo();
- await waitForPromises();
- });
-
- describe('on resize', () => {
- it.each`
- breakpoint | isSidebarExpanded
- ${'xs'} | ${false}
- ${'sm'} | ${false}
- ${'md'} | ${true}
- ${'lg'} | ${true}
- ${'xl'} | ${true}
- `(
- 'sets isSidebarExpanded to `$isSidebarExpanded` when the breakpoint is "$breakpoint"',
- async ({ breakpoint, isSidebarExpanded }) => {
- jest.spyOn(GlBreakpointInstance, 'getBreakpointSize').mockReturnValue(breakpoint);
-
- window.dispatchEvent(new Event('resize'));
- await nextTick();
-
- expect(findSidebar().exists()).toBe(isSidebarExpanded);
- },
- );
- });
-
- it('toggles expansion on button click', async () => {
- expect(findSidebar().exists()).toBe(true);
-
- wrapper.vm.toggleSidebar();
- await nextTick();
-
- expect(findSidebar().exists()).toBe(false);
- });
- });
-});
diff --git a/spec/frontend/jobs/bridge/components/empty_state_spec.js b/spec/frontend/jobs/bridge/components/empty_state_spec.js
deleted file mode 100644
index 38c55b296f0..00000000000
--- a/spec/frontend/jobs/bridge/components/empty_state_spec.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import { GlButton } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import BridgeEmptyState from '~/jobs/bridge/components/empty_state.vue';
-import { MOCK_EMPTY_ILLUSTRATION_PATH, MOCK_PATH_TO_DOWNSTREAM } from '../mock_data';
-
-describe('Bridge Empty State', () => {
- let wrapper;
-
- const createComponent = ({ downstreamPipelinePath }) => {
- wrapper = shallowMount(BridgeEmptyState, {
- provide: {
- emptyStateIllustrationPath: MOCK_EMPTY_ILLUSTRATION_PATH,
- },
- propsData: {
- downstreamPipelinePath,
- },
- });
- };
-
- const findSvg = () => wrapper.find('img');
- const findTitle = () => wrapper.find('h1');
- const findLinkBtn = () => wrapper.findComponent(GlButton);
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('template', () => {
- beforeEach(() => {
- createComponent({ downstreamPipelinePath: MOCK_PATH_TO_DOWNSTREAM });
- });
-
- it('renders illustration', () => {
- expect(findSvg().exists()).toBe(true);
- });
-
- it('renders title', () => {
- expect(findTitle().exists()).toBe(true);
- expect(findTitle().text()).toBe(wrapper.vm.$options.i18n.title);
- });
-
- it('renders CTA button', () => {
- expect(findLinkBtn().exists()).toBe(true);
- expect(findLinkBtn().text()).toBe(wrapper.vm.$options.i18n.linkBtnText);
- expect(findLinkBtn().attributes('href')).toBe(MOCK_PATH_TO_DOWNSTREAM);
- });
- });
-
- describe('without downstream pipeline', () => {
- beforeEach(() => {
- createComponent({ downstreamPipelinePath: undefined });
- });
-
- it('does not render CTA button', () => {
- expect(findLinkBtn().exists()).toBe(false);
- });
- });
-});
diff --git a/spec/frontend/jobs/bridge/components/sidebar_spec.js b/spec/frontend/jobs/bridge/components/sidebar_spec.js
deleted file mode 100644
index 5006d4f08a6..00000000000
--- a/spec/frontend/jobs/bridge/components/sidebar_spec.js
+++ /dev/null
@@ -1,99 +0,0 @@
-import { GlButton, GlDropdown } from '@gitlab/ui';
-import { shallowMount } from '@vue/test-utils';
-import BridgeSidebar from '~/jobs/bridge/components/sidebar.vue';
-import CommitBlock from '~/jobs/components/commit_block.vue';
-import { mockCommit, mockJob } from '../mock_data';
-
-describe('Bridge Sidebar', () => {
- let wrapper;
-
- const MockHeaderEl = {
- getBoundingClientRect() {
- return {
- bottom: '40',
- };
- },
- };
-
- const createComponent = ({ featureFlag } = {}) => {
- wrapper = shallowMount(BridgeSidebar, {
- provide: {
- glFeatures: {
- triggerJobRetryAction: featureFlag,
- },
- },
- propsData: {
- bridgeJob: mockJob,
- commit: mockCommit,
- },
- });
- };
-
- const findJobTitle = () => wrapper.find('h4');
- const findCommitBlock = () => wrapper.findComponent(CommitBlock);
- const findRetryDropdown = () => wrapper.find(GlDropdown);
- const findToggleBtn = () => wrapper.findComponent(GlButton);
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- describe('template', () => {
- beforeEach(() => {
- createComponent();
- });
-
- it('renders job name', () => {
- expect(findJobTitle().text()).toBe(mockJob.name);
- });
-
- it('renders commit information', () => {
- expect(findCommitBlock().exists()).toBe(true);
- });
- });
-
- describe('styles', () => {
- beforeEach(async () => {
- jest.spyOn(document, 'querySelector').mockReturnValue(MockHeaderEl);
- createComponent();
- });
-
- it('calculates root styles correctly', () => {
- expect(wrapper.attributes('style')).toBe('width: 290px; top: 40px;');
- });
- });
-
- describe('sidebar expansion', () => {
- beforeEach(() => {
- createComponent();
- });
-
- it('emits toggle sidebar event on button click', async () => {
- expect(wrapper.emitted('toggleSidebar')).toBe(undefined);
-
- findToggleBtn().vm.$emit('click');
-
- expect(wrapper.emitted('toggleSidebar')).toHaveLength(1);
- });
- });
-
- describe('retry action', () => {
- describe('when feature flag is ON', () => {
- beforeEach(() => {
- createComponent({ featureFlag: true });
- });
-
- it('renders retry dropdown', () => {
- expect(findRetryDropdown().exists()).toBe(true);
- });
- });
-
- describe('when feature flag is OFF', () => {
- it('does not render retry dropdown', () => {
- createComponent({ featureFlag: false });
-
- expect(findRetryDropdown().exists()).toBe(false);
- });
- });
- });
-});
diff --git a/spec/frontend/jobs/bridge/mock_data.js b/spec/frontend/jobs/bridge/mock_data.js
deleted file mode 100644
index 4084bb54163..00000000000
--- a/spec/frontend/jobs/bridge/mock_data.js
+++ /dev/null
@@ -1,102 +0,0 @@
-export const MOCK_EMPTY_ILLUSTRATION_PATH = '/path/to/svg';
-export const MOCK_PATH_TO_DOWNSTREAM = '/path/to/downstream/pipeline';
-export const MOCK_BUILD_ID = '1331';
-export const MOCK_PIPELINE_IID = '174';
-export const MOCK_PROJECT_FULL_PATH = '/root/project/';
-export const MOCK_SHA = '38f3d89147765427a7ce58be28cd76d14efa682a';
-
-export const mockCommit = {
- id: `gid://gitlab/CommitPresenter/${MOCK_SHA}`,
- shortId: '38f3d891',
- title: 'Update .gitlab-ci.yml file',
- webPath: `/root/project/-/commit/${MOCK_SHA}`,
- __typename: 'Commit',
-};
-
-export const mockJob = {
- createdAt: '2021-12-10T09:05:45Z',
- id: 'gid://gitlab/Ci::Build/1331',
- name: 'triggerJobName',
- scheduledAt: null,
- startedAt: '2021-12-10T09:13:43Z',
- status: 'SUCCESS',
- triggered: null,
- detailedStatus: {
- id: '1',
- detailsPath: '/root/project/-/jobs/1331',
- icon: 'status_success',
- group: 'success',
- text: 'passed',
- tooltip: 'passed',
- __typename: 'DetailedStatus',
- },
- downstreamPipeline: {
- id: '1',
- path: '/root/project/-/pipelines/175',
- },
- stage: {
- id: '1',
- name: 'build',
- __typename: 'CiStage',
- },
- __typename: 'CiJob',
-};
-
-export const mockUser = {
- id: 'gid://gitlab/User/1',
- avatarUrl: 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- name: 'Administrator',
- username: 'root',
- webPath: '/root',
- webUrl: 'http://gdk.test:3000/root',
- status: {
- message: 'making great things',
- __typename: 'UserStatus',
- },
- __typename: 'UserCore',
-};
-
-export const mockStage = {
- id: '1',
- name: 'build',
- jobs: {
- nodes: [mockJob],
- __typename: 'CiJobConnection',
- },
- __typename: 'CiStage',
-};
-
-export const mockPipelineQueryResponse = {
- data: {
- project: {
- id: '1',
- pipeline: {
- commit: mockCommit,
- id: 'gid://gitlab/Ci::Pipeline/174',
- iid: '88',
- path: '/root/project/-/pipelines/174',
- sha: MOCK_SHA,
- ref: 'main',
- refPath: 'path/to/ref',
- user: mockUser,
- detailedStatus: {
- id: '1',
- icon: 'status_failed',
- group: 'failed',
- __typename: 'DetailedStatus',
- },
- stages: {
- edges: [
- {
- node: mockStage,
- __typename: 'CiStageEdge',
- },
- ],
- __typename: 'CiStageConnection',
- },
- __typename: 'Pipeline',
- },
- __typename: 'Project',
- },
- },
-};
diff --git a/spec/frontend/jobs/components/job_app_spec.js b/spec/frontend/jobs/components/job_app_spec.js
index fc308766ab9..b4b5bc4669d 100644
--- a/spec/frontend/jobs/components/job_app_spec.js
+++ b/spec/frontend/jobs/components/job_app_spec.js
@@ -22,7 +22,6 @@ describe('Job App', () => {
let store;
let wrapper;
let mock;
- let origGon;
const initSettings = {
endpoint: `${TEST_HOST}jobs/123.json`,
@@ -80,17 +79,11 @@ describe('Job App', () => {
beforeEach(() => {
mock = new MockAdapter(axios);
store = createStore();
-
- origGon = window.gon;
-
- window.gon = { features: { infinitelyCollapsibleSections: false } }; // NOTE: All of this passes with the feature flag
});
afterEach(() => {
wrapper.destroy();
mock.restore();
-
- window.gon = origGon;
});
describe('while loading', () => {
diff --git a/spec/frontend/jobs/components/job_log_controllers_spec.js b/spec/frontend/jobs/components/job_log_controllers_spec.js
index cd3ee734466..cc97d111c06 100644
--- a/spec/frontend/jobs/components/job_log_controllers_spec.js
+++ b/spec/frontend/jobs/components/job_log_controllers_spec.js
@@ -1,6 +1,11 @@
+import { GlSearchBoxByClick } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';
import JobLogControllers from '~/jobs/components/job_log_controllers.vue';
+import HelpPopover from '~/vue_shared/components/help_popover.vue';
+import { mockJobLog } from '../mock_data';
+
+const mockToastShow = jest.fn();
describe('Job log controllers', () => {
let wrapper;
@@ -19,14 +24,30 @@ describe('Job log controllers', () => {
isScrollBottomDisabled: false,
isScrollingDown: true,
isJobLogSizeVisible: true,
+ jobLog: mockJobLog,
};
- const createWrapper = (props) => {
+ const createWrapper = (props, jobLogSearch = false) => {
wrapper = mount(JobLogControllers, {
propsData: {
...defaultProps,
...props,
},
+ provide: {
+ glFeatures: {
+ jobLogSearch,
+ },
+ },
+ data() {
+ return {
+ searchTerm: '82',
+ };
+ },
+ mocks: {
+ $toast: {
+ show: mockToastShow,
+ },
+ },
});
};
@@ -35,6 +56,8 @@ describe('Job log controllers', () => {
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);
describe('Truncate information', () => {
describe('with isJobLogSizeVisible', () => {
@@ -179,4 +202,40 @@ describe('Job log controllers', () => {
});
});
});
+
+ describe('Job log search', () => {
+ describe('with feature flag off', () => {
+ it('does not display job log search', () => {
+ createWrapper();
+
+ expect(findJobLogSearch().exists()).toBe(false);
+ expect(findSearchHelp().exists()).toBe(false);
+ });
+ });
+
+ describe('with feature flag on', () => {
+ beforeEach(() => {
+ createWrapper({}, { jobLogSearch: true });
+ });
+
+ 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_sidebar_details_container_spec.js b/spec/frontend/jobs/components/job_sidebar_details_container_spec.js
index cc9a5e4ee25..4046f0269dd 100644
--- a/spec/frontend/jobs/components/job_sidebar_details_container_spec.js
+++ b/spec/frontend/jobs/components/job_sidebar_details_container_spec.js
@@ -42,7 +42,7 @@ describe('Job Sidebar Details Container', () => {
expect(wrapper.html()).toBe('');
});
- it.each(['duration', 'erased_at', 'finished_at', 'queued', 'runner', 'coverage'])(
+ 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 });
@@ -59,7 +59,7 @@ describe('Job Sidebar Details Container', () => {
['duration', 'Elapsed time: 6 seconds'],
['erased_at', 'Erased: 3 weeks ago'],
['finished_at', 'Finished: 3 weeks ago'],
- ['queued', 'Queued: 9 seconds'],
+ ['queued_duration', 'Queued: 9 seconds'],
['runner', 'Runner: #1 (ABCDEFGH) local ci runner'],
['coverage', 'Coverage: 20%'],
])('uses %s to render job-%s', async (detail, value) => {
diff --git a/spec/frontend/jobs/components/jobs_container_spec.js b/spec/frontend/jobs/components/jobs_container_spec.js
index 1cde72682a2..127570b8184 100644
--- a/spec/frontend/jobs/components/jobs_container_spec.js
+++ b/spec/frontend/jobs/components/jobs_container_spec.js
@@ -106,7 +106,7 @@ describe('Jobs List block', () => {
});
expect(findJob().text()).toBe(job.name);
- expect(findJob().text()).not.toContain(job.id);
+ expect(findJob().text()).not.toContain(job.id.toString());
});
it('renders job id when job name is not available', () => {
diff --git a/spec/frontend/jobs/components/log/collapsible_section_spec.js b/spec/frontend/jobs/components/log/collapsible_section_spec.js
index 2ab7f5fe22d..646935568b1 100644
--- a/spec/frontend/jobs/components/log/collapsible_section_spec.js
+++ b/spec/frontend/jobs/components/log/collapsible_section_spec.js
@@ -5,7 +5,6 @@ import { collapsibleSectionClosed, collapsibleSectionOpened } from './mock_data'
describe('Job Log Collapsible Section', () => {
let wrapper;
- let origGon;
const jobLogEndpoint = 'jobs/335';
@@ -20,16 +19,8 @@ describe('Job Log Collapsible Section', () => {
});
};
- beforeEach(() => {
- origGon = window.gon;
-
- window.gon = { features: { infinitelyCollapsibleSections: false } }; // NOTE: This also works with true
- });
-
afterEach(() => {
wrapper.destroy();
-
- window.gon = origGon;
});
describe('with closed section', () => {
diff --git a/spec/frontend/jobs/components/log/line_spec.js b/spec/frontend/jobs/components/log/line_spec.js
index d184696cd1f..bf80d90e299 100644
--- a/spec/frontend/jobs/components/log/line_spec.js
+++ b/spec/frontend/jobs/components/log/line_spec.js
@@ -179,4 +179,46 @@ describe('Job Log Line', () => {
expect(findLink().exists()).toBe(false);
});
});
+
+ describe('job log search', () => {
+ const mockSearchResults = [
+ {
+ offset: 1533,
+ content: [{ text: '$ echo "82.71"', style: 'term-fg-l-green term-bold' }],
+ section: 'step-script',
+ lineNumber: 20,
+ },
+ { offset: 1560, content: [{ text: '82.71' }], section: 'step-script', lineNumber: 21 },
+ ];
+
+ it('applies highlight class to search result elements', () => {
+ createComponent({
+ line: {
+ offset: 1560,
+ content: [{ text: '82.71' }],
+ section: 'step-script',
+ lineNumber: 21,
+ },
+ path: '/root/ci-project/-/jobs/1089',
+ searchResults: mockSearchResults,
+ });
+
+ expect(wrapper.classes()).toContain('gl-bg-gray-500');
+ });
+
+ it('does not apply highlight class to search result elements', () => {
+ createComponent({
+ line: {
+ offset: 1560,
+ content: [{ text: 'docker' }],
+ section: 'step-script',
+ lineNumber: 29,
+ },
+ path: '/root/ci-project/-/jobs/1089',
+ searchResults: mockSearchResults,
+ });
+
+ expect(wrapper.classes()).not.toContain('gl-bg-gray-500');
+ });
+ });
});
diff --git a/spec/frontend/jobs/components/log/log_spec.js b/spec/frontend/jobs/components/log/log_spec.js
index 9cc56cce9b3..c933ed5c3e1 100644
--- a/spec/frontend/jobs/components/log/log_spec.js
+++ b/spec/frontend/jobs/components/log/log_spec.js
@@ -2,7 +2,7 @@ import { mount } from '@vue/test-utils';
import Vue from 'vue';
import Vuex from 'vuex';
import Log from '~/jobs/components/log/log.vue';
-import { logLinesParserLegacy, logLinesParser } from '~/jobs/store/utils';
+import { logLinesParser } from '~/jobs/store/utils';
import { jobLog } from './mock_data';
describe('Job Log', () => {
@@ -10,7 +10,6 @@ describe('Job Log', () => {
let actions;
let state;
let store;
- let origGon;
Vue.use(Vuex);
@@ -25,12 +24,8 @@ describe('Job Log', () => {
toggleCollapsibleLine: () => {},
};
- origGon = window.gon;
-
- window.gon = { features: { infinitelyCollapsibleSections: false } };
-
state = {
- jobLog: logLinesParserLegacy(jobLog),
+ jobLog: logLinesParser(jobLog),
jobLogEndpoint: 'jobs/id',
};
@@ -44,88 +39,6 @@ describe('Job Log', () => {
afterEach(() => {
wrapper.destroy();
-
- window.gon = origGon;
- });
-
- const findCollapsibleLine = () => wrapper.find('.collapsible-line');
-
- describe('line numbers', () => {
- it('renders a line number for each open line', () => {
- expect(wrapper.find('#L1').text()).toBe('1');
- expect(wrapper.find('#L2').text()).toBe('2');
- expect(wrapper.find('#L3').text()).toBe('3');
- });
-
- it('links to the provided path and correct line number', () => {
- expect(wrapper.find('#L1').attributes('href')).toBe(`${state.jobLogEndpoint}#L1`);
- });
- });
-
- describe('collapsible sections', () => {
- it('renders a clickable header section', () => {
- expect(findCollapsibleLine().attributes('role')).toBe('button');
- });
-
- it('renders an icon with the open state', () => {
- expect(findCollapsibleLine().find('[data-testid="chevron-lg-down-icon"]').exists()).toBe(
- true,
- );
- });
-
- describe('on click header section', () => {
- it('calls toggleCollapsibleLine', () => {
- jest.spyOn(wrapper.vm, 'toggleCollapsibleLine');
-
- findCollapsibleLine().trigger('click');
-
- expect(wrapper.vm.toggleCollapsibleLine).toHaveBeenCalled();
- });
- });
- });
-});
-
-describe('Job Log, infinitelyCollapsibleSections feature flag enabled', () => {
- let wrapper;
- let actions;
- let state;
- let store;
- let origGon;
-
- Vue.use(Vuex);
-
- const createComponent = () => {
- wrapper = mount(Log, {
- store,
- });
- };
-
- beforeEach(() => {
- actions = {
- toggleCollapsibleLine: () => {},
- };
-
- origGon = window.gon;
-
- window.gon = { features: { infinitelyCollapsibleSections: true } };
-
- state = {
- jobLog: logLinesParser(jobLog).parsedLines,
- jobLogEndpoint: 'jobs/id',
- };
-
- store = new Vuex.Store({
- actions,
- state,
- });
-
- createComponent();
- });
-
- afterEach(() => {
- wrapper.destroy();
-
- window.gon = origGon;
});
const findCollapsibleLine = () => wrapper.find('.collapsible-line');
diff --git a/spec/frontend/jobs/components/log/mock_data.js b/spec/frontend/jobs/components/log/mock_data.js
index 3ff0bd73581..eb8c4fe8bc9 100644
--- a/spec/frontend/jobs/components/log/mock_data.js
+++ b/spec/frontend/jobs/components/log/mock_data.js
@@ -58,80 +58,6 @@ export const utilsMockData = [
},
];
-export const multipleCollapsibleSectionsMockData = [
- {
- offset: 1001,
- content: [{ text: ' on docker-auto-scale-com 8a6210b8' }],
- },
- {
- offset: 1002,
- content: [
- {
- text: 'Executing "step_script" stage of the job script',
- },
- ],
- section: 'step-script',
- section_header: true,
- },
- {
- offset: 1003,
- content: [{ text: 'sleep 60' }],
- section: 'step-script',
- },
- {
- offset: 1004,
- content: [
- {
- text:
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lorem dolor, congue ac condimentum vitae',
- },
- ],
- section: 'step-script',
- },
- {
- offset: 1005,
- content: [{ text: 'executing...' }],
- section: 'step-script',
- },
- {
- offset: 1006,
- content: [{ text: '1st collapsible section' }],
- section: 'collapsible-1',
- section_header: true,
- },
- {
- offset: 1007,
- content: [
- {
- text:
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lorem dolor, congue ac condimentum vitae',
- },
- ],
- section: 'collapsible-1',
- },
- {
- offset: 1008,
- content: [],
- section: 'collapsible-1',
- section_duration: '01:00',
- },
- {
- offset: 1009,
- content: [],
- section: 'step-script',
- section_duration: '10:00',
- },
-];
-
-export const backwardsCompatibilityTrace = [
- {
- offset: 2365,
- content: [],
- section: 'download-artifacts',
- section_duration: '00:01',
- },
-];
-
export const originalTrace = [
{
offset: 1,
diff --git a/spec/frontend/jobs/components/table/cells/actions_cell_spec.js b/spec/frontend/jobs/components/table/cells/actions_cell_spec.js
index 976b128532d..7cc008f332d 100644
--- a/spec/frontend/jobs/components/table/cells/actions_cell_spec.js
+++ b/spec/frontend/jobs/components/table/cells/actions_cell_spec.js
@@ -12,17 +12,12 @@ import JobRetryMutation from '~/jobs/components/table/graphql/mutations/job_retr
import JobUnscheduleMutation from '~/jobs/components/table/graphql/mutations/job_unschedule.mutation.graphql';
import JobCancelMutation from '~/jobs/components/table/graphql/mutations/job_cancel.mutation.graphql';
import {
- playableJob,
- retryableJob,
- cancelableJob,
- scheduledJob,
- cannotRetryJob,
- cannotPlayJob,
- cannotPlayScheduledJob,
- retryMutationResponse,
+ mockJobsNodes,
+ mockJobsNodesAsGuest,
playMutationResponse,
- cancelMutationResponse,
+ retryMutationResponse,
unscheduleMutationResponse,
+ cancelMutationResponse,
} from '../../../mock_data';
jest.mock('~/lib/utils/url_utility');
@@ -32,6 +27,22 @@ Vue.use(VueApollo);
describe('Job actions cell', () => {
let wrapper;
+ const findMockJob = (jobName, nodes = mockJobsNodes) => {
+ const job = nodes.find(({ name }) => name === jobName);
+ expect(job).toBeDefined(); // ensure job is present
+ return job;
+ };
+
+ const mockJob = findMockJob('build');
+ const cancelableJob = findMockJob('cancelable');
+ const playableJob = findMockJob('playable');
+ const retryableJob = findMockJob('retryable');
+ const scheduledJob = findMockJob('scheduled');
+ const jobWithArtifact = findMockJob('with_artifact');
+ const cannotPlayJob = findMockJob('playable', mockJobsNodesAsGuest);
+ const cannotRetryJob = findMockJob('retryable', mockJobsNodesAsGuest);
+ const cannotPlayScheduledJob = findMockJob('scheduled', mockJobsNodesAsGuest);
+
const findRetryButton = () => wrapper.findByTestId('retry');
const findPlayButton = () => wrapper.findByTestId('play');
const findCancelButton = () => wrapper.findByTestId('cancel-button');
@@ -55,10 +66,10 @@ describe('Job actions cell', () => {
return createMockApollo(requestHandlers);
};
- const createComponent = (jobType, requestHandlers, props = {}) => {
+ const createComponent = (job, requestHandlers, props = {}) => {
wrapper = shallowMountExtended(ActionsCell, {
propsData: {
- job: jobType,
+ job,
...props,
},
apolloProvider: createMockApolloProvider(requestHandlers),
@@ -73,15 +84,15 @@ describe('Job actions cell', () => {
});
it('displays the artifacts download button with correct link', () => {
- createComponent(playableJob);
+ createComponent(jobWithArtifact);
expect(findDownloadArtifactsButton().attributes('href')).toBe(
- playableJob.artifacts.nodes[0].downloadPath,
+ jobWithArtifact.artifacts.nodes[0].downloadPath,
);
});
it('does not display an artifacts download button', () => {
- createComponent(retryableJob);
+ createComponent(mockJob);
expect(findDownloadArtifactsButton().exists()).toBe(false);
});
@@ -101,7 +112,7 @@ describe('Job actions cell', () => {
button | action | jobType
${findPlayButton} | ${'play'} | ${playableJob}
${findRetryButton} | ${'retry'} | ${retryableJob}
- ${findDownloadArtifactsButton} | ${'download artifacts'} | ${playableJob}
+ ${findDownloadArtifactsButton} | ${'download artifacts'} | ${jobWithArtifact}
${findCancelButton} | ${'cancel'} | ${cancelableJob}
`('displays the $action button', ({ button, jobType }) => {
createComponent(jobType);
diff --git a/spec/frontend/jobs/components/table/cells/job_cell_spec.js b/spec/frontend/jobs/components/table/cells/job_cell_spec.js
index fc4e5586349..ddc196129a7 100644
--- a/spec/frontend/jobs/components/table/cells/job_cell_spec.js
+++ b/spec/frontend/jobs/components/table/cells/job_cell_spec.js
@@ -2,16 +2,22 @@ import { shallowMount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
import JobCell from '~/jobs/components/table/cells/job_cell.vue';
-import { mockJobsInTable } from '../../../mock_data';
-
-const mockJob = mockJobsInTable[0];
-const mockJobCreatedByTag = mockJobsInTable[1];
-const mockJobLimitedAccess = mockJobsInTable[2];
-const mockStuckJob = mockJobsInTable[3];
+import { mockJobsNodes, mockJobsNodesAsGuest } from '../../../mock_data';
describe('Job Cell', () => {
let wrapper;
+ const findMockJob = (jobName, nodes = mockJobsNodes) => {
+ const job = nodes.find(({ name }) => name === jobName);
+ expect(job).toBeDefined(); // ensure job is present
+ return job;
+ };
+
+ const mockJob = findMockJob('build');
+ const jobCreatedByTag = findMockJob('created_by_tag');
+ const pendingJob = findMockJob('pending');
+ const jobAsGuest = findMockJob('build', mockJobsNodesAsGuest);
+
const findJobIdLink = () => wrapper.findByTestId('job-id-link');
const findJobIdNoLink = () => wrapper.findByTestId('job-id-limited-access');
const findJobRef = () => wrapper.findByTestId('job-ref');
@@ -23,11 +29,11 @@ describe('Job Cell', () => {
const findBadgeById = (id) => wrapper.findByTestId(id);
- const createComponent = (jobData = mockJob) => {
+ const createComponent = (job = mockJob) => {
wrapper = extendedWrapper(
shallowMount(JobCell, {
propsData: {
- job: jobData,
+ job,
},
}),
);
@@ -49,9 +55,9 @@ describe('Job Cell', () => {
});
it('display the job id with no link', () => {
- createComponent(mockJobLimitedAccess);
+ createComponent(jobAsGuest);
- const expectedJobId = `#${getIdFromGraphQLId(mockJobLimitedAccess.id)}`;
+ const expectedJobId = `#${getIdFromGraphQLId(jobAsGuest.id)}`;
expect(findJobIdNoLink().text()).toBe(expectedJobId);
expect(findJobIdNoLink().exists()).toBe(true);
@@ -75,7 +81,7 @@ describe('Job Cell', () => {
});
it('displays label icon when job is created by a tag', () => {
- createComponent(mockJobCreatedByTag);
+ createComponent(jobCreatedByTag);
expect(findLabelIcon().exists()).toBe(true);
expect(findForkIcon().exists()).toBe(false);
@@ -130,8 +136,8 @@ describe('Job Cell', () => {
expect(findStuckIcon().exists()).toBe(false);
});
- it('stuck icon is shown if job is stuck', () => {
- createComponent(mockStuckJob);
+ it('stuck icon is shown if job is pending', () => {
+ createComponent(pendingJob);
expect(findStuckIcon().exists()).toBe(true);
expect(findStuckIcon().attributes('name')).toBe('warning');
diff --git a/spec/frontend/jobs/components/table/job_table_app_spec.js b/spec/frontend/jobs/components/table/job_table_app_spec.js
index 986fba21fb9..374768c3ee4 100644
--- a/spec/frontend/jobs/components/table/job_table_app_spec.js
+++ b/spec/frontend/jobs/components/table/job_table_app_spec.js
@@ -6,7 +6,7 @@ import {
GlLoadingIcon,
} from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
+import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import { s__ } from '~/locale';
import createMockApollo from 'helpers/mock_apollo_helper';
@@ -18,8 +18,8 @@ import JobsTableApp from '~/jobs/components/table/jobs_table_app.vue';
import JobsTableTabs from '~/jobs/components/table/jobs_table_tabs.vue';
import JobsFilteredSearch from '~/jobs/components/filtered_search/jobs_filtered_search.vue';
import {
- mockJobsQueryResponse,
- mockJobsQueryEmptyResponse,
+ mockJobsResponsePaginated,
+ mockJobsResponseEmpty,
mockFailedSearchToken,
} from '../../mock_data';
@@ -30,11 +30,10 @@ jest.mock('~/flash');
describe('Job table app', () => {
let wrapper;
- let jobsTableVueSearch = true;
- const successHandler = jest.fn().mockResolvedValue(mockJobsQueryResponse);
+ const successHandler = jest.fn().mockResolvedValue(mockJobsResponsePaginated);
const failedHandler = jest.fn().mockRejectedValue(new Error('GraphQL error'));
- const emptyHandler = jest.fn().mockResolvedValue(mockJobsQueryEmptyResponse);
+ const emptyHandler = jest.fn().mockResolvedValue(mockJobsResponseEmpty);
const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
const findLoadingSpinner = () => wrapper.findComponent(GlLoadingIcon);
@@ -66,7 +65,6 @@ describe('Job table app', () => {
},
provide: {
fullPath: projectPath,
- glFeatures: { jobsTableVueSearch },
},
apolloProvider: createMockApolloProvider(handler),
});
@@ -77,17 +75,17 @@ describe('Job table app', () => {
});
describe('loading state', () => {
- beforeEach(() => {
+ it('should display skeleton loader when loading', () => {
createComponent();
- });
- it('should display skeleton loader when loading', () => {
expect(findSkeletonLoader().exists()).toBe(true);
expect(findTable().exists()).toBe(false);
expect(findLoadingSpinner().exists()).toBe(false);
});
it('when switching tabs only the skeleton loader should show', () => {
+ createComponent();
+
findTabs().vm.$emit('fetchJobsByStatus', null);
expect(findSkeletonLoader().exists()).toBe(true);
@@ -119,24 +117,29 @@ describe('Job table app', () => {
});
describe('when infinite scrolling is triggered', () => {
- beforeEach(() => {
+ it('does not display a skeleton loader', () => {
triggerInfiniteScroll();
- });
- it('does not display a skeleton loader', () => {
expect(findSkeletonLoader().exists()).toBe(false);
});
it('handles infinite scrolling by calling fetch more', async () => {
+ triggerInfiniteScroll();
+
+ await nextTick();
+
+ const pageSize = 30;
+
expect(findLoadingSpinner().exists()).toBe(true);
await waitForPromises();
expect(findLoadingSpinner().exists()).toBe(false);
- expect(successHandler).toHaveBeenCalledWith({
- after: 'eyJpZCI6IjIzMTcifQ',
- fullPath: 'gitlab-org/gitlab',
+ expect(successHandler).toHaveBeenLastCalledWith({
+ first: pageSize,
+ fullPath: projectPath,
+ after: mockJobsResponsePaginated.data.project.jobs.pageInfo.endCursor,
});
});
});
@@ -227,13 +230,5 @@ describe('Job table app', () => {
expect(createFlash).toHaveBeenCalledWith(expectedWarning);
expect(wrapper.vm.$apollo.queries.jobs.refetch).toHaveBeenCalledTimes(0);
});
-
- it('should not display filtered search', () => {
- jobsTableVueSearch = false;
-
- createComponent();
-
- expect(findFilteredSearch().exists()).toBe(false);
- });
});
});
diff --git a/spec/frontend/jobs/components/table/jobs_table_spec.js b/spec/frontend/jobs/components/table/jobs_table_spec.js
index ac8bef675f8..803df3df37f 100644
--- a/spec/frontend/jobs/components/table/jobs_table_spec.js
+++ b/spec/frontend/jobs/components/table/jobs_table_spec.js
@@ -3,7 +3,7 @@ import { mount } from '@vue/test-utils';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import JobsTable from '~/jobs/components/table/jobs_table.vue';
import CiBadge from '~/vue_shared/components/ci_badge_link.vue';
-import { mockJobsInTable } from '../../mock_data';
+import { mockJobsNodes } from '../../mock_data';
describe('Jobs Table', () => {
let wrapper;
@@ -19,7 +19,7 @@ describe('Jobs Table', () => {
wrapper = extendedWrapper(
mount(JobsTable, {
propsData: {
- jobs: mockJobsInTable,
+ jobs: mockJobsNodes,
...props,
},
}),
@@ -39,7 +39,7 @@ describe('Jobs Table', () => {
});
it('displays correct number of job rows', () => {
- expect(findTableRows()).toHaveLength(mockJobsInTable.length);
+ expect(findTableRows()).toHaveLength(mockJobsNodes.length);
});
it('displays job status', () => {
@@ -47,14 +47,14 @@ describe('Jobs Table', () => {
});
it('displays the job stage and name', () => {
- const firstJob = mockJobsInTable[0];
+ const firstJob = mockJobsNodes[0];
expect(findJobStage().text()).toBe(firstJob.stage.name);
expect(findJobName().text()).toBe(firstJob.name);
});
it('displays the coverage for only jobs that have coverage', () => {
- const jobsThatHaveCoverage = mockJobsInTable.filter((job) => job.coverage !== null);
+ const jobsThatHaveCoverage = mockJobsNodes.filter((job) => job.coverage !== null);
jobsThatHaveCoverage.forEach((job, index) => {
expect(findAllCoverageJobs().at(index).text()).toBe(`${job.coverage}%`);
diff --git a/spec/frontend/jobs/mock_data.js b/spec/frontend/jobs/mock_data.js
index 4676635cce0..bf238b2e39a 100644
--- a/spec/frontend/jobs/mock_data.js
+++ b/spec/frontend/jobs/mock_data.js
@@ -1,8 +1,18 @@
+import mockJobsEmpty from 'test_fixtures/graphql/jobs/get_jobs.query.graphql.empty.json';
+import mockJobsPaginated from 'test_fixtures/graphql/jobs/get_jobs.query.graphql.paginated.json';
+import mockJobs from 'test_fixtures/graphql/jobs/get_jobs.query.graphql.json';
+import mockJobsAsGuest from 'test_fixtures/graphql/jobs/get_jobs.query.graphql.as_guest.json';
import { TEST_HOST } from 'spec/test_constants';
const threeWeeksAgo = new Date();
threeWeeksAgo.setDate(threeWeeksAgo.getDate() - 21);
+// Fixtures generated at spec/frontend/fixtures/jobs.rb
+export const mockJobsResponsePaginated = mockJobsPaginated;
+export const mockJobsResponseEmpty = mockJobsEmpty;
+export const mockJobsNodes = mockJobs.data.project.jobs.nodes;
+export const mockJobsNodesAsGuest = mockJobsAsGuest.data.project.jobs.nodes;
+
export const stages = [
{
name: 'build',
@@ -924,7 +934,7 @@ export default {
created_at: threeWeeksAgo.toISOString(),
updated_at: threeWeeksAgo.toISOString(),
finished_at: threeWeeksAgo.toISOString(),
- queued: 9.54,
+ queued_duration: 9.54,
status: {
icon: 'status_success',
text: 'passed',
@@ -1283,602 +1293,6 @@ export const mockPipelineDetached = {
},
};
-export const mockJobsInTable = [
- {
- detailedStatus: {
- icon: 'status_manual',
- label: 'manual play action',
- text: 'manual',
- tooltip: 'manual action',
- action: {
- buttonTitle: 'Trigger this manual action',
- icon: 'play',
- method: 'post',
- path: '/root/ci-project/-/jobs/2004/play',
- title: 'Play',
- __typename: 'StatusAction',
- },
- detailsPath: '/root/ci-project/-/jobs/2004',
- __typename: 'DetailedStatus',
- },
- id: 'gid://gitlab/Ci::Build/2004',
- refName: 'main',
- refPath: '/root/ci-project/-/commits/main',
- tags: [],
- shortSha: '2d5d8323',
- commitPath: '/root/ci-project/-/commit/2d5d83230bdea0e003d83ef4c16d2bf9a8808ebe',
- pipeline: {
- id: 'gid://gitlab/Ci::Pipeline/423',
- path: '/root/ci-project/-/pipelines/423',
- user: {
- webPath: '/root',
- avatarUrl:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- __typename: 'User',
- },
- __typename: 'Pipeline',
- },
- stage: { name: 'test', __typename: 'CiStage' },
- name: 'test_manual_job',
- duration: null,
- finishedAt: null,
- coverage: null,
- createdByTag: false,
- retryable: false,
- playable: true,
- cancelable: false,
- active: false,
- stuck: false,
- userPermissions: { readBuild: true, __typename: 'JobPermissions' },
- __typename: 'CiJob',
- },
- {
- detailedStatus: {
- icon: 'status_skipped',
- label: 'skipped',
- text: 'skipped',
- tooltip: 'skipped',
- action: null,
- __typename: 'DetailedStatus',
- },
- id: 'gid://gitlab/Ci::Build/2021',
- refName: 'main',
- refPath: '/root/ci-project/-/commits/main',
- tags: [],
- shortSha: '2d5d8323',
- commitPath: '/root/ci-project/-/commit/2d5d83230bdea0e003d83ef4c16d2bf9a8808ebe',
- pipeline: {
- id: 'gid://gitlab/Ci::Pipeline/425',
- path: '/root/ci-project/-/pipelines/425',
- user: {
- webPath: '/root',
- avatarUrl:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- __typename: 'User',
- },
- __typename: 'Pipeline',
- },
- stage: { name: 'test', __typename: 'CiStage' },
- name: 'coverage_job',
- duration: null,
- finishedAt: null,
- coverage: null,
- createdByTag: true,
- retryable: false,
- playable: false,
- cancelable: false,
- active: false,
- stuck: false,
- userPermissions: { readBuild: true, __typename: 'JobPermissions' },
- __typename: 'CiJob',
- },
- {
- detailedStatus: {
- icon: 'status_success',
- label: 'passed',
- text: 'passed',
- tooltip: 'passed',
- action: {
- buttonTitle: 'Retry this job',
- icon: 'retry',
- method: 'post',
- path: '/root/ci-project/-/jobs/2015/retry',
- title: 'Retry',
- __typename: 'StatusAction',
- },
- __typename: 'DetailedStatus',
- },
- id: 'gid://gitlab/Ci::Build/2015',
- refName: 'main',
- refPath: '/root/ci-project/-/commits/main',
- tags: [],
- shortSha: '2d5d8323',
- commitPath: '/root/ci-project/-/commit/2d5d83230bdea0e003d83ef4c16d2bf9a8808ebe',
- pipeline: {
- id: 'gid://gitlab/Ci::Pipeline/424',
- path: '/root/ci-project/-/pipelines/424',
- user: {
- webPath: '/root',
- avatarUrl:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- __typename: 'User',
- },
- __typename: 'Pipeline',
- },
- stage: { name: 'deploy', __typename: 'CiStage' },
- name: 'artifact_job',
- duration: 2,
- finishedAt: '2021-04-01T17:36:18Z',
- coverage: 82.71,
- createdByTag: false,
- retryable: true,
- playable: false,
- cancelable: false,
- active: false,
- stuck: false,
- userPermissions: { readBuild: false, __typename: 'JobPermissions' },
- __typename: 'CiJob',
- },
- {
- artifacts: { nodes: [], __typename: 'CiJobArtifactConnection' },
- allowFailure: false,
- status: 'PENDING',
- scheduledAt: null,
- manualJob: false,
- triggered: null,
- createdByTag: false,
- detailedStatus: {
- detailsPath: '/root/ci-project/-/jobs/2391',
- group: 'pending',
- icon: 'status_pending',
- label: 'pending',
- text: 'pending',
- tooltip: 'pending',
- action: {
- buttonTitle: 'Cancel this job',
- icon: 'cancel',
- method: 'post',
- path: '/root/ci-project/-/jobs/2391/cancel',
- title: 'Cancel',
- __typename: 'StatusAction',
- },
- __typename: 'DetailedStatus',
- },
- id: 'gid://gitlab/Ci::Build/2391',
- refName: 'master',
- refPath: '/root/ci-project/-/commits/master',
- tags: [],
- shortSha: '916330b4',
- commitPath: '/root/ci-project/-/commit/916330b4fda5dae226524ceb51c756c0ed26679d',
- pipeline: {
- id: 'gid://gitlab/Ci::Pipeline/482',
- path: '/root/ci-project/-/pipelines/482',
- user: {
- webPath: '/root',
- avatarUrl:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- __typename: 'UserCore',
- },
- __typename: 'Pipeline',
- },
- stage: { name: 'build', __typename: 'CiStage' },
- name: 'build_job',
- duration: null,
- finishedAt: null,
- coverage: null,
- retryable: false,
- playable: false,
- cancelable: true,
- active: true,
- stuck: true,
- userPermissions: { readBuild: true, __typename: 'JobPermissions' },
- __typename: 'CiJob',
- },
-];
-
-export const mockJobsQueryResponse = {
- data: {
- project: {
- id: '1',
- jobs: {
- count: 1,
- pageInfo: {
- endCursor: 'eyJpZCI6IjIzMTcifQ',
- hasNextPage: true,
- hasPreviousPage: false,
- startCursor: 'eyJpZCI6IjIzMzYifQ',
- __typename: 'PageInfo',
- },
- nodes: [
- {
- artifacts: {
- nodes: [
- {
- downloadPath: '/root/ci-project/-/jobs/2336/artifacts/download?file_type=trace',
- fileType: 'TRACE',
- __typename: 'CiJobArtifact',
- },
- {
- downloadPath:
- '/root/ci-project/-/jobs/2336/artifacts/download?file_type=metadata',
- fileType: 'METADATA',
- __typename: 'CiJobArtifact',
- },
- {
- downloadPath: '/root/ci-project/-/jobs/2336/artifacts/download?file_type=archive',
- fileType: 'ARCHIVE',
- __typename: 'CiJobArtifact',
- },
- ],
- __typename: 'CiJobArtifactConnection',
- },
- allowFailure: false,
- status: 'SUCCESS',
- scheduledAt: null,
- manualJob: false,
- triggered: null,
- createdByTag: false,
- detailedStatus: {
- id: 'status-1',
- detailsPath: '/root/ci-project/-/jobs/2336',
- group: 'success',
- icon: 'status_success',
- label: 'passed',
- text: 'passed',
- tooltip: 'passed',
- action: {
- id: 'action-1',
- buttonTitle: 'Retry this job',
- icon: 'retry',
- method: 'post',
- path: '/root/ci-project/-/jobs/2336/retry',
- title: 'Retry',
- __typename: 'StatusAction',
- },
- __typename: 'DetailedStatus',
- },
- id: 'gid://gitlab/Ci::Build/2336',
- refName: 'main',
- refPath: '/root/ci-project/-/commits/main',
- tags: [],
- shortSha: '4408fa2a',
- commitPath: '/root/ci-project/-/commit/4408fa2a27aaadfdf42d8dda3d6a9c01ce6cad78',
- pipeline: {
- id: 'gid://gitlab/Ci::Pipeline/473',
- path: '/root/ci-project/-/pipelines/473',
- user: {
- id: 'user-1',
- webPath: '/root',
- avatarUrl:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- __typename: 'UserCore',
- },
- __typename: 'Pipeline',
- },
- stage: {
- id: 'stage-1',
- name: 'deploy',
- __typename: 'CiStage',
- },
- name: 'artifact_job',
- duration: 3,
- finishedAt: '2021-04-29T14:19:50Z',
- coverage: null,
- retryable: true,
- playable: false,
- cancelable: false,
- active: false,
- stuck: false,
- userPermissions: {
- readBuild: true,
- readJobArtifacts: true,
- updateBuild: true,
- __typename: 'JobPermissions',
- },
- __typename: 'CiJob',
- },
- ],
- __typename: 'CiJobConnection',
- },
- __typename: 'Project',
- },
- },
-};
-
-export const mockJobsQueryEmptyResponse = {
- data: {
- project: {
- id: '1',
- jobs: [],
- },
- },
-};
-
-export const retryableJob = {
- artifacts: {
- nodes: [
- {
- downloadPath: '/root/ci-project/-/jobs/847/artifacts/download?file_type=trace',
- fileType: 'TRACE',
- __typename: 'CiJobArtifact',
- },
- ],
- __typename: 'CiJobArtifactConnection',
- },
- allowFailure: false,
- status: 'SUCCESS',
- scheduledAt: null,
- manualJob: false,
- triggered: null,
- createdByTag: false,
- detailedStatus: {
- detailsPath: '/root/test-job-artifacts/-/jobs/1981',
- group: 'success',
- icon: 'status_success',
- label: 'passed',
- text: 'passed',
- tooltip: 'passed',
- action: {
- buttonTitle: 'Retry this job',
- icon: 'retry',
- method: 'post',
- path: '/root/test-job-artifacts/-/jobs/1981/retry',
- title: 'Retry',
- __typename: 'StatusAction',
- },
- __typename: 'DetailedStatus',
- },
- id: 'gid://gitlab/Ci::Build/1981',
- refName: 'main',
- refPath: '/root/test-job-artifacts/-/commits/main',
- tags: [],
- shortSha: '75daf01b',
- commitPath: '/root/test-job-artifacts/-/commit/75daf01b465e7eab5a04a315e44660c9a17c8055',
- pipeline: {
- id: 'gid://gitlab/Ci::Pipeline/288',
- path: '/root/test-job-artifacts/-/pipelines/288',
- user: {
- webPath: '/root',
- avatarUrl:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- __typename: 'UserCore',
- },
- __typename: 'Pipeline',
- },
- stage: { name: 'test', __typename: 'CiStage' },
- name: 'hello_world',
- duration: 7,
- finishedAt: '2021-08-30T20:33:56Z',
- coverage: null,
- retryable: true,
- playable: false,
- cancelable: false,
- active: false,
- stuck: false,
- userPermissions: { readBuild: true, updateBuild: true, __typename: 'JobPermissions' },
- __typename: 'CiJob',
-};
-
-export const cancelableJob = {
- artifacts: {
- nodes: [],
- __typename: 'CiJobArtifactConnection',
- },
- allowFailure: false,
- status: 'PENDING',
- scheduledAt: null,
- manualJob: false,
- triggered: null,
- createdByTag: false,
- detailedStatus: {
- id: 'pending-1305-1305',
- detailsPath: '/root/lots-of-jobs-project/-/jobs/1305',
- group: 'pending',
- icon: 'status_pending',
- label: 'pending',
- text: 'pending',
- tooltip: 'pending',
- action: {
- id: 'Ci::Build-pending-1305',
- buttonTitle: 'Cancel this job',
- icon: 'cancel',
- method: 'post',
- path: '/root/lots-of-jobs-project/-/jobs/1305/cancel',
- title: 'Cancel',
- __typename: 'StatusAction',
- },
- __typename: 'DetailedStatus',
- },
- id: 'gid://gitlab/Ci::Build/1305',
- refName: 'main',
- refPath: '/root/lots-of-jobs-project/-/commits/main',
- tags: [],
- shortSha: '750605f2',
- commitPath: '/root/lots-of-jobs-project/-/commit/750605f29530778cf0912779eba6d073128962a5',
- stage: {
- id: 'gid://gitlab/Ci::Stage/181',
- name: 'deploy',
- __typename: 'CiStage',
- },
- name: 'job_212',
- duration: null,
- finishedAt: null,
- coverage: null,
- retryable: false,
- playable: false,
- cancelable: true,
- active: true,
- stuck: false,
- userPermissions: {
- readBuild: true,
- readJobArtifacts: true,
- updateBuild: true,
- __typename: 'JobPermissions',
- },
- __typename: 'CiJob',
-};
-
-export const cannotRetryJob = {
- ...retryableJob,
- userPermissions: { readBuild: true, updateBuild: false, __typename: 'JobPermissions' },
-};
-
-export const playableJob = {
- artifacts: {
- nodes: [
- {
- downloadPath: '/root/ci-project/-/jobs/621/artifacts/download?file_type=archive',
- fileType: 'ARCHIVE',
- __typename: 'CiJobArtifact',
- },
- {
- downloadPath: '/root/ci-project/-/jobs/621/artifacts/download?file_type=metadata',
- fileType: 'METADATA',
- __typename: 'CiJobArtifact',
- },
- {
- downloadPath: '/root/ci-project/-/jobs/621/artifacts/download?file_type=trace',
- fileType: 'TRACE',
- __typename: 'CiJobArtifact',
- },
- ],
- __typename: 'CiJobArtifactConnection',
- },
- allowFailure: false,
- status: 'SUCCESS',
- scheduledAt: null,
- manualJob: true,
- triggered: null,
- createdByTag: false,
- detailedStatus: {
- detailsPath: '/root/test-job-artifacts/-/jobs/1982',
- group: 'success',
- icon: 'status_success',
- label: 'manual play action',
- text: 'passed',
- tooltip: 'passed',
- action: {
- buttonTitle: 'Trigger this manual action',
- icon: 'play',
- method: 'post',
- path: '/root/test-job-artifacts/-/jobs/1982/play',
- title: 'Play',
- __typename: 'StatusAction',
- },
- __typename: 'DetailedStatus',
- },
- id: 'gid://gitlab/Ci::Build/1982',
- refName: 'main',
- refPath: '/root/test-job-artifacts/-/commits/main',
- tags: [],
- shortSha: '75daf01b',
- commitPath: '/root/test-job-artifacts/-/commit/75daf01b465e7eab5a04a315e44660c9a17c8055',
- pipeline: {
- id: 'gid://gitlab/Ci::Pipeline/288',
- path: '/root/test-job-artifacts/-/pipelines/288',
- user: {
- webPath: '/root',
- avatarUrl:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- __typename: 'UserCore',
- },
- __typename: 'Pipeline',
- },
- stage: { name: 'test', __typename: 'CiStage' },
- name: 'hello_world_delayed',
- duration: 6,
- finishedAt: '2021-08-30T20:36:12Z',
- coverage: null,
- retryable: true,
- playable: true,
- cancelable: false,
- active: false,
- stuck: false,
- userPermissions: {
- readBuild: true,
- readJobArtifacts: true,
- updateBuild: true,
- __typename: 'JobPermissions',
- },
- __typename: 'CiJob',
-};
-
-export const cannotPlayJob = {
- ...playableJob,
- userPermissions: {
- readBuild: true,
- readJobArtifacts: true,
- updateBuild: false,
- __typename: 'JobPermissions',
- },
-};
-
-export const scheduledJob = {
- artifacts: { nodes: [], __typename: 'CiJobArtifactConnection' },
- allowFailure: false,
- status: 'SCHEDULED',
- scheduledAt: '2021-08-31T22:36:05Z',
- manualJob: true,
- triggered: null,
- createdByTag: false,
- detailedStatus: {
- detailsPath: '/root/test-job-artifacts/-/jobs/1986',
- group: 'scheduled',
- icon: 'status_scheduled',
- label: 'unschedule action',
- text: 'delayed',
- tooltip: 'delayed manual action (%{remainingTime})',
- action: {
- buttonTitle: 'Unschedule job',
- icon: 'time-out',
- method: 'post',
- path: '/root/test-job-artifacts/-/jobs/1986/unschedule',
- title: 'Unschedule',
- __typename: 'StatusAction',
- },
- __typename: 'DetailedStatus',
- },
- id: 'gid://gitlab/Ci::Build/1986',
- refName: 'main',
- refPath: '/root/test-job-artifacts/-/commits/main',
- tags: [],
- shortSha: '75daf01b',
- commitPath: '/root/test-job-artifacts/-/commit/75daf01b465e7eab5a04a315e44660c9a17c8055',
- pipeline: {
- id: 'gid://gitlab/Ci::Pipeline/290',
- path: '/root/test-job-artifacts/-/pipelines/290',
- user: {
- webPath: '/root',
- avatarUrl:
- 'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
- __typename: 'UserCore',
- },
- __typename: 'Pipeline',
- },
- stage: { name: 'test', __typename: 'CiStage' },
- name: 'hello_world_delayed',
- duration: null,
- finishedAt: null,
- coverage: null,
- retryable: false,
- playable: true,
- cancelable: false,
- active: false,
- stuck: false,
- userPermissions: { readBuild: true, updateBuild: true, __typename: 'JobPermissions' },
- __typename: 'CiJob',
-};
-
-export const cannotPlayScheduledJob = {
- ...scheduledJob,
- userPermissions: {
- readBuild: true,
- readJobArtifacts: true,
- updateBuild: false,
- __typename: 'JobPermissions',
- },
-};
-
export const CIJobConnectionIncomingCache = {
__typename: 'CiJobConnection',
pageInfo: {
@@ -2000,3 +1414,167 @@ export const unscheduleMutationResponse = {
},
},
};
+
+export const mockJobLog = [
+ { offset: 0, content: [{ text: 'Running with gitlab-runner 15.0.0 (febb2a09)' }], lineNumber: 0 },
+ { offset: 54, content: [{ text: ' on colima-docker EwM9WzgD' }], lineNumber: 1 },
+ {
+ isClosed: false,
+ isHeader: true,
+ line: {
+ offset: 91,
+ content: [{ text: 'Resolving secrets', style: 'term-fg-l-cyan term-bold' }],
+ section: 'resolve-secrets',
+ section_header: true,
+ lineNumber: 2,
+ section_duration: '00:00',
+ },
+ lines: [],
+ },
+ {
+ isClosed: false,
+ isHeader: true,
+ line: {
+ offset: 218,
+ content: [{ text: 'Preparing the "docker" executor', style: 'term-fg-l-cyan term-bold' }],
+ section: 'prepare-executor',
+ section_header: true,
+ lineNumber: 4,
+ section_duration: '00:01',
+ },
+ lines: [
+ {
+ offset: 317,
+ content: [{ text: 'Using Docker executor with image ruby:2.7 ...' }],
+ section: 'prepare-executor',
+ lineNumber: 5,
+ },
+ {
+ offset: 372,
+ content: [{ text: 'Pulling docker image ruby:2.7 ...' }],
+ section: 'prepare-executor',
+ lineNumber: 6,
+ },
+ {
+ offset: 415,
+ content: [
+ {
+ text:
+ 'Using docker image sha256:55106bf6ba7f452c38d01ea760affc6ceb67d4b60068ffadab98d1b7b007668c for ruby:2.7 with digest ruby@sha256:23d08a4bae1a12ee3fce017f83204fcf9a02243443e4a516e65e5ff73810a449 ...',
+ },
+ ],
+ section: 'prepare-executor',
+ lineNumber: 7,
+ },
+ ],
+ },
+ {
+ isClosed: false,
+ isHeader: true,
+ line: {
+ offset: 665,
+ content: [{ text: 'Preparing environment', style: 'term-fg-l-cyan term-bold' }],
+ section: 'prepare-script',
+ section_header: true,
+ lineNumber: 9,
+ section_duration: '00:01',
+ },
+ lines: [
+ {
+ offset: 752,
+ content: [
+ { text: 'Running on runner-ewm9wzgd-project-20-concurrent-0 via 8ea689ec6969...' },
+ ],
+ section: 'prepare-script',
+ lineNumber: 10,
+ },
+ ],
+ },
+ {
+ isClosed: false,
+ isHeader: true,
+ line: {
+ offset: 865,
+ content: [{ text: 'Getting source from Git repository', style: 'term-fg-l-cyan term-bold' }],
+ section: 'get-sources',
+ section_header: true,
+ lineNumber: 12,
+ section_duration: '00:01',
+ },
+ lines: [
+ {
+ offset: 962,
+ content: [
+ {
+ text: 'Fetching changes with git depth set to 20...',
+ style: 'term-fg-l-green term-bold',
+ },
+ ],
+ section: 'get-sources',
+ lineNumber: 13,
+ },
+ {
+ offset: 1019,
+ content: [
+ { text: 'Reinitialized existing Git repository in /builds/root/ci-project/.git/' },
+ ],
+ section: 'get-sources',
+ lineNumber: 14,
+ },
+ {
+ offset: 1090,
+ content: [{ text: 'Checking out e0f63d76 as main...', style: 'term-fg-l-green term-bold' }],
+ section: 'get-sources',
+ lineNumber: 15,
+ },
+ {
+ offset: 1136,
+ content: [{ text: 'Skipping Git submodules setup', style: 'term-fg-l-green term-bold' }],
+ section: 'get-sources',
+ lineNumber: 16,
+ },
+ ],
+ },
+ {
+ isClosed: false,
+ isHeader: true,
+ line: {
+ offset: 1217,
+ content: [
+ {
+ text: 'Executing "step_script" stage of the job script',
+ style: 'term-fg-l-cyan term-bold',
+ },
+ ],
+ section: 'step-script',
+ section_header: true,
+ lineNumber: 18,
+ section_duration: '00:00',
+ },
+ lines: [
+ {
+ offset: 1327,
+ content: [
+ {
+ text:
+ 'Using docker image sha256:55106bf6ba7f452c38d01ea760affc6ceb67d4b60068ffadab98d1b7b007668c for ruby:2.7 with digest ruby@sha256:23d08a4bae1a12ee3fce017f83204fcf9a02243443e4a516e65e5ff73810a449 ...',
+ },
+ ],
+ section: 'step-script',
+ lineNumber: 19,
+ },
+ {
+ offset: 1533,
+ content: [{ text: '$ echo "82.71"', style: 'term-fg-l-green term-bold' }],
+ section: 'step-script',
+ lineNumber: 20,
+ },
+ { offset: 1560, content: [{ text: '82.71' }], section: 'step-script', lineNumber: 21 },
+ ],
+ },
+ {
+ offset: 1605,
+ content: [{ text: 'Job succeeded', style: 'term-fg-l-green term-bold' }],
+ lineNumber: 23,
+ },
+];
diff --git a/spec/frontend/jobs/store/mutations_spec.js b/spec/frontend/jobs/store/mutations_spec.js
index b73aa8abf4e..ea1ec383d6e 100644
--- a/spec/frontend/jobs/store/mutations_spec.js
+++ b/spec/frontend/jobs/store/mutations_spec.js
@@ -4,21 +4,12 @@ import state from '~/jobs/store/state';
describe('Jobs Store Mutations', () => {
let stateCopy;
- let origGon;
const html =
'I, [2018-08-17T22:57:45.707325 #1841] INFO -- : Writing /builds/ab89e95b0fa0b9272ea0c797b76908f24d36992630e9325273a4ce3.png<br>I';
beforeEach(() => {
stateCopy = state();
-
- origGon = window.gon;
-
- window.gon = { features: { infinitelyCollapsibleSections: false } };
- });
-
- afterEach(() => {
- window.gon = origGon;
});
describe('SET_JOB_ENDPOINT', () => {
@@ -276,88 +267,3 @@ describe('Jobs Store Mutations', () => {
});
});
});
-
-describe('Job Store mutations, feature flag ON', () => {
- let stateCopy;
- let origGon;
-
- const html =
- 'I, [2018-08-17T22:57:45.707325 #1841] INFO -- : Writing /builds/ab89e95b0fa0b9272ea0c797b76908f24d36992630e9325273a4ce3.png<br>I';
-
- beforeEach(() => {
- stateCopy = state();
-
- origGon = window.gon;
-
- window.gon = { features: { infinitelyCollapsibleSections: true } };
- });
-
- afterEach(() => {
- window.gon = origGon;
- });
-
- describe('RECEIVE_JOB_LOG_SUCCESS', () => {
- describe('with new job log', () => {
- describe('log.lines', () => {
- describe('when append is true', () => {
- it('sets the parsed log ', () => {
- mutations[types.RECEIVE_JOB_LOG_SUCCESS](stateCopy, {
- append: true,
- size: 511846,
- complete: true,
- lines: [
- {
- offset: 1,
- content: [{ text: 'Running with gitlab-runner 11.12.1 (5a147c92)' }],
- },
- ],
- });
-
- expect(stateCopy.jobLog).toEqual([
- {
- offset: 1,
- content: [{ text: 'Running with gitlab-runner 11.12.1 (5a147c92)' }],
- lineNumber: 1,
- },
- ]);
- });
- });
-
- describe('when lines are defined', () => {
- it('sets the parsed log ', () => {
- mutations[types.RECEIVE_JOB_LOG_SUCCESS](stateCopy, {
- append: false,
- size: 511846,
- complete: true,
- lines: [
- { offset: 0, content: [{ text: 'Running with gitlab-runner 11.11.1 (5a147c92)' }] },
- ],
- });
-
- expect(stateCopy.jobLog).toEqual([
- {
- offset: 0,
- content: [{ text: 'Running with gitlab-runner 11.11.1 (5a147c92)' }],
- lineNumber: 1,
- },
- ]);
- });
- });
-
- describe('when lines are null', () => {
- it('sets the default value', () => {
- mutations[types.RECEIVE_JOB_LOG_SUCCESS](stateCopy, {
- append: true,
- html,
- size: 511846,
- complete: false,
- lines: null,
- });
-
- expect(stateCopy.jobLog).toEqual([]);
- });
- });
- });
- });
- });
-});
diff --git a/spec/frontend/jobs/store/utils_spec.js b/spec/frontend/jobs/store/utils_spec.js
index 92ac33c8792..9458c2184f5 100644
--- a/spec/frontend/jobs/store/utils_spec.js
+++ b/spec/frontend/jobs/store/utils_spec.js
@@ -1,6 +1,5 @@
import {
logLinesParser,
- logLinesParserLegacy,
updateIncrementalJobLog,
parseHeaderLine,
parseLine,
@@ -18,8 +17,6 @@ import {
headerTraceIncremental,
collapsibleTrace,
collapsibleTraceIncremental,
- multipleCollapsibleSectionsMockData,
- backwardsCompatibilityTrace,
} from '../components/log/mock_data';
describe('Jobs Store Utils', () => {
@@ -178,11 +175,11 @@ describe('Jobs Store Utils', () => {
expect(isCollapsibleSection()).toEqual(false);
});
});
- describe('logLinesParserLegacy', () => {
+ describe('logLinesParser', () => {
let result;
beforeEach(() => {
- result = logLinesParserLegacy(utilsMockData);
+ result = logLinesParser(utilsMockData);
});
describe('regular line', () => {
@@ -219,102 +216,6 @@ describe('Jobs Store Utils', () => {
});
});
- describe('logLinesParser', () => {
- let result;
-
- beforeEach(() => {
- result = logLinesParser(utilsMockData);
- });
-
- describe('regular line', () => {
- it('adds a lineNumber property with correct index', () => {
- expect(result.parsedLines[0].lineNumber).toEqual(1);
- expect(result.parsedLines[1].line.lineNumber).toEqual(2);
- });
- });
-
- describe('collapsible section', () => {
- it('adds a `isClosed` property', () => {
- expect(result.parsedLines[1].isClosed).toEqual(false);
- });
-
- it('adds a `isHeader` property', () => {
- expect(result.parsedLines[1].isHeader).toEqual(true);
- });
-
- it('creates a lines array property with the content of the collapsible section', () => {
- expect(result.parsedLines[1].lines.length).toEqual(2);
- expect(result.parsedLines[1].lines[0].content).toEqual(utilsMockData[2].content);
- expect(result.parsedLines[1].lines[1].content).toEqual(utilsMockData[3].content);
- });
- });
-
- describe('section duration', () => {
- it('adds the section information to the header section', () => {
- expect(result.parsedLines[1].line.section_duration).toEqual(
- utilsMockData[4].section_duration,
- );
- });
-
- it('does not add section duration as a line', () => {
- expect(result.parsedLines[1].lines.includes(utilsMockData[4])).toEqual(false);
- });
- });
-
- describe('multiple collapsible sections', () => {
- beforeEach(() => {
- result = logLinesParser(multipleCollapsibleSectionsMockData);
- });
-
- it('should contain a section inside another section', () => {
- const innerSection = [
- {
- isClosed: false,
- isHeader: true,
- line: {
- content: [{ text: '1st collapsible section' }],
- lineNumber: 6,
- offset: 1006,
- section: 'collapsible-1',
- section_duration: '01:00',
- section_header: true,
- },
- lines: [
- {
- content: [
- {
- text:
- 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam lorem dolor, congue ac condimentum vitae',
- },
- ],
- lineNumber: 7,
- offset: 1007,
- section: 'collapsible-1',
- },
- ],
- },
- ];
-
- expect(result.parsedLines[1].lines).toEqual(expect.arrayContaining(innerSection));
- });
- });
-
- describe('backwards compatibility', () => {
- beforeEach(() => {
- result = logLinesParser(backwardsCompatibilityTrace);
- });
-
- it('should return an object with a parsedLines prop', () => {
- expect(result).toEqual(
- expect.objectContaining({
- parsedLines: expect.any(Array),
- }),
- );
- expect(result.parsedLines).toHaveLength(1);
- });
- });
- });
-
describe('findOffsetAndRemove', () => {
describe('when last item is header', () => {
const existingLog = [
@@ -490,7 +391,7 @@ describe('Jobs Store Utils', () => {
describe('updateIncrementalJobLog', () => {
describe('without repeated section', () => {
it('concats and parses both arrays', () => {
- const oldLog = logLinesParserLegacy(originalTrace);
+ const oldLog = logLinesParser(originalTrace);
const result = updateIncrementalJobLog(regularIncremental, oldLog);
expect(result).toEqual([
@@ -518,7 +419,7 @@ describe('Jobs Store Utils', () => {
describe('with regular line repeated offset', () => {
it('updates the last line and formats with the incremental part', () => {
- const oldLog = logLinesParserLegacy(originalTrace);
+ const oldLog = logLinesParser(originalTrace);
const result = updateIncrementalJobLog(regularIncrementalRepeated, oldLog);
expect(result).toEqual([
@@ -537,7 +438,7 @@ describe('Jobs Store Utils', () => {
describe('with header line repeated', () => {
it('updates the header line and formats with the incremental part', () => {
- const oldLog = logLinesParserLegacy(headerTrace);
+ const oldLog = logLinesParser(headerTrace);
const result = updateIncrementalJobLog(headerTraceIncremental, oldLog);
expect(result).toEqual([
@@ -563,7 +464,7 @@ describe('Jobs Store Utils', () => {
describe('with collapsible line repeated', () => {
it('updates the collapsible line and formats with the incremental part', () => {
- const oldLog = logLinesParserLegacy(collapsibleTrace);
+ const oldLog = logLinesParser(collapsibleTrace);
const result = updateIncrementalJobLog(collapsibleTraceIncremental, oldLog);
expect(result).toEqual([