Commit 9b1e9da9 authored by Filipa Lacerda's avatar Filipa Lacerda

Merge branch 'multi-editor-store-specs' into 'master'

Added tests to multi-file Vuex store

See merge request gitlab-org/gitlab-ce!15147
parents 3eff7b67 76152c0f
......@@ -3,7 +3,7 @@ import flash from '../../flash';
import service from '../services';
import * as types from './mutation_types';
export const redirectToUrl = url => gl.utils.visitUrl(url);
export const redirectToUrl = (_, url) => gl.utils.visitUrl(url);
export const setInitialData = ({ commit }, data) => commit(types.SET_INITIAL_DATA, data);
......@@ -84,7 +84,7 @@ export const commitChanges = ({ commit, state, dispatch, getters }, { payload, n
flash(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice');
if (newMr) {
redirectToUrl(`${state.endpoints.newMergeRequestUrl}${branch}`);
dispatch('redirectToUrl', `${state.endpoints.newMergeRequestUrl}${branch}`);
} else {
commit(types.SET_COMMIT_REF, data.id);
......
......@@ -3,16 +3,16 @@ import * as types from '../mutation_types';
import { pushState } from '../utils';
// eslint-disable-next-line import/prefer-default-export
export const createNewBranch = ({ rootState, commit }, branch) => service.createBranch(
rootState.project.id,
export const createNewBranch = ({ state, commit }, branch) => service.createBranch(
state.project.id,
{
branch,
ref: rootState.currentBranch,
ref: state.currentBranch,
},
).then(res => res.json())
.then((data) => {
const branchName = data.name;
const url = location.href.replace(rootState.currentBranch, branchName);
const url = location.href.replace(state.currentBranch, branchName);
pushState(url);
......
......@@ -12,9 +12,4 @@ export const file = (name = 'name', id = name, type = '') => decorateData({
url: 'url',
name,
path: name,
last_commit: {
id: '123',
message: 'test',
committed_date: new Date().toISOString(),
},
});
import store from '~/repo/stores';
import service from '~/repo/services';
import { resetStore } from '../../helpers';
describe('Multi-file store branch actions', () => {
afterEach(() => {
resetStore(store);
});
describe('createNewBranch', () => {
beforeEach(() => {
spyOn(service, 'createBranch').and.returnValue(Promise.resolve({
json: () => ({
name: 'testing',
}),
}));
spyOn(history, 'pushState');
store.state.project.id = 2;
store.state.currentBranch = 'testing';
});
it('creates new branch', (done) => {
store.dispatch('createNewBranch', 'master')
.then(() => {
expect(store.state.currentBranch).toBe('testing');
expect(service.createBranch).toHaveBeenCalledWith(2, {
branch: 'master',
ref: 'testing',
});
expect(history.pushState).toHaveBeenCalled();
done();
})
.catch(done.fail);
});
});
});
import Vue from 'vue';
import store from '~/repo/stores';
import service from '~/repo/services';
import { file, resetStore } from '../../helpers';
describe('Multi-file store file actions', () => {
afterEach(() => {
resetStore(store);
});
describe('closeFile', () => {
let localFile;
let getLastCommitDataSpy;
let oldGetLastCommitData;
beforeEach(() => {
getLastCommitDataSpy = jasmine.createSpy('getLastCommitData');
oldGetLastCommitData = store._actions.getLastCommitData; // eslint-disable-line
store._actions.getLastCommitData = [getLastCommitDataSpy]; // eslint-disable-line
localFile = file();
localFile.active = true;
localFile.opened = true;
localFile.parentTreeUrl = 'parentTreeUrl';
store.state.openFiles.push(localFile);
spyOn(history, 'pushState');
});
afterEach(() => {
store._actions.getLastCommitData = oldGetLastCommitData; // eslint-disable-line
});
it('closes open files', (done) => {
store.dispatch('closeFile', { file: localFile })
.then(() => {
expect(localFile.opened).toBeFalsy();
expect(localFile.active).toBeFalsy();
expect(store.state.openFiles.length).toBe(0);
done();
}).catch(done.fail);
});
it('does not close file if has changed', (done) => {
localFile.changed = 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('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 })
.then(() => {
expect(localFile.opened).toBeFalsy();
expect(localFile.active).toBeFalsy();
expect(store.state.openFiles.length).toBe(0);
done();
}).catch(done.fail);
});
it('calls pushState when no open files are left', (done) => {
store.dispatch('closeFile', { file: localFile })
.then(() => {
expect(history.pushState).toHaveBeenCalledWith(jasmine.anything(), '', 'parentTreeUrl');
done();
}).catch(done.fail);
});
it('sets next file as active', (done) => {
const f = file();
store.state.openFiles.push(f);
expect(f.active).toBeFalsy();
store.dispatch('closeFile', { file: localFile })
.then(() => {
expect(f.active).toBeTruthy();
done();
}).catch(done.fail);
});
it('calls getLastCommitData', (done) => {
store.dispatch('closeFile', { file: localFile })
.then(() => {
expect(getLastCommitDataSpy).toHaveBeenCalled();
done();
}).catch(done.fail);
});
});
describe('setFileActive', () => {
let scrollToTabSpy;
let oldScrollToTab;
beforeEach(() => {
scrollToTabSpy = jasmine.createSpy('scrollToTab');
oldScrollToTab = store._actions.scrollToTab; // eslint-disable-line
store._actions.scrollToTab = [scrollToTabSpy]; // eslint-disable-line
});
afterEach(() => {
store._actions.scrollToTab = oldScrollToTab; // eslint-disable-line
});
it('calls scrollToTab', (done) => {
store.dispatch('setFileActive', file())
.then(() => {
expect(scrollToTabSpy).toHaveBeenCalled();
done();
}).catch(done.fail);
});
it('sets the file active', (done) => {
const localFile = file();
store.dispatch('setFileActive', localFile)
.then(() => {
expect(localFile.active).toBeTruthy();
done();
}).catch(done.fail);
});
it('returns early if file is already active', (done) => {
const localFile = file();
localFile.active = true;
store.dispatch('setFileActive', localFile)
.then(() => {
expect(scrollToTabSpy).not.toHaveBeenCalled();
done();
}).catch(done.fail);
});
it('sets current active file to not active', (done) => {
const localFile = file();
localFile.active = true;
store.state.openFiles.push(localFile);
store.dispatch('setFileActive', file())
.then(() => {
expect(localFile.active).toBeFalsy();
done();
}).catch(done.fail);
});
it('resets location.hash for line highlighting', (done) => {
location.hash = 'test';
store.dispatch('setFileActive', file())
.then(() => {
expect(location.hash).not.toBe('test');
done();
}).catch(done.fail);
});
});
describe('getFileData', () => {
let localFile = file();
beforeEach(() => {
spyOn(service, 'getFileData').and.returnValue(Promise.resolve({
headers: {
'page-title': 'testing getFileData',
},
json: () => Promise.resolve({
blame_path: 'blame_path',
commits_path: 'commits_path',
permalink: 'permalink',
raw_path: 'raw_path',
binary: false,
html: '123',
render_error: '',
}),
}));
localFile = file();
localFile.url = 'getFileDataURL';
});
it('calls the service', (done) => {
store.dispatch('getFileData', localFile)
.then(() => {
expect(service.getFileData).toHaveBeenCalledWith('getFileDataURL');
done();
}).catch(done.fail);
});
it('sets the file data', (done) => {
store.dispatch('getFileData', localFile)
.then(Vue.nextTick)
.then(() => {
expect(localFile.blamePath).toBe('blame_path');
done();
}).catch(done.fail);
});
it('sets document title', (done) => {
store.dispatch('getFileData', localFile)
.then(() => {
expect(document.title).toBe('testing getFileData');
done();
}).catch(done.fail);
});
it('sets the file as active', (done) => {
store.dispatch('getFileData', localFile)
.then(Vue.nextTick)
.then(() => {
expect(localFile.active).toBeTruthy();
done();
}).catch(done.fail);
});
it('adds the file to open files', (done) => {
store.dispatch('getFileData', localFile)
.then(Vue.nextTick)
.then(() => {
expect(store.state.openFiles.length).toBe(1);
expect(store.state.openFiles[0].name).toBe(localFile.name);
done();
}).catch(done.fail);
});
it('toggles the file loading', (done) => {
store.dispatch('getFileData', localFile)
.then(() => {
expect(localFile.loading).toBeTruthy();
return Vue.nextTick();
})
.then(() => {
expect(localFile.loading).toBeFalsy();
done();
}).catch(done.fail);
});
});
describe('getRawFileData', () => {
let tmpFile;
beforeEach(() => {
spyOn(service, 'getRawFileData').and.returnValue(Promise.resolve('raw'));
tmpFile = file();
});
it('calls getRawFileData service method', (done) => {
store.dispatch('getRawFileData', tmpFile)
.then(() => {
expect(service.getRawFileData).toHaveBeenCalledWith(tmpFile);
done();
}).catch(done.fail);
});
it('updates file raw data', (done) => {
store.dispatch('getRawFileData', tmpFile)
.then(() => {
expect(tmpFile.raw).toBe('raw');
done();
}).catch(done.fail);
});
});
describe('changeFileContent', () => {
let tmpFile;
beforeEach(() => {
tmpFile = file();
});
it('updates file content', (done) => {
store.dispatch('changeFileContent', {
file: tmpFile,
content: 'content',
})
.then(() => {
expect(tmpFile.content).toBe('content');
done();
}).catch(done.fail);
});
});
describe('createTempFile', () => {
beforeEach(() => {
document.body.innerHTML += '<div class="flash-container"></div>';
});
afterEach(() => {
document.querySelector('.flash-container').remove();
});
it('creates temp file', (done) => {
store.dispatch('createTempFile', {
tree: store.state,
name: 'test',
}).then((f) => {
expect(f.tempFile).toBeTruthy();
expect(store.state.tree.length).toBe(1);
done();
}).catch(done.fail);
});
it('adds tmp file to open files', (done) => {
store.dispatch('createTempFile', {
tree: store.state,
name: 'test',
}).then((f) => {
expect(store.state.openFiles.length).toBe(1);
expect(store.state.openFiles[0].name).toBe(f.name);
done();
}).catch(done.fail);
});
it('sets tmp file as active', (done) => {
store.dispatch('createTempFile', {
tree: store.state,
name: 'test',
}).then((f) => {
expect(f.active).toBeTruthy();
done();
}).catch(done.fail);
});
it('enters edit mode if file is not base64', (done) => {
store.dispatch('createTempFile', {
tree: store.state,
name: 'test',
}).then(() => {
expect(store.state.editMode).toBeTruthy();
done();
}).catch(done.fail);
});
it('does not enter edit mode if file is base64', (done) => {
store.dispatch('createTempFile', {
tree: store.state,
name: 'test',
base64: true,
}).then(() => {
expect(store.state.editMode).toBeFalsy();
done();
}).catch(done.fail);
});
it('creates flash message is file already exists', (done) => {
store.state.tree.push(file('test', '1', 'blob'));
store.dispatch('createTempFile', {
tree: store.state,
name: 'test',
}).then(() => {
expect(document.querySelector('.flash-alert')).not.toBeNull();
done();
}).catch(done.fail);
});
it('increases level of file', (done) => {
store.state.level = 1;
store.dispatch('createTempFile', {
tree: store.state,
name: 'test',
}).then((f) => {
expect(f.level).toBe(2);
done();
}).catch(done.fail);
});
});
});
import Vue from 'vue';
import store from '~/repo/stores';
import service from '~/repo/services';
import { file, resetStore } from '../../helpers';
describe('Multi-file store tree actions', () => {
afterEach(() => {
resetStore(store);
});
describe('getTreeData', () => {
beforeEach(() => {
spyOn(service, 'getTreeData').and.returnValue(Promise.resolve({
headers: {
'page-title': 'test',
},
json: () => Promise.resolve({
last_commit_path: 'last_commit_path',
parent_tree_url: 'parent_tree_url',
path: '/',
trees: [{ name: 'tree' }],
blobs: [{ name: 'blob' }],
submodules: [{ name: 'submodule' }],
}),
}));
spyOn(history, 'pushState');
Object.assign(store.state.endpoints, {
rootEndpoint: 'rootEndpoint',
});
});
it('calls service getTreeData', (done) => {
store.dispatch('getTreeData')
.then(() => {
expect(service.getTreeData).toHaveBeenCalledWith('rootEndpoint');
done();
}).catch(done.fail);
});
it('adds data into tree', (done) => {
store.dispatch('getTreeData')
.then(Vue.nextTick)
.then(() => {
expect(store.state.tree.length).toBe(3);
expect(store.state.tree[0].type).toBe('tree');
expect(store.state.tree[1].type).toBe('submodule');
expect(store.state.tree[2].type).toBe('blob');
done();
}).catch(done.fail);
});
it('sets parent tree URL', (done) => {
store.dispatch('getTreeData')
.then(Vue.nextTick)
.then(() => {
expect(store.state.parentTreeUrl).toBe('parent_tree_url');
done();
}).catch(done.fail);
});
it('sets last commit path', (done) => {
store.dispatch('getTreeData')
.then(Vue.nextTick)
.then(() => {
expect(store.state.lastCommitPath).toBe('last_commit_path');
done();
}).catch(done.fail);
});
it('sets root if not currently at root', (done) => {
store.state.isInitialRoot = false;
store.dispatch('getTreeData')
.then(Vue.nextTick)
.then(() => {
expect(store.state.isInitialRoot).toBeTruthy();
expect(store.state.isRoot).toBeTruthy();
done();
}).catch(done.fail);
});
it('sets page title', (done) => {
store.dispatch('getTreeData')
.then(() => {
expect(document.title).toBe('test');
done();
}).catch(done.fail);
});
it('toggles loading', (done) => {
store.dispatch('getTreeData')
.then(() => {
expect(store.state.loading).toBeTruthy();
return Vue.nextTick();
})
.then(() => {
expect(store.state.loading).toBeFalsy();
done();
}).catch(done.fail);
});
it('calls pushState with endpoint', (done) => {
store.dispatch('getTreeData')
.then(Vue.nextTick)
.then(() => {
expect(history.pushState).toHaveBeenCalledWith(jasmine.anything(), '', 'rootEndpoint');
done();
}).catch(done.fail);
});
it('calls getLastCommitData if prevLastCommitPath is not null', (done) => {
const getLastCommitDataSpy = jasmine.createSpy('getLastCommitData');
const oldGetLastCommitData = store._actions.getLastCommitData; // eslint-disable-line
store._actions.getLastCommitData = [getLastCommitDataSpy]; // eslint-disable-line
store.state.prevLastCommitPath = 'test';
store.dispatch('getTreeData')
.then(Vue.nextTick)
.then(() => {
expect(getLastCommitDataSpy).toHaveBeenCalledWith(store.state);
store._actions.getLastCommitData = oldGetLastCommitData; // eslint-disable-line
done();
}).catch(done.fail);
});
});
describe('toggleTreeOpen', () => {
let oldGetTreeData;
let getTreeDataSpy;
let tree;
beforeEach(() => {
getTreeDataSpy = jasmine.createSpy('getTreeData');
oldGetTreeData = store._actions.getTreeData; // eslint-disable-line
store._actions.getTreeData = [getTreeDataSpy]; // eslint-disable-line
tree = {
opened: false,
tree: [],
};
});
afterEach(() => {
store._actions.getTreeData = oldGetTreeData; // eslint-disable-line
});
it('toggles the tree open', (done) => {
store.dispatch('toggleTreeOpen', {
endpoint: 'test',
tree,
}).then(() => {
expect(tree.opened).toBeTruthy();
done();
}).catch(done.fail);
});
it('calls getTreeData if tree is closed', (done) => {
store.dispatch('toggleTreeOpen', {
endpoint: 'test',
tree,
}).then(() => {
expect(getTreeDataSpy).toHaveBeenCalledWith({
endpoint: 'test',
tree,
});
expect(store.state.previousUrl).toBe('test');
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);
});
it('pushes new state', (done) => {
spyOn(history, 'pushState');
Object.assign(tree, {
opened: true,
parentTreeUrl: 'testing',
});
store.dispatch('toggleTreeOpen', {
endpoint: 'test',
tree,
}).then(() => {
expect(history.pushState).toHaveBeenCalledWith(jasmine.anything(), '', 'testing');
done();
}).catch(done.fail);
});
});
describe('clickedTreeRow', () => {
describe('tree', () => {
let toggleTreeOpenSpy;
let oldToggleTreeOpen;
beforeEach(() => {
toggleTreeOpenSpy = jasmine.createSpy('toggleTreeOpen');
oldToggleTreeOpen = store._actions.toggleTreeOpen; // eslint-disable-line
store._actions.toggleTreeOpen = [toggleTreeOpenSpy]; // eslint-disable-line
});
afterEach(() => {
store._actions.toggleTreeOpen = oldToggleTreeOpen; // eslint-disable-line
});
it('opens tree', (done) => {
const tree = {
url: 'a',
type: 'tree',
};
store.dispatch('clickedTreeRow', tree)
.then(() => {
expect(toggleTreeOpenSpy).toHaveBeenCalledWith({
endpoint: tree.url,
tree,
});
done();
}).catch(done.fail);
});
});
describe('submodule', () => {
let row;
beforeEach(() => {
spyOn(gl.utils, 'visitUrl');
row = {
url: 'submoduleurl',
type: 'submodule',
loading: false,
};
});
it('toggles loading for row', (done) => {
store.dispatch('clickedTreeRow', row)
.then(() => {
expect(row.loading).toBeTruthy();
done();
}).catch(done.fail);
});
it('opens submodule URL', (done) => {
store.dispatch('clickedTreeRow', row)
.then(() => {
expect(gl.utils.visitUrl).toHaveBeenCalledWith('submoduleurl');
done();
}).catch(done.fail);
});
});
describe('blob', () => {
let row;
beforeEach(() => {
row = {
type: 'blob',
opened: false,
};
});
it('calls getFileData', (done) => {
const getFileDataSpy = jasmine.createSpy('getFileData');
const oldGetFileData = store._actions.getFileData; // eslint-disable-line
store._actions.getFileData = [getFileDataSpy]; // eslint-disable-line
store.dispatch('clickedTreeRow', row)
.then(() => {
expect(getFileDataSpy).toHaveBeenCalledWith(row);
store._actions.getFileData = oldGetFileData; // eslint-disable-line
done();
}).catch(done.fail);
});
it('calls setFileActive when file is opened', (done) => {
const setFileActiveSpy = jasmine.createSpy('setFileActive');
const oldSetFileActive = store._actions.setFileActive; // eslint-disable-line
store._actions.setFileActive = [setFileActiveSpy]; // eslint-disable-line
row.opened = true;
store.dispatch('clickedTreeRow', row)
.then(() => {
expect(setFileActiveSpy).toHaveBeenCalledWith(row);
store._actions.setFileActive = oldSetFileActive; // eslint-disable-line
done();
}).catch(done.fail);
});
});
});
describe('createTempTree', () => {
it('creates temp tree', (done) => {
store.dispatch('createTempTree', 'test')
.then(() => {
expect(store.state.tree[0].tempFile).toBeTruthy();
expect(store.state.tree[0].name).toBe('test');
expect(store.state.tree[0].type).toBe('tree');
done();
}).catch(done.fail);
});
it('creates .gitkeep file in temp tree', (done) => {
store.dispatch('createTempTree', 'test')
.then(() => {
expect(store.state.tree[0].tree[0].tempFile).toBeTruthy();
expect(store.state.tree[0].tree[0].name).toBe('.gitkeep');
done();
}).catch(done.fail);
});
it('creates new folder inside another tree', (done) => {
const tree = {
type: 'tree',
name: 'testing',
tree: [],
};
store.state.tree.push(tree);
store.dispatch('createTempTree', 'testing/test')
.then(() => {
expect(store.state.tree[0].name).toBe('testing');
expect(store.state.tree[0].tree[0].tempFile).toBeTruthy();
expect(store.state.tree[0].tree[0].name).toBe('test');
expect(store.state.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',
tree: [],
};
store.state.tree.push(tree);
store.dispatch('createTempTree', 'testing/test')
.then(() => {
expect(store.state.tree[0].name).toBe('testing');
expect(store.state.tree[0].tempFile).toBeUndefined();
done();
}).catch(done.fail);
});
});
describe('getLastCommitData', () => {
beforeEach(() => {
spyOn(service, 'getTreeLastCommit').and.returnValue(Promise.resolve({
headers: {
'more-logs-url': null,
},
json: () => Promise.resolve([{
type: 'tree',
file_name: 'testing',
commit: {
message: 'commit message',
authored_date: '123',
},
}]),
}));
store.state.tree.push(file('testing', '1', 'tree'));
store.state.lastCommitPath = 'lastcommitpath';
});
it('calls service with lastCommitPath', (done) => {
store.dispatch('getLastCommitData')
.then(() => {
expect(service.getTreeLastCommit).toHaveBeenCalledWith('lastcommitpath');
done();
}).catch(done.fail);
});
it('updates trees last commit data', (done) => {
store.dispatch('getLastCommitData')
.then(Vue.nextTick)
.then(() => {
expect(store.state.tree[0].lastCommit.message).toBe('commit message');
done();
}).catch(done.fail);
});
it('does not update entry if not found', (done) => {
store.state.tree[0].name = 'a';
store.dispatch('getLastCommitData')
.then(Vue.nextTick)
.then(() => {
expect(store.state.tree[0].lastCommit.message).not.toBe('commit message');
done();
}).catch(done.fail);
});
});
describe('updateDirectoryData', () => {
it('adds data into tree', (done) => {
const tree = {
tree: [],
};
const data = {
trees: [{ name: 'tree' }],
submodules: [{ name: 'submodule' }],
blobs: [{ name: 'blob' }],
};
store.dispatch('updateDirectoryData', {
data,
tree,
}).then(() => {
expect(tree.tree[0].name).toBe('tree');
expect(tree.tree[0].type).toBe('tree');
expect(tree.tree[1].name).toBe('submodule');
expect(tree.tree[1].type).toBe('submodule');
expect(tree.tree[2].name).toBe('blob');
expect(tree.tree[2].type).toBe('blob');
done();
}).catch(done.fail);
});
});
});
import Vue from 'vue';
import store from '~/repo/stores';
import service from '~/repo/services';
import { resetStore, file } from '../helpers';
describe('Multi-file store actions', () => {
afterEach(() => {
resetStore(store);
});
describe('redirectToUrl', () => {
it('calls visitUrl', (done) => {
spyOn(gl.utils, 'visitUrl');
store.dispatch('redirectToUrl', 'test')
.then(() => {
expect(gl.utils.visitUrl).toHaveBeenCalledWith('test');
done();
})
.catch(done.fail);
});
});
describe('setInitialData', () => {
it('commits initial data', (done) => {
store.dispatch('setInitialData', { canCommit: true })
.then(() => {
expect(store.state.canCommit).toBeTruthy();
done();
})
.catch(done.fail);
});
});
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());
store.state.openFiles[0].changed = true;
});
});
describe('closeAllFiles', () => {
beforeEach(() => {
store.state.openFiles.push(file());
store.state.openFiles[0].opened = true;
});
it('closes all open files', (done) => {
store.dispatch('closeAllFiles')
.then(() => {
expect(store.state.openFiles.length).toBe(0);
done();
})
.catch(done.fail);
});
});
describe('toggleEditMode', () => {
it('toggles edit mode', (done) => {
store.state.editMode = true;
store.dispatch('toggleEditMode')
.then(() => {
expect(store.state.editMode).toBeFalsy();
done();
}).catch(done.fail);
});
it('sets preview mode', (done) => {
store.state.currentBlobView = 'repo-editor';
store.state.editMode = true;
store.dispatch('toggleEditMode')
.then(Vue.nextTick)
.then(() => {
expect(store.state.currentBlobView).toBe('repo-preview');
done();
}).catch(done.fail);
});
it('opens discard popup if there are changed files', (done) => {
store.state.editMode = true;
store.state.openFiles.push(file());
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());
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();
store.state.editMode = true;
store.state.tree.push(f);
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', () => {
it('sets edit mode view if in edit mode', (done) => {
store.state.editMode = true;
store.dispatch('toggleBlobView')
.then(() => {
expect(store.state.currentBlobView).toBe('repo-editor');
done();
})
.catch(done.fail);
});
it('sets preview mode view if not in edit mode', (done) => {
store.dispatch('toggleBlobView')
.then(() => {
expect(store.state.currentBlobView).toBe('repo-preview');
done();
})
.catch(done.fail);
});
});
describe('checkCommitStatus', () => {
beforeEach(() => {
store.state.project.id = 2;
store.state.currentBranch = 'master';
store.state.currentRef = '1';
});
it('calls service', (done) => {
spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({
commit: { id: '123' },
}));
store.dispatch('checkCommitStatus')
.then(() => {
expect(service.getBranchData).toHaveBeenCalledWith(2, 'master');
done();
})
.catch(done.fail);
});
it('returns true if current ref does not equal returned ID', (done) => {
spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({
commit: { id: '123' },
}));
store.dispatch('checkCommitStatus')
.then((val) => {
expect(val).toBeTruthy();
done();
})
.catch(done.fail);
});
it('returns false if current ref equals returned ID', (done) => {
spyOn(service, 'getBranchData').and.returnValue(Promise.resolve({
commit: { id: '1' },
}));
store.dispatch('checkCommitStatus')
.then((val) => {
expect(val).toBeFalsy();
done();
})
.catch(done.fail);
});
});
describe('commitChanges', () => {
let payload;
beforeEach(() => {
spyOn(window, 'scrollTo');
document.body.innerHTML += '<div class="flash-container"></div>';
store.state.project.id = 123;
payload = {
branch: 'master',
};
});
afterEach(() => {
document.querySelector('.flash-container').remove();
});
describe('success', () => {
beforeEach(() => {
spyOn(service, 'commit').and.returnValue(Promise.resolve({
id: '123456',
short_id: '123',
message: 'test message',
committed_date: 'date',
stats: {
additions: '1',
deletions: '2',
},
}));
});
it('calls service', (done) => {
store.dispatch('commitChanges', { payload, newMr: false })
.then(() => {
expect(service.commit).toHaveBeenCalledWith(123, payload);
done();
}).catch(done.fail);
});
it('shows flash notice', (done) => {
store.dispatch('commitChanges', { payload, newMr: false })
.then(() => {
const alert = document.querySelector('.flash-container');
expect(alert.querySelector('.flash-notice')).not.toBeNull();
expect(alert.textContent.trim()).toBe(
'Your changes have been committed. Commit 123 with 1 additions, 2 deletions.',
);
done();
}).catch(done.fail);
});
it('adds commit data to changed files', (done) => {
const changedFile = file();
const f = file();
changedFile.changed = true;
store.state.openFiles.push(changedFile, f);
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);
});
it('toggles edit mode', (done) => {
store.state.editMode = true;
store.dispatch('commitChanges', { payload, newMr: false })
.then(() => {
expect(store.state.editMode).toBeFalsy();
done();
}).catch(done.fail);
});
it('closes all files', (done) => {
store.state.openFiles.push(file());
store.state.openFiles[0].opened = true;
store.dispatch('commitChanges', { payload, newMr: false })
.then(Vue.nextTick)
.then(() => {
expect(store.state.openFiles.length).toBe(0);
done();
}).catch(done.fail);
});
it('scrolls to top of page', (done) => {
store.dispatch('commitChanges', { payload, newMr: false })
.then(() => {
expect(window.scrollTo).toHaveBeenCalledWith(0, 0);
done();
}).catch(done.fail);
});
it('updates commit ref', (done) => {
store.dispatch('commitChanges', { payload, newMr: false })
.then(() => {
expect(store.state.currentRef).toBe('123456');
done();
}).catch(done.fail);
});
it('redirects to new merge request page', (done) => {
spyOn(gl.utils, 'visitUrl');
store.state.endpoints.newMergeRequestUrl = 'newMergeRequestUrl?branch=';
store.dispatch('commitChanges', { payload, newMr: true })
.then(() => {
expect(gl.utils.visitUrl).toHaveBeenCalledWith('newMergeRequestUrl?branch=master');
done();
}).catch(done.fail);
});
});
describe('failed', () => {
beforeEach(() => {
spyOn(service, 'commit').and.returnValue(Promise.resolve({
message: 'failed message',
}));
});
it('shows failed message', (done) => {
store.dispatch('commitChanges', { payload, newMr: false })
.then(() => {
const alert = document.querySelector('.flash-container');
expect(alert.textContent.trim()).toBe(
'failed message',
);
done();
}).catch(done.fail);
});
});
});
describe('createTempEntry', () => {
it('creates a temp tree', (done) => {
store.dispatch('createTempEntry', {
name: 'test',
type: 'tree',
})
.then(() => {
expect(store.state.tree.length).toBe(1);
expect(store.state.tree[0].tempFile).toBeTruthy();
expect(store.state.tree[0].type).toBe('tree');
done();
})
.catch(done.fail);
});
it('creates temp file', (done) => {
store.dispatch('createTempEntry', {
name: 'test',
type: 'blob',
})
.then(() => {
expect(store.state.tree.length).toBe(1);
expect(store.state.tree[0].tempFile).toBeTruthy();
expect(store.state.tree[0].type).toBe('blob');
done();
})
.catch(done.fail);
});
});
describe('popHistoryState', () => {
});
describe('scrollToTab', () => {
it('focuses the current active element', (done) => {
document.body.innerHTML += '<div id="tabs"><div class="active"><div class="repo-tab"></div></div></div>';
const el = document.querySelector('.repo-tab');
spyOn(el, 'focus');
store.dispatch('scrollToTab')
.then(() => {
setTimeout(() => {
expect(el.focus).toHaveBeenCalled();
document.getElementById('tabs').remove();
done();
});
})
.catch(done.fail);
});
});
});
import * as getters from '~/repo/stores/getters';
import state from '~/repo/stores/state';
import { file } from '../helpers';
describe('Multi-file store getters', () => {
let localState;
beforeEach(() => {
localState = state();
});
describe('treeList', () => {
it('returns flat tree list', () => {
localState.tree.push(file('1'));
localState.tree[0].tree.push(file('2'));
localState.tree[0].tree[0].tree.push(file('3'));
const treeList = getters.treeList(localState);
expect(treeList.length).toBe(3);
expect(treeList[1].name).toBe(localState.tree[0].tree[0].name);
expect(treeList[2].name).toBe(localState.tree[0].tree[0].tree[0].name);
});
});
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());
localState.openFiles.push(file('active'));
localState.openFiles[1].active = true;
expect(getters.activeFile(localState).name).toBe('active');
});
it('returns undefined if no active files are found', () => {
localState.openFiles.push(file());
localState.openFiles.push(file('active'));
expect(getters.activeFile(localState)).toBeUndefined();
});
});
describe('activeFileExtension', () => {
it('returns the file extension for the current active file', () => {
localState.openFiles.push(file('active'));
localState.openFiles[0].active = true;
localState.openFiles[0].path = 'test.js';
expect(getters.activeFileExtension(localState)).toBe('.js');
localState.openFiles[0].path = 'test.es6.js';
expect(getters.activeFileExtension(localState)).toBe('.js');
});
});
describe('isCollapsed', () => {
it('returns true if state has open files', () => {
localState.openFiles.push(file());
expect(getters.isCollapsed(localState)).toBeTruthy();
});
it('returns false if state has no open files', () => {
expect(getters.isCollapsed(localState)).toBeFalsy();
});
});
describe('canEditFile', () => {
beforeEach(() => {
localState.onTopOfBranch = true;
localState.canCommit = true;
localState.openFiles.push(file());
localState.openFiles[0].active = true;
});
it('returns true if user can commit and has open files', () => {
expect(getters.canEditFile(localState)).toBeTruthy();
});
it('returns false if user can commit and has no open files', () => {
localState.openFiles = [];
expect(getters.canEditFile(localState)).toBeFalsy();
});
it('returns false if user can commit and active file is binary', () => {
localState.openFiles[0].binary = true;
expect(getters.canEditFile(localState)).toBeFalsy();
});
it('returns false if user cant commit', () => {
localState.canCommit = false;
expect(getters.canEditFile(localState)).toBeFalsy();
});
it('returns false if user can commit but on a branch', () => {
localState.onTopOfBranch = false;
expect(getters.canEditFile(localState)).toBeFalsy();
});
});
});
import mutations from '~/repo/stores/mutations/branch';
import state from '~/repo/stores/state';
describe('Multi-file store branch mutations', () => {
let localState;
beforeEach(() => {
localState = state();
});
describe('SET_CURRENT_BRANCH', () => {
it('sets currentBranch', () => {
mutations.SET_CURRENT_BRANCH(localState, 'master');
expect(localState.currentBranch).toBe('master');
});
});
});
import mutations from '~/repo/stores/mutations/file';
import state from '~/repo/stores/state';
import { file } from '../../helpers';
describe('Multi-file store file mutations', () => {
let localState;
let localFile;
beforeEach(() => {
localState = state();
localFile = file();
});
describe('SET_FILE_ACTIVE', () => {
it('sets the file active', () => {
mutations.SET_FILE_ACTIVE(localState, {
file: localFile,
active: true,
});
expect(localFile.active).toBeTruthy();
});
});
describe('TOGGLE_FILE_OPEN', () => {
beforeEach(() => {
mutations.TOGGLE_FILE_OPEN(localState, localFile);
});
it('adds into opened files', () => {
expect(localFile.opened).toBeTruthy();
expect(localState.openFiles.length).toBe(1);
});
it('removes from opened files', () => {
mutations.TOGGLE_FILE_OPEN(localState, localFile);
expect(localFile.opened).toBeFalsy();
expect(localState.openFiles.length).toBe(0);
});
});
describe('SET_FILE_DATA', () => {
it('sets extra file data', () => {
mutations.SET_FILE_DATA(localState, {
data: {
blame_path: 'blame',
commits_path: 'commits',
permalink: 'permalink',
raw_path: 'raw',
binary: true,
html: 'html',
render_error: 'render_error',
},
file: localFile,
});
expect(localFile.blamePath).toBe('blame');
expect(localFile.commitsPath).toBe('commits');
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');
});
});
describe('SET_FILE_RAW_DATA', () => {
it('sets raw data', () => {
mutations.SET_FILE_RAW_DATA(localState, {
file: localFile,
raw: 'testing',
});
expect(localFile.raw).toBe('testing');
});
});
describe('UPDATE_FILE_CONTENT', () => {
beforeEach(() => {
localFile.raw = 'test';
});
it('sets content', () => {
mutations.UPDATE_FILE_CONTENT(localState, {
file: localFile,
content: 'test',
});
expect(localFile.content).toBe('test');
});
it('sets changed if content does not match raw', () => {
mutations.UPDATE_FILE_CONTENT(localState, {
file: localFile,
content: 'testing',
});
expect(localFile.content).toBe('testing');
expect(localFile.changed).toBeTruthy();
});
});
describe('DISCARD_FILE_CHANGES', () => {
beforeEach(() => {
localFile.content = 'test';
localFile.changed = true;
});
it('resets content and changed', () => {
mutations.DISCARD_FILE_CHANGES(localState, localFile);
expect(localFile.content).toBe('');
expect(localFile.changed).toBeFalsy();
});
});
describe('CREATE_TMP_FILE', () => {
it('adds file into parent tree', () => {
const f = file();
mutations.CREATE_TMP_FILE(localState, {
file: f,
parent: localFile,
});
expect(localFile.tree.length).toBe(1);
expect(localFile.tree[0].name).toBe(f.name);
});
});
});
import mutations from '~/repo/stores/mutations/tree';
import state from '~/repo/stores/state';
import { file } from '../../helpers';
describe('Multi-file store tree mutations', () => {
let localState;
let localTree;
beforeEach(() => {
localState = state();
localTree = file();
});
describe('TOGGLE_TREE_OPEN', () => {
it('toggles tree open', () => {
mutations.TOGGLE_TREE_OPEN(localState, localTree);
expect(localTree.opened).toBeTruthy();
mutations.TOGGLE_TREE_OPEN(localState, localTree);
expect(localTree.opened).toBeFalsy();
});
});
describe('SET_DIRECTORY_DATA', () => {
const data = [{
name: 'tree',
},
{
name: 'submodule',
},
{
name: 'blob',
}];
it('adds directory data', () => {
mutations.SET_DIRECTORY_DATA(localState, {
data,
tree: localState,
});
expect(localState.tree.length).toBe(3);
expect(localState.tree[0].name).toBe('tree');
expect(localState.tree[1].name).toBe('submodule');
expect(localState.tree[2].name).toBe('blob');
});
});
describe('SET_PARENT_TREE_URL', () => {
it('sets the parent tree url', () => {
mutations.SET_PARENT_TREE_URL(localState, 'test');
expect(localState.parentTreeUrl).toBe('test');
});
});
describe('CREATE_TMP_TREE', () => {
it('adds tree into parent tree', () => {
const tmpEntry = file();
mutations.CREATE_TMP_TREE(localState, {
tmpEntry,
parent: localTree,
});
expect(localTree.tree.length).toBe(1);
expect(localTree.tree[0].name).toBe(tmpEntry.name);
});
});
});
import mutations from '~/repo/stores/mutations';
import state from '~/repo/stores/state';
import { file } from '../helpers';
describe('Multi-file store mutations', () => {
let localState;
let entry;
beforeEach(() => {
localState = state();
entry = file();
});
describe('SET_INITIAL_DATA', () => {
it('sets all initial data', () => {
mutations.SET_INITIAL_DATA(localState, {
test: 'test',
});
expect(localState.test).toBe('test');
});
});
describe('SET_PREVIEW_MODE', () => {
it('sets currentBlobView to repo-preview', () => {
mutations.SET_PREVIEW_MODE(localState);
expect(localState.currentBlobView).toBe('repo-preview');
localState.currentBlobView = 'testing';
mutations.SET_PREVIEW_MODE(localState);
expect(localState.currentBlobView).toBe('repo-preview');
});
});
describe('SET_EDIT_MODE', () => {
it('sets currentBlobView to repo-editor', () => {
mutations.SET_EDIT_MODE(localState);
expect(localState.currentBlobView).toBe('repo-editor');
localState.currentBlobView = 'testing';
mutations.SET_EDIT_MODE(localState);
expect(localState.currentBlobView).toBe('repo-editor');
});
});
describe('TOGGLE_LOADING', () => {
it('toggles loading of entry', () => {
mutations.TOGGLE_LOADING(localState, entry);
expect(entry.loading).toBeTruthy();
mutations.TOGGLE_LOADING(localState, entry);
expect(entry.loading).toBeFalsy();
});
});
describe('TOGGLE_EDIT_MODE', () => {
it('toggles editMode', () => {
mutations.TOGGLE_EDIT_MODE(localState);
expect(localState.editMode).toBeTruthy();
mutations.TOGGLE_EDIT_MODE(localState);
expect(localState.editMode).toBeFalsy();
});
});
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_COMMIT_REF', () => {
it('sets currentRef', () => {
mutations.SET_COMMIT_REF(localState, '123');
expect(localState.currentRef).toBe('123');
});
});
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_PREVIOUS_URL', () => {
it('sets previousUrl', () => {
mutations.SET_PREVIOUS_URL(localState, 'testing');
expect(localState.previousUrl).toBe('testing');
});
});
});
import * as utils from '~/repo/stores/utils';
describe('Multi-file store utils', () => {
describe('setPageTitle', () => {
it('sets the document page title', () => {
utils.setPageTitle('test');
expect(document.title).toBe('test');
});
});
describe('pushState', () => {
it('calls history.pushState', () => {
spyOn(history, 'pushState');
utils.pushState('test');
expect(history.pushState).toHaveBeenCalledWith({ url: 'test' }, '', 'test');
});
});
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 state;
beforeEach(() => {
state = [{
path: '1',
}, {
path: '2',
}];
});
it('finds in the index of an entry by path', () => {
const index = utils.findIndexOfFile(state, {
path: '2',
});
expect(index).toBe(1);
});
});
describe('findEntry', () => {
let state;
beforeEach(() => {
state = {
tree: [{
type: 'tree',
name: 'test',
}, {
type: 'blob',
name: 'file',
}],
};
});
it('returns an entry found by name', () => {
const foundEntry = utils.findEntry(state, 'tree', 'test');
expect(foundEntry.type).toBe('tree');
expect(foundEntry.name).toBe('test');
});
it('returns undefined when no entry found', () => {
const foundEntry = utils.findEntry(state, 'blob', 'test');
expect(foundEntry).toBeUndefined();
});
});
});
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