diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-13 21:11:28 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2021-04-13 21:11:28 +0300 |
commit | a5605d87fb839e0b1015ad9e736c44fbb2ada202 (patch) | |
tree | 9717afb7cc7d663de6bda5d78c651aafb73a16a3 /spec/frontend_integration | |
parent | 536d72ba7ea2226b56ddc55a3eb35c96a9ba3b6d (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/frontend_integration')
5 files changed, 215 insertions, 0 deletions
diff --git a/spec/frontend_integration/diffs/diffs_interopability_api.js b/spec/frontend_integration/diffs/diffs_interopability_api.js new file mode 100644 index 00000000000..adfb93f27a2 --- /dev/null +++ b/spec/frontend_integration/diffs/diffs_interopability_api.js @@ -0,0 +1,25 @@ +/** + * This helper module contains the API expectation of the diff output HTML. + * + * This helps simulate what third-party HTML scrapers, such as Sourcegraph, + * should be looking for. + */ +export const getDiffCodePart = (codeElement) => { + const el = codeElement.closest('[data-interop-type]'); + + return el.dataset.interopType === 'old' ? 'base' : 'head'; +}; + +export const getCodeElementFromLineNumber = (codeView, line, part) => { + const type = part === 'base' ? 'old' : 'new'; + + const el = codeView.querySelector(`[data-interop-${type}-line="${line}"]`); + + return el ? el.querySelector('span.line') : null; +}; + +export const getLineNumberFromCodeElement = (codeElement) => { + const el = codeElement.closest('[data-interop-line]'); + + return parseInt(el.dataset.interopLine || '', 10); +}; diff --git a/spec/frontend_integration/diffs/diffs_interopability_spec.js b/spec/frontend_integration/diffs/diffs_interopability_spec.js new file mode 100644 index 00000000000..cb7659e16d3 --- /dev/null +++ b/spec/frontend_integration/diffs/diffs_interopability_spec.js @@ -0,0 +1,161 @@ +import { waitFor } from '@testing-library/dom'; +import { TEST_HOST } from 'helpers/test_constants'; +import initDiffsApp from '~/diffs'; +import { createStore } from '~/mr_notes/stores'; +import { + getDiffCodePart, + getLineNumberFromCodeElement, + getCodeElementFromLineNumber, +} from './diffs_interopability_api'; + +jest.mock('~/vue_shared/mixins/gl_feature_flags_mixin', () => () => ({ + inject: { + glFeatures: { + from: 'window.gon.features', + default: () => global.window.gon?.features, + }, + }, +})); + +const TEST_PROJECT_PATH = 'gitlab-org/gitlab-test'; +const TEST_BASE_URL = `/${TEST_PROJECT_PATH}/-/merge_requests/1/`; +const TEST_DIFF_FILE = 'files/js/commit.coffee'; +const EXPECT_INLINE = [ + ['head', 1], + ['head', 2], + ['head', 3], + ['base', 4], + ['head', 4], + null, + ['base', 6], + ['head', 6], + null, +]; +const EXPECT_PARALLEL_LEFT_SIDE = [ + ['base', 1], + ['base', 2], + ['base', 3], + ['base', 4], + null, + ['base', 6], + null, +]; +const EXPECT_PARALLEL_RIGHT_SIDE = [ + ['head', 1], + ['head', 2], + ['head', 3], + ['head', 4], + null, + ['head', 6], + null, +]; + +const startDiffsApp = () => { + const el = document.createElement('div'); + el.id = 'js-diffs-app'; + document.body.appendChild(el); + Object.assign(el.dataset, { + endpoint: TEST_BASE_URL, + endpointMetadata: `${TEST_BASE_URL}diffs_metadata.json`, + endpointBatch: `${TEST_BASE_URL}diffs_batch.json`, + projectPath: TEST_PROJECT_PATH, + helpPagePath: '/help', + currentUserData: 'null', + changesEmptyStateIllustration: '', + isFluidLayout: 'false', + dismissEndpoint: '', + showSuggestPopover: 'false', + showWhitespaceDefault: 'true', + viewDiffsFileByFile: 'false', + defaultSuggestionCommitMessage: 'Lorem ipsum', + }); + + const store = createStore(); + + const vm = initDiffsApp(store); + + store.dispatch('setActiveTab', 'diffs'); + + return vm; +}; + +describe('diffs third party interoperability', () => { + let vm; + + afterEach(() => { + vm.$destroy(); + document.body.innerHTML = ''; + }); + + const tryOrErrorMessage = (fn) => (...args) => { + try { + return fn(...args); + } catch (e) { + return e.message; + } + }; + + const findDiffFile = () => document.querySelector(`.diff-file[data-path="${TEST_DIFF_FILE}"]`); + const hasLines = (sel = 'tr.line_holder') => findDiffFile().querySelectorAll(sel).length > 0; + const findLineElements = (sel = 'tr.line_holder') => + Array.from(findDiffFile().querySelectorAll(sel)); + + const findCodeElements = (lines, sel = 'td.line_content') => { + return lines.map((x) => x.querySelector(`${sel} span.line`)); + }; + + const getCodeElementsInteropModel = (codeElements) => + codeElements.map( + (x) => + x && [ + tryOrErrorMessage(getDiffCodePart)(x), + tryOrErrorMessage(getLineNumberFromCodeElement)(x), + ], + ); + + describe.each` + desc | unifiedDiffComponents | view | rowSelector | codeSelector | expectation + ${'inline view'} | ${false} | ${'inline'} | ${'tr.line_holder'} | ${'td.line_content'} | ${EXPECT_INLINE} + ${'parallel view left side'} | ${false} | ${'parallel'} | ${'tr.line_holder'} | ${'td.line_content.left-side'} | ${EXPECT_PARALLEL_LEFT_SIDE} + ${'parallel view right side'} | ${false} | ${'parallel'} | ${'tr.line_holder'} | ${'td.line_content.right-side'} | ${EXPECT_PARALLEL_RIGHT_SIDE} + ${'inline view'} | ${true} | ${'inline'} | ${'.diff-tr.line_holder'} | ${'.diff-td.line_content'} | ${EXPECT_INLINE} + ${'parallel view left side'} | ${true} | ${'parallel'} | ${'.diff-tr.line_holder'} | ${'.diff-td.line_content.left-side'} | ${EXPECT_PARALLEL_LEFT_SIDE} + ${'parallel view right side'} | ${true} | ${'parallel'} | ${'.diff-tr.line_holder'} | ${'.diff-td.line_content.right-side'} | ${EXPECT_PARALLEL_RIGHT_SIDE} + `( + '$desc (unifiedDiffComponents=$unifiedDiffComponents)', + ({ unifiedDiffComponents, view, rowSelector, codeSelector, expectation }) => { + beforeEach(async () => { + global.jsdom.reconfigure({ + url: `${TEST_HOST}/${TEST_BASE_URL}/diffs?view=${view}`, + }); + window.gon.features = { unifiedDiffComponents }; + + vm = startDiffsApp(); + + await waitFor(() => expect(hasLines(rowSelector)).toBe(true)); + }); + + it('should match diff model', () => { + const lines = findLineElements(rowSelector); + const codes = findCodeElements(lines, codeSelector); + + expect(getCodeElementsInteropModel(codes)).toEqual(expectation); + }); + + it.each` + lineNumber | part | expectedText + ${4} | ${'base'} | ${'new CommitFile(this)'} + ${4} | ${'head'} | ${'new CommitFile(@)'} + ${2} | ${'base'} | ${'constructor: ->'} + ${2} | ${'head'} | ${'constructor: ->'} + `( + 'should find code element lineNumber=$lineNumber part=$part', + ({ lineNumber, part, expectedText }) => { + const codeElement = getCodeElementFromLineNumber(findDiffFile(), lineNumber, part); + + expect(codeElement.textContent.trim()).toBe(expectedText); + }, + ); + }, + ); +}); diff --git a/spec/frontend_integration/test_helpers/fixtures.js b/spec/frontend_integration/test_helpers/fixtures.js index b2768440607..5673e36197f 100644 --- a/spec/frontend_integration/test_helpers/fixtures.js +++ b/spec/frontend_integration/test_helpers/fixtures.js @@ -40,6 +40,12 @@ export const getMergeRequestVersions = factory.json(() => export const getRepositoryFiles = factory.json(() => require('test_fixtures/projects_json/files.json'), ); +export const getDiffsMetadata = factory.json(() => + require('test_fixtures/merge_request_diffs/diffs_metadata.json'), +); +export const getDiffsBatch = factory.json(() => + require('test_fixtures/merge_request_diffs/diffs_batch.json'), +); export const getPipelinesEmptyResponse = factory.json(() => require('test_fixtures/projects_json/pipelines_empty.json'), ); diff --git a/spec/frontend_integration/test_helpers/mock_server/routes/diffs.js b/spec/frontend_integration/test_helpers/mock_server/routes/diffs.js new file mode 100644 index 00000000000..8301627e842 --- /dev/null +++ b/spec/frontend_integration/test_helpers/mock_server/routes/diffs.js @@ -0,0 +1,22 @@ +import { getDiffsMetadata, getDiffsBatch } from 'test_helpers/fixtures'; +import { withValues } from 'test_helpers/utils/obj'; + +export default (server) => { + server.get('/:namespace/:project/-/merge_requests/:mrid/diffs_metadata.json', () => { + return getDiffsMetadata(); + }); + + server.get('/:namespace/:project/-/merge_requests/:mrid/diffs_batch.json', () => { + const { pagination, ...result } = getDiffsBatch(); + + return { + ...result, + pagination: withValues(pagination, { + current_page: null, + next_page: null, + total_pages: 1, + next_page_href: null, + }), + }; + }); +}; diff --git a/spec/frontend_integration/test_helpers/mock_server/routes/index.js b/spec/frontend_integration/test_helpers/mock_server/routes/index.js index e30fecf2f06..48eff2702dd 100644 --- a/spec/frontend_integration/test_helpers/mock_server/routes/index.js +++ b/spec/frontend_integration/test_helpers/mock_server/routes/index.js @@ -5,6 +5,7 @@ export default (server) => { require('./projects'), require('./repository'), require('./ci'), + require('./diffs'), require('./404'), ].forEach(({ default: setup }) => { setup(server); |