summaryrefslogtreecommitdiff
path: root/spec/frontend_integration/diffs/diffs_interopability_spec.js
blob: 448641ed83432badceefe0aa6f30c03c9ad327cd (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
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';

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                          | view          | rowSelector               | codeSelector                          | expectation
    ${'inline view'}              | ${'inline'}   | ${'.diff-tr.line_holder'} | ${'.diff-td.line_content'}            | ${EXPECT_INLINE}
    ${'parallel view left side'}  | ${'parallel'} | ${'.diff-tr.line_holder'} | ${'.diff-td.line_content.left-side'}  | ${EXPECT_PARALLEL_LEFT_SIDE}
    ${'parallel view right side'} | ${'parallel'} | ${'.diff-tr.line_holder'} | ${'.diff-td.line_content.right-side'} | ${EXPECT_PARALLEL_RIGHT_SIDE}
  `('$desc', ({ view, rowSelector, codeSelector, expectation }) => {
    beforeEach(async () => {
      global.jsdom.reconfigure({
        url: `${TEST_HOST}/${TEST_BASE_URL}/diffs?view=${view}`,
      });

      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);
      },
    );
  });
});