Commit 1684c86f authored by Phil Hughes's avatar Phil Hughes

Merge branch 'tz-ide-load-full-file-structure' into 'master'

IDE: Load full Files structure through API

See merge request gitlab-org/gitlab-ee!4859
parents ce65cd37 72d0efc9
......@@ -46,19 +46,35 @@
background: $white-normal;
}
.repo-file-name {
.ide-file-name {
flex: 1;
white-space: nowrap;
text-overflow: ellipsis;
svg {
vertical-align: middle;
margin-right: 2px;
}
.loading-container {
margin-right: 4px;
display: inline-block;
}
}
.repo-new-btn {
.ide-file-changed-icon {
margin-left: auto;
}
.ide-new-btn {
display: none;
margin-top: -4px;
margin-bottom: -4px;
margin-right: -8px;
}
&:hover {
.repo-new-btn {
.ide-new-btn {
display: block;
}
}
......@@ -81,10 +97,10 @@
}
}
.multi-file-table-name,
.multi-file-table-col-commit-message {
.file-name,
.file-col-commit-message {
display: flex;
overflow: visible;
max-width: 0;
padding: 6px 12px;
}
......@@ -101,21 +117,6 @@
}
}
table.table tr td.multi-file-table-name {
width: 350px;
padding: 6px 12px;
svg {
vertical-align: middle;
margin-right: 2px;
}
.loading-container {
margin-right: 4px;
display: inline-block;
}
}
.multi-file-table-col-commit-message {
white-space: nowrap;
width: 50%;
......@@ -558,7 +559,7 @@ table.table tr td.multi-file-table-name {
justify-content: center;
}
.repo-new-btn {
.ide-new-btn {
.dropdown-toggle svg {
margin-top: -2px;
margin-bottom: 2px;
......
......@@ -26,6 +26,6 @@
<icon
:name="changedIcon"
:size="12"
:css-classes="`multi-file-changed-icon ${changedIconClass}`"
:css-classes="`ide-file-changed-icon ${changedIconClass}`"
/>
</template>
<script>
import { mapState } from 'vuex';
import skeletonLoadingContainer from '~/vue_shared/components/skeleton_loading_container.vue';
import repoPreviousDirectory from './repo_prev_directory.vue';
import repoFile from './repo_file.vue';
import { treeList } from '../stores/utils';
export default {
components: {
repoPreviousDirectory,
repoFile,
skeletonLoadingContainer,
},
......@@ -20,55 +17,40 @@ export default {
computed: {
...mapState([
'trees',
'isRoot',
]),
...mapState({
projectName(state) {
return state.project.name;
},
}),
fetchedList() {
return treeList(this.$store.state, this.treeId);
},
hasPreviousDirectory() {
return !this.isRoot && this.fetchedList.length;
selctedTree() {
return this.trees[this.treeId].tree;
},
showLoading() {
if (this.trees[this.treeId]) {
return this.trees[this.treeId].loading;
}
return true;
return !this.trees[this.treeId] || this.trees[this.treeId].loading;
},
},
};
</script>
<template>
<div>
<div class="ide-file-list">
<table class="table">
<tbody
v-if="treeId"
>
<repo-previous-directory
v-if="hasPreviousDirectory"
/>
<template v-if="showLoading">
<div
class="multi-file-loading-container"
v-for="n in 3"
:key="n"
>
<skeleton-loading-container />
</div>
</template>
<repo-file
v-for="file in fetchedList"
:key="file.key"
:file="file"
/>
</tbody>
</table>
</div>
<div
class="ide-file-list"
v-if="treeId"
>
<template v-if="showLoading">
<div
class="multi-file-loading-container"
v-for="n in 3"
:key="n"
>
<skeleton-loading-container />
</div>
</template>
<repo-file
v-for="file in selctedTree"
:key="file.key"
:file="file"
/>
</div>
</template>
......@@ -47,7 +47,7 @@
</script>
<template>
<div class="repo-new-btn pull-right">
<div class="ide-new-btn">
<div
class="dropdown"
:class="{
......
......@@ -10,6 +10,7 @@
import changedFileIcon from 'ee/ide/components/changed_file_icon.vue'; // eslint-disable-line import/first
export default {
name: 'RepoFile',
components: {
skeletonLoadingContainer,
newDropdown,
......@@ -51,9 +52,6 @@
shortId() {
return this.file.id.substr(0, 8);
},
submoduleColSpan() {
return !this.leftPanelCollapsed && this.isSubmodule ? 3 : 1;
},
fileClass() {
if (this.file.type === 'blob') {
if (this.file.active) {
......@@ -87,82 +85,62 @@
</script>
<template>
<tr
class="file"
:class="fileClass"
>
<td
class="multi-file-table-name"
:colspan="submoduleColSpan"
@click="clickFile(file)"
<div>
<div
class="file"
:class="fileClass"
>
<a
class="repo-file-name str-truncated"
<div
class="file-name"
@click="clickFile(file)"
>
<file-icon
:file-name="file.name"
:loading="file.loading"
:folder="file.type === 'tree'"
:opened="file.opened"
:style="levelIndentation"
:size="16"
/>
{{ file.name }}
<file-status-icon :file="file" />
</a>
<new-dropdown
v-if="isTree"
:project-id="file.projectId"
:branch="file.branchId"
:path="file.path"
:parent="file"
/>
<changed-file-icon
v-if="file.changed || file.tempFile"
:file="file"
class="prepend-top-5 pull-right"
/>
<template v-if="isSubmodule && file.id">
@
<span class="commit-sha">
<a
@click.stop
:href="file.tree_url"
>
{{ shortId }}
</a>
</span>
</template>
</td>
<template v-if="showExtraColumns && !isSubmodule">
<td class="multi-file-table-col-commit-message hidden-sm hidden-xs">
<a
v-if="file.lastCommit.message"
@click.stop
:href="file.lastCommit.url"
class="ide-file-name str-truncated"
>
{{ file.lastCommit.message }}
<file-icon
:file-name="file.name"
:loading="file.loading"
:folder="file.type === 'tree'"
:opened="file.opened"
:style="levelIndentation"
:size="16"
/>
{{ file.name }}
<file-status-icon :file="file" />
</a>
<skeleton-loading-container
v-else
:small="true"
<new-dropdown
v-if="isTree"
:project-id="file.projectId"
:branch="file.branchId"
:path="file.path"
:parent="file"
/>
</td>
<td class="commit-update hidden-xs text-right">
<span
v-if="file.lastCommit.updatedAt"
:title="tooltipTitle(file.lastCommit.updatedAt)"
>
{{ timeFormated(file.lastCommit.updatedAt) }}
</span>
<skeleton-loading-container
v-else
class="animation-container-right"
:small="true"
<changed-file-icon
:file="file"
v-if="file.changed || file.tempFile"
class="prepend-top-5"
/>
</td>
<template v-if="isSubmodule && file.id">
@
<span class="commit-sha">
<a
@click.stop
:href="file.tree_url"
>
{{ shortId }}
</a>
</span>
</template>
</div>
</div>
<template
v-if="file.opened"
>
<repo-file
v-for="childFile in file.tree"
:key="childFile.key"
:file="childFile"
/>
</template>
</tr>
</div>
</template>
<script>
import { mapState, mapActions } from 'vuex';
export default {
computed: {
...mapState([
'parentTreeUrl',
'leftPanelCollapsed',
]),
colSpanCondition() {
return this.leftPanelCollapsed ? undefined : 3;
},
},
methods: {
...mapActions([
'getTreeData',
]),
},
};
</script>
<template>
<tr class="file prev-directory">
<td
:colspan="colSpanCondition"
class="table-cell"
@click.prevent="getTreeData({ endpoint: parentTreeUrl })"
>
<a :href="parentTreeUrl">...</a>
</td>
</tr>
</template>
......@@ -70,10 +70,9 @@ router.beforeEach((to, from, next) => {
branchId: to.params.branch,
});
store.dispatch('getTreeData', {
store.dispatch('getFiles', {
projectId: fullProjectId,
branch: to.params.branch,
endpoint: `/tree/${to.params.branch}`,
branchId: to.params.branch,
})
.then(() => {
if (to.params[0]) {
......
......@@ -44,4 +44,12 @@ export default {
},
});
},
getFiles(projectUrl, branchId) {
const url = `${projectUrl}/files/${branchId}`;
return Vue.http.get(url, {
params: {
format: 'json',
},
});
},
};
......@@ -49,7 +49,7 @@ export const setFileActive = ({ commit, state, getters, dispatch }, file) => {
};
export const getFileData = ({ state, commit, dispatch }, file) => {
commit(types.TOGGLE_LOADING, file);
commit(types.TOGGLE_LOADING, { entry: file });
service.getFileData(file.url)
.then((res) => {
......@@ -63,10 +63,10 @@ export const getFileData = ({ state, commit, dispatch }, file) => {
commit(types.SET_FILE_DATA, { data, file });
commit(types.TOGGLE_FILE_OPEN, file);
dispatch('setFileActive', file);
commit(types.TOGGLE_LOADING, file);
commit(types.TOGGLE_LOADING, { entry: file });
})
.catch(() => {
commit(types.TOGGLE_LOADING, file);
commit(types.TOGGLE_LOADING, { entry: file });
flash('Error loading file data. Please try again.', 'alert', document, null, false, true);
});
};
......
......@@ -8,11 +8,11 @@ export const getProjectData = (
{ namespace, projectId, force = false } = {},
) => new Promise((resolve, reject) => {
if (!state.projects[`${namespace}/${projectId}`] || force) {
commit(types.TOGGLE_LOADING, state);
commit(types.TOGGLE_LOADING, { entry: state });
service.getProjectData(namespace, projectId)
.then(res => res.data)
.then((data) => {
commit(types.TOGGLE_LOADING, state);
commit(types.TOGGLE_LOADING, { entry: state });
commit(types.SET_PROJECT, { projectPath: `${namespace}/${projectId}`, project: data });
if (!state.currentProjectId) commit(types.SET_CURRENT_PROJECT, `${namespace}/${projectId}`);
resolve(data);
......
......@@ -9,6 +9,7 @@ import {
findEntry,
createTemp,
createOrMergeEntry,
sortTree,
} from '../utils';
export const getTreeData = (
......@@ -19,7 +20,7 @@ export const getTreeData = (
if (!tree && state.trees[`${projectId}/${branch}`] && !force) {
resolve();
} else {
if (tree) commit(types.TOGGLE_LOADING, tree);
if (tree) commit(types.TOGGLE_LOADING, { entry: tree });
const selectedProject = state.projects[projectId];
// We are merging the web_url that we got on the project info with the endpoint
// we got on the tree entry, as both contain the projectId, we replace it in the tree endpoint
......@@ -34,16 +35,12 @@ export const getTreeData = (
return res.json();
})
.then((data) => {
if (!state.isInitialRoot) {
commit(types.SET_ROOT, data.path === '/');
}
dispatch('updateDirectoryData', { data, tree, projectId, branch, clearTree: false });
const selectedTree = tree || state.trees[`${projectId}/${branch}`];
commit(types.SET_PARENT_TREE_URL, data.parent_tree_url);
commit(types.SET_LAST_COMMIT_URL, { tree: selectedTree, url: data.last_commit_path });
if (tree) commit(types.TOGGLE_LOADING, selectedTree);
if (tree) commit(types.TOGGLE_LOADING, { entry: selectedTree });
const prevLastCommitPath = selectedTree.lastCommitPath;
if (prevLastCommitPath !== null) {
......@@ -53,7 +50,7 @@ export const getTreeData = (
})
.catch((e) => {
flash('Error loading tree data. Please try again.', 'alert', document, null, false, true);
if (tree) commit(types.TOGGLE_LOADING, tree);
if (tree) commit(types.TOGGLE_LOADING, { entry: tree });
reject(e);
});
} else {
......@@ -62,16 +59,7 @@ export const getTreeData = (
}
});
export const toggleTreeOpen = ({ commit, dispatch }, { endpoint, tree }) => {
if (tree.opened) {
// send empty data to clear the tree
const data = { trees: [], blobs: [], submodules: [] };
dispatch('updateDirectoryData', { data, tree, projectId: tree.projectId, branchId: tree.branchId });
} else {
dispatch('getTreeData', { endpoint, tree, projectId: tree.projectId, branch: tree.branchId });
}
export const toggleTreeOpen = ({ commit, dispatch }, { tree }) => {
commit(types.TOGGLE_TREE_OPEN, tree);
};
......@@ -82,7 +70,7 @@ export const handleTreeEntryAction = ({ commit, dispatch }, row) => {
tree: row,
});
} else if (row.type === 'submodule') {
commit(types.TOGGLE_LOADING, row);
commit(types.TOGGLE_LOADING, { entry: row });
visitUrl(row.url);
} else if (row.type === 'blob' && (row.opened || row.changed)) {
if (row.changed && !row.opened) {
......@@ -198,3 +186,95 @@ export const updateDirectoryData = (
commit(types.SET_DIRECTORY_DATA, { tree: selectedTree, data: formattedData });
};
export const getFiles = (
{ state, commit, dispatch },
{ projectId, branchId } = {},
) => new Promise((resolve, reject) => {
if (!state.trees[`${projectId}/${branchId}`]) {
const selectedProject = state.projects[projectId];
commit(types.CREATE_TREE, { treePath: `${projectId}/${branchId}` });
service
.getFiles(selectedProject.web_url, branchId)
.then(res => res.json())
.then((data) => {
const newTree = data.reduce((outputArray, file) => {
const pathSplit = file.split('/');
const blobName = pathSplit.pop();
let selectedFolderTree;
let foundFolder = null;
let fullPath = '';
if (pathSplit.length > 0) {
const newBaseFolders = pathSplit.reduce((newFolders, folder, currentIndex) => {
fullPath += `/${folder}`;
foundFolder = findEntry(selectedFolderTree || outputArray, 'tree', fullPath, 'path');
if (!foundFolder) {
foundFolder = createOrMergeEntry({
projectId,
branchId,
entry: {
id: fullPath,
name: folder,
path: fullPath,
url: `/${projectId}/tree/${branchId}/${fullPath}`,
},
level: currentIndex,
type: 'tree',
parentTreeUrl: '',
state,
});
if (selectedFolderTree) {
selectedFolderTree.push(foundFolder);
} else {
newFolders.push(foundFolder);
}
}
selectedFolderTree = foundFolder.tree;
return newFolders;
}, []);
if (newBaseFolders.length) outputArray.push(newBaseFolders[0]);
}
// Add file
const blobEntry = createOrMergeEntry({
projectId,
branchId,
entry: {
id: file,
name: blobName,
path: file,
url: `/${projectId}/blob/${branchId}/${file}`,
},
level: foundFolder ? (foundFolder.level + 1) : 0,
type: 'blob',
parentTreeUrl: foundFolder ? foundFolder.url : '',
state,
});
if (selectedFolderTree) {
selectedFolderTree.push(blobEntry);
} else {
outputArray.push(blobEntry);
}
return outputArray;
}, []);
const selectedTree = state.trees[`${projectId}/${branchId}`];
commit(types.SET_DIRECTORY_DATA, { tree: selectedTree, data: sortTree(newTree) });
commit(types.TOGGLE_LOADING, { entry: selectedTree, forceValue: false });
resolve();
})
.catch((e) => {
flash('Error loading tree data. Please try again.', 'alert', document, null, false, true);
reject(e);
});
} else {
resolve();
}
});
export const SET_INITIAL_DATA = 'SET_INITIAL_DATA';
export const TOGGLE_LOADING = 'TOGGLE_LOADING';
export const SET_PARENT_TREE_URL = 'SET_PARENT_TREE_URL';
export const SET_ROOT = 'SET_ROOT';
export const SET_LAST_COMMIT_DATA = 'SET_LAST_COMMIT_DATA';
export const SET_LAST_COMMIT_MSG = 'SET_LAST_COMMIT_MSG';
export const SET_LEFT_PANEL_COLLAPSED = 'SET_LEFT_PANEL_COLLAPSED';
......
......@@ -18,9 +18,9 @@ export default {
currentBlobView: 'repo-editor',
});
},
[types.TOGGLE_LOADING](state, entry) {
[types.TOGGLE_LOADING](state, { entry, forceValue = undefined }) {
Object.assign(entry, {
loading: !entry.loading,
loading: forceValue !== undefined ? forceValue : !entry.loading,
});
},
[types.TOGGLE_EDIT_MODE](state) {
......@@ -28,12 +28,6 @@ export default {
editMode: !state.editMode,
});
},
[types.SET_ROOT](state, isRoot) {
Object.assign(state, {
isRoot,
isInitialRoot: isRoot,
});
},
[types.SET_LEFT_PANEL_COLLAPSED](state, collapsed) {
Object.assign(state, {
leftPanelCollapsed: collapsed,
......
......@@ -24,12 +24,12 @@ export default {
},
[types.SET_FILE_DATA](state, { data, file }) {
Object.assign(file, {
id: data.id,
blamePath: data.blame_path,
commitsPath: data.commits_path,
permalink: data.permalink,
rawPath: data.raw_path,
binary: data.binary,
html: data.html,
renderError: data.render_error,
});
},
......
......@@ -11,6 +11,7 @@ export default {
trees: Object.assign({}, state.trees, {
[treePath]: {
tree: [],
loading: true,
},
}),
});
......
......@@ -6,7 +6,6 @@ export default () => ({
changedFiles: [],
editMode: true,
endpoints: {},
isRoot: false,
isInitialRoot: false,
lastCommitMsg: '',
lastCommitPath: '',
......
......@@ -202,3 +202,23 @@ export const createCommitPayload = (branch, newBranch, state, rootState) => ({
export const createNewMergeRequestUrl = (projectUrl, source, target) =>
`${projectUrl}/merge_requests/new?merge_request[source_branch]=${source}&merge_request[target_branch]=${target}`;
const sortTreesByTypeAndName = (a, b) => {
if (a.type === 'tree' && b.type === 'blob') {
return -1;
} else if (a.type === 'blob' && b.type === 'tree') {
return 1;
}
if (a.name.toLowerCase() < b.name.toLowerCase()) return -1;
if (a.name.toLowerCase() > b.name.toLowerCase()) return 1;
return 0;
};
export const sortTree = (sortedTree) => {
sortedTree.forEach((el) => {
Object.assign(el, {
tree: el && el.tree ? sortTree(el.tree) : [],
});
});
return sortedTree.sort(sortTreesByTypeAndName);
};
......@@ -17,7 +17,6 @@ describe('IdeRepoTree', () => {
});
vm.$store.state.currentBranch = 'master';
vm.$store.state.isRoot = true;
vm.$store.state.trees['abcproject/mybranch'] = {
tree: [file()],
};
......@@ -32,16 +31,17 @@ describe('IdeRepoTree', () => {
});
it('renders a sidebar', () => {
const tbody = vm.$el.querySelector('tbody');
expect(vm.$el.classList.contains('sidebar-mini')).toBeFalsy();
expect(tbody.querySelector('.repo-file-options')).toBeFalsy();
expect(tbody.querySelector('.prev-directory')).toBeFalsy();
expect(tbody.querySelector('.loading-file')).toBeFalsy();
expect(tbody.querySelector('.file')).toBeTruthy();
expect(vm.$el.querySelector('.repo-file-options')).toBeFalsy();
expect(vm.$el.querySelector('.loading-file')).toBeFalsy();
expect(vm.$el.querySelector('.file')).toBeTruthy();
});
it('renders 3 loading files if tree is loading', (done) => {
vm.$store.state.trees['123'] = {
tree: [],
loading: true,
};
vm.treeId = '123';
Vue.nextTick(() => {
......@@ -50,14 +50,4 @@ describe('IdeRepoTree', () => {
done();
});
});
it('renders a prev directory if is not root', (done) => {
vm.$store.state.isRoot = false;
Vue.nextTick(() => {
expect(vm.$el.querySelector('tbody .prev-directory')).toBeTruthy();
done();
});
});
});
......@@ -31,7 +31,7 @@ describe('RepoFile', () => {
spyOn(vm, 'timeFormated').and.returnValue(updated);
vm.$mount();
const name = vm.$el.querySelector('.repo-file-name');
const name = vm.$el.querySelector('.ide-file-name');
expect(name.href).toMatch('');
expect(name.textContent.trim()).toEqual(vm.file.name);
......@@ -66,7 +66,7 @@ describe('RepoFile', () => {
spyOn(vm, 'clickFile');
vm.$el.querySelector('td').click();
vm.$el.querySelector('.file-name').click();
expect(vm.clickFile).toHaveBeenCalledWith(vm.file);
});
......@@ -90,10 +90,6 @@ describe('RepoFile', () => {
it('renders submodule short ID', () => {
expect(vm.$el.querySelector('.commit-sha').textContent.trim()).toBe('12345678');
});
it('renders ID next to submodule name', () => {
expect(vm.$el.querySelector('td').textContent.replace(/\s+/g, ' ')).toContain('submodule name @ 12345678');
});
});
describe('locked file', () => {
......@@ -122,7 +118,7 @@ describe('RepoFile', () => {
});
it('renders a tooltip', () => {
expect(vm.$el.querySelector('.repo-file-name span:nth-child(2)').dataset.originalTitle).toContain('Locked by testuser');
expect(vm.$el.querySelector('.ide-file-name span:nth-child(2)').dataset.originalTitle).toContain('Locked by testuser');
});
});
});
import Vue from 'vue';
import store from 'ee/ide/stores';
import repoPrevDirectory from 'ee/ide/components/repo_prev_directory.vue';
import { resetStore } from '../helpers';
describe('RepoPrevDirectory', () => {
let vm;
const parentLink = 'parent';
function createComponent() {
const RepoPrevDirectory = Vue.extend(repoPrevDirectory);
const comp = new RepoPrevDirectory({
store,
});
comp.$store.state.parentTreeUrl = parentLink;
return comp.$mount();
}
beforeEach(() => {
vm = createComponent();
});
afterEach(() => {
vm.$destroy();
resetStore(vm.$store);
});
it('renders a prev dir link', () => {
const link = vm.$el.querySelector('a');
expect(link.href).toMatch(`/${parentLink}`);
expect(link.textContent).toEqual('...');
});
it('clicking row triggers getTreeData', () => {
spyOn(vm, 'getTreeData');
vm.$el.querySelector('td').click();
expect(vm.getTreeData).toHaveBeenCalledWith({ endpoint: parentLink });
});
});
......@@ -11,6 +11,7 @@ describe('Multi-file store tree actions', () => {
endpoint: 'rootEndpoint',
projectId: 'abcproject',
branch: 'master',
branchId: 'master',
};
beforeEach(() => {
......@@ -113,18 +114,6 @@ describe('Multi-file store tree actions', () => {
}).catch(done.fail);
});
it('sets root if not currently at root', (done) => {
store.state.isInitialRoot = false;
store.dispatch('getTreeData', basicCallParameters)
.then(() => {
expect(store.state.isInitialRoot).toBeTruthy();
expect(store.state.isRoot).toBeTruthy();
done();
}).catch(done.fail);
});
it('sets page title', (done) => {
store.dispatch('getTreeData', basicCallParameters)
.then(() => {
......@@ -151,6 +140,42 @@ describe('Multi-file store tree actions', () => {
});
});
describe('getFiles', () => {
beforeEach(() => {
spyOn(service, 'getFiles').and.returnValue(Promise.resolve({
json: () => Promise.resolve([
'file.txt',
'folder/fileinfolder.js',
'folder/subfolder/fileinsubfolder.js',
]),
}));
});
it('calls service getFiles', (done) => {
store.dispatch('getFiles', basicCallParameters)
.then(() => {
expect(service.getFiles).toHaveBeenCalledWith('', 'master');
done();
}).catch(done.fail);
});
it('adds data into tree', (done) => {
store.dispatch('getFiles', basicCallParameters)
.then(() => {
projectTree = store.state.trees['abcproject/master'];
expect(projectTree.tree.length).toBe(2);
expect(projectTree.tree[0].type).toBe('tree');
expect(projectTree.tree[0].tree[1].name).toBe('fileinfolder.js');
expect(projectTree.tree[1].type).toBe('blob');
expect(projectTree.tree[0].tree[0].tree[0].type).toBe('blob');
expect(projectTree.tree[0].tree[0].tree[0].name).toBe('fileinsubfolder.js');
done();
}).catch(done.fail);
});
});
describe('toggleTreeOpen', () => {
let oldGetTreeData;
let getTreeDataSpy;
......@@ -176,7 +201,6 @@ describe('Multi-file store tree actions', () => {
it('toggles the tree open', (done) => {
store.dispatch('toggleTreeOpen', {
endpoint: 'test',
tree,
}).then(() => {
expect(tree.opened).toBeTruthy();
......@@ -184,38 +208,6 @@ describe('Multi-file store tree actions', () => {
done();
}).catch(done.fail);
});
it('calls getTreeData if tree is closed', (done) => {
store.dispatch('toggleTreeOpen', {
endpoint: 'test',
tree,
}).then(() => {
expect(getTreeDataSpy).toHaveBeenCalledWith({
projectId: 'abcproject',
branch: 'master',
endpoint: 'test',
tree,
});
done();
}).catch(done.fail);
});
it('resets entries tree', (done) => {
Object.assign(tree, {
opened: true,
tree: ['a'],
});
store.dispatch('toggleTreeOpen', {
endpoint: 'test',
tree,
}).then(() => {
expect(tree.tree.length).toBe(0);
done();
}).catch(done.fail);
});
});
describe('createTempTree', () => {
......
......@@ -49,7 +49,6 @@ describe('Multi-file store file mutations', () => {
permalink: 'permalink',
raw_path: 'raw',
binary: true,
html: 'html',
render_error: 'render_error',
},
file: localFile,
......@@ -60,7 +59,6 @@ describe('Multi-file store file mutations', () => {
expect(localFile.permalink).toBe('permalink');
expect(localFile.rawPath).toBe('raw');
expect(localFile.binary).toBeTruthy();
expect(localFile.html).toBe('html');
expect(localFile.renderError).toBe('render_error');
});
});
......
......@@ -51,14 +51,24 @@ describe('Multi-file store mutations', () => {
describe('TOGGLE_LOADING', () => {
it('toggles loading of entry', () => {
mutations.TOGGLE_LOADING(localState, entry);
mutations.TOGGLE_LOADING(localState, { entry });
expect(entry.loading).toBeTruthy();
mutations.TOGGLE_LOADING(localState, entry);
mutations.TOGGLE_LOADING(localState, { entry });
expect(entry.loading).toBeFalsy();
});
it('toggles loading of entry and sets specific value', () => {
mutations.TOGGLE_LOADING(localState, { entry });
expect(entry.loading).toBeTruthy();
mutations.TOGGLE_LOADING(localState, { entry, forceValue: true });
expect(entry.loading).toBeTruthy();
});
});
describe('TOGGLE_EDIT_MODE', () => {
......@@ -73,20 +83,6 @@ describe('Multi-file store mutations', () => {
});
});
describe('SET_ROOT', () => {
it('sets isRoot & initialRoot', () => {
mutations.SET_ROOT(localState, true);
expect(localState.isRoot).toBeTruthy();
expect(localState.isInitialRoot).toBeTruthy();
mutations.SET_ROOT(localState, false);
expect(localState.isRoot).toBeFalsy();
expect(localState.isInitialRoot).toBeFalsy();
});
});
describe('SET_LEFT_PANEL_COLLAPSED', () => {
it('sets left panel collapsed', () => {
mutations.SET_LEFT_PANEL_COLLAPSED(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