From e8d2c2579383897a1dd7f9debd359abe8ae8373d Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 20 Jul 2021 09:55:51 +0000 Subject: Add latest changes from gitlab-org/gitlab@14-1-stable-ee --- .../components/log/collapsible_section_spec.js | 9 +++ spec/frontend/jobs/components/log/line_spec.js | 30 +++++++ spec/frontend/jobs/components/log/log_spec.js | 91 +++++++++++++++++++++- spec/frontend/jobs/components/log/mock_data.js | 65 ++++++++++++++++ 4 files changed, 193 insertions(+), 2 deletions(-) (limited to 'spec/frontend/jobs/components/log') diff --git a/spec/frontend/jobs/components/log/collapsible_section_spec.js b/spec/frontend/jobs/components/log/collapsible_section_spec.js index 66f22162c97..4e23a3ba7b8 100644 --- a/spec/frontend/jobs/components/log/collapsible_section_spec.js +++ b/spec/frontend/jobs/components/log/collapsible_section_spec.js @@ -4,6 +4,7 @@ import { collapsibleSectionClosed, collapsibleSectionOpened } from './mock_data' describe('Job Log Collapsible Section', () => { let wrapper; + let origGon; const traceEndpoint = 'jobs/335'; @@ -18,8 +19,16 @@ 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 367154e7f82..d184696cd1f 100644 --- a/spec/frontend/jobs/components/log/line_spec.js +++ b/spec/frontend/jobs/components/log/line_spec.js @@ -94,6 +94,16 @@ describe('Job Log Line', () => { expect(findLinkAttributeByIndex(0).href).toBe(queryUrl); }); + it('renders links that have brackets `[]` in their parameters', () => { + const url = `${httpUrl}?label_name[]=frontend`; + + createComponent(mockProps({ text: url })); + + expect(findLine().text()).toBe(url); + expect(findLinks().at(0).text()).toBe(url); + expect(findLinks().at(0).attributes('href')).toBe(url); + }); + it('renders multiple links surrounded by text', () => { createComponent( mockProps({ text: `Well, my HTTP url: ${httpUrl} and my HTTPS url: ${httpsUrl}` }), @@ -125,6 +135,26 @@ describe('Job Log Line', () => { expect(findLinkAttributeByIndex(4).href).toBe(httpsUrl); }); + it('renders multiple links surrounded by brackets', () => { + createComponent(mockProps({ text: `(${httpUrl}) <${httpUrl}> {${httpsUrl}}` })); + expect(findLine().text()).toBe( + '(http://example.com) {https://example.com}', + ); + + const links = findLinks(); + + expect(links).toHaveLength(3); + + expect(links.at(0).text()).toBe(httpUrl); + expect(links.at(0).attributes('href')).toBe(httpUrl); + + expect(links.at(1).text()).toBe(httpUrl); + expect(links.at(1).attributes('href')).toBe(httpUrl); + + expect(links.at(2).text()).toBe(httpsUrl); + expect(links.at(2).attributes('href')).toBe(httpsUrl); + }); + it('renders text with symbols in it', () => { const text = 'apt-get update < /dev/null > /dev/null'; createComponent(mockProps({ text })); diff --git a/spec/frontend/jobs/components/log/log_spec.js b/spec/frontend/jobs/components/log/log_spec.js index b7aff1f3e3b..99fb6846ce5 100644 --- a/spec/frontend/jobs/components/log/log_spec.js +++ b/spec/frontend/jobs/components/log/log_spec.js @@ -1,7 +1,7 @@ import { mount, createLocalVue } from '@vue/test-utils'; import Vuex from 'vuex'; import Log from '~/jobs/components/log/log.vue'; -import { logLinesParser } from '~/jobs/store/utils'; +import { logLinesParserLegacy, logLinesParser } from '~/jobs/store/utils'; import { jobLog } from './mock_data'; describe('Job Log', () => { @@ -9,6 +9,7 @@ describe('Job Log', () => { let actions; let state; let store; + let origGon; const localVue = createLocalVue(); localVue.use(Vuex); @@ -25,8 +26,12 @@ describe('Job Log', () => { toggleCollapsibleLine: () => {}, }; + origGon = window.gon; + + window.gon = { features: { infinitelyCollapsibleSections: false } }; + state = { - trace: logLinesParser(jobLog), + trace: logLinesParserLegacy(jobLog), traceEndpoint: 'jobs/id', }; @@ -40,6 +45,88 @@ 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.traceEndpoint}#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="angle-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; + + const localVue = createLocalVue(); + localVue.use(Vuex); + + const createComponent = () => { + wrapper = mount(Log, { + localVue, + store, + }); + }; + + beforeEach(() => { + actions = { + toggleCollapsibleLine: () => {}, + }; + + origGon = window.gon; + + window.gon = { features: { infinitelyCollapsibleSections: true } }; + + state = { + trace: logLinesParser(jobLog).parsedLines, + traceEndpoint: '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 eb8c4fe8bc9..76c35703106 100644 --- a/spec/frontend/jobs/components/log/mock_data.js +++ b/spec/frontend/jobs/components/log/mock_data.js @@ -58,6 +58,71 @@ 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 originalTrace = [ { offset: 1, -- cgit v1.2.3