Commit c194d4ac authored by Phil Hughes's avatar Phil Hughes

EE port of ide-close-changed-files

parent bdbb6942
<script>
import { mapActions } from 'vuex';
import icon from '../../../vue_shared/components/icon.vue';
export default {
......@@ -19,6 +20,11 @@
return `multi-file-${this.file.tempFile ? 'addition' : 'modified'} append-right-8`;
},
},
methods: {
...mapActions([
'discardFileChanges',
]),
},
};
</script>
......@@ -32,5 +38,12 @@
<span class="multi-file-commit-list-path">
{{ file.path }}
</span>
<button
type="button"
class="btn btn-blank multi-file-discard-btn"
@click="discardFileChanges(file)"
>
Discard
</button>
</div>
</template>
......@@ -36,9 +36,9 @@
...mapState([
'currentBlobView',
'selectedFile',
'changedFiles',
]),
...mapGetters([
'changedFiles',
'activeFile',
]),
},
......
<script>
import { mapGetters, mapState, mapActions } from 'vuex';
import { mapState, mapActions } from 'vuex';
import repoCommitSection from './repo_commit_section.vue';
import icon from '../../vue_shared/components/icon.vue';
import panelResizer from '../../vue_shared/components/panel_resizer.vue';
......@@ -28,8 +28,6 @@
computed: {
...mapState([
'rightPanelCollapsed',
]),
...mapGetters([
'changedFiles',
]),
currentIcon() {
......
<script>
import { mapGetters, mapState, mapActions } from 'vuex';
import { mapState, mapActions } from 'vuex';
import tooltip from '../../vue_shared/directives/tooltip';
import icon from '../../vue_shared/components/icon.vue';
import modal from '../../vue_shared/components/modal.vue';
......@@ -38,8 +38,6 @@ export default {
'currentBranchId',
'rightPanelCollapsed',
'lastCommitMsg',
]),
...mapGetters([
'changedFiles',
]),
commitButtonDisabled() {
......
......@@ -9,7 +9,6 @@ export default {
computed: {
...mapState([
'editMode',
'discardPopupOpen',
]),
...mapGetters([
'canEditFile',
......@@ -21,7 +20,6 @@ export default {
methods: {
...mapActions([
'toggleEditMode',
'closeDiscardPopup',
]),
},
};
......@@ -43,15 +41,5 @@ export default {
{{ buttonLabel }}
</span>
</button>
<modal
v-if="discardPopupOpen"
class="text-left"
:primary-button-label="__('Discard changes')"
kind="warning"
:title="__('Are you sure?')"
:text="__('Are you sure you want to discard your changes?')"
@cancel="closeDiscardPopup"
@submit="toggleEditMode(true)"
/>
</div>
</template>
......@@ -19,6 +19,9 @@ export default {
shouldHideEditor() {
return this.activeFile && this.activeFile.binary && !this.activeFile.raw;
},
activeFileChanged() {
return this.activeFile && this.activeFile.changed;
},
},
watch: {
activeFile(oldVal, newVal) {
......@@ -26,6 +29,13 @@ export default {
this.initMonaco();
}
},
activeFileChanged(newVal) {
if (!this.editor) return;
if (!newVal && this.model) {
this.model.setValue(this.model.getOriginalModel().getValue());
}
},
leftPanelCollapsed() {
this.editor.updateDimensions();
},
......@@ -78,11 +88,11 @@ export default {
setupEditor() {
if (!this.activeFile) return;
const model = this.editor.createModel(this.activeFile);
this.model = this.editor.createModel(this.activeFile);
this.editor.attachModel(model);
this.editor.attachModel(this.model);
model.onChange((m) => {
this.model.onChange((m) => {
this.changeFileContent({
file: this.activeFile,
content: m.getValue(),
......@@ -104,12 +114,12 @@ export default {
// Handle File Language
this.setFileLanguage({
fileLanguage: model.language,
fileLanguage: this.model.language,
});
// Get File eol
this.setFileEOL({
eol: model.eol,
eol: this.model.eol,
});
},
},
......
......@@ -2,11 +2,13 @@
import { mapActions } from 'vuex';
import fileStatusIcon from './repo_file_status_icon.vue';
import fileIcon from '../../vue_shared/components/file_icon.vue';
import icon from '../../vue_shared/components/icon.vue';
export default {
components: {
fileStatusIcon,
fileIcon,
icon,
},
props: {
tab: {
......@@ -14,6 +16,11 @@
required: true,
},
},
data() {
return {
tabMouseOver: false,
};
},
computed: {
closeLabel() {
if (this.tab.changed || this.tab.tempFile) {
......@@ -21,12 +28,14 @@
}
return `Close ${this.tab.name}`;
},
changedClass() {
const tabChangedObj = {
'fa-times close-icon': !this.tab.changed && !this.tab.tempFile,
'fa-circle unsaved-icon': this.tab.changed || this.tab.tempFile,
};
return tabChangedObj;
showChangedIcon() {
return this.tab.changed ? !this.tabMouseOver : false;
},
changedIcon() {
return this.tab.tempFile ? 'file-addition' : 'file-modified';
},
changedIconClass() {
return this.tab.tempFile ? 'multi-file-addition' : 'multi-file-modified';
},
},
......@@ -37,28 +46,43 @@
clickFile(tab) {
this.$router.push(`/project${tab.url}`);
},
mouseOverTab() {
if (this.tab.changed) {
this.tabMouseOver = true;
}
},
mouseOutTab() {
if (this.tab.changed) {
this.tabMouseOver = false;
}
},
},
};
</script>
<template>
<li @click="clickFile(tab)">
<li
@click="clickFile(tab)"
@mouseover="mouseOverTab"
@mouseout="mouseOutTab"
>
<button
type="button"
class="multi-file-tab-close"
@click.stop.prevent="closeFile({ file: tab })"
@click.stop.prevent="closeFile(tab)"
:aria-label="closeLabel"
:class="{
'modified': tab.changed,
}"
:disabled="tab.changed"
>
<i
class="fa"
:class="changedClass"
aria-hidden="true"
>
</i>
<icon
v-if="!showChangedIcon"
name="close"
:size="12"
/>
<icon
v-else
:name="changedIcon"
:size="12"
:css-classes="changedIconClass"
/>
</button>
<div
......
......@@ -48,6 +48,10 @@ export default class Model {
return this.originalModel;
}
setValue(value) {
this.getModel().setValue(value);
}
onChange(cb) {
this.events.set(
this.path,
......
......@@ -10,42 +10,23 @@ export const redirectToUrl = (_, url) => visitUrl(url);
export const setInitialData = ({ commit }, data) =>
commit(types.SET_INITIAL_DATA, data);
export const closeDiscardPopup = ({ commit }) =>
commit(types.TOGGLE_DISCARD_POPUP, false);
export const discardAllChanges = ({ commit, getters, dispatch }) => {
const changedFiles = getters.changedFiles;
changedFiles.forEach((file) => {
export const discardAllChanges = ({ state, commit, dispatch }) => {
state.changedFiles.forEach((file) => {
commit(types.DISCARD_FILE_CHANGES, file);
if (file.tempFile) {
dispatch('closeFile', { file, force: true });
dispatch('closeFile', file);
}
});
};
export const closeAllFiles = ({ state, dispatch }) => {
state.openFiles.forEach(file => dispatch('closeFile', { file }));
state.openFiles.forEach(file => dispatch('closeFile', file));
};
export const toggleEditMode = (
{ state, commit, getters, dispatch },
force = false,
) => {
const changedFiles = getters.changedFiles;
if (changedFiles.length && !force) {
commit(types.TOGGLE_DISCARD_POPUP, true);
} else {
export const toggleEditMode = ({ commit, dispatch }) => {
commit(types.TOGGLE_EDIT_MODE);
commit(types.TOGGLE_DISCARD_POPUP, false);
dispatch('toggleBlobView');
if (!state.editMode) {
dispatch('discardAllChanges');
}
}
};
export const toggleBlobView = ({ commit, state }) => {
......@@ -85,7 +66,7 @@ export const checkCommitStatus = ({ state }) =>
.catch(() => flash('Error checking branch data. Please try again.', 'alert', document, null, false, true));
export const commitChanges = (
{ commit, state, dispatch, getters },
{ commit, state, dispatch },
{ payload, newMr },
) =>
service
......@@ -125,7 +106,7 @@ export const commitChanges = (
reference: data.id,
});
getters.changedFiles.forEach((entry) => {
state.changedFiles.forEach((entry) => {
commit(types.SET_LAST_COMMIT_DATA, {
entry,
lastCommit,
......
......@@ -10,9 +10,7 @@ import {
findIndexOfFile,
} from '../utils';
export const closeFile = ({ commit, state, dispatch }, { file, force = false }) => {
if ((file.changed || file.tempFile) && !force) return;
export const closeFile = ({ commit, state, dispatch }, file) => {
const indexOfClosedFile = findIndexOfFile(state.openFiles, file);
const fileWasActive = file.active;
......@@ -79,8 +77,16 @@ export const getRawFileData = ({ commit, dispatch }, file) => service.getRawFile
})
.catch(() => flash('Error loading file content. Please try again.', 'alert', document, null, false, true));
export const changeFileContent = ({ commit }, { file, content }) => {
export const changeFileContent = ({ state, commit }, { file, content }) => {
commit(types.UPDATE_FILE_CONTENT, { file, content });
const indexOfChangedFile = findIndexOfFile(state.changedFiles, file);
if (file.changed && indexOfChangedFile === -1) {
commit(types.ADD_FILE_TO_CHANGED, file);
} else if (!file.changed && indexOfChangedFile !== -1) {
commit(types.REMOVE_FILE_FROM_CHANGED, file);
}
};
export const setFileLanguage = ({ state, commit }, { fileLanguage }) => {
......@@ -125,6 +131,7 @@ export const createTempFile = ({ state, commit, dispatch }, { projectId, branchI
file,
});
commit(types.TOGGLE_FILE_OPEN, file);
commit(types.ADD_FILE_TO_CHANGED, file);
dispatch('setFileActive', file);
if (!state.editMode && !file.base64) {
......@@ -135,3 +142,12 @@ export const createTempFile = ({ state, commit, dispatch }, { projectId, branchI
return Promise.resolve(file);
};
export const discardFileChanges = ({ commit }, file) => {
commit(types.DISCARD_FILE_CHANGES, file);
commit(types.REMOVE_FILE_FROM_CHANGED, file);
if (file.tempFile && file.opened) {
commit(types.TOGGLE_FILE_OPEN, file);
}
};
export const changedFiles = state => state.openFiles.filter(file => file.changed);
export const activeFile = state => state.openFiles.find(file => file.active) || null;
export const activeFileExtension = (state) => {
......@@ -14,6 +12,6 @@ export const canEditFile = (state) => {
(currentActiveFile && !currentActiveFile.renderError && !currentActiveFile.binary);
};
export const addedFiles = state => changedFiles(state).filter(f => f.tempFile);
export const addedFiles = state => state.changedFiles.filter(f => f.tempFile);
export const modifiedFiles = state => changedFiles(state).filter(f => !f.tempFile);
export const modifiedFiles = state => state.changedFiles.filter(f => !f.tempFile);
......@@ -36,12 +36,12 @@ export const SET_FILE_POSITION = 'SET_FILE_POSITION';
export const SET_FILE_EOL = 'SET_FILE_EOL';
export const DISCARD_FILE_CHANGES = 'DISCARD_FILE_CHANGES';
export const CREATE_TMP_FILE = 'CREATE_TMP_FILE';
export const ADD_FILE_TO_CHANGED = 'ADD_FILE_TO_CHANGED';
export const REMOVE_FILE_FROM_CHANGED = 'REMOVE_FILE_FROM_CHANGED';
// Viewer mutation types
export const SET_PREVIEW_MODE = 'SET_PREVIEW_MODE';
export const SET_EDIT_MODE = 'SET_EDIT_MODE';
export const TOGGLE_EDIT_MODE = 'TOGGLE_EDIT_MODE';
export const TOGGLE_DISCARD_POPUP = 'TOGGLE_DISCARD_POPUP';
export const SET_CURRENT_BRANCH = 'SET_CURRENT_BRANCH';
......@@ -28,11 +28,6 @@ export default {
editMode: !state.editMode,
});
},
[types.TOGGLE_DISCARD_POPUP](state, discardPopupOpen) {
Object.assign(state, {
discardPopupOpen,
});
},
[types.SET_ROOT](state, isRoot) {
Object.assign(state, {
isRoot,
......
......@@ -71,4 +71,12 @@ export default {
[types.CREATE_TMP_FILE](state, { file, parent }) {
parent.tree.push(file);
},
[types.ADD_FILE_TO_CHANGED](state, file) {
state.changedFiles.push(file);
},
[types.REMOVE_FILE_FROM_CHANGED](state, file) {
const indexOfChangedFile = findIndexOfFile(state.changedFiles, file);
state.changedFiles.splice(indexOfChangedFile, 1);
},
};
......@@ -3,7 +3,7 @@ export default () => ({
currentProjectId: '',
currentBranchId: '',
currentBlobView: 'repo-editor',
discardPopupOpen: false,
changedFiles: [],
editMode: true,
endpoints: {},
isRoot: false,
......
......@@ -172,20 +172,32 @@ table.table tr td.multi-file-table-name {
position: absolute;
right: 8px;
top: 50%;
width: 16px;
height: 16px;
padding: 0;
background: none;
border: 0;
font-size: $gl-font-size;
color: $gray-darkest;
border-radius: $border-radius-default;
color: $theme-gray-900;
transform: translateY(-50%);
&:not(.modified):hover,
&:not(.modified):focus {
color: $hint-color;
svg {
position: relative;
top: -1px;
}
&.modified {
color: $indigo-700;
&:hover {
background-color: $theme-gray-200;
}
&:focus {
background-color: $blue-500;
color: $white-light;
outline: 0;
svg {
fill: currentColor;
}
}
}
......@@ -412,7 +424,24 @@ table.table tr td.multi-file-table-name {
.multi-file-commit-list-item {
display: flex;
margin-bottom: $grid-size;
align-items: center;
> svg {
min-width: 16px;
}
.multi-file-discard-btn {
display: none;
margin-left: auto;
color: $gl-link-color;
}
&:hover {
.multi-file-discard-btn {
display: block;
}
}
}
.multi-file-addition {
......
......@@ -12,13 +12,8 @@ describe('Multi-file editor commit sidebar list collapsed', () => {
vm = createComponentWithStore(Component, store);
vm.$store.state.openFiles.push(file('file1'), file('file2'));
vm.$store.state.openFiles[0].tempFile = true;
vm.$store.state.openFiles.forEach((f) => {
Object.assign(f, {
changed: true,
});
});
vm.$store.state.changedFiles.push(file('file1'), file('file2'));
vm.$store.state.changedFiles[0].tempFile = true;
vm.$mount();
});
......
......@@ -25,6 +25,14 @@ describe('Multi-file editor commit sidebar list item', () => {
expect(vm.$el.querySelector('.multi-file-commit-list-path').textContent.trim()).toBe(f.path);
});
it('calls discardFileChanges when clicking discard button', () => {
spyOn(vm, 'discardFileChanges');
vm.$el.querySelector('.multi-file-discard-btn').click();
expect(vm.discardFileChanges).toHaveBeenCalled();
});
describe('computed', () => {
describe('iconName', () => {
it('returns modified when not a tempFile', () => {
......
......@@ -31,8 +31,8 @@ describe('RepoCommitSection', () => {
vm.$store.state.rightPanelCollapsed = false;
vm.$store.state.currentBranch = 'master';
vm.$store.state.openFiles = [file('file1'), file('file2')];
vm.$store.state.openFiles.forEach(f => Object.assign(f, {
vm.$store.state.changedFiles = [file('file1'), file('file2')];
vm.$store.state.changedFiles.forEach(f => Object.assign(f, {
changed: true,
content: 'testing',
}));
......@@ -91,7 +91,7 @@ describe('RepoCommitSection', () => {
expect(changedFileElements.length).toEqual(2);
changedFileElements.forEach((changedFile, i) => {
expect(changedFile.textContent.trim()).toEqual(vm.$store.getters.changedFiles[i].path);
expect(changedFile.textContent.trim()).toContain(vm.$store.state.changedFiles[i].path);
});
expect(submitCommit.disabled).toBeTruthy();
......@@ -103,7 +103,7 @@ describe('RepoCommitSection', () => {
beforeEach(() => {
vm.commitMessage = 'testing';
changedFiles = JSON.parse(JSON.stringify(vm.$store.getters.changedFiles));
changedFiles = JSON.parse(JSON.stringify(vm.$store.state.changedFiles));
spyOn(service, 'commit').and.returnValue(Promise.resolve({
data: {
......
......@@ -55,29 +55,4 @@ describe('RepoEditButton', () => {
done();
});
});
describe('discardPopupOpen', () => {
beforeEach(() => {
vm.$store.state.discardPopupOpen = true;
vm.$store.state.editMode = true;
vm.$store.state.openFiles[0].changed = true;
vm.$mount();
});
it('renders popup', () => {
expect(vm.$el.querySelector('.modal')).not.toBeNull();
});
it('removes all changed files', (done) => {
vm.$el.querySelector('.btn-warning').click();
vm.$nextTick(() => {
expect(vm.$store.getters.changedFiles.length).toBe(0);
expect(vm.$el.querySelector('.modal')).toBeNull();
done();
});
});
});
});
......@@ -57,4 +57,18 @@ describe('RepoEditor', () => {
expect(vm.$el.textContent).toContain('testing');
});
});
describe('computed', () => {
describe('activeFileChanged', () => {
it('returns false when file has no changes', () => {
expect(vm.activeFileChanged).toBeFalsy();
});
it('returns true when file has changes', () => {
vm.$store.getters.activeFile.changed = true;
expect(vm.activeFileChanged).toBeTruthy();
});
});
});
});
......@@ -27,7 +27,7 @@ describe('RepoTab', () => {
const close = vm.$el.querySelector('.multi-file-tab-close');
const name = vm.$el.querySelector(`[title="${vm.tab.url}"]`);
expect(close.querySelector('.fa-times')).toBeTruthy();
expect(close.innerHTML).toContain('#close');
expect(name.textContent.trim()).toEqual(vm.tab.name);
});
......@@ -52,17 +52,41 @@ describe('RepoTab', () => {
vm.$el.querySelector('.multi-file-tab-close').click();
expect(vm.closeFile).toHaveBeenCalledWith({ file: vm.tab });
expect(vm.closeFile).toHaveBeenCalledWith(vm.tab);
});
it('renders an fa-circle icon if tab is changed', () => {
it('shows changed icon if tab is changed', () => {
const tab = file('changedFile');
tab.changed = true;
vm = createComponent({
tab,
});
expect(vm.$el.querySelector('.multi-file-tab-close .fa-circle')).not.toBeNull();
expect(vm.changedIcon).toBe('file-modified');
});
it('changes icon on hover', (done) => {
const tab = file();
tab.changed = true;
vm = createComponent({
tab,
});
vm.$el.dispatchEvent(new Event('mouseover'));
Vue.nextTick()
.then(() => {
expect(vm.$el.querySelector('.multi-file-modified')).toBeNull();
vm.$el.dispatchEvent(new Event('mouseout'));
})
.then(Vue.nextTick)
.then(() => {
expect(vm.$el.querySelector('.multi-file-modified')).not.toBeNull();
done();
})
.catch(done.fail);
});
describe('locked file', () => {
......@@ -97,20 +121,22 @@ describe('RepoTab', () => {
describe('methods', () => {
describe('closeTab', () => {
it('does not close tab if is changed', (done) => {
const tab = file('closeFile');
it('closes tab if file has changed', (done) => {
const tab = file();
tab.changed = true;
tab.opened = true;
vm = createComponent({
tab,
});
vm.$store.state.openFiles.push(tab);
vm.$store.state.changedFiles.push(tab);
vm.$store.dispatch('setFileActive', tab);
vm.$el.querySelector('.multi-file-tab-close').click();
vm.$nextTick(() => {
expect(tab.opened).toBeTruthy();
expect(tab.opened).toBeFalsy();
expect(vm.$store.state.changedFiles.length).toBe(1);
done();
});
......
......@@ -41,6 +41,14 @@ describe('Multi-file editor library model', () => {
});
});
describe('setValue', () => {
it('updates models value', () => {
model.setValue('testing 123');
expect(model.getModel().getValue()).toBe('testing 123');
});
});
describe('onChange', () => {
it('caches event by path', () => {
model.onChange(() => {});
......
......@@ -31,7 +31,7 @@ describe('Multi-file store file actions', () => {
});
it('closes open files', (done) => {
store.dispatch('closeFile', { file: localFile })
store.dispatch('closeFile', localFile)
.then(() => {
expect(localFile.opened).toBeFalsy();
expect(localFile.active).toBeFalsy();
......@@ -41,43 +41,18 @@ describe('Multi-file store file actions', () => {
}).catch(done.fail);
});
it('does not close file if has changed', (done) => {
localFile.changed = true;
it('closes file even if file has changes', (done) => {
store.state.changedFiles.push(localFile);
store.dispatch('closeFile', { file: localFile })
.then(() => {
expect(localFile.opened).toBeTruthy();
expect(localFile.active).toBeTruthy();
expect(store.state.openFiles.length).toBe(1);
done();
}).catch(done.fail);
});
it('does not close file if temp file', (done) => {
localFile.tempFile = true;
store.dispatch('closeFile', { file: localFile })
.then(() => {
expect(localFile.opened).toBeTruthy();
expect(localFile.active).toBeTruthy();
expect(store.state.openFiles.length).toBe(1);
done();
}).catch(done.fail);
});
it('force closes a changed file', (done) => {
localFile.changed = true;
store.dispatch('closeFile', { file: localFile, force: true })
store.dispatch('closeFile', localFile)
.then(Vue.nextTick)
.then(() => {
expect(localFile.opened).toBeFalsy();
expect(localFile.active).toBeFalsy();
expect(store.state.openFiles.length).toBe(0);
expect(store.state.changedFiles.length).toBe(1);
done();
}).catch(done.fail);
})
.catch(done.fail);
});
it('sets next file as active', (done) => {
......@@ -86,7 +61,7 @@ describe('Multi-file store file actions', () => {
expect(f.active).toBeFalsy();
store.dispatch('closeFile', { file: localFile })
store.dispatch('closeFile', localFile)
.then(() => {
expect(f.active).toBeTruthy();
......@@ -95,7 +70,7 @@ describe('Multi-file store file actions', () => {
});
it('calls getLastCommitData', (done) => {
store.dispatch('closeFile', { file: localFile })
store.dispatch('closeFile', localFile)
.then(() => {
expect(getLastCommitDataSpy).toHaveBeenCalled();
......@@ -194,7 +169,7 @@ describe('Multi-file store file actions', () => {
}),
}));
localFile = file('newCreate');
localFile = file(`newCreate-${Math.random()}`);
localFile.url = 'getFileDataURL';
});
......@@ -315,6 +290,50 @@ describe('Multi-file store file actions', () => {
done();
}).catch(done.fail);
});
it('adds file into changedFiles array', (done) => {
store.dispatch('changeFileContent', {
file: tmpFile,
content: 'content',
})
.then(() => {
expect(store.state.changedFiles.length).toBe(1);
done();
}).catch(done.fail);
});
it('adds file once into changedFiles array', (done) => {
store.dispatch('changeFileContent', {
file: tmpFile,
content: 'content',
})
.then(() => store.dispatch('changeFileContent', {
file: tmpFile,
content: 'content 123',
}))
.then(() => {
expect(store.state.changedFiles.length).toBe(1);
done();
}).catch(done.fail);
});
it('removes file from changedFiles array if not changed', (done) => {
store.dispatch('changeFileContent', {
file: tmpFile,
content: 'content',
})
.then(() => store.dispatch('changeFileContent', {
file: tmpFile,
content: '',
}))
.then(() => {
expect(store.state.changedFiles.length).toBe(0);
done();
}).catch(done.fail);
});
});
describe('createTempFile', () => {
......@@ -372,6 +391,20 @@ describe('Multi-file store file actions', () => {
}).catch(done.fail);
});
it('adds tmp file to changed files', (done) => {
store.dispatch('createTempFile', {
name: 'test',
projectId: 'abcproject',
branchId: 'mybranch',
parent: projectTree,
}).then((f) => {
expect(store.state.changedFiles.length).toBe(1);
expect(store.state.changedFiles[0].name).toBe(f.name);
done();
}).catch(done.fail);
});
it('sets tmp file as active', (done) => {
store.dispatch('createTempFile', {
name: 'test',
......@@ -428,4 +461,62 @@ describe('Multi-file store file actions', () => {
}).catch(done.fail);
});
});
describe('discardFileChanges', () => {
let tmpFile;
beforeEach(() => {
tmpFile = file();
tmpFile.content = 'testing';
store.state.changedFiles.push(tmpFile);
});
it('resets file content', (done) => {
store.dispatch('discardFileChanges', tmpFile)
.then(() => {
expect(tmpFile.content).not.toBe('testing');
done();
})
.catch(done.fail);
});
it('removes file from changedFiles array', (done) => {
store.dispatch('discardFileChanges', tmpFile)
.then(() => {
expect(store.state.changedFiles.length).toBe(0);
done();
})
.catch(done.fail);
});
it('closes temp file', (done) => {
tmpFile.tempFile = true;
tmpFile.opened = true;
store.dispatch('discardFileChanges', tmpFile)
.then(() => {
expect(tmpFile.opened).toBeFalsy();
done();
})
.catch(done.fail);
});
it('does not re-open a closed temp file', (done) => {
tmpFile.tempFile = true;
expect(tmpFile.opened).toBeFalsy();
store.dispatch('discardFileChanges', tmpFile)
.then(() => {
expect(tmpFile.opened).toBeFalsy();
done();
})
.catch(done.fail);
});
});
});
......@@ -34,18 +34,6 @@ describe('Multi-file store actions', () => {
});
});
describe('closeDiscardPopup', () => {
it('closes the discard popup', (done) => {
store.dispatch('closeDiscardPopup', false)
.then(() => {
expect(store.state.discardPopupOpen).toBeFalsy();
done();
})
.catch(done.fail);
});
});
describe('discardAllChanges', () => {
beforeEach(() => {
store.state.openFiles.push(file('discardAll'));
......@@ -94,49 +82,6 @@ describe('Multi-file store actions', () => {
done();
}).catch(done.fail);
});
it('opens discard popup if there are changed files', (done) => {
store.state.editMode = true;
store.state.openFiles.push(file('discardChanges'));
store.state.openFiles[0].changed = true;
store.dispatch('toggleEditMode')
.then(() => {
expect(store.state.discardPopupOpen).toBeTruthy();
done();
}).catch(done.fail);
});
it('can force closed if there are changed files', (done) => {
store.state.editMode = true;
store.state.openFiles.push(file('forceClose'));
store.state.openFiles[0].changed = true;
store.dispatch('toggleEditMode', true)
.then(() => {
expect(store.state.discardPopupOpen).toBeFalsy();
expect(store.state.editMode).toBeFalsy();
done();
}).catch(done.fail);
});
it('discards file changes', (done) => {
const f = file('discard');
store.state.editMode = true;
store.state.openFiles.push(f);
f.changed = true;
store.dispatch('toggleEditMode', true)
.then(Vue.nextTick)
.then(() => {
expect(f.changed).toBeFalsy();
done();
}).catch(done.fail);
});
});
describe('toggleBlobView', () => {
......@@ -290,16 +235,13 @@ describe('Multi-file store actions', () => {
});
it('adds commit data to changed files', (done) => {
const changedFile = file('changed');
const f = file('newfile');
changedFile.changed = true;
const changedFile = file();
store.state.openFiles.push(changedFile, f);
store.state.changedFiles.push(changedFile);
store.dispatch('commitChanges', { payload, newMr: false })
.then(() => {
expect(changedFile.lastCommit.message).toBe('test message');
expect(f.lastCommit.message).not.toBe('test message');
done();
}).catch(done.fail);
......
......@@ -9,19 +9,6 @@ describe('Multi-file store getters', () => {
localState = state();
});
describe('changedFiles', () => {
it('returns a list of changed opened files', () => {
localState.openFiles.push(file());
localState.openFiles.push(file('changed'));
localState.openFiles[1].changed = true;
const changedFiles = getters.changedFiles(localState);
expect(changedFiles.length).toBe(1);
expect(changedFiles[0].name).toBe('changed');
});
});
describe('activeFile', () => {
it('returns the current active file', () => {
localState.openFiles.push(file());
......@@ -88,8 +75,8 @@ describe('Multi-file store getters', () => {
describe('modifiedFiles', () => {
it('returns a list of modified files', () => {
localState.openFiles.push(file());
localState.openFiles.push(file('changed'));
localState.openFiles[1].changed = true;
localState.changedFiles.push(file('changed'));
localState.changedFiles[0].changed = true;
const modifiedFiles = getters.modifiedFiles(localState);
......@@ -101,9 +88,9 @@ describe('Multi-file store getters', () => {
describe('addedFiles', () => {
it('returns a list of added files', () => {
localState.openFiles.push(file());
localState.openFiles.push(file('added'));
localState.openFiles[1].changed = true;
localState.openFiles[1].tempFile = true;
localState.changedFiles.push(file('added'));
localState.changedFiles[0].changed = true;
localState.changedFiles[0].tempFile = true;
const modifiedFiles = getters.addedFiles(localState);
......
......@@ -99,6 +99,17 @@ describe('Multi-file store file mutations', () => {
expect(localFile.content).toBe('testing');
expect(localFile.changed).toBeTruthy();
});
it('sets changed if file is a temp file', () => {
localFile.tempFile = true;
mutations.UPDATE_FILE_CONTENT(localState, {
file: localFile,
content: '',
});
expect(localFile.changed).toBeTruthy();
});
});
describe('DISCARD_FILE_CHANGES', () => {
......@@ -128,4 +139,26 @@ describe('Multi-file store file mutations', () => {
expect(localFile.tree[0].name).toBe(f.name);
});
});
describe('ADD_FILE_TO_CHANGED', () => {
it('adds file into changed files array', () => {
const f = file();
mutations.ADD_FILE_TO_CHANGED(localState, f);
expect(localState.changedFiles.length).toBe(1);
});
});
describe('REMOVE_FILE_FROM_CHANGED', () => {
it('removes files from changed files array', () => {
const f = file();
localState.changedFiles.push(f);
mutations.REMOVE_FILE_FROM_CHANGED(localState, f);
expect(localState.changedFiles.length).toBe(0);
});
});
});
......@@ -73,18 +73,6 @@ describe('Multi-file store mutations', () => {
});
});
describe('TOGGLE_DISCARD_POPUP', () => {
it('sets discardPopupOpen', () => {
mutations.TOGGLE_DISCARD_POPUP(localState, true);
expect(localState.discardPopupOpen).toBeTruthy();
mutations.TOGGLE_DISCARD_POPUP(localState, false);
expect(localState.discardPopupOpen).toBeFalsy();
});
});
describe('SET_ROOT', () => {
it('sets isRoot & initialRoot', () => {
mutations.SET_ROOT(localState, true);
......
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