Commit 2f40aa68 authored by Phil Hughes's avatar Phil Hughes

Added dropdown for diff settings

Dropdown includes buttons for tree view rendering mode
and buttons for the compare view (inline or side-by-side)

Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/55491
parent da251c64
...@@ -2,10 +2,10 @@ ...@@ -2,10 +2,10 @@
import { mapActions, mapGetters, mapState } from 'vuex'; import { mapActions, mapGetters, mapState } from 'vuex';
import { GlTooltipDirective, GlLink, GlButton } from '@gitlab/ui'; import { GlTooltipDirective, GlLink, GlButton } from '@gitlab/ui';
import { __ } from '~/locale'; import { __ } from '~/locale';
import { getParameterValues, mergeUrlParams } from '~/lib/utils/url_utility';
import { polyfillSticky } from '~/lib/utils/sticky'; import { polyfillSticky } from '~/lib/utils/sticky';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import CompareVersionsDropdown from './compare_versions_dropdown.vue'; import CompareVersionsDropdown from './compare_versions_dropdown.vue';
import SettingsDropdown from './settings_dropdown.vue';
export default { export default {
components: { components: {
...@@ -13,6 +13,7 @@ export default { ...@@ -13,6 +13,7 @@ export default {
Icon, Icon,
GlLink, GlLink,
GlButton, GlButton,
SettingsDropdown,
}, },
directives: { directives: {
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
...@@ -35,23 +36,10 @@ export default { ...@@ -35,23 +36,10 @@ export default {
}, },
computed: { computed: {
...mapState('diffs', ['commit', 'showTreeList', 'startVersion', 'latestVersionPath']), ...mapState('diffs', ['commit', 'showTreeList', 'startVersion', 'latestVersionPath']),
...mapGetters('diffs', ['isInlineView', 'isParallelView', 'hasCollapsedFile']), ...mapGetters('diffs', ['hasCollapsedFile']),
comparableDiffs() { comparableDiffs() {
return this.mergeRequestDiffs.slice(1); return this.mergeRequestDiffs.slice(1);
}, },
toggleWhitespaceText() {
if (this.isWhitespaceVisible()) {
return __('Hide whitespace changes');
}
return __('Show whitespace changes');
},
toggleWhitespacePath() {
if (this.isWhitespaceVisible()) {
return mergeUrlParams({ w: 1 }, window.location.href);
}
return mergeUrlParams({ w: 0 }, window.location.href);
},
showDropdowns() { showDropdowns() {
return !this.commit && this.mergeRequestDiffs.length; return !this.commit && this.mergeRequestDiffs.length;
}, },
...@@ -75,9 +63,6 @@ export default { ...@@ -75,9 +63,6 @@ export default {
'expandAllFiles', 'expandAllFiles',
'toggleShowTreeList', 'toggleShowTreeList',
]), ]),
isWhitespaceVisible() {
return getParameterValues('w')[0] !== '1';
},
}, },
}; };
</script> </script>
...@@ -118,7 +103,7 @@ export default { ...@@ -118,7 +103,7 @@ export default {
{{ __('Viewing commit') }} {{ __('Viewing commit') }}
<gl-link :href="commit.commit_url" class="monospace">{{ commit.short_id }}</gl-link> <gl-link :href="commit.commit_url" class="monospace">{{ commit.short_id }}</gl-link>
</div> </div>
<div class="inline-parallel-buttons d-none d-lg-flex ml-auto"> <div class="inline-parallel-buttons d-none d-md-flex ml-auto">
<gl-button <gl-button
v-if="commit || startVersion" v-if="commit || startVersion"
:href="latestVersionPath" :href="latestVersionPath"
...@@ -129,31 +114,7 @@ export default { ...@@ -129,31 +114,7 @@ export default {
<a v-show="hasCollapsedFile" class="btn btn-default append-right-8" @click="expandAllFiles"> <a v-show="hasCollapsedFile" class="btn btn-default append-right-8" @click="expandAllFiles">
{{ __('Expand all') }} {{ __('Expand all') }}
</a> </a>
<a :href="toggleWhitespacePath" class="btn btn-default qa-toggle-whitespace"> <settings-dropdown />
{{ toggleWhitespaceText }}
</a>
<div class="btn-group prepend-left-8">
<button
id="inline-diff-btn"
:class="{ active: isInlineView }"
type="button"
class="btn js-inline-diff-button"
data-view-type="inline"
@click="setInlineDiffViewType"
>
{{ __('Inline') }}
</button>
<button
id="parallel-diff-btn"
:class="{ active: isParallelView }"
type="button"
class="btn js-parallel-diff-button"
data-view-type="parallel"
@click="setParallelDiffViewType"
>
{{ __('Side-by-side') }}
</button>
</div>
</div> </div>
</div> </div>
</div> </div>
......
<script>
import { mapActions, mapGetters, mapState } from 'vuex';
import { GlButton } from '@gitlab/ui';
import Icon from '~/vue_shared/components/icon.vue';
export default {
components: {
GlButton,
Icon,
},
computed: {
...mapGetters('diffs', ['isInlineView', 'isParallelView']),
...mapState('diffs', ['renderTreeList', 'showWhitespace']),
},
methods: {
...mapActions('diffs', [
'setInlineDiffViewType',
'setParallelDiffViewType',
'setRenderTreeList',
'setShowWhitespace',
]),
},
};
</script>
<template>
<div class="dropdown">
<button
type="button"
class="btn btn-default js-show-diff-settings"
data-toggle="dropdown"
data-display="static"
>
<icon name="settings" /> <icon name="arrow-down" />
</button>
<div class="dropdown-menu dropdown-menu-right p-2 pt-3 pb-3">
<div>
<span class="bold d-block mb-1">{{ __('File browser') }}</span>
<div class="btn-group d-flex">
<gl-button
:class="{ active: !renderTreeList }"
class="w-100 js-list-view"
@click="setRenderTreeList(false)"
>
{{ __('List view') }}
</gl-button>
<gl-button
:class="{ active: renderTreeList }"
class="w-100 js-tree-view"
@click="setRenderTreeList(true)"
>
{{ __('Tree view') }}
</gl-button>
</div>
</div>
<div class="mt-2">
<span class="bold d-block mb-1">{{ __('Compare changes') }}</span>
<div class="btn-group d-flex js-diff-view-buttons">
<gl-button
id="inline-diff-btn"
:class="{ active: isInlineView }"
class="w-100 js-inline-diff-button"
data-view-type="inline"
@click="setInlineDiffViewType"
>
{{ __('Inline') }}
</gl-button>
<gl-button
id="parallel-diff-btn"
:class="{ active: isParallelView }"
class="w-100 js-parallel-diff-button"
data-view-type="parallel"
@click="setParallelDiffViewType"
>
{{ __('Side-by-side') }}
</gl-button>
</div>
</div>
<div class="mt-2">
<label class="mb-0">
<input
id="show-whitespace"
type="checkbox"
:checked="showWhitespace"
@change="setShowWhitespace({ showWhitespace: $event.target.checked, pushState: true })"
/>
{{ __('Show whitespace changes') }}
</label>
</div>
</div>
</div>
</template>
<script> <script>
import { mapActions, mapGetters, mapState } from 'vuex'; import { mapActions, mapGetters, mapState } from 'vuex';
import { GlTooltipDirective } from '@gitlab/ui'; import { GlTooltipDirective } from '@gitlab/ui';
import { parseBoolean } from '~/lib/utils/common_utils';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
import FileRow from '~/vue_shared/components/file_row.vue'; import FileRow from '~/vue_shared/components/file_row.vue';
import FileRowStats from './file_row_stats.vue'; import FileRowStats from './file_row_stats.vue';
const treeListStorageKey = 'mr_diff_tree_list';
export default { export default {
directives: { directives: {
GlTooltip: GlTooltipDirective, GlTooltip: GlTooltipDirective,
...@@ -17,17 +14,12 @@ export default { ...@@ -17,17 +14,12 @@ export default {
FileRow, FileRow,
}, },
data() { data() {
const treeListStored = localStorage.getItem(treeListStorageKey);
const renderTreeList = treeListStored !== null ? parseBoolean(treeListStored) : true;
return { return {
search: '', search: '',
renderTreeList,
focusSearch: false,
}; };
}, },
computed: { computed: {
...mapState('diffs', ['tree', 'addedLines', 'removedLines']), ...mapState('diffs', ['tree', 'addedLines', 'removedLines', 'renderTreeList']),
...mapGetters('diffs', ['allBlobs', 'diffFilesLength']), ...mapGetters('diffs', ['allBlobs', 'diffFilesLength']),
filteredTreeList() { filteredTreeList() {
const search = this.search.toLowerCase().trim(); const search = this.search.toLowerCase().trim();
...@@ -52,19 +44,6 @@ export default { ...@@ -52,19 +44,6 @@ export default {
...mapActions('diffs', ['toggleTreeOpen', 'scrollToFile']), ...mapActions('diffs', ['toggleTreeOpen', 'scrollToFile']),
clearSearch() { clearSearch() {
this.search = ''; this.search = '';
this.toggleFocusSearch(false);
},
toggleRenderTreeList(toggle) {
this.renderTreeList = toggle;
localStorage.setItem(treeListStorageKey, this.renderTreeList);
},
toggleFocusSearch(toggle) {
this.focusSearch = toggle;
},
blurSearch() {
if (this.search.trim() === '') {
this.toggleFocusSearch(false);
}
}, },
}, },
FileRowStats, FileRowStats,
...@@ -81,8 +60,6 @@ export default { ...@@ -81,8 +60,6 @@ export default {
:placeholder="s__('MergeRequest|Filter files')" :placeholder="s__('MergeRequest|Filter files')"
type="search" type="search"
class="form-control" class="form-control"
@focus="toggleFocusSearch(true)"
@blur="blurSearch"
/> />
<button <button
v-show="search" v-show="search"
...@@ -94,34 +71,6 @@ export default { ...@@ -94,34 +71,6 @@ export default {
<icon name="close" /> <icon name="close" />
</button> </button>
</div> </div>
<div v-show="!focusSearch" class="btn-group prepend-left-8 tree-list-view-toggle">
<button
v-gl-tooltip.hover
:aria-label="__('List view')"
:title="__('List view')"
:class="{
active: !renderTreeList,
}"
class="btn btn-default pt-0 pb-0 d-flex align-items-center"
type="button"
@click="toggleRenderTreeList(false)"
>
<icon name="hamburger" />
</button>
<button
v-gl-tooltip.hover
:aria-label="__('Tree view')"
:title="__('Tree view')"
:class="{
active: renderTreeList,
}"
class="btn btn-default pt-0 pb-0 d-flex align-items-center"
type="button"
@click="toggleRenderTreeList(true)"
>
<icon name="file-tree" />
</button>
</div>
</div> </div>
<div :class="{ 'pt-0 tree-list-blobs': !renderTreeList }" class="tree-list-scroll"> <div :class="{ 'pt-0 tree-list-blobs': !renderTreeList }" class="tree-list-scroll">
<template v-if="filteredTreeList.length"> <template v-if="filteredTreeList.length">
......
...@@ -34,3 +34,5 @@ export const MAX_LINES_TO_BE_RENDERED = 2000; ...@@ -34,3 +34,5 @@ export const MAX_LINES_TO_BE_RENDERED = 2000;
export const MR_TREE_SHOW_KEY = 'mr_tree_show'; export const MR_TREE_SHOW_KEY = 'mr_tree_show';
export const TREE_TYPE = 'tree'; export const TREE_TYPE = 'tree';
export const TREE_LIST_STORAGE_KEY = 'mr_diff_tree_list';
export const WHITESPACE_STORAGE_KEY = 'mr_show_whitespace';
import Vue from 'vue'; import Vue from 'vue';
import { mapState } from 'vuex'; import { mapActions, mapState } from 'vuex';
import { parseBoolean } from '~/lib/utils/common_utils';
import { getParameterValues } from '~/lib/utils/url_utility';
import diffsApp from './components/app.vue'; import diffsApp from './components/app.vue';
import { TREE_LIST_STORAGE_KEY } from './constants';
export default function initDiffsApp(store) { export default function initDiffsApp(store) {
return new Vue({ return new Vue({
...@@ -26,6 +29,16 @@ export default function initDiffsApp(store) { ...@@ -26,6 +29,16 @@ export default function initDiffsApp(store) {
activeTab: state => state.page.activeTab, activeTab: state => state.page.activeTab,
}), }),
}, },
created() {
const treeListStored = localStorage.getItem(TREE_LIST_STORAGE_KEY);
const renderTreeList = treeListStored !== null ? parseBoolean(treeListStored) : true;
this.setRenderTreeList(renderTreeList);
this.setShowWhitespace({ showWhitespace: getParameterValues('w')[0] !== '1' });
},
methods: {
...mapActions('diffs', ['setRenderTreeList', 'setShowWhitespace']),
},
render(createElement) { render(createElement) {
return createElement('diffs-app', { return createElement('diffs-app', {
props: { props: {
......
...@@ -14,6 +14,8 @@ import { ...@@ -14,6 +14,8 @@ import {
INLINE_DIFF_VIEW_TYPE, INLINE_DIFF_VIEW_TYPE,
DIFF_VIEW_COOKIE_NAME, DIFF_VIEW_COOKIE_NAME,
MR_TREE_SHOW_KEY, MR_TREE_SHOW_KEY,
TREE_LIST_STORAGE_KEY,
WHITESPACE_STORAGE_KEY,
} from '../constants'; } from '../constants';
export const setBaseConfig = ({ commit }, options) => { export const setBaseConfig = ({ commit }, options) => {
...@@ -33,7 +35,7 @@ export const fetchDiffFiles = ({ state, commit }) => { ...@@ -33,7 +35,7 @@ export const fetchDiffFiles = ({ state, commit }) => {
}); });
return axios return axios
.get(state.endpoint) .get(state.endpoint, { params: { w: state.showWhitespace ? null : '1' } })
.then(res => { .then(res => {
commit(types.SET_LOADING, false); commit(types.SET_LOADING, false);
commit(types.SET_MERGE_REQUEST_DIFFS, res.data.merge_request_diffs || []); commit(types.SET_MERGE_REQUEST_DIFFS, res.data.merge_request_diffs || []);
...@@ -278,5 +280,21 @@ export const closeDiffFileCommentForm = ({ commit }, fileHash) => { ...@@ -278,5 +280,21 @@ export const closeDiffFileCommentForm = ({ commit }, fileHash) => {
commit(types.CLOSE_DIFF_FILE_COMMENT_FORM, fileHash); commit(types.CLOSE_DIFF_FILE_COMMENT_FORM, fileHash);
}; };
export const setRenderTreeList = ({ commit }, renderTreeList) => {
commit(types.SET_RENDER_TREE_LIST, renderTreeList);
localStorage.setItem(TREE_LIST_STORAGE_KEY, renderTreeList);
};
export const setShowWhitespace = ({ commit }, { showWhitespace, pushState = false }) => {
commit(types.SET_SHOW_WHITESPACE, showWhitespace);
localStorage.setItem(WHITESPACE_STORAGE_KEY, showWhitespace);
if (pushState) {
historyPushState(showWhitespace ? '?w=0' : '?w=1');
}
};
// prevent babel-plugin-rewire from generating an invalid default during karma tests // prevent babel-plugin-rewire from generating an invalid default during karma tests
export default () => {}; export default () => {};
...@@ -27,4 +27,6 @@ export default () => ({ ...@@ -27,4 +27,6 @@ export default () => ({
projectPath: '', projectPath: '',
commentForms: [], commentForms: [],
highlightedRow: null, highlightedRow: null,
renderTreeList: true,
showWhitespace: true,
}); });
...@@ -20,3 +20,5 @@ export const CLOSE_DIFF_FILE_COMMENT_FORM = 'CLOSE_DIFF_FILE_COMMENT_FORM'; ...@@ -20,3 +20,5 @@ export const CLOSE_DIFF_FILE_COMMENT_FORM = 'CLOSE_DIFF_FILE_COMMENT_FORM';
export const SET_HIGHLIGHTED_ROW = 'SET_HIGHLIGHTED_ROW'; export const SET_HIGHLIGHTED_ROW = 'SET_HIGHLIGHTED_ROW';
export const SET_TREE_DATA = 'SET_TREE_DATA'; 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';
...@@ -238,4 +238,10 @@ export default { ...@@ -238,4 +238,10 @@ export default {
state.treeEntries = treeEntries; state.treeEntries = treeEntries;
state.tree = tree; state.tree = tree;
}, },
[types.SET_RENDER_TREE_LIST](state, renderTreeList) {
state.renderTreeList = renderTreeList;
},
[types.SET_SHOW_WHITESPACE](state, showWhitespace) {
state.showWhitespace = showWhitespace;
},
}; };
...@@ -428,7 +428,7 @@ export default class MergeRequestTabs { ...@@ -428,7 +428,7 @@ export default class MergeRequestTabs {
} }
diffViewType() { diffViewType() {
return $('.inline-parallel-buttons button.active').data('viewType'); return $('.js-diff-view-buttons button.active').data('viewType');
} }
isDiffAction(action) { isDiffAction(action) {
......
...@@ -1095,12 +1095,6 @@ ...@@ -1095,12 +1095,6 @@
} }
} }
.tree-list-view-toggle {
svg {
top: 0;
}
}
.image-diff-overlay, .image-diff-overlay,
.image-diff-overlay-add-comment { .image-diff-overlay-add-comment {
top: 0; top: 0;
......
...@@ -2015,6 +2015,9 @@ msgstr "" ...@@ -2015,6 +2015,9 @@ msgstr ""
msgid "Compare Revisions" msgid "Compare Revisions"
msgstr "" msgstr ""
msgid "Compare changes"
msgstr ""
msgid "Compare changes with the last commit" msgid "Compare changes with the last commit"
msgstr "" msgstr ""
...@@ -3139,6 +3142,9 @@ msgstr "" ...@@ -3139,6 +3142,9 @@ msgstr ""
msgid "File added" msgid "File added"
msgstr "" msgstr ""
msgid "File browser"
msgstr ""
msgid "File deleted" msgid "File deleted"
msgstr "" msgstr ""
...@@ -3591,9 +3597,6 @@ msgstr[1] "" ...@@ -3591,9 +3597,6 @@ msgstr[1] ""
msgid "Hide values" msgid "Hide values"
msgstr "" msgstr ""
msgid "Hide whitespace changes"
msgstr ""
msgid "History" msgid "History"
msgstr "" msgstr ""
......
...@@ -91,6 +91,7 @@ describe 'User comments on a diff', :js do ...@@ -91,6 +91,7 @@ describe 'User comments on a diff', :js do
# Check the same comments in the side-by-side view. # Check the same comments in the side-by-side view.
execute_script("window.scrollTo(0,0);") execute_script("window.scrollTo(0,0);")
find('.js-show-diff-settings').click
click_button 'Side-by-side' click_button 'Side-by-side'
wait_for_requests wait_for_requests
......
...@@ -126,6 +126,7 @@ describe 'Merge request > User resolves diff notes and discussions', :js do ...@@ -126,6 +126,7 @@ describe 'Merge request > User resolves diff notes and discussions', :js do
describe 'side-by-side view' do describe 'side-by-side view' do
before do before do
page.within('.merge-request-tabs') { click_link 'Changes' } page.within('.merge-request-tabs') { click_link 'Changes' }
find('.js-show-diff-settings').click
page.find('#parallel-diff-btn').click page.find('#parallel-diff-btn').click
end end
......
...@@ -9,17 +9,23 @@ describe 'Merge request > User toggles whitespace changes', :js do ...@@ -9,17 +9,23 @@ describe 'Merge request > User toggles whitespace changes', :js do
project.add_maintainer(user) project.add_maintainer(user)
sign_in(user) sign_in(user)
visit diffs_project_merge_request_path(project, merge_request) visit diffs_project_merge_request_path(project, merge_request)
find('.js-show-diff-settings').click
end end
it 'has a button to toggle whitespace changes' do it 'has a button to toggle whitespace changes' do
expect(page).to have_content 'Hide whitespace changes' expect(page).to have_content 'Show whitespace changes'
end end
describe 'clicking "Hide whitespace changes" button' do describe 'clicking "Hide whitespace changes" button' do
it 'toggles the "Hide whitespace changes" button' do it 'toggles the "Hide whitespace changes" button' do
click_link 'Hide whitespace changes' find('#show-whitespace').click
expect(page).to have_content 'Show whitespace changes' visit diffs_project_merge_request_path(project, merge_request)
find('.js-show-diff-settings').click
expect(find('#show-whitespace')).to be_checked
end end
end end
end end
...@@ -23,6 +23,8 @@ describe 'User views diffs', :js do ...@@ -23,6 +23,8 @@ describe 'User views diffs', :js do
end end
it 'shows diffs' do it 'shows diffs' do
find('.js-show-diff-settings').click
expect(page).to have_css('.tab-content #diffs.active') expect(page).to have_css('.tab-content #diffs.active')
expect(page).to have_css('#parallel-diff-btn', count: 1) expect(page).to have_css('#parallel-diff-btn', count: 1)
expect(page).to have_css('#inline-diff-btn', count: 1) expect(page).to have_css('#inline-diff-btn', count: 1)
...@@ -38,6 +40,8 @@ describe 'User views diffs', :js do ...@@ -38,6 +40,8 @@ describe 'User views diffs', :js do
context 'when in the side-by-side view' do context 'when in the side-by-side view' do
before do before do
find('.js-show-diff-settings').click
click_button 'Side-by-side' click_button 'Side-by-side'
wait_for_requests wait_for_requests
......
...@@ -51,15 +51,6 @@ describe('CompareVersions', () => { ...@@ -51,15 +51,6 @@ describe('CompareVersions', () => {
}); });
}); });
it('should render whitespace toggle button with correct attributes', () => {
const whitespaceBtn = vm.$el.querySelector('.qa-toggle-whitespace');
const href = vm.toggleWhitespacePath;
expect(whitespaceBtn).not.toBeNull();
expect(whitespaceBtn.getAttribute('href')).toEqual(href);
expect(whitespaceBtn.innerHTML).toContain('Hide whitespace changes');
});
it('should render view types buttons with correct values', () => { it('should render view types buttons with correct values', () => {
const inlineBtn = vm.$el.querySelector('#inline-diff-btn'); const inlineBtn = vm.$el.querySelector('#inline-diff-btn');
const parallelBtn = vm.$el.querySelector('#parallel-diff-btn'); const parallelBtn = vm.$el.querySelector('#parallel-diff-btn');
...@@ -106,30 +97,6 @@ describe('CompareVersions', () => { ...@@ -106,30 +97,6 @@ describe('CompareVersions', () => {
}); });
}); });
describe('isWhitespaceVisible', () => {
const originalHref = window.location.href;
afterEach(() => {
window.history.replaceState({}, null, originalHref);
});
it('should return "true" when no "w" flag is present in the URL (default)', () => {
expect(vm.isWhitespaceVisible()).toBe(true);
});
it('should return "false" when the flag is set to "1" in the URL', () => {
window.history.replaceState({}, null, '?w=1');
expect(vm.isWhitespaceVisible()).toBe(false);
});
it('should return "true" when the flag is set to "0" in the URL', () => {
window.history.replaceState({}, null, '?w=0');
expect(vm.isWhitespaceVisible()).toBe(true);
});
});
describe('commit', () => { describe('commit', () => {
beforeEach(done => { beforeEach(done => {
vm.$store.state.diffs.commit = getDiffWithCommit().commit; vm.$store.state.diffs.commit = getDiffWithCommit().commit;
......
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';
describe('Diff settiings dropdown component', () => {
let vm;
let actions;
function createComponent(extendStore = () => {}) {
const localVue = createLocalVue();
localVue.use(Vuex);
const store = new Vuex.Store({
modules: {
diffs: {
namespaced: true,
actions,
state: diffModule().state,
getters: diffModule().getters,
},
},
});
extendStore(store);
vm = mount(SettingsDropdown, {
localVue,
store,
});
}
beforeEach(() => {
actions = {
setInlineDiffViewType: jasmine.createSpy('setInlineDiffViewType'),
setParallelDiffViewType: jasmine.createSpy('setParallelDiffViewType'),
setRenderTreeList: jasmine.createSpy('setRenderTreeList'),
setShowWhitespace: jasmine.createSpy('setShowWhitespace'),
};
});
afterEach(() => {
vm.destroy();
});
describe('tree view buttons', () => {
it('list view button dispatches setRenderTreeList with false', () => {
createComponent();
vm.find('.js-list-view').trigger('click');
expect(actions.setRenderTreeList).toHaveBeenCalledWith(jasmine.anything(), false, undefined);
});
it('tree view button dispatches setRenderTreeList with true', () => {
createComponent();
vm.find('.js-tree-view').trigger('click');
expect(actions.setRenderTreeList).toHaveBeenCalledWith(jasmine.anything(), true, undefined);
});
it('sets list button as active when renderTreeList is false', () => {
createComponent(store => {
Object.assign(store.state.diffs, {
renderTreeList: false,
});
});
expect(vm.find('.js-list-view').classes('active')).toBe(true);
expect(vm.find('.js-tree-view').classes('active')).toBe(false);
});
it('sets tree button as active when renderTreeList is true', () => {
createComponent(store => {
Object.assign(store.state.diffs, {
renderTreeList: true,
});
});
expect(vm.find('.js-list-view').classes('active')).toBe(false);
expect(vm.find('.js-tree-view').classes('active')).toBe(true);
});
});
describe('compare changes', () => {
it('sets inline button as active', () => {
createComponent(store => {
Object.assign(store.state.diffs, {
diffViewType: INLINE_DIFF_VIEW_TYPE,
});
});
expect(vm.find('.js-inline-diff-button').classes('active')).toBe(true);
expect(vm.find('.js-parallel-diff-button').classes('active')).toBe(false);
});
it('sets parallel button as active', () => {
createComponent(store => {
Object.assign(store.state.diffs, {
diffViewType: PARALLEL_DIFF_VIEW_TYPE,
});
});
expect(vm.find('.js-inline-diff-button').classes('active')).toBe(false);
expect(vm.find('.js-parallel-diff-button').classes('active')).toBe(true);
});
it('calls setInlineDiffViewType when clicking inline button', () => {
createComponent();
vm.find('.js-inline-diff-button').trigger('click');
expect(actions.setInlineDiffViewType).toHaveBeenCalled();
});
it('calls setParallelDiffViewType when clicking parallel button', () => {
createComponent();
vm.find('.js-parallel-diff-button').trigger('click');
expect(actions.setParallelDiffViewType).toHaveBeenCalled();
});
});
describe('whitespace toggle', () => {
it('does not set as checked when showWhitespace is false', () => {
createComponent(store => {
Object.assign(store.state.diffs, {
showWhitespace: false,
});
});
expect(vm.find('#show-whitespace').element.checked).toBe(false);
});
it('sets as checked when showWhitespace is true', () => {
createComponent(store => {
Object.assign(store.state.diffs, {
showWhitespace: true,
});
});
expect(vm.find('#show-whitespace').element.checked).toBe(true);
});
it('calls setShowWhitespace on change', () => {
createComponent();
const checkbox = vm.find('#show-whitespace');
checkbox.element.checked = true;
checkbox.trigger('change');
expect(actions.setShowWhitespace).toHaveBeenCalledWith(
jasmine.anything(),
{
showWhitespace: true,
pushState: true,
},
undefined,
);
});
});
});
...@@ -111,7 +111,7 @@ describe('Diffs tree list component', () => { ...@@ -111,7 +111,7 @@ describe('Diffs tree list component', () => {
}); });
it('renders as file list when renderTreeList is false', done => { it('renders as file list when renderTreeList is false', done => {
vm.renderTreeList = false; vm.$store.state.diffs.renderTreeList = false;
vm.$nextTick(() => { vm.$nextTick(() => {
expect(vm.$el.querySelectorAll('.file-row').length).toBe(1); expect(vm.$el.querySelectorAll('.file-row').length).toBe(1);
...@@ -121,7 +121,7 @@ describe('Diffs tree list component', () => { ...@@ -121,7 +121,7 @@ describe('Diffs tree list component', () => {
}); });
it('renders file paths when renderTreeList is false', done => { it('renders file paths when renderTreeList is false', done => {
vm.renderTreeList = false; vm.$store.state.diffs.renderTreeList = false;
vm.$nextTick(() => { vm.$nextTick(() => {
expect(vm.$el.querySelector('.file-row').textContent).toContain('index.js'); expect(vm.$el.querySelector('.file-row').textContent).toContain('index.js');
...@@ -129,34 +129,6 @@ describe('Diffs tree list component', () => { ...@@ -129,34 +129,6 @@ describe('Diffs tree list component', () => {
done(); done();
}); });
}); });
it('hides render buttons when input is focused', done => {
const focusEvent = new Event('focus');
vm.$el.querySelector('.form-control').dispatchEvent(focusEvent);
vm.$nextTick(() => {
expect(vm.$el.querySelector('.tree-list-view-toggle').style.display).toBe('none');
done();
});
});
it('shows render buttons when input is blurred', done => {
const blurEvent = new Event('blur');
vm.focusSearch = true;
vm.$nextTick()
.then(() => {
vm.$el.querySelector('.form-control').dispatchEvent(blurEvent);
})
.then(vm.$nextTick)
.then(() => {
expect(vm.$el.querySelector('.tree-list-view-toggle').style.display).not.toBe('none');
})
.then(done)
.catch(done.fail);
});
}); });
describe('clearSearch', () => { describe('clearSearch', () => {
...@@ -168,24 +140,4 @@ describe('Diffs tree list component', () => { ...@@ -168,24 +140,4 @@ describe('Diffs tree list component', () => {
expect(vm.search).toBe(''); expect(vm.search).toBe('');
}); });
}); });
describe('toggleRenderTreeList', () => {
it('updates renderTreeList', () => {
expect(vm.renderTreeList).toBe(true);
vm.toggleRenderTreeList(false);
expect(vm.renderTreeList).toBe(false);
});
});
describe('toggleFocusSearch', () => {
it('updates focusSearch', () => {
expect(vm.focusSearch).toBe(false);
vm.toggleFocusSearch(true);
expect(vm.focusSearch).toBe(true);
});
});
}); });
...@@ -27,6 +27,8 @@ import actions, { ...@@ -27,6 +27,8 @@ import actions, {
scrollToFile, scrollToFile,
toggleShowTreeList, toggleShowTreeList,
renderFileForDiscussionId, renderFileForDiscussionId,
setRenderTreeList,
setShowWhitespace,
} from '~/diffs/store/actions'; } from '~/diffs/store/actions';
import eventHub from '~/notes/event_hub'; import eventHub from '~/notes/event_hub';
import * as types from '~/diffs/store/mutation_types'; import * as types from '~/diffs/store/mutation_types';
...@@ -796,4 +798,55 @@ describe('DiffsStoreActions', () => { ...@@ -796,4 +798,55 @@ describe('DiffsStoreActions', () => {
expect(scrollToElement).not.toHaveBeenCalled(); expect(scrollToElement).not.toHaveBeenCalled();
}); });
}); });
describe('setRenderTreeList', () => {
it('commits SET_RENDER_TREE_LIST', done => {
testAction(
setRenderTreeList,
true,
{},
[{ type: types.SET_RENDER_TREE_LIST, payload: true }],
[],
done,
);
});
it('sets localStorage', () => {
spyOn(localStorage, 'setItem').and.stub();
setRenderTreeList({ commit() {} }, true);
expect(localStorage.setItem).toHaveBeenCalledWith('mr_diff_tree_list', true);
});
});
describe('setShowWhitespace', () => {
it('commits SET_SHOW_WHITESPACE', done => {
testAction(
setShowWhitespace,
{ showWhitespace: true },
{},
[{ type: types.SET_SHOW_WHITESPACE, payload: true }],
[],
done,
);
});
it('sets localStorage', () => {
spyOn(localStorage, 'setItem').and.stub();
setShowWhitespace({ commit() {} }, { showWhitespace: true });
expect(localStorage.setItem).toHaveBeenCalledWith('mr_show_whitespace', true);
});
it('calls history pushState', () => {
spyOn(localStorage, 'setItem').and.stub();
spyOn(window.history, 'pushState').and.stub();
setShowWhitespace({ commit() {} }, { showWhitespace: true, pushState: true });
expect(window.history.pushState).toHaveBeenCalled();
});
});
}); });
...@@ -650,4 +650,28 @@ describe('DiffsStoreMutations', () => { ...@@ -650,4 +650,28 @@ describe('DiffsStoreMutations', () => {
expect(state.tree).toEqual(['tree']); expect(state.tree).toEqual(['tree']);
}); });
}); });
describe('SET_RENDER_TREE_LIST', () => {
it('sets renderTreeList', () => {
const state = {
renderTreeList: true,
};
mutations[types.SET_RENDER_TREE_LIST](state, false);
expect(state.renderTreeList).toBe(false);
});
});
describe('SET_SHOW_WHITESPACE', () => {
it('sets showWhitespace', () => {
const state = {
showWhitespace: true,
};
mutations[types.SET_SHOW_WHITESPACE](state, false);
expect(state.showWhitespace).toBe(false);
});
});
}); });
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