Commit b1fd4ac3 authored by Phil Hughes's avatar Phil Hughes

create temp entry now goes through a single action

this reduces the amount of duplicated code between creating a temp tree & a temp file. We just pass a type that dispatches some extra actions for files
parent ed6669f1
import Vue from 'vue';
import { visitUrl } from '~/lib/utils/url_utility';
import flash from '~/flash';
import * as types from './mutation_types';
import FilesDecoratorWorker from './workers/files_decorator_worker';
export const redirectToUrl = (_, url) => visitUrl(url);
......@@ -36,23 +38,52 @@ export const setResizingStatus = ({ commit }, resizing) => {
};
export const createTempEntry = (
{ state, dispatch },
{ state, commit, dispatch },
{ branchId, name, type, content = '', base64 = false },
) => {
if (type === 'tree') {
dispatch('createTempTree', {
branchId,
name,
});
} else if (type === 'blob') {
dispatch('createTempFile', {
) => new Promise((resolve) => {
const worker = new FilesDecoratorWorker();
const fullName = name.slice(-1) !== '/' && type === 'tree' ? `${name}/` : name;
if (state.entries[name]) {
flash(`The name "${name.split('/').pop()}" is already taken in this directory.`, 'alert', document, null, false, true);
resolve();
return null;
}
worker.addEventListener('message', ({ data }) => {
const { file } = data;
worker.terminate();
commit(types.CREATE_TMP_ENTRY, {
data,
projectId: state.currentProjectId,
branchId,
name,
base64,
content,
});
}
};
if (type === 'blob') {
commit(types.TOGGLE_FILE_OPEN, file.path);
commit(types.ADD_FILE_TO_CHANGED, file.path);
dispatch('setFileActive', file.path);
}
resolve(file);
});
worker.postMessage({
data: [fullName],
projectId: state.currentProjectId,
branchId,
type,
tempFile: true,
base64,
content,
});
return null;
});
export const scrollToTab = () => {
Vue.nextTick(() => {
......
......@@ -6,7 +6,6 @@ import router from '../../ide_router';
import {
setPageTitle,
} from '../utils';
import FilesDecoratorWorker from '../workers/files_decorator_worker';
export const closeFile = ({ commit, state, getters, dispatch }, path) => {
const indexOfClosedFile = state.openFiles.indexOf(path);
......@@ -105,43 +104,6 @@ export const setEditorPosition = ({ getters, commit }, { editorRow, editorColumn
}
};
export const createTempFile = ({ state, commit, dispatch }, { branchId, name, content = '', base64 = '' }) =>
new Promise((resolve) => {
const worker = new FilesDecoratorWorker();
if (state.entries[name]) {
return flash(`The name "${name.split('/').pop()}" is already taken in this directory.`, 'alert', document, null, false, true);
}
worker.addEventListener('message', ({ data }) => {
const { file } = data;
worker.terminate();
commit(types.CREATE_TMP_ENTRY, {
data,
projectId: state.currentProjectId,
branchId,
});
commit(types.TOGGLE_FILE_OPEN, file.path);
commit(types.ADD_FILE_TO_CHANGED, file.path);
dispatch('setFileActive', file.path);
resolve();
});
worker.postMessage({
data: [name],
projectId: state.currentProjectId,
branchId,
tempFile: true,
content,
base64,
});
return null;
});
export const discardFileChanges = ({ state, commit }, path) => {
const file = state.entries[path];
......
......@@ -29,33 +29,6 @@ export const handleTreeEntryAction = ({ commit, dispatch }, row) => {
}
};
export const createTempTree = (
{ state, commit, dispatch },
{ branchId, name },
) => new Promise((resolve) => {
const dirName = name.replace(new RegExp(`^${state.path}/`), '');
const worker = new FilesDecoratorWorker();
worker.addEventListener('message', ({ data }) => {
worker.terminate();
commit(types.CREATE_TMP_ENTRY, {
data,
projectId: state.currentProjectId,
branchId,
});
resolve();
});
worker.postMessage({
data: [`${dirName}/`],
projectId: state.currentProjectId,
branchId,
tempFile: true,
});
});
export const getLastCommitData = ({ state, commit, dispatch, getters }, tree = state) => {
if (!tree || tree.lastCommitPath === null || !tree.lastCommitPath) return;
......
......@@ -94,29 +94,6 @@ export const setPageTitle = (title) => {
document.title = title;
};
export const createTemp = ({
projectId, branchId, name, path, type, level, changed, content, base64, url,
}) => {
const treePath = path ? `${path}/${name}` : name;
return decorateData({
id: new Date().getTime().toString(),
projectId,
branchId,
name,
type,
tempFile: true,
path: treePath,
changed,
content,
parentTreeUrl: '',
level,
base64,
renderError: base64,
url,
});
};
export const createCommitPayload = (branch, newBranch, state, rootState) => ({
branch,
commit_message: state.commitMessage,
......
......@@ -327,132 +327,6 @@ describe('Multi-file store file actions', () => {
});
});
describe('createTempFile', () => {
let projectTree;
beforeEach(() => {
document.body.innerHTML += '<div class="flash-container"></div>';
store.state.currentProjectId = 'abcproject';
store.state.currentBranchId = 'master';
store.state.projects.abcproject = {
branches: {
master: {
workingReference: '1',
},
},
};
store.state.trees['abcproject/mybranch'] = {
tree: [],
};
projectTree = store.state.trees['abcproject/mybranch'];
});
afterEach(() => {
document.querySelector('.flash-container').remove();
});
it('creates temp file', (done) => {
store.dispatch('createTempFile', {
name: 'test',
projectId: 'abcproject',
branchId: 'mybranch',
parent: projectTree,
}).then((f) => {
expect(f.tempFile).toBeTruthy();
expect(store.state.trees['abcproject/mybranch'].tree.length).toBe(1);
done();
}).catch(done.fail);
});
it('adds tmp file to open files', (done) => {
store.dispatch('createTempFile', {
name: 'test',
projectId: 'abcproject',
branchId: 'mybranch',
parent: projectTree,
}).then((f) => {
expect(store.state.openFiles.length).toBe(1);
expect(store.state.openFiles[0].name).toBe(f.name);
done();
}).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',
projectId: 'abcproject',
branchId: 'mybranch',
parent: projectTree,
}).then((f) => {
expect(f.active).toBeTruthy();
done();
}).catch(done.fail);
});
it('enters edit mode if file is not base64', (done) => {
store.dispatch('createTempFile', {
name: 'test',
projectId: 'abcproject',
branchId: 'mybranch',
parent: projectTree,
}).then(() => {
expect(store.state.editMode).toBeTruthy();
done();
}).catch(done.fail);
});
it('creates flash message is file already exists', (done) => {
store.state.trees['abcproject/mybranch'].tree.push(file('test', '1', 'blob'));
store.dispatch('createTempFile', {
name: 'test',
projectId: 'abcproject',
branchId: 'mybranch',
parent: projectTree,
}).then(() => {
expect(document.querySelector('.flash-alert')).not.toBeNull();
done();
}).catch(done.fail);
});
it('increases level of file', (done) => {
store.state.trees['abcproject/mybranch'].level = 1;
store.dispatch('createTempFile', {
name: 'test',
projectId: 'abcproject',
branchId: 'mybranch',
parent: projectTree,
}).then((f) => {
expect(f.level).toBe(2);
done();
}).catch(done.fail);
});
});
describe('discardFileChanges', () => {
let tmpFile;
......
......@@ -103,79 +103,6 @@ describe('Multi-file store tree actions', () => {
});
});
describe('createTempTree', () => {
beforeEach(() => {
store.state.trees['abcproject/mybranch'] = {
tree: [],
};
projectTree = store.state.trees['abcproject/mybranch'];
});
it('creates temp tree', (done) => {
store.dispatch('createTempTree', {
projectId: store.state.currentProjectId,
branchId: store.state.currentBranchId,
name: 'test',
parent: projectTree,
})
.then(() => {
expect(projectTree.tree[0].name).toBe('test');
expect(projectTree.tree[0].type).toBe('tree');
done();
}).catch(done.fail);
});
it('creates new folder inside another tree', (done) => {
const tree = {
type: 'tree',
name: 'testing',
tree: [],
};
projectTree.tree.push(tree);
store.dispatch('createTempTree', {
projectId: store.state.currentProjectId,
branchId: store.state.currentBranchId,
name: 'testing/test',
parent: projectTree,
})
.then(() => {
expect(projectTree.tree[0].name).toBe('testing');
expect(projectTree.tree[0].tree[0].tempFile).toBeTruthy();
expect(projectTree.tree[0].tree[0].name).toBe('test');
expect(projectTree.tree[0].tree[0].type).toBe('tree');
done();
}).catch(done.fail);
});
it('does not create new tree if already exists', (done) => {
const tree = {
type: 'tree',
name: 'testing',
endpoint: 'test',
tree: [],
};
projectTree.tree.push(tree);
store.dispatch('createTempTree', {
projectId: store.state.currentProjectId,
branchId: store.state.currentBranchId,
name: 'testing/test',
parent: projectTree,
})
.then(() => {
expect(projectTree.tree[0].name).toBe('testing');
expect(projectTree.tree[0].tempFile).toBeUndefined();
done();
}).catch(done.fail);
});
});
describe('getLastCommitData', () => {
beforeEach(() => {
spyOn(service, 'getTreeLastCommit').and.returnValue(Promise.resolve({
......
......@@ -85,6 +85,11 @@ describe('Multi-file store actions', () => {
describe('createTempEntry', () => {
beforeEach(() => {
document.body.innerHTML += '<div class="flash-container"></div>';
store.state.currentProjectId = 'abcproject';
store.state.currentBranchId = 'mybranch';
store.state.trees['abcproject/mybranch'] = {
tree: [],
};
......@@ -93,46 +98,142 @@ describe('Multi-file store actions', () => {
};
});
it('creates a temp tree', (done) => {
const projectTree = store.state.trees['abcproject/mybranch'];
store.dispatch('createTempEntry', {
projectId: 'abcproject',
branchId: 'mybranch',
parent: projectTree,
name: 'test',
type: 'tree',
})
.then(() => {
const baseTree = projectTree.tree;
expect(baseTree.length).toBe(1);
expect(baseTree[0].tempFile).toBeTruthy();
expect(baseTree[0].type).toBe('tree');
done();
})
.catch(done.fail);
afterEach(() => {
document.querySelector('.flash-container').remove();
});
it('creates temp file', (done) => {
const projectTree = store.state.trees['abcproject/mybranch'];
store.dispatch('createTempEntry', {
projectId: 'abcproject',
branchId: 'mybranch',
parent: projectTree,
name: 'test',
type: 'blob',
})
.then(() => {
const baseTree = projectTree.tree;
expect(baseTree.length).toBe(1);
expect(baseTree[0].tempFile).toBeTruthy();
expect(baseTree[0].type).toBe('blob');
done();
})
.catch(done.fail);
describe('tree', () => {
it('creates temp tree', (done) => {
store.dispatch('createTempEntry', {
branchId: store.state.currentBranchId,
name: 'test',
type: 'tree',
})
.then(() => {
const entry = store.state.entries.test;
expect(entry).not.toBeNull();
expect(entry.type).toBe('tree');
done();
}).catch(done.fail);
});
it('creates new folder inside another tree', (done) => {
const tree = {
type: 'tree',
name: 'testing',
path: 'testing',
tree: [],
};
store.state.entries[tree.path] = tree;
store.dispatch('createTempEntry', {
branchId: store.state.currentBranchId,
name: 'testing/test',
type: 'tree',
})
.then(() => {
expect(tree.tree[0].tempFile).toBeTruthy();
expect(tree.tree[0].name).toBe('test');
expect(tree.tree[0].type).toBe('tree');
done();
}).catch(done.fail);
});
it('does not create new tree if already exists', (done) => {
const tree = {
type: 'tree',
path: 'testing',
tempFile: false,
tree: [],
};
store.state.entries[tree.path] = tree;
store.dispatch('createTempEntry', {
branchId: store.state.currentBranchId,
name: 'testing',
type: 'tree',
})
.then(() => {
expect(store.state.entries[tree.path].tempFile).toEqual(false);
expect(document.querySelector('.flash-alert')).not.toBeNull();
done();
}).catch(done.fail);
});
});
describe('blob', () => {
it('creates temp file', (done) => {
store.dispatch('createTempEntry', {
name: 'test',
branchId: 'mybranch',
type: 'blob',
}).then((f) => {
expect(f.tempFile).toBeTruthy();
expect(store.state.trees['abcproject/mybranch'].tree.length).toBe(1);
done();
}).catch(done.fail);
});
it('adds tmp file to open files', (done) => {
store.dispatch('createTempEntry', {
name: 'test',
branchId: 'mybranch',
type: 'blob',
}).then((f) => {
expect(store.state.openFiles.length).toBe(1);
expect(store.state.openFiles[0].name).toBe(f.name);
done();
}).catch(done.fail);
});
it('adds tmp file to changed files', (done) => {
store.dispatch('createTempEntry', {
name: 'test',
branchId: 'mybranch',
type: 'blob',
}).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('createTempEntry', {
name: 'test',
branchId: 'mybranch',
type: 'blob',
}).then((f) => {
expect(f.active).toBeTruthy();
done();
}).catch(done.fail);
});
it('creates flash message if file already exists', (done) => {
const f = file('test', '1', 'blob');
store.state.trees['abcproject/mybranch'].tree = [f];
store.state.entries[f.path] = f;
store.dispatch('createTempEntry', {
name: 'test',
branchId: 'mybranch',
type: 'blob',
}).then(() => {
expect(document.querySelector('.flash-alert')).not.toBeNull();
done();
}).catch(done.fail);
});
});
});
......
import * as utils from 'ee/ide/stores/utils';
import state from 'ee/ide/stores/state';
import { file } from '../helpers';
describe('Multi-file store utils', () => {
describe('setPageTitle', () => {
......@@ -11,63 +9,6 @@ describe('Multi-file store utils', () => {
});
});
describe('treeList', () => {
let localState;
beforeEach(() => {
localState = state();
});
it('returns flat tree list', () => {
localState.trees = [];
localState.trees['abcproject/mybranch'] = {
tree: [],
};
const baseTree = localState.trees['abcproject/mybranch'].tree;
baseTree.push(file('1'));
baseTree[0].tree.push(file('2'));
baseTree[0].tree[0].tree.push(file('3'));
const treeList = utils.treeList(localState, 'abcproject/mybranch');
expect(treeList.length).toBe(3);
expect(treeList[1].name).toBe(baseTree[0].tree[0].name);
expect(treeList[2].name).toBe(baseTree[0].tree[0].tree[0].name);
});
});
describe('createTemp', () => {
it('creates temp tree', () => {
const tmp = utils.createTemp({
name: 'test',
path: 'test',
type: 'tree',
level: 0,
changed: false,
content: '',
base64: '',
});
expect(tmp.tempFile).toBeTruthy();
expect(tmp.icon).toBe('fa-folder');
});
it('creates temp file', () => {
const tmp = utils.createTemp({
name: 'test',
path: 'test',
type: 'blob',
level: 0,
changed: false,
content: '',
base64: '',
});
expect(tmp.tempFile).toBeTruthy();
expect(tmp.icon).toBe('fa-file-text-o');
});
});
describe('findIndexOfFile', () => {
let localState;
......
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