From 0c872e02b2c822e3397515ec324051ff540f0cd5 Mon Sep 17 00:00:00 2001 From: GitLab Bot Date: Tue, 20 Dec 2022 14:22:11 +0000 Subject: Add latest changes from gitlab-org/gitlab@15-7-stable-ee --- .../diffs/components/diff_code_quality_spec.js | 15 +++++--- .../diffs/components/diff_discussion_reply_spec.js | 36 ++++++++++++++++-- .../diffs/components/diff_discussions_spec.js | 3 +- spec/frontend/diffs/mock_data/diff_code_quality.js | 28 ++++++++++---- spec/frontend/diffs/store/actions_spec.js | 44 ++++++++++++++++++++++ spec/frontend/diffs/utils/merge_request_spec.js | 40 ++++++++++++++++++-- 6 files changed, 147 insertions(+), 19 deletions(-) (limited to 'spec/frontend/diffs') diff --git a/spec/frontend/diffs/components/diff_code_quality_spec.js b/spec/frontend/diffs/components/diff_code_quality_spec.js index b5dce4fc924..7bd9afab648 100644 --- a/spec/frontend/diffs/components/diff_code_quality_spec.js +++ b/spec/frontend/diffs/components/diff_code_quality_spec.js @@ -1,12 +1,14 @@ import { GlIcon } from '@gitlab/ui'; import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper'; import DiffCodeQuality from '~/diffs/components/diff_code_quality.vue'; -import { SEVERITY_CLASSES, SEVERITY_ICONS } from '~/reports/codequality_report/constants'; +import { SEVERITY_CLASSES, SEVERITY_ICONS } from '~/ci/reports/codequality_report/constants'; +import { NEW_CODE_QUALITY_FINDINGS } from '~/diffs/i18n'; import { multipleFindingsArr } from '../mock_data/diff_code_quality'; let wrapper; const findIcon = () => wrapper.findComponent(GlIcon); +const findHeading = () => wrapper.findByTestId(`diff-codequality-findings-heading`); describe('DiffCodeQuality', () => { afterEach(() => { @@ -30,14 +32,17 @@ describe('DiffCodeQuality', () => { expect(wrapper.emitted('hideCodeQualityFindings').length).toBe(1); }); - it('renders correct amount of list items for codequality array and their description', async () => { + it('renders heading and correct amount of list items for codequality array and their description', async () => { wrapper = createWrapper(multipleFindingsArr); - const listItems = wrapper.findAll('li'); + expect(findHeading().text()).toEqual(NEW_CODE_QUALITY_FINDINGS); - expect(wrapper.findAll('li').length).toBe(3); + const listItems = wrapper.findAll('li'); + expect(wrapper.findAll('li').length).toBe(5); listItems.wrappers.map((e, i) => { - return expect(e.text()).toEqual(multipleFindingsArr[i].description); + return expect(e.text()).toContain( + `${multipleFindingsArr[i].severity} - ${multipleFindingsArr[i].description}`, + ); }); }); diff --git a/spec/frontend/diffs/components/diff_discussion_reply_spec.js b/spec/frontend/diffs/components/diff_discussion_reply_spec.js index 5ccd2002462..bf4a1a1c1f7 100644 --- a/spec/frontend/diffs/components/diff_discussion_reply_spec.js +++ b/spec/frontend/diffs/components/diff_discussion_reply_spec.js @@ -1,10 +1,12 @@ import { shallowMount } from '@vue/test-utils'; +import { GlButton } from '@gitlab/ui'; import Vue from 'vue'; import Vuex from 'vuex'; import DiffDiscussionReply from '~/diffs/components/diff_discussion_reply.vue'; -import ReplyPlaceholder from '~/notes/components/discussion_reply_placeholder.vue'; import NoteSignedOutWidget from '~/notes/components/note_signed_out_widget.vue'; +import { START_THREAD } from '~/diffs/i18n'; + Vue.use(Vuex); describe('DiffDiscussionReply', () => { @@ -58,14 +60,42 @@ describe('DiffDiscussionReply', () => { expect(wrapper.find('#test-form').exists()).toBe(true); }); - it('should render a reply placeholder if there is no form', () => { + it('should render a reply placeholder button if there is no form', () => { createComponent({ renderReplyPlaceholder: true, hasForm: false, }); - expect(wrapper.findComponent(ReplyPlaceholder).exists()).toBe(true); + expect(wrapper.findComponent(GlButton).text()).toBe(START_THREAD); }); + + it.each` + userCanReply | hasForm | renderReplyPlaceholder | showButton + ${false} | ${false} | ${false} | ${false} + ${true} | ${false} | ${false} | ${false} + ${true} | ${true} | ${false} | ${false} + ${true} | ${true} | ${true} | ${false} + ${true} | ${false} | ${true} | ${true} + ${false} | ${false} | ${true} | ${false} + `( + 'reply button existence is `$showButton` when userCanReply is `$userCanReply`, hasForm is `$hasForm` and renderReplyPlaceholder is `$renderReplyPlaceholder`', + ({ userCanReply, hasForm, renderReplyPlaceholder, showButton }) => { + getters = { + userCanReply: () => userCanReply, + }; + + store = new Vuex.Store({ + getters, + }); + + createComponent({ + renderReplyPlaceholder, + hasForm, + }); + + expect(wrapper.findComponent(GlButton).exists()).toBe(showButton); + }, + ); }); it('renders a signed out widget when user is not logged in', () => { diff --git a/spec/frontend/diffs/components/diff_discussions_spec.js b/spec/frontend/diffs/components/diff_discussions_spec.js index e9a0e0745fd..5092ae6ab6e 100644 --- a/spec/frontend/diffs/components/diff_discussions_spec.js +++ b/spec/frontend/diffs/components/diff_discussions_spec.js @@ -5,9 +5,10 @@ import { createStore } from '~/mr_notes/stores'; import DiscussionNotes from '~/notes/components/discussion_notes.vue'; import NoteableDiscussion from '~/notes/components/noteable_discussion.vue'; import TimelineEntryItem from '~/vue_shared/components/notes/timeline_entry_item.vue'; -import '~/behaviors/markdown/render_gfm'; import discussionsMockData from '../mock_data/diff_discussions'; +jest.mock('~/behaviors/markdown/render_gfm'); + describe('DiffDiscussions', () => { let store; let wrapper; diff --git a/spec/frontend/diffs/mock_data/diff_code_quality.js b/spec/frontend/diffs/mock_data/diff_code_quality.js index befab3b676b..7558592f6a4 100644 --- a/spec/frontend/diffs/mock_data/diff_code_quality.js +++ b/spec/frontend/diffs/mock_data/diff_code_quality.js @@ -1,25 +1,39 @@ export const multipleFindingsArr = [ { severity: 'minor', - description: 'Unexpected Debugger Statement.', + description: 'mocked minor Issue', line: 2, }, { severity: 'major', - description: - 'Function `aVeryLongFunction` has 52 lines of code (exceeds 25 allowed). Consider refactoring.', + description: 'mocked major Issue', line: 3, }, { - severity: 'minor', - description: 'Arrow function has too many statements (52). Maximum allowed is 30.', + severity: 'info', + description: 'mocked info Issue', + line: 3, + }, + { + severity: 'critical', + description: 'mocked critical Issue', + line: 3, + }, + { + severity: 'blocker', + description: 'mocked blocker Issue', line: 3, }, ]; -export const multipleFindings = { +export const fiveFindings = { + filePath: 'index.js', + codequality: multipleFindingsArr.slice(0, 5), +}; + +export const threeFindings = { filePath: 'index.js', - codequality: multipleFindingsArr, + codequality: multipleFindingsArr.slice(0, 3), }; export const singularFinding = { diff --git a/spec/frontend/diffs/store/actions_spec.js b/spec/frontend/diffs/store/actions_spec.js index 87366cdbfc5..9e0ffbf757f 100644 --- a/spec/frontend/diffs/store/actions_spec.js +++ b/spec/frontend/diffs/store/actions_spec.js @@ -606,6 +606,50 @@ describe('DiffsStoreActions', () => { params: { commit_id: '123', w: '0' }, }); }); + + describe('version parameters', () => { + const diffId = '4'; + const startSha = 'abc'; + const pathRoot = 'a/a/-/merge_requests/1'; + let file; + let getters; + + beforeAll(() => { + file = { load_collapsed_diff_url: '/load/collapsed/diff/url' }; + getters = {}; + }); + + beforeEach(() => { + jest.spyOn(axios, 'get').mockReturnValue(Promise.resolve({ data: {} })); + }); + + it('fetches the data when there is no mergeRequestDiff', () => { + diffActions.loadCollapsedDiff({ commit() {}, getters, state }, file); + + expect(axios.get).toHaveBeenCalledWith(file.load_collapsed_diff_url, { + params: expect.any(Object), + }); + }); + + it.each` + desc | versionPath | start_sha | diff_id + ${'no additional version information'} | ${`${pathRoot}?search=terms`} | ${undefined} | ${undefined} + ${'the diff_id'} | ${`${pathRoot}?diff_id=${diffId}`} | ${undefined} | ${diffId} + ${'the start_sha'} | ${`${pathRoot}?start_sha=${startSha}`} | ${startSha} | ${undefined} + ${'all available version information'} | ${`${pathRoot}?diff_id=${diffId}&start_sha=${startSha}`} | ${startSha} | ${diffId} + `('fetches the data and includes $desc', ({ versionPath, start_sha, diff_id }) => { + jest.spyOn(axios, 'get').mockReturnValue(Promise.resolve({ data: {} })); + + diffActions.loadCollapsedDiff( + { commit() {}, getters, state: { mergeRequestDiff: { version_path: versionPath } } }, + file, + ); + + expect(axios.get).toHaveBeenCalledWith(file.load_collapsed_diff_url, { + params: expect.objectContaining({ start_sha, diff_id }), + }); + }); + }); }); describe('toggleFileDiscussions', () => { diff --git a/spec/frontend/diffs/utils/merge_request_spec.js b/spec/frontend/diffs/utils/merge_request_spec.js index 8c7b1e1f2a5..c070e8c004d 100644 --- a/spec/frontend/diffs/utils/merge_request_spec.js +++ b/spec/frontend/diffs/utils/merge_request_spec.js @@ -2,30 +2,64 @@ import { getDerivedMergeRequestInformation } from '~/diffs/utils/merge_request'; import { diffMetadata } from '../mock_data/diff_metadata'; describe('Merge Request utilities', () => { - const derivedMrInfo = { + const derivedBaseInfo = { mrPath: '/gitlab-org/gitlab-test/-/merge_requests/4', userOrGroup: 'gitlab-org', project: 'gitlab-test', id: '4', }; + const derivedVersionInfo = { + diffId: '4', + startSha: 'eb227b3e214624708c474bdab7bde7afc17cefcc', + }; + const noVersion = { + diffId: undefined, + startSha: undefined, + }; const unparseableEndpoint = { mrPath: undefined, userOrGroup: undefined, project: undefined, id: undefined, + ...noVersion, }; describe('getDerivedMergeRequestInformation', () => { - const endpoint = `${diffMetadata.latest_version_path}.json?searchParam=irrelevant`; + let endpoint = `${diffMetadata.latest_version_path}.json?searchParam=irrelevant`; it.each` argument | response - ${{ endpoint }} | ${derivedMrInfo} + ${{ endpoint }} | ${{ ...derivedBaseInfo, ...noVersion }} ${{}} | ${unparseableEndpoint} ${{ endpoint: undefined }} | ${unparseableEndpoint} ${{ endpoint: null }} | ${unparseableEndpoint} `('generates the correct derived results based on $argument', ({ argument, response }) => { expect(getDerivedMergeRequestInformation(argument)).toStrictEqual(response); }); + + describe('version information', () => { + const bare = diffMetadata.latest_version_path; + endpoint = diffMetadata.merge_request_diffs[0].compare_path; + + it('still gets the correct derived information', () => { + expect(getDerivedMergeRequestInformation({ endpoint })).toMatchObject(derivedBaseInfo); + }); + + it.each` + url | versionPart + ${endpoint} | ${derivedVersionInfo} + ${`${bare}?diff_id=${derivedVersionInfo.diffId}`} | ${{ ...derivedVersionInfo, startSha: undefined }} + ${`${bare}?start_sha=${derivedVersionInfo.startSha}`} | ${{ ...derivedVersionInfo, diffId: undefined }} + `( + 'generates the correct derived version information based on $url', + ({ url, versionPart }) => { + expect(getDerivedMergeRequestInformation({ endpoint: url })).toMatchObject(versionPart); + }, + ); + + it('extracts nothing if there is no available version-like information in the URL', () => { + expect(getDerivedMergeRequestInformation({ endpoint: bare })).toMatchObject(noVersion); + }); + }); }); }); -- cgit v1.2.1