Commit 06e65234 authored by Andrew Fontaine's avatar Andrew Fontaine

Merge branch 'feature/mr-file-by-file' into 'master'

Toggle File-By-File setting from the MR settings dropdown

See merge request gitlab-org/gitlab!47726
parents 133fa2a8 143c0158
......@@ -10,7 +10,10 @@ import PanelResizer from '~/vue_shared/components/panel_resizer.vue';
import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin';
import { isSingleViewStyle } from '~/helpers/diffs_helper';
import { updateHistory } from '~/lib/utils/url_utility';
import eventHub from '../../notes/event_hub';
import notesEventHub from '../../notes/event_hub';
import eventHub from '../event_hub';
import CompareVersions from './compare_versions.vue';
import DiffFile from './diff_file.vue';
import NoChanges from './no_changes.vue';
......@@ -22,6 +25,7 @@ import MergeConflictWarning from './merge_conflict_warning.vue';
import CollapsedFilesWarning from './collapsed_files_warning.vue';
import { diffsApp } from '../utils/performance';
import { fileByFile } from '../utils/preferences';
import {
TREE_LIST_WIDTH_STORAGE_KEY,
......@@ -34,6 +38,7 @@ import {
ALERT_OVERFLOW_HIDDEN,
ALERT_MERGE_CONFLICT,
ALERT_COLLAPSED_FILES,
EVT_VIEW_FILE_BY_FILE,
} from '../constants';
export default {
......@@ -114,7 +119,7 @@ export default {
required: false,
default: false,
},
viewDiffsFileByFile: {
fileByFileUserPreference: {
type: Boolean,
required: false,
default: false,
......@@ -154,6 +159,7 @@ export default {
'conflictResolutionPath',
'canMerge',
'hasConflicts',
'viewDiffsFileByFile',
]),
...mapGetters('diffs', ['whichCollapsedTypes', 'isParallelView', 'currentDiffIndex']),
...mapGetters(['isNotesFetched', 'getNoteableData']),
......@@ -254,7 +260,7 @@ export default {
projectPath: this.projectPath,
dismissEndpoint: this.dismissEndpoint,
showSuggestPopover: this.showSuggestPopover,
viewDiffsFileByFile: this.viewDiffsFileByFile,
viewDiffsFileByFile: fileByFile(this.fileByFileUserPreference),
});
if (this.shouldShow) {
......@@ -278,8 +284,10 @@ export default {
created() {
this.adjustView();
eventHub.$once('fetchDiffData', this.fetchData);
eventHub.$on('refetchDiffData', this.refetchDiffData);
notesEventHub.$once('fetchDiffData', this.fetchData);
notesEventHub.$on('refetchDiffData', this.refetchDiffData);
eventHub.$on(EVT_VIEW_FILE_BY_FILE, this.fileByFileListener);
this.CENTERED_LIMITED_CONTAINER_CLASSES = CENTERED_LIMITED_CONTAINER_CLASSES;
this.unwatchDiscussions = this.$watch(
......@@ -300,8 +308,10 @@ export default {
beforeDestroy() {
diffsApp.deinstrument();
eventHub.$off('fetchDiffData', this.fetchData);
eventHub.$off('refetchDiffData', this.refetchDiffData);
eventHub.$off(EVT_VIEW_FILE_BY_FILE, this.fileByFileListener);
notesEventHub.$off('refetchDiffData', this.refetchDiffData);
notesEventHub.$off('fetchDiffData', this.fetchData);
this.removeEventListeners();
},
methods: {
......@@ -319,7 +329,11 @@ export default {
'scrollToFile',
'setShowTreeList',
'navigateToDiffFileIndex',
'setFileByFile',
]),
fileByFileListener({ setting } = {}) {
this.setFileByFile({ fileByFile: setting });
},
navigateToDiffFileNumber(number) {
this.navigateToDiffFileIndex(number - 1);
},
......@@ -371,7 +385,7 @@ export default {
}
if (!this.isNotesFetched) {
eventHub.$emit('fetchNotesData');
notesEventHub.$emit('fetchNotesData');
}
},
setDiscussions() {
......
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
import { GlButtonGroup, GlButton, GlDropdown } from '@gitlab/ui';
import { GlButtonGroup, GlButton, GlDropdown, GlFormCheckbox } from '@gitlab/ui';
import eventHub from '../event_hub';
import { EVT_VIEW_FILE_BY_FILE } from '../constants';
import { SETTINGS_DROPDOWN } from '../i18n';
export default {
i18n: SETTINGS_DROPDOWN,
components: {
GlButtonGroup,
GlButton,
GlDropdown,
GlFormCheckbox,
},
data() {
return {
checked: false,
};
},
computed: {
...mapGetters('diffs', ['isInlineView', 'isParallelView']),
...mapState('diffs', ['renderTreeList', 'showWhitespace']),
...mapState('diffs', ['renderTreeList', 'showWhitespace', 'viewDiffsFileByFile']),
},
watch: {
viewDiffsFileByFile() {
this.checked = this.viewDiffsFileByFile;
},
checked() {
eventHub.$emit(EVT_VIEW_FILE_BY_FILE, { setting: this.checked });
},
},
created() {
this.checked = this.viewDiffsFileByFile;
},
methods: {
...mapActions('diffs', [
......@@ -19,6 +41,9 @@ export default {
'setRenderTreeList',
'setShowWhitespace',
]),
toggleFileByFile() {
eventHub.$emit(EVT_VIEW_FILE_BY_FILE, { setting: !this.viewDiffsFileByFile });
},
},
};
</script>
......@@ -84,5 +109,10 @@ export default {
{{ __('Show whitespace changes') }}
</label>
</div>
<div class="gl-mt-3 gl-px-3">
<gl-form-checkbox v-model="checked" data-testid="file-by-file" class="gl-mb-0">
{{ $options.i18n.fileByFile }}
</gl-form-checkbox>
</div>
</gl-dropdown>
</template>
......@@ -77,6 +77,11 @@ export const ALERT_COLLAPSED_FILES = 'collapsed';
export const DIFF_FILE_AUTOMATIC_COLLAPSE = 'automatic';
export const DIFF_FILE_MANUAL_COLLAPSE = 'manual';
// Diff view single file mode
export const DIFF_FILE_BY_FILE_COOKIE_NAME = 'fileViewMode';
export const DIFF_VIEW_FILE_BY_FILE = 'single';
export const DIFF_VIEW_ALL_FILES = 'all';
// State machine states
export const STATE_IDLING = 'idle';
export const STATE_LOADING = 'loading';
......@@ -98,6 +103,7 @@ export const RENAMED_DIFF_TRANSITIONS = {
// MR Diffs known events
export const EVT_EXPAND_ALL_FILES = 'mr:diffs:expandAllFiles';
export const EVT_VIEW_FILE_BY_FILE = 'mr:diffs:preference:fileByFile';
export const EVT_PERF_MARK_FILE_TREE_START = 'mr:diffs:perf:fileTreeStart';
export const EVT_PERF_MARK_FILE_TREE_END = 'mr:diffs:perf:fileTreeEnd';
export const EVT_PERF_MARK_DIFF_FILES_START = 'mr:diffs:perf:filesStart';
......
......@@ -16,3 +16,7 @@ export const DIFF_FILE = {
autoCollapsed: __('Files with large changes are collapsed by default.'),
expand: __('Expand file'),
};
export const SETTINGS_DROPDOWN = {
fileByFile: __('Show one file at a time'),
};
......@@ -116,7 +116,7 @@ export default function initDiffsApp(store) {
isFluidLayout: this.isFluidLayout,
dismissEndpoint: this.dismissEndpoint,
showSuggestPopover: this.showSuggestPopover,
viewDiffsFileByFile: this.viewDiffsFileByFile,
fileByFileUserPreference: this.viewDiffsFileByFile,
},
});
},
......
......@@ -44,6 +44,9 @@ import {
EVT_PERF_MARK_FILE_TREE_START,
EVT_PERF_MARK_FILE_TREE_END,
EVT_PERF_MARK_DIFF_FILES_START,
DIFF_VIEW_FILE_BY_FILE,
DIFF_VIEW_ALL_FILES,
DIFF_FILE_BY_FILE_COOKIE_NAME,
} from '../constants';
import { diffViewerModes } from '~/ide/constants';
import { isCollapsed } from '../diff_file';
......@@ -57,6 +60,7 @@ export const setBaseConfig = ({ commit }, options) => {
projectPath,
dismissEndpoint,
showSuggestPopover,
viewDiffsFileByFile,
} = options;
commit(types.SET_BASE_CONFIG, {
endpoint,
......@@ -66,6 +70,7 @@ export const setBaseConfig = ({ commit }, options) => {
projectPath,
dismissEndpoint,
showSuggestPopover,
viewDiffsFileByFile,
});
};
......@@ -694,3 +699,14 @@ export const navigateToDiffFileIndex = ({ commit, state }, index) => {
commit(types.VIEW_DIFF_FILE, fileHash);
};
export const setFileByFile = ({ commit }, { fileByFile }) => {
const fileViewMode = fileByFile ? DIFF_VIEW_FILE_BY_FILE : DIFF_VIEW_ALL_FILES;
commit(types.SET_FILE_BY_FILE, fileByFile);
Cookies.set(DIFF_FILE_BY_FILE_COOKIE_NAME, fileViewMode);
historyPushState(
mergeUrlParams({ [DIFF_FILE_BY_FILE_COOKIE_NAME]: fileViewMode }, window.location.href),
);
};
......@@ -5,6 +5,8 @@ import {
DIFF_VIEW_COOKIE_NAME,
DIFF_WHITESPACE_COOKIE_NAME,
} from '../../constants';
import { fileByFile } from '../../utils/preferences';
import { getDefaultWhitespace } from '../utils';
const viewTypeFromQueryString = getParameterValues('view')[0];
......@@ -39,6 +41,7 @@ export default () => ({
highlightedRow: null,
renderTreeList: true,
showWhitespace: getDefaultWhitespace(whiteSpaceFromQueryString, whiteSpaceFromCookie),
viewDiffsFileByFile: fileByFile(),
fileFinderVisible: false,
dismissEndpoint: '',
showSuggestPopover: true,
......
......@@ -28,6 +28,7 @@ export const SET_HIGHLIGHTED_ROW = 'SET_HIGHLIGHTED_ROW';
export const SET_TREE_DATA = 'SET_TREE_DATA';
export const SET_RENDER_TREE_LIST = 'SET_RENDER_TREE_LIST';
export const SET_SHOW_WHITESPACE = 'SET_SHOW_WHITESPACE';
export const SET_FILE_BY_FILE = 'SET_FILE_BY_FILE';
export const TOGGLE_FILE_FINDER_VISIBLE = 'TOGGLE_FILE_FINDER_VISIBLE';
export const REQUEST_FULL_DIFF = 'REQUEST_FULL_DIFF';
......
......@@ -36,6 +36,7 @@ export default {
projectPath,
dismissEndpoint,
showSuggestPopover,
viewDiffsFileByFile,
} = options;
Object.assign(state, {
endpoint,
......@@ -45,6 +46,7 @@ export default {
projectPath,
dismissEndpoint,
showSuggestPopover,
viewDiffsFileByFile,
});
},
......@@ -352,4 +354,7 @@ export default {
[types.SET_SHOW_SUGGEST_POPOVER](state) {
state.showSuggestPopover = false;
},
[types.SET_FILE_BY_FILE](state, fileByFile) {
state.viewDiffsFileByFile = fileByFile;
},
};
import Cookies from 'js-cookie';
import { getParameterValues } from '~/lib/utils/url_utility';
import { DIFF_FILE_BY_FILE_COOKIE_NAME, DIFF_VIEW_FILE_BY_FILE } from '../constants';
export function fileByFile(pref = false) {
const search = getParameterValues(DIFF_FILE_BY_FILE_COOKIE_NAME)?.[0];
const cookie = Cookies.get(DIFF_FILE_BY_FILE_COOKIE_NAME);
let viewFileByFile = pref;
// use the cookie first, if it exists
if (cookie) {
viewFileByFile = cookie === DIFF_VIEW_FILE_BY_FILE;
}
// the search parameter of the URL should override, if it exists
if (search) {
viewFileByFile = search === DIFF_VIEW_FILE_BY_FILE;
}
return viewFileByFile;
}
---
title: Toggle File-By-File setting from the MR settings dropdown
merge_request: 47726
author:
type: added
......@@ -92,6 +92,17 @@ From there, when reviewing merge requests' **Changes** tab, you will see only on
![File-by-file diff navigation](img/file_by_file_v13_2.png)
From [GitLab 13.7](https://gitlab.com/gitlab-org/gitlab/-/issues/233898) onwards, if you want to change
this behavior, you can do so from your **User preferences** (as explained above) or directly in a
merge request:
1. Go to the merge request's **Changes** tab.
1. Click the cog icon (**{settings}**) to reveal the merge request's settings dropdown.
1. Select or unselect the checkbox **Show one file at a time** to change the setting accordingly.
This change overrides the choice you made in your user preferences and persists until you clear your
browser's cookies or change this behavior again.
#### Enable or disable file-by-file diff navigation **(CORE ONLY)**
File-by-file diff navigation is under development but ready for production use. It is
......
......@@ -25107,6 +25107,9 @@ msgstr ""
msgid "Show me the basics"
msgstr ""
msgid "Show one file at a time"
msgstr ""
msgid "Show only direct members"
msgstr ""
......
......@@ -17,10 +17,14 @@ import axios from '~/lib/utils/axios_utils';
import * as urlUtils from '~/lib/utils/url_utility';
import diffsMockData from '../mock_data/merge_request_diffs';
import { EVT_VIEW_FILE_BY_FILE } from '~/diffs/constants';
import eventHub from '~/diffs/event_hub';
const mergeRequestDiff = { version_index: 1 };
const TEST_ENDPOINT = `${TEST_HOST}/diff/endpoint`;
const COMMIT_URL = '[BASE URL]/OLD';
const UPDATED_COMMIT_URL = '[BASE URL]/NEW';
const COMMIT_URL = `${TEST_HOST}/COMMIT/OLD`;
const UPDATED_COMMIT_URL = `${TEST_HOST}/COMMIT/NEW`;
function getCollapsedFilesWarning(wrapper) {
return wrapper.find(CollapsedFilesWarning);
......@@ -61,7 +65,7 @@ describe('diffs/components/app', () => {
changesEmptyStateIllustration: '',
dismissEndpoint: '',
showSuggestPopover: true,
viewDiffsFileByFile: false,
fileByFileUserPreference: false,
...props,
},
provide,
......@@ -700,12 +704,14 @@ describe('diffs/components/app', () => {
});
describe('file-by-file', () => {
it('renders a single diff', () => {
createComponent({ viewDiffsFileByFile: true }, ({ state }) => {
it('renders a single diff', async () => {
createComponent({ fileByFileUserPreference: true }, ({ state }) => {
state.diffs.diffFiles.push({ file_hash: '123' });
state.diffs.diffFiles.push({ file_hash: '312' });
});
await wrapper.vm.$nextTick();
expect(wrapper.findAll(DiffFile).length).toBe(1);
});
......@@ -713,31 +719,37 @@ describe('diffs/components/app', () => {
const fileByFileNav = () => wrapper.find('[data-testid="file-by-file-navigation"]');
const paginator = () => fileByFileNav().find(GlPagination);
it('sets previous button as disabled', () => {
createComponent({ viewDiffsFileByFile: true }, ({ state }) => {
it('sets previous button as disabled', async () => {
createComponent({ fileByFileUserPreference: true }, ({ state }) => {
state.diffs.diffFiles.push({ file_hash: '123' }, { file_hash: '312' });
});
await wrapper.vm.$nextTick();
expect(paginator().attributes('prevpage')).toBe(undefined);
expect(paginator().attributes('nextpage')).toBe('2');
});
it('sets next button as disabled', () => {
createComponent({ viewDiffsFileByFile: true }, ({ state }) => {
it('sets next button as disabled', async () => {
createComponent({ fileByFileUserPreference: true }, ({ state }) => {
state.diffs.diffFiles.push({ file_hash: '123' }, { file_hash: '312' });
state.diffs.currentDiffFileId = '312';
});
await wrapper.vm.$nextTick();
expect(paginator().attributes('prevpage')).toBe('1');
expect(paginator().attributes('nextpage')).toBe(undefined);
});
it("doesn't display when there's fewer than 2 files", () => {
createComponent({ viewDiffsFileByFile: true }, ({ state }) => {
it("doesn't display when there's fewer than 2 files", async () => {
createComponent({ fileByFileUserPreference: true }, ({ state }) => {
state.diffs.diffFiles.push({ file_hash: '123' });
state.diffs.currentDiffFileId = '123';
});
await wrapper.vm.$nextTick();
expect(fileByFileNav().exists()).toBe(false);
});
......@@ -748,11 +760,13 @@ describe('diffs/components/app', () => {
`(
'it calls navigateToDiffFileIndex with $index when $link is clicked',
async ({ currentDiffFileId, targetFile }) => {
createComponent({ viewDiffsFileByFile: true }, ({ state }) => {
createComponent({ fileByFileUserPreference: true }, ({ state }) => {
state.diffs.diffFiles.push({ file_hash: '123' }, { file_hash: '312' });
state.diffs.currentDiffFileId = currentDiffFileId;
});
await wrapper.vm.$nextTick();
jest.spyOn(wrapper.vm, 'navigateToDiffFileIndex');
paginator().vm.$emit('input', targetFile);
......@@ -763,5 +777,24 @@ describe('diffs/components/app', () => {
},
);
});
describe('control via event stream', () => {
it.each`
setting
${true}
${false}
`(
'triggers the action with the new fileByFile setting - $setting - when the event with that setting is received',
async ({ setting }) => {
createComponent();
await wrapper.vm.$nextTick();
eventHub.$emit(EVT_VIEW_FILE_BY_FILE, { setting });
await wrapper.vm.$nextTick();
expect(store.state.diffs.viewDiffsFileByFile).toBe(setting);
},
);
});
});
});
......@@ -2,12 +2,18 @@ import { mount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex';
import diffModule from '~/diffs/store/modules';
import SettingsDropdown from '~/diffs/components/settings_dropdown.vue';
import { PARALLEL_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE } from '~/diffs/constants';
import {
EVT_VIEW_FILE_BY_FILE,
PARALLEL_DIFF_VIEW_TYPE,
INLINE_DIFF_VIEW_TYPE,
} from '~/diffs/constants';
import eventHub from '~/diffs/event_hub';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('Diff settings dropdown component', () => {
let wrapper;
let vm;
let actions;
......@@ -25,10 +31,15 @@ describe('Diff settings dropdown component', () => {
extendStore(store);
vm = mount(SettingsDropdown, {
wrapper = mount(SettingsDropdown, {
localVue,
store,
});
vm = wrapper.vm;
}
function getFileByFileCheckbox(vueWrapper) {
return vueWrapper.find('[data-testid="file-by-file"]');
}
beforeEach(() => {
......@@ -41,14 +52,14 @@ describe('Diff settings dropdown component', () => {
});
afterEach(() => {
vm.destroy();
wrapper.destroy();
});
describe('tree view buttons', () => {
it('list view button dispatches setRenderTreeList with false', () => {
createComponent();
vm.find('.js-list-view').trigger('click');
wrapper.find('.js-list-view').trigger('click');
expect(actions.setRenderTreeList).toHaveBeenCalledWith(expect.anything(), false);
});
......@@ -56,7 +67,7 @@ describe('Diff settings dropdown component', () => {
it('tree view button dispatches setRenderTreeList with true', () => {
createComponent();
vm.find('.js-tree-view').trigger('click');
wrapper.find('.js-tree-view').trigger('click');
expect(actions.setRenderTreeList).toHaveBeenCalledWith(expect.anything(), true);
});
......@@ -68,8 +79,8 @@ describe('Diff settings dropdown component', () => {
});
});
expect(vm.find('.js-list-view').classes('selected')).toBe(true);
expect(vm.find('.js-tree-view').classes('selected')).toBe(false);
expect(wrapper.find('.js-list-view').classes('selected')).toBe(true);
expect(wrapper.find('.js-tree-view').classes('selected')).toBe(false);
});
it('sets tree button as selected when renderTreeList is true', () => {
......@@ -79,8 +90,8 @@ describe('Diff settings dropdown component', () => {
});
});
expect(vm.find('.js-list-view').classes('selected')).toBe(false);
expect(vm.find('.js-tree-view').classes('selected')).toBe(true);
expect(wrapper.find('.js-list-view').classes('selected')).toBe(false);
expect(wrapper.find('.js-tree-view').classes('selected')).toBe(true);
});
});
......@@ -92,8 +103,8 @@ describe('Diff settings dropdown component', () => {
});
});
expect(vm.find('.js-inline-diff-button').classes('selected')).toBe(true);
expect(vm.find('.js-parallel-diff-button').classes('selected')).toBe(false);
expect(wrapper.find('.js-inline-diff-button').classes('selected')).toBe(true);
expect(wrapper.find('.js-parallel-diff-button').classes('selected')).toBe(false);
});
it('sets parallel button as selected', () => {
......@@ -103,14 +114,14 @@ describe('Diff settings dropdown component', () => {
});
});
expect(vm.find('.js-inline-diff-button').classes('selected')).toBe(false);
expect(vm.find('.js-parallel-diff-button').classes('selected')).toBe(true);
expect(wrapper.find('.js-inline-diff-button').classes('selected')).toBe(false);
expect(wrapper.find('.js-parallel-diff-button').classes('selected')).toBe(true);
});
it('calls setInlineDiffViewType when clicking inline button', () => {
createComponent();
vm.find('.js-inline-diff-button').trigger('click');
wrapper.find('.js-inline-diff-button').trigger('click');
expect(actions.setInlineDiffViewType).toHaveBeenCalled();
});
......@@ -118,7 +129,7 @@ describe('Diff settings dropdown component', () => {
it('calls setParallelDiffViewType when clicking parallel button', () => {
createComponent();
vm.find('.js-parallel-diff-button').trigger('click');
wrapper.find('.js-parallel-diff-button').trigger('click');
expect(actions.setParallelDiffViewType).toHaveBeenCalled();
});
......@@ -132,7 +143,7 @@ describe('Diff settings dropdown component', () => {
});
});
expect(vm.find('#show-whitespace').element.checked).toBe(false);
expect(wrapper.find('#show-whitespace').element.checked).toBe(false);
});
it('sets as checked when showWhitespace is true', () => {
......@@ -142,13 +153,13 @@ describe('Diff settings dropdown component', () => {
});
});
expect(vm.find('#show-whitespace').element.checked).toBe(true);
expect(wrapper.find('#show-whitespace').element.checked).toBe(true);
});
it('calls setShowWhitespace on change', () => {
createComponent();
const checkbox = vm.find('#show-whitespace');
const checkbox = wrapper.find('#show-whitespace');
checkbox.element.checked = true;
checkbox.trigger('change');
......@@ -159,4 +170,52 @@ describe('Diff settings dropdown component', () => {
});
});
});
describe('file-by-file toggle', () => {
beforeEach(() => {
jest.spyOn(eventHub, '$emit');
});
it.each`
fileByFile | checked
${true} | ${true}
${false} | ${false}
`(
'sets { checked: $checked } if the fileByFile setting is $fileByFile',
async ({ fileByFile, checked }) => {
createComponent(store => {
Object.assign(store.state.diffs, {
viewDiffsFileByFile: fileByFile,
});
});
await vm.$nextTick();
expect(vm.checked).toBe(checked);
},
);
it.each`
start | emit
${true} | ${false}
${false} | ${true}
`(
'when the file by file setting starts as $start, toggling the checkbox should emit an event set to $emit',
async ({ start, emit }) => {
createComponent(store => {
Object.assign(store.state.diffs, {
viewDiffsFileByFile: start,
});
});
await vm.$nextTick();
getFileByFileCheckbox(wrapper).trigger('click');
await vm.$nextTick();
expect(eventHub.$emit).toHaveBeenCalledWith(EVT_VIEW_FILE_BY_FILE, { setting: emit });
},
);
});
});
......@@ -48,6 +48,7 @@ import {
moveToNeighboringCommit,
setCurrentDiffFileIdFromNote,
navigateToDiffFileIndex,
setFileByFile,
} from '~/diffs/store/actions';
import eventHub from '~/notes/event_hub';
import * as types from '~/diffs/store/mutation_types';
......@@ -1455,4 +1456,20 @@ describe('DiffsStoreActions', () => {
);
});
});
describe('setFileByFile', () => {
it.each`
value
${true}
${false}
`('commits SET_FILE_BY_FILE with the new value $value', ({ value }) => {
return testAction(
setFileByFile,
{ fileByFile: value },
{ viewDiffsFileByFile: null },
[{ type: types.SET_FILE_BY_FILE, payload: value }],
[],
);
});
});
});
......@@ -892,4 +892,18 @@ describe('DiffsStoreMutations', () => {
expect(state.showSuggestPopover).toBe(false);
});
});
describe('SET_FILE_BY_FILE', () => {
it.each`
value | opposite
${true} | ${false}
${false} | ${true}
`('sets viewDiffsFileByFile to $value', ({ value, opposite }) => {
const state = { viewDiffsFileByFile: opposite };
mutations[types.SET_FILE_BY_FILE](state, value);
expect(state.viewDiffsFileByFile).toBe(value);
});
});
});
import Cookies from 'js-cookie';
import { getParameterValues } from '~/lib/utils/url_utility';
import { fileByFile } from '~/diffs/utils/preferences';
import {
DIFF_FILE_BY_FILE_COOKIE_NAME,
DIFF_VIEW_FILE_BY_FILE,
DIFF_VIEW_ALL_FILES,
} from '~/diffs/constants';
jest.mock('~/lib/utils/url_utility');
describe('diffs preferences', () => {
describe('fileByFile', () => {
it.each`
result | preference | cookie | searchParam
${false} | ${false} | ${undefined} | ${undefined}
${true} | ${true} | ${undefined} | ${undefined}
${true} | ${false} | ${DIFF_VIEW_FILE_BY_FILE} | ${undefined}
${false} | ${true} | ${DIFF_VIEW_ALL_FILES} | ${undefined}
${true} | ${false} | ${undefined} | ${[DIFF_VIEW_FILE_BY_FILE]}
${false} | ${true} | ${undefined} | ${[DIFF_VIEW_ALL_FILES]}
${true} | ${false} | ${DIFF_VIEW_FILE_BY_FILE} | ${[DIFF_VIEW_FILE_BY_FILE]}
${true} | ${true} | ${DIFF_VIEW_ALL_FILES} | ${[DIFF_VIEW_FILE_BY_FILE]}
${false} | ${false} | ${DIFF_VIEW_ALL_FILES} | ${[DIFF_VIEW_ALL_FILES]}
${false} | ${true} | ${DIFF_VIEW_FILE_BY_FILE} | ${[DIFF_VIEW_ALL_FILES]}
`(
'should return $result when { preference: $preference, cookie: $cookie, search: $searchParam }',
({ result, preference, cookie, searchParam }) => {
if (cookie) {
Cookies.set(DIFF_FILE_BY_FILE_COOKIE_NAME, cookie);
}
getParameterValues.mockReturnValue(searchParam);
expect(fileByFile(preference)).toBe(result);
},
);
});
});
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment