summaryrefslogtreecommitdiff
path: root/spec/frontend/diffs
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 09:55:51 +0000
committerGitLab Bot <gitlab-bot@gitlab.com>2021-07-20 09:55:51 +0000
commite8d2c2579383897a1dd7f9debd359abe8ae8373d (patch)
treec42be41678c2586d49a75cabce89322082698334 /spec/frontend/diffs
parentfc845b37ec3a90aaa719975f607740c22ba6a113 (diff)
downloadgitlab-ce-e8d2c2579383897a1dd7f9debd359abe8ae8373d.tar.gz
Add latest changes from gitlab-org/gitlab@14-1-stable-eev14.1.0-rc42
Diffstat (limited to 'spec/frontend/diffs')
-rw-r--r--spec/frontend/diffs/components/app_spec.js46
-rw-r--r--spec/frontend/diffs/components/collapsed_files_warning_spec.js93
-rw-r--r--spec/frontend/diffs/components/diff_content_spec.js17
-rw-r--r--spec/frontend/diffs/components/diff_file_spec.js5
-rw-r--r--spec/frontend/diffs/components/diff_row_spec.js127
-rw-r--r--spec/frontend/diffs/components/diff_row_utils_spec.js43
-rw-r--r--spec/frontend/diffs/components/diff_view_spec.js18
-rw-r--r--spec/frontend/diffs/components/inline_diff_table_row_spec.js325
-rw-r--r--spec/frontend/diffs/components/inline_diff_view_spec.js57
-rw-r--r--spec/frontend/diffs/components/parallel_diff_table_row_spec.js445
-rw-r--r--spec/frontend/diffs/components/parallel_diff_view_spec.js37
-rw-r--r--spec/frontend/diffs/store/actions_spec.js31
-rw-r--r--spec/frontend/diffs/store/getters_versions_dropdowns_spec.js2
13 files changed, 206 insertions, 1040 deletions
diff --git a/spec/frontend/diffs/components/app_spec.js b/spec/frontend/diffs/components/app_spec.js
index 8a1c5547581..b5eb3e1713c 100644
--- a/spec/frontend/diffs/components/app_spec.js
+++ b/spec/frontend/diffs/components/app_spec.js
@@ -6,14 +6,19 @@ import Vue, { nextTick } from 'vue';
import Vuex from 'vuex';
import { TEST_HOST } from 'spec/test_constants';
import App from '~/diffs/components/app.vue';
-import CollapsedFilesWarning from '~/diffs/components/collapsed_files_warning.vue';
import CommitWidget from '~/diffs/components/commit_widget.vue';
import CompareVersions from '~/diffs/components/compare_versions.vue';
import DiffFile from '~/diffs/components/diff_file.vue';
-import HiddenFilesWarning from '~/diffs/components/hidden_files_warning.vue';
import NoChanges from '~/diffs/components/no_changes.vue';
import TreeList from '~/diffs/components/tree_list.vue';
+/* eslint-disable import/order */
+/* You know what: sometimes alphabetical isn't the best order */
+import CollapsedFilesWarning from '~/diffs/components/collapsed_files_warning.vue';
+import HiddenFilesWarning from '~/diffs/components/hidden_files_warning.vue';
+import MergeConflictWarning from '~/diffs/components/merge_conflict_warning.vue';
+/* eslint-enable import/order */
+
import axios from '~/lib/utils/axios_utils';
import * as urlUtils from '~/lib/utils/url_utility';
import createDiffsStore from '../create_diffs_store';
@@ -541,6 +546,43 @@ describe('diffs/components/app', () => {
expect(getCollapsedFilesWarning(wrapper).exists()).toBe(false);
});
});
+
+ describe('merge conflicts', () => {
+ it('should render the merge conflicts banner if viewing the whole changeset and there are conflicts', () => {
+ createComponent({}, ({ state }) => {
+ Object.assign(state.diffs, {
+ latestDiff: true,
+ startVersion: null,
+ hasConflicts: true,
+ canMerge: false,
+ conflictResolutionPath: 'path',
+ });
+ });
+
+ expect(wrapper.find(MergeConflictWarning).exists()).toBe(true);
+ });
+
+ it.each`
+ prop | value
+ ${'latestDiff'} | ${false}
+ ${'startVersion'} | ${'notnull'}
+ ${'hasConflicts'} | ${false}
+ `(
+ "should not render if any of the MR properties aren't correct - like $prop: $value",
+ ({ prop, value }) => {
+ createComponent({}, ({ state }) => {
+ Object.assign(state.diffs, {
+ latestDiff: true,
+ startVersion: null,
+ hasConflicts: true,
+ [prop]: value,
+ });
+ });
+
+ expect(wrapper.find(MergeConflictWarning).exists()).toBe(false);
+ },
+ );
+ });
});
it('should display commit widget if store has a commit', () => {
diff --git a/spec/frontend/diffs/components/collapsed_files_warning_spec.js b/spec/frontend/diffs/components/collapsed_files_warning_spec.js
index 77c2e19cb68..46caeb01132 100644
--- a/spec/frontend/diffs/components/collapsed_files_warning_spec.js
+++ b/spec/frontend/diffs/components/collapsed_files_warning_spec.js
@@ -1,10 +1,13 @@
import { shallowMount, mount, createLocalVue } from '@vue/test-utils';
+import { nextTick } from 'vue';
import Vuex from 'vuex';
import CollapsedFilesWarning from '~/diffs/components/collapsed_files_warning.vue';
import { CENTERED_LIMITED_CONTAINER_CLASSES, EVT_EXPAND_ALL_FILES } from '~/diffs/constants';
import eventHub from '~/diffs/event_hub';
import createStore from '~/diffs/store/modules';
+import file from '../mock_data/diff_file';
+
const propsData = {
limited: true,
mergeable: true,
@@ -12,6 +15,13 @@ const propsData = {
};
const limitedClasses = CENTERED_LIMITED_CONTAINER_CLASSES.split(' ');
+async function files(store, count) {
+ const copies = Array(count).fill(file);
+ store.state.diffs.diffFiles.push(...copies);
+
+ return nextTick();
+}
+
describe('CollapsedFilesWarning', () => {
const localVue = createLocalVue();
let store;
@@ -42,48 +52,63 @@ describe('CollapsedFilesWarning', () => {
wrapper.destroy();
});
- it.each`
- limited | containerClasses
- ${true} | ${limitedClasses}
- ${false} | ${[]}
- `(
- 'has the correct container classes when limited is $limited',
- ({ limited, containerClasses }) => {
- createComponent({ limited });
-
- expect(wrapper.classes()).toEqual(['col-12'].concat(containerClasses));
- },
- );
-
- it.each`
- present | dismissed
- ${false} | ${true}
- ${true} | ${false}
- `('toggles the alert when dismissed is $dismissed', ({ present, dismissed }) => {
- createComponent({ dismissed });
-
- expect(wrapper.find('[data-testid="root"]').exists()).toBe(present);
- });
+ describe('when there is more than one file', () => {
+ it.each`
+ limited | containerClasses
+ ${true} | ${limitedClasses}
+ ${false} | ${[]}
+ `(
+ 'has the correct container classes when limited is $limited',
+ async ({ limited, containerClasses }) => {
+ createComponent({ limited });
+ await files(store, 2);
+
+ expect(wrapper.classes()).toEqual(['col-12'].concat(containerClasses));
+ },
+ );
- it('dismisses the component when the alert "x" is clicked', async () => {
- createComponent({}, { full: true });
+ it.each`
+ present | dismissed
+ ${false} | ${true}
+ ${true} | ${false}
+ `('toggles the alert when dismissed is $dismissed', async ({ present, dismissed }) => {
+ createComponent({ dismissed });
+ await files(store, 2);
- expect(wrapper.find('[data-testid="root"]').exists()).toBe(true);
+ expect(wrapper.find('[data-testid="root"]').exists()).toBe(present);
+ });
- getAlertCloseButton().element.click();
+ it('dismisses the component when the alert "x" is clicked', async () => {
+ createComponent({}, { full: true });
+ await files(store, 2);
- await wrapper.vm.$nextTick();
+ expect(wrapper.find('[data-testid="root"]').exists()).toBe(true);
- expect(wrapper.find('[data-testid="root"]').exists()).toBe(false);
- });
+ getAlertCloseButton().element.click();
- it(`emits the \`${EVT_EXPAND_ALL_FILES}\` event when the alert action button is clicked`, () => {
- createComponent({}, { full: true });
+ await wrapper.vm.$nextTick();
- jest.spyOn(eventHub, '$emit');
+ expect(wrapper.find('[data-testid="root"]').exists()).toBe(false);
+ });
- getAlertActionButton().vm.$emit('click');
+ it(`emits the \`${EVT_EXPAND_ALL_FILES}\` event when the alert action button is clicked`, async () => {
+ createComponent({}, { full: true });
+ await files(store, 2);
- expect(eventHub.$emit).toHaveBeenCalledWith(EVT_EXPAND_ALL_FILES);
+ jest.spyOn(eventHub, '$emit');
+
+ getAlertActionButton().vm.$emit('click');
+
+ expect(eventHub.$emit).toHaveBeenCalledWith(EVT_EXPAND_ALL_FILES);
+ });
+ });
+
+ describe('when there is a single file', () => {
+ it('should not display', async () => {
+ createComponent();
+ await files(store, 1);
+
+ expect(wrapper.find('[data-testid="root"]').exists()).toBe(false);
+ });
});
});
diff --git a/spec/frontend/diffs/components/diff_content_spec.js b/spec/frontend/diffs/components/diff_content_spec.js
index 7012889440c..0a7dfc02c65 100644
--- a/spec/frontend/diffs/components/diff_content_spec.js
+++ b/spec/frontend/diffs/components/diff_content_spec.js
@@ -4,8 +4,6 @@ import Vuex from 'vuex';
import DiffContentComponent from '~/diffs/components/diff_content.vue';
import DiffDiscussions from '~/diffs/components/diff_discussions.vue';
import DiffView from '~/diffs/components/diff_view.vue';
-import InlineDiffView from '~/diffs/components/inline_diff_view.vue';
-import ParallelDiffView from '~/diffs/components/parallel_diff_view.vue';
import { IMAGE_DIFF_POSITION_TYPE } from '~/diffs/constants';
import { diffViewerModes } from '~/ide/constants';
import NoteForm from '~/notes/components/note_form.vue';
@@ -107,25 +105,10 @@ describe('DiffContent', () => {
});
const textDiffFile = { ...defaultProps.diffFile, viewer: { name: diffViewerModes.text } };
- it('should render diff inline view if `isInlineView` is true', () => {
- isInlineViewGetterMock.mockReturnValue(true);
- createComponent({ props: { diffFile: textDiffFile } });
-
- expect(wrapper.find(InlineDiffView).exists()).toBe(true);
- });
-
- it('should render parallel view if `isParallelView` getter is true', () => {
- isParallelViewGetterMock.mockReturnValue(true);
- createComponent({ props: { diffFile: textDiffFile } });
-
- expect(wrapper.find(ParallelDiffView).exists()).toBe(true);
- });
it('should render diff view if `unifiedDiffComponents` are true', () => {
- isParallelViewGetterMock.mockReturnValue(true);
createComponent({
props: { diffFile: textDiffFile },
- provide: { glFeatures: { unifiedDiffComponents: true } },
});
expect(wrapper.find(DiffView).exists()).toBe(true);
diff --git a/spec/frontend/diffs/components/diff_file_spec.js b/spec/frontend/diffs/components/diff_file_spec.js
index 1e8ad9344f2..99dda8d5deb 100644
--- a/spec/frontend/diffs/components/diff_file_spec.js
+++ b/spec/frontend/diffs/components/diff_file_spec.js
@@ -110,7 +110,6 @@ const findLoader = (wrapper) => wrapper.find('[data-testid="loader-icon"]');
const findToggleButton = (wrapper) => wrapper.find('[data-testid="expand-button"]');
const toggleFile = (wrapper) => findDiffHeader(wrapper).vm.$emit('toggleFile');
-const isDisplayNone = (element) => element.style.display === 'none';
const getReadableFile = () => JSON.parse(JSON.stringify(diffFileMockDataReadable));
const getUnreadableFile = () => JSON.parse(JSON.stringify(diffFileMockDataUnreadable));
@@ -305,9 +304,7 @@ describe('DiffFile', () => {
it('should not have any content at all', async () => {
await wrapper.vm.$nextTick();
- Array.from(findDiffContentArea(wrapper).element.children).forEach((child) => {
- expect(isDisplayNone(child)).toBe(true);
- });
+ expect(findDiffContentArea(wrapper).element.children.length).toBe(0);
});
it('should not have the class `has-body` to present the header differently', () => {
diff --git a/spec/frontend/diffs/components/diff_row_spec.js b/spec/frontend/diffs/components/diff_row_spec.js
index 137cc7e3f86..c0c92908701 100644
--- a/spec/frontend/diffs/components/diff_row_spec.js
+++ b/spec/frontend/diffs/components/diff_row_spec.js
@@ -8,6 +8,12 @@ import diffsModule from '~/diffs/store/modules';
import { findInteropAttributes } from '../find_interop_attributes';
import diffFileMockData from '../mock_data/diff_file';
+const showCommentForm = jest.fn();
+const enterdragging = jest.fn();
+const stopdragging = jest.fn();
+const setHighlightedRow = jest.fn();
+let wrapper;
+
describe('DiffRow', () => {
const testLines = [
{
@@ -29,7 +35,7 @@ describe('DiffRow', () => {
},
];
- const createWrapper = ({ props, state, actions, isLoggedIn = true }) => {
+ const createWrapper = ({ props, state = {}, actions, isLoggedIn = true }) => {
Vue.use(Vuex);
const diffs = diffsModule();
@@ -43,11 +49,25 @@ describe('DiffRow', () => {
getters,
});
+ window.gon = { current_user_id: isLoggedIn ? 1 : 0 };
+ const coverageFileData = state.coverageFiles?.files ? state.coverageFiles.files : {};
+
const propsData = {
fileHash: 'abc',
filePath: 'abc',
line: {},
index: 0,
+ isHighlighted: false,
+ fileLineCoverage: (file, line) => {
+ const hits = coverageFileData[file]?.[line];
+ if (hits) {
+ return { text: `Test coverage: ${hits} hits`, class: 'coverage' };
+ } else if (hits === 0) {
+ return { text: 'No test coverage', class: 'no-coverage' };
+ }
+
+ return {};
+ },
...props,
};
@@ -55,49 +75,37 @@ describe('DiffRow', () => {
glFeatures: { dragCommentSelection: true },
};
- return shallowMount(DiffRow, { propsData, store, provide });
+ return shallowMount(DiffRow, {
+ propsData,
+ store,
+ provide,
+ listeners: {
+ enterdragging,
+ stopdragging,
+ setHighlightedRow,
+ showCommentForm,
+ },
+ });
};
- it('isHighlighted returns true given line.left', () => {
- const props = {
- line: {
- left: {
- line_code: 'abc',
- },
- },
- };
- const state = { highlightedRow: 'abc' };
- const wrapper = createWrapper({ props, state });
- expect(wrapper.vm.isHighlighted).toBe(true);
- });
+ afterEach(() => {
+ wrapper.destroy();
+ wrapper = null;
- it('isHighlighted returns true given line.right', () => {
- const props = {
- line: {
- right: {
- line_code: 'abc',
- },
- },
- };
- const state = { highlightedRow: 'abc' };
- const wrapper = createWrapper({ props, state });
- expect(wrapper.vm.isHighlighted).toBe(true);
- });
+ window.gon = {};
+ showCommentForm.mockReset();
+ enterdragging.mockReset();
+ stopdragging.mockReset();
+ setHighlightedRow.mockReset();
- it('isHighlighted returns false given line.left', () => {
- const props = {
- line: {
- left: {
- line_code: 'abc',
- },
- },
- };
- const wrapper = createWrapper({ props });
- expect(wrapper.vm.isHighlighted).toBe(false);
+ Object.values(DiffRow).forEach(({ cache }) => {
+ if (cache) {
+ cache.clear();
+ }
+ });
});
- const getCommentButton = (wrapper, side) =>
- wrapper.find(`[data-testid="${side}-comment-button"]`);
+ const getCommentButton = (side) => wrapper.find(`[data-testid="${side}-comment-button"]`);
describe.each`
side
@@ -105,33 +113,30 @@ describe('DiffRow', () => {
${'right'}
`('$side side', ({ side }) => {
it(`renders empty cells if ${side} is unavailable`, () => {
- const wrapper = createWrapper({ props: { line: testLines[2], inline: false } });
+ wrapper = createWrapper({ props: { line: testLines[2], inline: false } });
expect(wrapper.find(`[data-testid="${side}-line-number"]`).exists()).toBe(false);
expect(wrapper.find(`[data-testid="${side}-empty-cell"]`).exists()).toBe(true);
});
describe('comment button', () => {
- const showCommentForm = jest.fn();
let line;
beforeEach(() => {
- showCommentForm.mockReset();
// https://eslint.org/docs/rules/prefer-destructuring#when-not-to-use-it
// eslint-disable-next-line prefer-destructuring
line = testLines[3];
});
it('renders', () => {
- const wrapper = createWrapper({ props: { line, inline: false } });
- expect(getCommentButton(wrapper, side).exists()).toBe(true);
+ wrapper = createWrapper({ props: { line, inline: false } });
+ expect(getCommentButton(side).exists()).toBe(true);
});
it('responds to click and keyboard events', async () => {
- const wrapper = createWrapper({
+ wrapper = createWrapper({
props: { line, inline: false },
- actions: { showCommentForm },
});
- const commentButton = getCommentButton(wrapper, side);
+ const commentButton = getCommentButton(side);
await commentButton.trigger('click');
await commentButton.trigger('keydown.enter');
@@ -142,11 +147,10 @@ describe('DiffRow', () => {
it('ignores click and keyboard events when comments are disabled', async () => {
line[side].commentsDisabled = true;
- const wrapper = createWrapper({
+ wrapper = createWrapper({
props: { line, inline: false },
- actions: { showCommentForm },
});
- const commentButton = getCommentButton(wrapper, side);
+ const commentButton = getCommentButton(side);
await commentButton.trigger('click');
await commentButton.trigger('keydown.enter');
@@ -157,19 +161,20 @@ describe('DiffRow', () => {
});
it('renders avatars', () => {
- const wrapper = createWrapper({ props: { line: testLines[0], inline: false } });
+ wrapper = createWrapper({ props: { line: testLines[0], inline: false } });
+
expect(wrapper.find(`[data-testid="${side}-discussions"]`).exists()).toBe(true);
});
});
it('renders left line numbers', () => {
- const wrapper = createWrapper({ props: { line: testLines[0] } });
+ wrapper = createWrapper({ props: { line: testLines[0] } });
const lineNumber = testLines[0].left.old_line;
expect(wrapper.find(`[data-linenumber="${lineNumber}"]`).exists()).toBe(true);
});
it('renders right line numbers', () => {
- const wrapper = createWrapper({ props: { line: testLines[0] } });
+ wrapper = createWrapper({ props: { line: testLines[0] } });
const lineNumber = testLines[0].right.new_line;
expect(wrapper.find(`[data-linenumber="${lineNumber}"]`).exists()).toBe(true);
});
@@ -186,12 +191,10 @@ describe('DiffRow', () => {
${'left'}
${'right'}
`('emits `enterdragging` onDragEnter $side side', ({ side }) => {
- const expectation = { ...line[side], index: 0 };
- const wrapper = createWrapper({ props: { line } });
+ wrapper = createWrapper({ props: { line } });
fireEvent.dragEnter(getByTestId(wrapper.element, `${side}-side`));
- expect(wrapper.emitted().enterdragging).toBeTruthy();
- expect(wrapper.emitted().enterdragging[0]).toEqual([expectation]);
+ expect(enterdragging).toHaveBeenCalledWith({ ...line[side], index: 0 });
});
it.each`
@@ -199,10 +202,10 @@ describe('DiffRow', () => {
${'left'}
${'right'}
`('emits `stopdragging` onDrop $side side', ({ side }) => {
- const wrapper = createWrapper({ props: { line } });
+ wrapper = createWrapper({ props: { line } });
fireEvent.dragEnd(getByTestId(wrapper.element, `${side}-side`));
- expect(wrapper.emitted().stopdragging).toBeTruthy();
+ expect(stopdragging).toHaveBeenCalled();
});
});
@@ -231,7 +234,7 @@ describe('DiffRow', () => {
it('for lines with coverage', () => {
const coverageFiles = { files: { [name]: { [line]: 5 } } };
- const wrapper = createWrapper({ props, state: { coverageFiles } });
+ wrapper = createWrapper({ props, state: { coverageFiles } });
const coverage = wrapper.find('.line-coverage.right-side');
expect(coverage.attributes('title')).toContain('Test coverage: 5 hits');
@@ -240,7 +243,7 @@ describe('DiffRow', () => {
it('for lines without coverage', () => {
const coverageFiles = { files: { [name]: { [line]: 0 } } };
- const wrapper = createWrapper({ props, state: { coverageFiles } });
+ wrapper = createWrapper({ props, state: { coverageFiles } });
const coverage = wrapper.find('.line-coverage.right-side');
expect(coverage.attributes('title')).toContain('No test coverage');
@@ -249,7 +252,7 @@ describe('DiffRow', () => {
it('for unknown lines', () => {
const coverageFiles = {};
- const wrapper = createWrapper({ props, state: { coverageFiles } });
+ wrapper = createWrapper({ props, state: { coverageFiles } });
const coverage = wrapper.find('.line-coverage.right-side');
expect(coverage.attributes('title')).toBeFalsy();
@@ -267,7 +270,7 @@ describe('DiffRow', () => {
${'with parallel and no left side'} | ${{ right: { old_line: 3, new_line: 5 } }} | ${false} | ${null} | ${{ type: 'new', line: '5', newLine: '5' }}
${'with parallel and right side'} | ${{ left: { old_line: 3 }, right: { new_line: 5 } }} | ${false} | ${{ type: 'old', line: '3', oldLine: '3' }} | ${{ type: 'new', line: '5', newLine: '5' }}
`('$desc, sets interop data attributes', ({ line, inline, leftSide, rightSide }) => {
- const wrapper = createWrapper({ props: { line, inline } });
+ wrapper = createWrapper({ props: { line, inline } });
expect(findInteropAttributes(wrapper, '[data-testid="left-side"]')).toEqual(leftSide);
expect(findInteropAttributes(wrapper, '[data-testid="right-side"]')).toEqual(rightSide);
diff --git a/spec/frontend/diffs/components/diff_row_utils_spec.js b/spec/frontend/diffs/components/diff_row_utils_spec.js
index 47ae3cd5867..930b8bcdb08 100644
--- a/spec/frontend/diffs/components/diff_row_utils_spec.js
+++ b/spec/frontend/diffs/components/diff_row_utils_spec.js
@@ -11,24 +11,21 @@ const LINE_CODE = 'abc123';
describe('isHighlighted', () => {
it('should return true if line is highlighted', () => {
- const state = { diffs: { highlightedRow: LINE_CODE } };
const line = { line_code: LINE_CODE };
const isCommented = false;
- expect(utils.isHighlighted(state, line, isCommented)).toBe(true);
+ expect(utils.isHighlighted(LINE_CODE, line, isCommented)).toBe(true);
});
it('should return false if line is not highlighted', () => {
- const state = { diffs: { highlightedRow: 'xxx' } };
const line = { line_code: LINE_CODE };
const isCommented = false;
- expect(utils.isHighlighted(state, line, isCommented)).toBe(false);
+ expect(utils.isHighlighted('xxx', line, isCommented)).toBe(false);
});
it('should return true if isCommented is true', () => {
- const state = { diffs: { highlightedRow: 'xxx' } };
const line = { line_code: LINE_CODE };
const isCommented = true;
- expect(utils.isHighlighted(state, line, isCommented)).toBe(true);
+ expect(utils.isHighlighted('xxx', line, isCommented)).toBe(true);
});
});
@@ -143,19 +140,14 @@ describe('addCommentTooltip', () => {
'Commenting on symbolic links that replace or are replaced by files is currently not supported.';
const brokenRealTooltip =
'Commenting on files that replace or are replaced by symbolic links is currently not supported.';
- const commentTooltip = 'Add a comment to this line';
const dragTooltip = 'Add a comment to this line or drag for multiple lines';
it('should return default tooltip', () => {
expect(utils.addCommentTooltip()).toBeUndefined();
});
- it('should return comment tooltip', () => {
- expect(utils.addCommentTooltip({})).toEqual(commentTooltip);
- });
-
it('should return drag comment tooltip when dragging is enabled', () => {
- expect(utils.addCommentTooltip({}, true)).toEqual(dragTooltip);
+ expect(utils.addCommentTooltip({})).toEqual(dragTooltip);
});
it('should return broken symlink tooltip', () => {
@@ -258,30 +250,3 @@ describe('mapParallel', () => {
expect(mapped.right).toMatchObject(rightExpectation);
});
});
-
-describe('mapInline', () => {
- it('should assign computed properties to the line object', () => {
- const content = {
- diffFile: {},
- shouldRenderDraftRow: () => false,
- };
- const line = {
- discussions: [{}],
- discussionsExpanded: true,
- hasForm: true,
- };
- const expectation = {
- commentRowClasses: '',
- hasDiscussions: true,
- isContextLine: false,
- isMatchLine: false,
- isMetaLine: false,
- renderDiscussion: true,
- hasDraft: false,
- hasCommentForm: true,
- };
- const mapped = utils.mapInline(content)(line);
-
- expect(mapped).toMatchObject(expectation);
- });
-});
diff --git a/spec/frontend/diffs/components/diff_view_spec.js b/spec/frontend/diffs/components/diff_view_spec.js
index 83b173c1f5d..3af66526050 100644
--- a/spec/frontend/diffs/components/diff_view_spec.js
+++ b/spec/frontend/diffs/components/diff_view_spec.js
@@ -28,7 +28,7 @@ describe('DiffView', () => {
};
const diffs = {
actions: { showCommentForm },
- getters: { commitId: () => 'abc123' },
+ getters: { commitId: () => 'abc123', fileLineCoverage: () => ({}) },
namespaced: true,
};
const notes = {
@@ -41,7 +41,7 @@ describe('DiffView', () => {
});
const propsData = {
- diffFile: {},
+ diffFile: { file_hash: '123' },
diffLines: [],
...props,
};
@@ -84,15 +84,15 @@ describe('DiffView', () => {
it('sets `dragStart` onStartDragging', () => {
const wrapper = createWrapper({ diffLines: [{}] });
- wrapper.findComponent(DiffRow).vm.$emit('startdragging', { test: true });
- expect(wrapper.vm.dragStart).toEqual({ test: true });
+ wrapper.findComponent(DiffRow).vm.$emit('startdragging', { line: { test: true } });
+ expect(wrapper.vm.idState.dragStart).toEqual({ test: true });
});
it('does not call `setSelectedCommentPosition` on different chunks onDragOver', () => {
const wrapper = createWrapper({ diffLines: [{}] });
const diffRow = getDiffRow(wrapper);
- diffRow.$emit('startdragging', { chunk: 0 });
+ diffRow.$emit('startdragging', { line: { chunk: 0 } });
diffRow.$emit('enterdragging', { chunk: 1 });
expect(setSelectedCommentPosition).not.toHaveBeenCalled();
@@ -109,7 +109,7 @@ describe('DiffView', () => {
const wrapper = createWrapper({ diffLines: [{}] });
const diffRow = getDiffRow(wrapper);
- diffRow.$emit('startdragging', { chunk: 1, index: start });
+ diffRow.$emit('startdragging', { line: { chunk: 1, index: start } });
diffRow.$emit('enterdragging', { chunk: 1, index: end });
const arg = setSelectedCommentPosition.mock.calls[0][1];
@@ -122,11 +122,11 @@ describe('DiffView', () => {
const wrapper = createWrapper({ diffLines: [{}] });
const diffRow = getDiffRow(wrapper);
- diffRow.$emit('startdragging', { test: true });
- expect(wrapper.vm.dragStart).toEqual({ test: true });
+ diffRow.$emit('startdragging', { line: { test: true } });
+ expect(wrapper.vm.idState.dragStart).toEqual({ test: true });
diffRow.$emit('stopdragging');
- expect(wrapper.vm.dragStart).toBeNull();
+ expect(wrapper.vm.idState.dragStart).toBeNull();
expect(showCommentForm).toHaveBeenCalled();
});
});
diff --git a/spec/frontend/diffs/components/inline_diff_table_row_spec.js b/spec/frontend/diffs/components/inline_diff_table_row_spec.js
deleted file mode 100644
index 9c3e00cd6cf..00000000000
--- a/spec/frontend/diffs/components/inline_diff_table_row_spec.js
+++ /dev/null
@@ -1,325 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import DiffGutterAvatars from '~/diffs/components/diff_gutter_avatars.vue';
-import { mapInline } from '~/diffs/components/diff_row_utils';
-import InlineDiffTableRow from '~/diffs/components/inline_diff_table_row.vue';
-import { createStore } from '~/mr_notes/stores';
-import { findInteropAttributes } from '../find_interop_attributes';
-import discussionsMockData from '../mock_data/diff_discussions';
-import diffFileMockData from '../mock_data/diff_file';
-
-const TEST_USER_ID = 'abc123';
-const TEST_USER = { id: TEST_USER_ID };
-
-describe('InlineDiffTableRow', () => {
- let wrapper;
- let store;
- const mockDiffContent = {
- diffFile: diffFileMockData,
- shouldRenderDraftRow: jest.fn(),
- hasParallelDraftLeft: jest.fn(),
- hasParallelDraftRight: jest.fn(),
- draftForLine: jest.fn(),
- };
-
- const applyMap = mapInline(mockDiffContent);
- const thisLine = applyMap(diffFileMockData.highlighted_diff_lines[0]);
-
- const createComponent = (props = {}, propsStore = store) => {
- wrapper = shallowMount(InlineDiffTableRow, {
- store: propsStore,
- propsData: {
- line: thisLine,
- fileHash: diffFileMockData.file_hash,
- filePath: diffFileMockData.file_path,
- contextLinesPath: 'contextLinesPath',
- isHighlighted: false,
- ...props,
- },
- });
- };
-
- beforeEach(() => {
- store = createStore();
- store.state.notes.userData = TEST_USER;
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('does not add hll class to line content when line does not match highlighted row', () => {
- createComponent();
- expect(wrapper.find('.line_content').classes('hll')).toBe(false);
- });
-
- it('adds hll class to lineContent when line is the highlighted row', () => {
- store.state.diffs.highlightedRow = thisLine.line_code;
- createComponent({}, store);
- expect(wrapper.find('.line_content').classes('hll')).toBe(true);
- });
-
- it('adds hll class to lineContent when line is part of a multiline comment', () => {
- createComponent({ isCommented: true });
- expect(wrapper.find('.line_content').classes('hll')).toBe(true);
- });
-
- describe('sets coverage title and class', () => {
- it('for lines with coverage', () => {
- const name = diffFileMockData.file_path;
- const line = thisLine.new_line;
-
- store.state.diffs.coverageFiles = { files: { [name]: { [line]: 5 } } };
- createComponent({}, store);
- const coverage = wrapper.find('.line-coverage');
-
- expect(coverage.attributes('title')).toContain('Test coverage: 5 hits');
- expect(coverage.classes('coverage')).toBe(true);
- });
-
- it('for lines without coverage', () => {
- const name = diffFileMockData.file_path;
- const line = thisLine.new_line;
-
- store.state.diffs.coverageFiles = { files: { [name]: { [line]: 0 } } };
- createComponent({}, store);
- const coverage = wrapper.find('.line-coverage');
-
- expect(coverage.attributes('title')).toContain('No test coverage');
- expect(coverage.classes('no-coverage')).toBe(true);
- });
-
- it('for unknown lines', () => {
- store.state.diffs.coverageFiles = {};
- createComponent({}, store);
-
- const coverage = wrapper.find('.line-coverage');
-
- expect(coverage.attributes('title')).toBeUndefined();
- expect(coverage.classes('coverage')).toBe(false);
- expect(coverage.classes('no-coverage')).toBe(false);
- });
- });
-
- describe('Table Cells', () => {
- const findNewTd = () => wrapper.find({ ref: 'newTd' });
- const findOldTd = () => wrapper.find({ ref: 'oldTd' });
-
- describe('td', () => {
- it('highlights when isHighlighted true', () => {
- store.state.diffs.highlightedRow = thisLine.line_code;
- createComponent({}, store);
-
- expect(findNewTd().classes()).toContain('hll');
- expect(findOldTd().classes()).toContain('hll');
- });
-
- it('does not highlight when isHighlighted false', () => {
- createComponent();
-
- expect(findNewTd().classes()).not.toContain('hll');
- expect(findOldTd().classes()).not.toContain('hll');
- });
- });
-
- describe('comment button', () => {
- const findNoteButton = () => wrapper.find({ ref: 'addDiffNoteButton' });
-
- it.each`
- userData | expectation
- ${TEST_USER} | ${true}
- ${null} | ${false}
- `('exists is $expectation - with userData ($userData)', ({ userData, expectation }) => {
- store.state.notes.userData = userData;
- createComponent({}, store);
-
- expect(findNoteButton().exists()).toBe(expectation);
- });
-
- it.each`
- isHover | line | expectation
- ${true} | ${{ ...thisLine, discussions: [] }} | ${true}
- ${false} | ${{ ...thisLine, discussions: [] }} | ${false}
- ${true} | ${{ ...thisLine, type: 'context', discussions: [] }} | ${false}
- ${true} | ${{ ...thisLine, type: 'old-nonewline', discussions: [] }} | ${false}
- ${true} | ${{ ...thisLine, discussions: [{}] }} | ${false}
- `('visible is $expectation - line ($line)', ({ isHover, line, expectation }) => {
- createComponent({ line: applyMap(line) });
- wrapper.setData({ isHover });
-
- return wrapper.vm.$nextTick().then(() => {
- expect(findNoteButton().isVisible()).toBe(expectation);
- });
- });
-
- it.each`
- disabled | commentsDisabled
- ${'disabled'} | ${true}
- ${undefined} | ${false}
- `(
- 'has attribute disabled=$disabled when the outer component has prop commentsDisabled=$commentsDisabled',
- ({ disabled, commentsDisabled }) => {
- createComponent({
- line: applyMap({ ...thisLine, commentsDisabled }),
- });
-
- wrapper.setData({ isHover: true });
-
- return wrapper.vm.$nextTick().then(() => {
- expect(findNoteButton().attributes('disabled')).toBe(disabled);
- });
- },
- );
-
- const symlinkishFileTooltip =
- 'Commenting on symbolic links that replace or are replaced by files is currently not supported.';
- const realishFileTooltip =
- 'Commenting on files that replace or are replaced by symbolic links is currently not supported.';
- const otherFileTooltip = 'Add a comment to this line';
- const findTooltip = () => wrapper.find({ ref: 'addNoteTooltip' });
-
- it.each`
- tooltip | commentsDisabled
- ${symlinkishFileTooltip} | ${{ wasSymbolic: true }}
- ${symlinkishFileTooltip} | ${{ isSymbolic: true }}
- ${realishFileTooltip} | ${{ wasReal: true }}
- ${realishFileTooltip} | ${{ isReal: true }}
- ${otherFileTooltip} | ${false}
- `(
- 'has the correct tooltip when commentsDisabled=$commentsDisabled',
- ({ tooltip, commentsDisabled }) => {
- createComponent({
- line: applyMap({ ...thisLine, commentsDisabled }),
- });
-
- wrapper.setData({ isHover: true });
-
- return wrapper.vm.$nextTick().then(() => {
- expect(findTooltip().attributes('title')).toBe(tooltip);
- });
- },
- );
- });
-
- describe('line number', () => {
- const findLineNumberOld = () => wrapper.find({ ref: 'lineNumberRefOld' });
- const findLineNumberNew = () => wrapper.find({ ref: 'lineNumberRefNew' });
-
- it('renders line numbers in correct cells', () => {
- createComponent();
-
- expect(findLineNumberOld().exists()).toBe(false);
- expect(findLineNumberNew().exists()).toBe(true);
- });
-
- describe('with lineNumber prop', () => {
- const TEST_LINE_CODE = 'LC_42';
- const TEST_LINE_NUMBER = 1;
-
- describe.each`
- lineProps | findLineNumber | expectedHref | expectedClickArg
- ${{ line_code: TEST_LINE_CODE, old_line: TEST_LINE_NUMBER }} | ${findLineNumberOld} | ${`#${TEST_LINE_CODE}`} | ${TEST_LINE_CODE}
- ${{ line_code: undefined, old_line: TEST_LINE_NUMBER }} | ${findLineNumberOld} | ${'#'} | ${undefined}
- ${{ line_code: undefined, left: { line_code: TEST_LINE_CODE }, old_line: TEST_LINE_NUMBER }} | ${findLineNumberOld} | ${'#'} | ${TEST_LINE_CODE}
- ${{ line_code: undefined, right: { line_code: TEST_LINE_CODE }, new_line: TEST_LINE_NUMBER }} | ${findLineNumberNew} | ${'#'} | ${TEST_LINE_CODE}
- `(
- 'with line ($lineProps)',
- ({ lineProps, findLineNumber, expectedHref, expectedClickArg }) => {
- beforeEach(() => {
- jest.spyOn(store, 'dispatch').mockImplementation();
- createComponent({
- line: applyMap({ ...thisLine, ...lineProps }),
- });
- });
-
- it('renders', () => {
- expect(findLineNumber().exists()).toBe(true);
- expect(findLineNumber().attributes()).toEqual({
- href: expectedHref,
- 'data-linenumber': TEST_LINE_NUMBER.toString(),
- });
- });
-
- it('on click, dispatches setHighlightedRow', () => {
- expect(store.dispatch).toHaveBeenCalledTimes(1);
-
- findLineNumber().trigger('click');
-
- expect(store.dispatch).toHaveBeenCalledWith(
- 'diffs/setHighlightedRow',
- expectedClickArg,
- );
- expect(store.dispatch).toHaveBeenCalledTimes(2);
- });
- },
- );
- });
- });
-
- describe('diff-gutter-avatars', () => {
- const TEST_LINE_CODE = 'LC_42';
- const TEST_FILE_HASH = diffFileMockData.file_hash;
- const findAvatars = () => wrapper.find(DiffGutterAvatars);
- let line;
-
- beforeEach(() => {
- jest.spyOn(store, 'dispatch').mockImplementation();
-
- line = {
- line_code: TEST_LINE_CODE,
- type: 'new',
- old_line: null,
- new_line: 1,
- discussions: [{ ...discussionsMockData }],
- discussionsExpanded: true,
- text: '+<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n',
- rich_text: '+<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n',
- meta_data: null,
- };
- });
-
- describe('with showCommentButton', () => {
- it('renders if line has discussions', () => {
- createComponent({ line: applyMap(line) });
-
- expect(findAvatars().props()).toEqual({
- discussions: line.discussions,
- discussionsExpanded: line.discussionsExpanded,
- });
- });
-
- it('does notrender if line has no discussions', () => {
- line.discussions = [];
- createComponent({ line: applyMap(line) });
-
- expect(findAvatars().exists()).toEqual(false);
- });
-
- it('toggles line discussion', () => {
- createComponent({ line: applyMap(line) });
-
- expect(store.dispatch).toHaveBeenCalledTimes(1);
-
- findAvatars().vm.$emit('toggleLineDiscussions');
-
- expect(store.dispatch).toHaveBeenCalledWith('diffs/toggleLineDiscussions', {
- lineCode: TEST_LINE_CODE,
- fileHash: TEST_FILE_HASH,
- expanded: !line.discussionsExpanded,
- });
- });
- });
- });
- });
-
- describe('interoperability', () => {
- it.each`
- desc | line | expectation
- ${'with type old'} | ${{ ...thisLine, type: 'old', old_line: 3, new_line: 5 }} | ${{ type: 'old', line: '3', oldLine: '3', newLine: '5' }}
- ${'with type new'} | ${{ ...thisLine, type: 'new', old_line: 3, new_line: 5 }} | ${{ type: 'new', line: '5', oldLine: '3', newLine: '5' }}
- `('$desc, sets interop data attributes', ({ line, expectation }) => {
- createComponent({ line });
-
- expect(findInteropAttributes(wrapper)).toEqual(expectation);
- });
- });
-});
diff --git a/spec/frontend/diffs/components/inline_diff_view_spec.js b/spec/frontend/diffs/components/inline_diff_view_spec.js
deleted file mode 100644
index 27834804f77..00000000000
--- a/spec/frontend/diffs/components/inline_diff_view_spec.js
+++ /dev/null
@@ -1,57 +0,0 @@
-import '~/behaviors/markdown/render_gfm';
-import { getByText } from '@testing-library/dom';
-import { mount } from '@vue/test-utils';
-import { mapInline } from '~/diffs/components/diff_row_utils';
-import InlineDiffView from '~/diffs/components/inline_diff_view.vue';
-import { createStore } from '~/mr_notes/stores';
-import discussionsMockData from '../mock_data/diff_discussions';
-import diffFileMockData from '../mock_data/diff_file';
-
-describe('InlineDiffView', () => {
- let wrapper;
- const getDiffFileMock = () => ({ ...diffFileMockData });
- const getDiscussionsMockData = () => [{ ...discussionsMockData }];
- const notesLength = getDiscussionsMockData()[0].notes.length;
-
- const setup = (diffFile, diffLines) => {
- const mockDiffContent = {
- diffFile,
- shouldRenderDraftRow: jest.fn(),
- };
-
- const store = createStore();
-
- store.dispatch('diffs/setInlineDiffViewType');
- wrapper = mount(InlineDiffView, {
- store,
- propsData: {
- diffFile,
- diffLines: diffLines.map(mapInline(mockDiffContent)),
- },
- });
- };
-
- describe('template', () => {
- it('should have rendered diff lines', () => {
- const diffFile = getDiffFileMock();
- setup(diffFile, diffFile.highlighted_diff_lines);
-
- expect(wrapper.findAll('tr.line_holder').length).toEqual(8);
- expect(wrapper.findAll('tr.line_holder.new').length).toEqual(4);
- expect(wrapper.findAll('tr.line_expansion.match').length).toEqual(1);
- getByText(wrapper.element, /Bad dates/i);
- });
-
- it('should render discussions', () => {
- const diffFile = getDiffFileMock();
- diffFile.highlighted_diff_lines[1].discussions = getDiscussionsMockData();
- diffFile.highlighted_diff_lines[1].discussionsExpanded = true;
- setup(diffFile, diffFile.highlighted_diff_lines);
-
- expect(wrapper.findAll('.notes_holder').length).toEqual(1);
- expect(wrapper.findAll('.notes_holder .note').length).toEqual(notesLength + 1);
- getByText(wrapper.element, 'comment 5');
- wrapper.vm.$store.dispatch('setInitialNotes', []);
- });
- });
-});
diff --git a/spec/frontend/diffs/components/parallel_diff_table_row_spec.js b/spec/frontend/diffs/components/parallel_diff_table_row_spec.js
deleted file mode 100644
index ed191d849fd..00000000000
--- a/spec/frontend/diffs/components/parallel_diff_table_row_spec.js
+++ /dev/null
@@ -1,445 +0,0 @@
-import { shallowMount } from '@vue/test-utils';
-import Vue from 'vue';
-import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
-import DiffGutterAvatars from '~/diffs/components/diff_gutter_avatars.vue';
-import { mapParallel } from '~/diffs/components/diff_row_utils';
-import ParallelDiffTableRow from '~/diffs/components/parallel_diff_table_row.vue';
-import { createStore } from '~/mr_notes/stores';
-import { findInteropAttributes } from '../find_interop_attributes';
-import discussionsMockData from '../mock_data/diff_discussions';
-import diffFileMockData from '../mock_data/diff_file';
-
-describe('ParallelDiffTableRow', () => {
- const mockDiffContent = {
- diffFile: diffFileMockData,
- shouldRenderDraftRow: jest.fn(),
- hasParallelDraftLeft: jest.fn(),
- hasParallelDraftRight: jest.fn(),
- draftForLine: jest.fn(),
- };
-
- const applyMap = mapParallel(mockDiffContent);
-
- describe('when one side is empty', () => {
- let wrapper;
- let vm;
- const thisLine = diffFileMockData.parallel_diff_lines[0];
- const rightLine = diffFileMockData.parallel_diff_lines[0].right;
-
- beforeEach(() => {
- wrapper = shallowMount(ParallelDiffTableRow, {
- store: createStore(),
- propsData: {
- line: applyMap(thisLine),
- fileHash: diffFileMockData.file_hash,
- filePath: diffFileMockData.file_path,
- contextLinesPath: 'contextLinesPath',
- isHighlighted: false,
- },
- });
-
- vm = wrapper.vm;
- });
-
- it('does not highlight non empty line content when line does not match highlighted row', (done) => {
- vm.$nextTick()
- .then(() => {
- expect(vm.$el.querySelector('.line_content.right-side').classList).not.toContain('hll');
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('highlights nonempty line content when line is the highlighted row', (done) => {
- vm.$nextTick()
- .then(() => {
- vm.$store.state.diffs.highlightedRow = rightLine.line_code;
-
- return vm.$nextTick();
- })
- .then(() => {
- expect(vm.$el.querySelector('.line_content.right-side').classList).toContain('hll');
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('highlights nonempty line content when line is part of a multiline comment', () => {
- wrapper.setProps({ isCommented: true });
- return vm.$nextTick().then(() => {
- expect(vm.$el.querySelector('.line_content.right-side').classList).toContain('hll');
- });
- });
- });
-
- describe('when both sides have content', () => {
- let vm;
- const thisLine = diffFileMockData.parallel_diff_lines[2];
- const rightLine = diffFileMockData.parallel_diff_lines[2].right;
-
- beforeEach(() => {
- vm = createComponentWithStore(Vue.extend(ParallelDiffTableRow), createStore(), {
- line: applyMap(thisLine),
- fileHash: diffFileMockData.file_hash,
- filePath: diffFileMockData.file_path,
- contextLinesPath: 'contextLinesPath',
- isHighlighted: false,
- }).$mount();
- });
-
- it('does not highlight either line when line does not match highlighted row', (done) => {
- vm.$nextTick()
- .then(() => {
- expect(vm.$el.querySelector('.line_content.right-side').classList).not.toContain('hll');
- expect(vm.$el.querySelector('.line_content.left-side').classList).not.toContain('hll');
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('adds hll class to lineContent when line is the highlighted row', (done) => {
- vm.$nextTick()
- .then(() => {
- vm.$store.state.diffs.highlightedRow = rightLine.line_code;
-
- return vm.$nextTick();
- })
- .then(() => {
- expect(vm.$el.querySelector('.line_content.right-side').classList).toContain('hll');
- expect(vm.$el.querySelector('.line_content.left-side').classList).toContain('hll');
- })
- .then(done)
- .catch(done.fail);
- });
-
- describe('sets coverage title and class', () => {
- it('for lines with coverage', (done) => {
- vm.$nextTick()
- .then(() => {
- const name = diffFileMockData.file_path;
- const line = rightLine.new_line;
-
- vm.$store.state.diffs.coverageFiles = { files: { [name]: { [line]: 5 } } };
-
- return vm.$nextTick();
- })
- .then(() => {
- const coverage = vm.$el.querySelector('.line-coverage.right-side');
-
- expect(coverage.title).toContain('Test coverage: 5 hits');
- expect(coverage.classList).toContain('coverage');
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('for lines without coverage', (done) => {
- vm.$nextTick()
- .then(() => {
- const name = diffFileMockData.file_path;
- const line = rightLine.new_line;
-
- vm.$store.state.diffs.coverageFiles = { files: { [name]: { [line]: 0 } } };
-
- return vm.$nextTick();
- })
- .then(() => {
- const coverage = vm.$el.querySelector('.line-coverage.right-side');
-
- expect(coverage.title).toContain('No test coverage');
- expect(coverage.classList).toContain('no-coverage');
- })
- .then(done)
- .catch(done.fail);
- });
-
- it('for unknown lines', (done) => {
- vm.$nextTick()
- .then(() => {
- vm.$store.state.diffs.coverageFiles = {};
-
- return vm.$nextTick();
- })
- .then(() => {
- const coverage = vm.$el.querySelector('.line-coverage.right-side');
-
- expect(coverage.title).not.toContain('Coverage');
- expect(coverage.classList).not.toContain('coverage');
- expect(coverage.classList).not.toContain('no-coverage');
- })
- .then(done)
- .catch(done.fail);
- });
- });
- });
-
- describe('Table Cells', () => {
- let wrapper;
- let store;
- let thisLine;
- const TEST_USER_ID = 'abc123';
- const TEST_USER = { id: TEST_USER_ID };
-
- const createComponent = (props = {}, propsStore = store, data = {}) => {
- wrapper = shallowMount(ParallelDiffTableRow, {
- store: propsStore,
- propsData: {
- line: thisLine,
- fileHash: diffFileMockData.file_hash,
- filePath: diffFileMockData.file_path,
- contextLinesPath: 'contextLinesPath',
- isHighlighted: false,
- ...props,
- },
- data() {
- return data;
- },
- });
- };
-
- beforeEach(() => {
- // eslint-disable-next-line prefer-destructuring
- thisLine = diffFileMockData.parallel_diff_lines[2];
- store = createStore();
- store.state.notes.userData = TEST_USER;
- });
-
- afterEach(() => {
- wrapper.destroy();
- });
-
- const findNewTd = () => wrapper.find({ ref: 'newTd' });
- const findOldTd = () => wrapper.find({ ref: 'oldTd' });
-
- describe('td', () => {
- it('highlights when isHighlighted true', () => {
- store.state.diffs.highlightedRow = thisLine.left.line_code;
- createComponent({}, store);
-
- expect(findNewTd().classes()).toContain('hll');
- expect(findOldTd().classes()).toContain('hll');
- });
-
- it('does not highlight when isHighlighted false', () => {
- createComponent();
-
- expect(findNewTd().classes()).not.toContain('hll');
- expect(findOldTd().classes()).not.toContain('hll');
- });
- });
-
- describe('comment button', () => {
- const findNoteButton = () => wrapper.find({ ref: 'addDiffNoteButtonLeft' });
-
- it.each`
- hover | line | userData | expectation
- ${true} | ${{}} | ${TEST_USER} | ${true}
- ${true} | ${{ line: { left: null } }} | ${TEST_USER} | ${false}
- ${true} | ${{}} | ${null} | ${false}
- ${false} | ${{}} | ${TEST_USER} | ${false}
- `(
- 'exists is $expectation - with userData ($userData)',
- async ({ hover, line, userData, expectation }) => {
- store.state.notes.userData = userData;
- createComponent(line, store);
- if (hover) await wrapper.find('.line_holder').trigger('mouseover');
-
- expect(findNoteButton().exists()).toBe(expectation);
- },
- );
-
- it.each`
- line | expectation
- ${{ ...thisLine, left: { discussions: [] } }} | ${true}
- ${{ ...thisLine, left: { type: 'context', discussions: [] } }} | ${false}
- ${{ ...thisLine, left: { type: 'old-nonewline', discussions: [] } }} | ${false}
- ${{ ...thisLine, left: { discussions: [{}] } }} | ${false}
- `('visible is $expectation - line ($line)', async ({ line, expectation }) => {
- createComponent({ line: applyMap(line) }, store, {
- isLeftHover: true,
- isCommentButtonRendered: true,
- });
-
- expect(findNoteButton().isVisible()).toBe(expectation);
- });
-
- it.each`
- disabled | commentsDisabled
- ${'disabled'} | ${true}
- ${undefined} | ${false}
- `(
- 'has attribute disabled=$disabled when the outer component has prop commentsDisabled=$commentsDisabled',
- ({ disabled, commentsDisabled }) => {
- thisLine.left.commentsDisabled = commentsDisabled;
- createComponent({ line: { ...thisLine } }, store, {
- isLeftHover: true,
- isCommentButtonRendered: true,
- });
-
- expect(findNoteButton().attributes('disabled')).toBe(disabled);
- },
- );
-
- const symlinkishFileTooltip =
- 'Commenting on symbolic links that replace or are replaced by files is currently not supported.';
- const realishFileTooltip =
- 'Commenting on files that replace or are replaced by symbolic links is currently not supported.';
- const otherFileTooltip = 'Add a comment to this line';
- const findTooltip = () => wrapper.find({ ref: 'addNoteTooltipLeft' });
-
- it.each`
- tooltip | commentsDisabled
- ${symlinkishFileTooltip} | ${{ wasSymbolic: true }}
- ${symlinkishFileTooltip} | ${{ isSymbolic: true }}
- ${realishFileTooltip} | ${{ wasReal: true }}
- ${realishFileTooltip} | ${{ isReal: true }}
- ${otherFileTooltip} | ${false}
- `(
- 'has the correct tooltip when commentsDisabled=$commentsDisabled',
- ({ tooltip, commentsDisabled }) => {
- thisLine.left.commentsDisabled = commentsDisabled;
- createComponent({ line: { ...thisLine } }, store, {
- isLeftHover: true,
- isCommentButtonRendered: true,
- });
-
- expect(findTooltip().attributes('title')).toBe(tooltip);
- },
- );
- });
-
- describe('line number', () => {
- const findLineNumberOld = () => wrapper.find({ ref: 'lineNumberRefOld' });
- const findLineNumberNew = () => wrapper.find({ ref: 'lineNumberRefNew' });
-
- it('renders line numbers in correct cells', () => {
- createComponent();
-
- expect(findLineNumberOld().exists()).toBe(true);
- expect(findLineNumberNew().exists()).toBe(true);
- });
-
- describe('with lineNumber prop', () => {
- const TEST_LINE_CODE = 'LC_42';
- const TEST_LINE_NUMBER = 1;
-
- describe.each`
- lineProps | findLineNumber | expectedHref | expectedClickArg
- ${{ line_code: TEST_LINE_CODE, old_line: TEST_LINE_NUMBER }} | ${findLineNumberOld} | ${`#${TEST_LINE_CODE}`} | ${TEST_LINE_CODE}
- ${{ line_code: undefined, old_line: TEST_LINE_NUMBER }} | ${findLineNumberOld} | ${'#'} | ${undefined}
- `(
- 'with line ($lineProps)',
- ({ lineProps, findLineNumber, expectedHref, expectedClickArg }) => {
- beforeEach(() => {
- jest.spyOn(store, 'dispatch').mockImplementation();
- Object.assign(thisLine.left, lineProps);
- Object.assign(thisLine.right, lineProps);
- createComponent({
- line: applyMap({ ...thisLine }),
- });
- });
-
- it('renders', () => {
- expect(findLineNumber().exists()).toBe(true);
- expect(findLineNumber().attributes()).toEqual({
- href: expectedHref,
- 'data-linenumber': TEST_LINE_NUMBER.toString(),
- });
- });
-
- it('on click, dispatches setHighlightedRow', () => {
- expect(store.dispatch).toHaveBeenCalledTimes(1);
-
- findLineNumber().trigger('click');
-
- expect(store.dispatch).toHaveBeenCalledWith(
- 'diffs/setHighlightedRow',
- expectedClickArg,
- );
- expect(store.dispatch).toHaveBeenCalledTimes(2);
- });
- },
- );
- });
- });
-
- describe('diff-gutter-avatars', () => {
- const TEST_LINE_CODE = 'LC_42';
- const TEST_FILE_HASH = diffFileMockData.file_hash;
- const findAvatars = () => wrapper.find(DiffGutterAvatars);
- let line;
-
- beforeEach(() => {
- jest.spyOn(store, 'dispatch').mockImplementation();
-
- line = applyMap({
- left: {
- line_code: TEST_LINE_CODE,
- type: 'new',
- old_line: null,
- new_line: 1,
- discussions: [{ ...discussionsMockData }],
- discussionsExpanded: true,
- text: '+<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n',
- rich_text: '+<span id="LC1" class="line" lang="plaintext"> - Bad dates</span>\n',
- meta_data: null,
- },
- });
- });
-
- describe('with showCommentButton', () => {
- it('renders if line has discussions', () => {
- createComponent({ line });
-
- expect(findAvatars().props()).toEqual({
- discussions: line.left.discussions,
- discussionsExpanded: line.left.discussionsExpanded,
- });
- });
-
- it('does notrender if line has no discussions', () => {
- line.left.discussions = [];
- createComponent({ line: applyMap(line) });
-
- expect(findAvatars().exists()).toEqual(false);
- });
-
- it('toggles line discussion', () => {
- createComponent({ line });
-
- expect(store.dispatch).toHaveBeenCalledTimes(1);
-
- findAvatars().vm.$emit('toggleLineDiscussions');
-
- expect(store.dispatch).toHaveBeenCalledWith('diffs/toggleLineDiscussions', {
- lineCode: TEST_LINE_CODE,
- fileHash: TEST_FILE_HASH,
- expanded: !line.left.discussionsExpanded,
- });
- });
- });
- });
-
- describe('interoperability', () => {
- beforeEach(() => {
- createComponent();
- });
-
- it('adds old side interoperability data attributes', () => {
- expect(findInteropAttributes(wrapper, '.line_content.left-side')).toEqual({
- type: 'old',
- line: thisLine.left.old_line.toString(),
- oldLine: thisLine.left.old_line.toString(),
- });
- });
-
- it('adds new side interoperability data attributes', () => {
- expect(findInteropAttributes(wrapper, '.line_content.right-side')).toEqual({
- type: 'new',
- line: thisLine.right.new_line.toString(),
- newLine: thisLine.right.new_line.toString(),
- });
- });
- });
- });
-});
diff --git a/spec/frontend/diffs/components/parallel_diff_view_spec.js b/spec/frontend/diffs/components/parallel_diff_view_spec.js
deleted file mode 100644
index 452e1f58551..00000000000
--- a/spec/frontend/diffs/components/parallel_diff_view_spec.js
+++ /dev/null
@@ -1,37 +0,0 @@
-import { shallowMount, createLocalVue } from '@vue/test-utils';
-import Vuex from 'vuex';
-import parallelDiffTableRow from '~/diffs/components/parallel_diff_table_row.vue';
-import ParallelDiffView from '~/diffs/components/parallel_diff_view.vue';
-import { createStore } from '~/mr_notes/stores';
-import diffFileMockData from '../mock_data/diff_file';
-
-let wrapper;
-const localVue = createLocalVue();
-
-localVue.use(Vuex);
-
-function factory() {
- const diffFile = { ...diffFileMockData };
- const store = createStore();
-
- wrapper = shallowMount(ParallelDiffView, {
- localVue,
- store,
- propsData: {
- diffFile,
- diffLines: diffFile.parallel_diff_lines,
- },
- });
-}
-
-describe('ParallelDiffView', () => {
- afterEach(() => {
- wrapper.destroy();
- });
-
- it('renders diff lines', () => {
- factory();
-
- expect(wrapper.findAll(parallelDiffTableRow).length).toBe(8);
- });
-});
diff --git a/spec/frontend/diffs/store/actions_spec.js b/spec/frontend/diffs/store/actions_spec.js
index 14f8e090be9..c2e5d07bcfd 100644
--- a/spec/frontend/diffs/store/actions_spec.js
+++ b/spec/frontend/diffs/store/actions_spec.js
@@ -8,7 +8,6 @@ import {
DIFF_VIEW_COOKIE_NAME,
INLINE_DIFF_VIEW_TYPE,
PARALLEL_DIFF_VIEW_TYPE,
- DIFFS_PER_PAGE,
} from '~/diffs/constants';
import {
setBaseConfig,
@@ -154,16 +153,16 @@ describe('DiffsStoreActions', () => {
it('should fetch batch diff files', (done) => {
const endpointBatch = '/fetch/diffs_batch';
- const res1 = { diff_files: [{ file_hash: 'test' }], pagination: { next_page: 2 } };
- const res2 = { diff_files: [{ file_hash: 'test2' }], pagination: {} };
+ const res1 = { diff_files: [{ file_hash: 'test' }], pagination: { total_pages: 7 } };
+ const res2 = { diff_files: [{ file_hash: 'test2' }], pagination: { total_pages: 7 } };
mock
.onGet(
mergeUrlParams(
{
w: '1',
view: 'inline',
- page: 1,
- per_page: DIFFS_PER_PAGE,
+ page: 0,
+ per_page: 5,
},
endpointBatch,
),
@@ -174,8 +173,8 @@ describe('DiffsStoreActions', () => {
{
w: '1',
view: 'inline',
- page: 2,
- per_page: DIFFS_PER_PAGE,
+ page: 5,
+ per_page: 7,
},
endpointBatch,
),
@@ -1020,10 +1019,12 @@ describe('DiffsStoreActions', () => {
const endpointUpdateUser = 'user/prefs';
let putSpy;
let mock;
+ let gon;
beforeEach(() => {
mock = new MockAdapter(axios);
putSpy = jest.spyOn(axios, 'put');
+ gon = window.gon;
mock.onPut(endpointUpdateUser).reply(200, {});
jest.spyOn(eventHub, '$emit').mockImplementation();
@@ -1031,6 +1032,7 @@ describe('DiffsStoreActions', () => {
afterEach(() => {
mock.restore();
+ window.gon = gon;
});
it('commits SET_SHOW_WHITESPACE', (done) => {
@@ -1044,7 +1046,9 @@ describe('DiffsStoreActions', () => {
);
});
- it('saves to the database', async () => {
+ it('saves to the database when the user is logged in', async () => {
+ window.gon = { current_user_id: 12345 };
+
await setShowWhitespace(
{ state: { endpointUpdateUser }, commit() {} },
{ showWhitespace: true, updateDatabase: true },
@@ -1053,6 +1057,17 @@ describe('DiffsStoreActions', () => {
expect(putSpy).toHaveBeenCalledWith(endpointUpdateUser, { show_whitespace_in_diffs: true });
});
+ it('does not try to save to the API if the user is not logged in', async () => {
+ window.gon = {};
+
+ await setShowWhitespace(
+ { state: { endpointUpdateUser }, commit() {} },
+ { showWhitespace: true, updateDatabase: true },
+ );
+
+ expect(putSpy).not.toHaveBeenCalled();
+ });
+
it('emits eventHub event', async () => {
await setShowWhitespace(
{ state: {}, commit() {} },
diff --git a/spec/frontend/diffs/store/getters_versions_dropdowns_spec.js b/spec/frontend/diffs/store/getters_versions_dropdowns_spec.js
index dbef547c297..99f13a1c84c 100644
--- a/spec/frontend/diffs/store/getters_versions_dropdowns_spec.js
+++ b/spec/frontend/diffs/store/getters_versions_dropdowns_spec.js
@@ -54,7 +54,7 @@ describe('Compare diff version dropdowns', () => {
Object.defineProperty(window, 'location', {
writable: true,
- value: { href: `https://example.gitlab.com${diffHeadParam}` },
+ value: { search: diffHeadParam },
});
expectedFirstVersion = {