updated karma specs
This commit is contained in:
parent
3811fbff7a
commit
47c906eb57
27 changed files with 621 additions and 1039 deletions
|
@ -74,7 +74,7 @@ export default {
|
|||
},
|
||||
watch: {
|
||||
activeFile(oldVal, newVal) {
|
||||
if (!newVal.active) {
|
||||
if (newVal && !newVal.active) {
|
||||
this.initMonaco();
|
||||
}
|
||||
},
|
||||
|
|
|
@ -2,9 +2,8 @@ import Vue from 'vue';
|
|||
import flash from '../../flash';
|
||||
import service from '../services';
|
||||
import * as types from './mutation_types';
|
||||
import { visitUrl } from '../../lib/utils/url_utility';
|
||||
|
||||
export const redirectToUrl = url => visitUrl(url);
|
||||
export const redirectToUrl = url => gl.utils.visitUrl(url);
|
||||
|
||||
export const setInitialData = ({ commit }, data) => commit(types.SET_INITIAL_DATA, data);
|
||||
|
||||
|
@ -26,7 +25,7 @@ export const closeAllFiles = ({ state, dispatch }) => {
|
|||
state.openFiles.forEach(file => dispatch('closeFile', { file }));
|
||||
};
|
||||
|
||||
export const toggleEditMode = ({ commit, getters, dispatch }, force = false) => {
|
||||
export const toggleEditMode = ({ state, commit, getters, dispatch }, force = false) => {
|
||||
const changedFiles = getters.changedFiles;
|
||||
|
||||
if (changedFiles.length && !force) {
|
||||
|
@ -35,7 +34,10 @@ export const toggleEditMode = ({ commit, getters, dispatch }, force = false) =>
|
|||
commit(types.TOGGLE_EDIT_MODE);
|
||||
commit(types.TOGGLE_DISCARD_POPUP, false);
|
||||
dispatch('toggleBlobView');
|
||||
dispatch('discardAllChanges');
|
||||
|
||||
if (!state.editMode) {
|
||||
dispatch('discardAllChanges');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -111,9 +113,12 @@ export const popHistoryState = ({ state, dispatch, getters }) => {
|
|||
export const scrollToTab = () => {
|
||||
Vue.nextTick(() => {
|
||||
const tabs = document.getElementById('tabs');
|
||||
const tabEl = tabs.querySelector('.active');
|
||||
|
||||
tabs.scrollLeft = tabEl.offsetLeft;
|
||||
if (tabs) {
|
||||
const tabEl = tabs.querySelector('.active');
|
||||
|
||||
tabs.scrollLeft = tabEl.offsetLeft;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
@ -3,6 +3,7 @@ import flash from '../../../flash';
|
|||
import service from '../../services';
|
||||
import * as types from '../mutation_types';
|
||||
import {
|
||||
findEntry,
|
||||
pushState,
|
||||
setPageTitle,
|
||||
createTemp,
|
||||
|
@ -88,11 +89,16 @@ export const createTempFile = ({ state, commit, dispatch }, { tree, name }) => {
|
|||
changed: true,
|
||||
});
|
||||
|
||||
if (findEntry(tree, 'blob', file.name)) return;
|
||||
|
||||
commit(types.CREATE_TMP_FILE, {
|
||||
parent: tree,
|
||||
file,
|
||||
});
|
||||
commit(types.TOGGLE_FILE_OPEN, file);
|
||||
dispatch('setFileActive', file);
|
||||
dispatch('toggleEditMode', true);
|
||||
|
||||
if (!state.editMode) {
|
||||
dispatch('toggleEditMode', true);
|
||||
}
|
||||
};
|
||||
|
|
|
@ -76,7 +76,7 @@ export const clickedTreeRow = ({ commit, dispatch }, row) => {
|
|||
|
||||
export const createTempTree = ({ state, commit, dispatch }, name) => {
|
||||
let tree = state;
|
||||
const dirNames = name.replace(`${state.path}/`, '').split('/');
|
||||
const dirNames = name.replace(new RegExp(`^${state.path}/`), '').split('/');
|
||||
|
||||
dirNames.forEach((dirName) => {
|
||||
const foundEntry = findEntry(tree, 'tree', dirName);
|
||||
|
@ -101,8 +101,10 @@ export const createTempTree = ({ state, commit, dispatch }, name) => {
|
|||
}
|
||||
});
|
||||
|
||||
dispatch('createTempFile', {
|
||||
tree,
|
||||
name: '.gitkeep',
|
||||
});
|
||||
if (tree.tempFile) {
|
||||
dispatch('createTempFile', {
|
||||
tree,
|
||||
name: '.gitkeep',
|
||||
});
|
||||
}
|
||||
};
|
||||
|
|
|
@ -15,11 +15,7 @@ export const changedFiles = (state) => {
|
|||
return files.filter(file => file.changed);
|
||||
};
|
||||
|
||||
export const activeFile = (state) => {
|
||||
const openedFiles = state.openFiles;
|
||||
|
||||
return openedFiles.find(file => file.active);
|
||||
};
|
||||
export const activeFile = state => state.openFiles.find(file => file.active);
|
||||
|
||||
export const activeFileExtension = (state) => {
|
||||
const file = activeFile(state);
|
||||
|
|
|
@ -8,7 +8,7 @@ import mutations from './mutations';
|
|||
Vue.use(Vuex);
|
||||
|
||||
export default new Vuex.Store({
|
||||
state,
|
||||
state: state(),
|
||||
actions,
|
||||
mutations,
|
||||
getters,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
export default {
|
||||
export default () => ({
|
||||
project: {
|
||||
id: 0,
|
||||
name: '',
|
||||
|
@ -20,4 +20,4 @@ export default {
|
|||
openFiles: [],
|
||||
parentTreeUrl: '',
|
||||
previousUrl: '',
|
||||
};
|
||||
});
|
||||
|
|
|
@ -36,8 +36,8 @@ export const decorateData = (entity, projectUrl = '') => {
|
|||
last_commit,
|
||||
tree_url,
|
||||
path,
|
||||
tempFile,
|
||||
renderError,
|
||||
tempFile = false,
|
||||
active = false,
|
||||
opened = false,
|
||||
changed = false,
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
export const createComponentWithStore = (Component, store, propsData = {}) => new Component({
|
||||
store,
|
||||
propsData,
|
||||
});
|
||||
|
||||
export default (Component, props = {}, el = null) => new Component({
|
||||
propsData: props,
|
||||
}).$mount(el);
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import Vue from 'vue';
|
||||
import store from '~/repo/stores';
|
||||
import newBranchForm from '~/repo/components/new_branch_form.vue';
|
||||
import eventHub from '~/repo/event_hub';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import createComponent from '../../helpers/vue_mount_component_helper';
|
||||
import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
|
||||
import { resetStore } from '../helpers';
|
||||
|
||||
describe('Multi-file editor new branch form', () => {
|
||||
let vm;
|
||||
|
@ -10,17 +10,17 @@ describe('Multi-file editor new branch form', () => {
|
|||
beforeEach(() => {
|
||||
const Component = Vue.extend(newBranchForm);
|
||||
|
||||
RepoStore.currentBranch = 'master';
|
||||
vm = createComponentWithStore(Component, store);
|
||||
|
||||
vm = createComponent(Component, {
|
||||
currentBranch: RepoStore.currentBranch,
|
||||
});
|
||||
vm.$store.state.currentBranch = 'master';
|
||||
|
||||
vm.$mount();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
|
||||
RepoStore.currentBranch = '';
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
describe('template', () => {
|
||||
|
@ -48,6 +48,10 @@ describe('Multi-file editor new branch form', () => {
|
|||
});
|
||||
|
||||
describe('submitNewBranch', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(vm, 'createNewBranch').and.returnValue(Promise.resolve());
|
||||
});
|
||||
|
||||
it('sets to loading', () => {
|
||||
vm.submitNewBranch();
|
||||
|
||||
|
@ -66,57 +70,45 @@ describe('Multi-file editor new branch form', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('emits an event with branchName', () => {
|
||||
spyOn(eventHub, '$emit');
|
||||
|
||||
it('calls createdNewBranch with branchName', () => {
|
||||
vm.branchName = 'testing';
|
||||
|
||||
vm.submitNewBranch();
|
||||
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('createNewBranch', 'testing');
|
||||
expect(vm.createNewBranch).toHaveBeenCalledWith('testing');
|
||||
});
|
||||
});
|
||||
|
||||
describe('showErrorMessage', () => {
|
||||
it('sets loading to false', () => {
|
||||
describe('submitNewBranch with error', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(vm, 'createNewBranch').and.returnValue(Promise.reject({
|
||||
json: () => Promise.resolve({
|
||||
message: 'error message',
|
||||
}),
|
||||
}));
|
||||
});
|
||||
|
||||
it('sets loading to false', (done) => {
|
||||
vm.loading = true;
|
||||
|
||||
vm.showErrorMessage();
|
||||
vm.submitNewBranch();
|
||||
|
||||
expect(vm.loading).toBeFalsy();
|
||||
setTimeout(() => {
|
||||
expect(vm.loading).toBeFalsy();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('creates flash element', () => {
|
||||
vm.showErrorMessage('error message');
|
||||
it('creates flash element', (done) => {
|
||||
vm.submitNewBranch();
|
||||
|
||||
expect(vm.$el.querySelector('.flash-alert')).not.toBeNull();
|
||||
expect(vm.$el.querySelector('.flash-alert').textContent.trim()).toBe('error message');
|
||||
});
|
||||
});
|
||||
setTimeout(() => {
|
||||
expect(vm.$el.querySelector('.flash-alert')).not.toBeNull();
|
||||
expect(vm.$el.querySelector('.flash-alert').textContent.trim()).toBe('error message');
|
||||
|
||||
describe('createdNewBranch', () => {
|
||||
it('set loading to false', () => {
|
||||
vm.loading = true;
|
||||
|
||||
vm.createdNewBranch();
|
||||
|
||||
expect(vm.loading).toBeFalsy();
|
||||
});
|
||||
|
||||
it('resets branch name', () => {
|
||||
vm.branchName = 'testing';
|
||||
|
||||
vm.createdNewBranch();
|
||||
|
||||
expect(vm.branchName).toBe('');
|
||||
});
|
||||
|
||||
it('sets the dropdown toggle text', () => {
|
||||
vm.dropdownText = document.createElement('span');
|
||||
|
||||
vm.createdNewBranch('branch name');
|
||||
|
||||
expect(vm.dropdownText.textContent).toBe('branch name');
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import Vue from 'vue';
|
||||
import store from '~/repo/stores';
|
||||
import newDropdown from '~/repo/components/new_dropdown/index.vue';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import RepoHelper from '~/repo/helpers/repo_helper';
|
||||
import eventHub from '~/repo/event_hub';
|
||||
import createComponent from '../../../helpers/vue_mount_component_helper';
|
||||
import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
|
||||
import { resetStore } from '../../helpers';
|
||||
|
||||
describe('new dropdown component', () => {
|
||||
let vm;
|
||||
|
@ -11,15 +10,13 @@ describe('new dropdown component', () => {
|
|||
beforeEach(() => {
|
||||
const component = Vue.extend(newDropdown);
|
||||
|
||||
vm = createComponent(component);
|
||||
vm = createComponentWithStore(component, store).$mount();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
|
||||
RepoStore.files = [];
|
||||
RepoStore.openedFiles = [];
|
||||
RepoStore.setViewToPreview();
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
it('renders new file and new directory links', () => {
|
||||
|
@ -67,125 +64,4 @@ describe('new dropdown component', () => {
|
|||
.catch(done.fail);
|
||||
});
|
||||
});
|
||||
|
||||
describe('createEntryInStore', () => {
|
||||
['tree', 'blob'].forEach((type) => {
|
||||
describe(type, () => {
|
||||
it('closes modal after creating file', () => {
|
||||
vm.openModal = true;
|
||||
|
||||
eventHub.$emit('createNewEntry', 'testing', type);
|
||||
|
||||
expect(vm.openModal).toBeFalsy();
|
||||
});
|
||||
|
||||
it('sets editMode to true', () => {
|
||||
eventHub.$emit('createNewEntry', 'testing', type);
|
||||
|
||||
expect(RepoStore.editMode).toBeTruthy();
|
||||
});
|
||||
|
||||
it('toggles blob view', () => {
|
||||
eventHub.$emit('createNewEntry', 'testing', type);
|
||||
|
||||
expect(RepoStore.isPreviewView()).toBeFalsy();
|
||||
});
|
||||
|
||||
it('adds file into activeFiles', () => {
|
||||
eventHub.$emit('createNewEntry', 'testing', type);
|
||||
|
||||
expect(RepoStore.openedFiles.length).toBe(1);
|
||||
});
|
||||
|
||||
it(`creates ${type} in the current stores path`, () => {
|
||||
RepoStore.path = 'testing';
|
||||
|
||||
eventHub.$emit('createNewEntry', 'testing/app', type);
|
||||
|
||||
expect(RepoStore.files[0].path).toBe('testing/app');
|
||||
expect(RepoStore.files[0].name).toBe('app');
|
||||
|
||||
if (type === 'tree') {
|
||||
expect(RepoStore.files[0].files.length).toBe(1);
|
||||
}
|
||||
|
||||
RepoStore.path = '';
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('file', () => {
|
||||
it('creates new file', () => {
|
||||
eventHub.$emit('createNewEntry', 'testing', 'blob');
|
||||
|
||||
expect(RepoStore.files.length).toBe(1);
|
||||
expect(RepoStore.files[0].name).toBe('testing');
|
||||
expect(RepoStore.files[0].type).toBe('blob');
|
||||
expect(RepoStore.files[0].tempFile).toBeTruthy();
|
||||
});
|
||||
|
||||
it('does not create temp file when file already exists', () => {
|
||||
RepoStore.files.push(RepoHelper.serializeRepoEntity('blob', {
|
||||
name: 'testing',
|
||||
}));
|
||||
|
||||
eventHub.$emit('createNewEntry', 'testing', 'blob');
|
||||
|
||||
expect(RepoStore.files.length).toBe(1);
|
||||
expect(RepoStore.files[0].name).toBe('testing');
|
||||
expect(RepoStore.files[0].type).toBe('blob');
|
||||
expect(RepoStore.files[0].tempFile).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('tree', () => {
|
||||
it('creates new tree', () => {
|
||||
eventHub.$emit('createNewEntry', 'testing', 'tree');
|
||||
|
||||
expect(RepoStore.files.length).toBe(1);
|
||||
expect(RepoStore.files[0].name).toBe('testing');
|
||||
expect(RepoStore.files[0].type).toBe('tree');
|
||||
expect(RepoStore.files[0].tempFile).toBeTruthy();
|
||||
expect(RepoStore.files[0].files.length).toBe(1);
|
||||
expect(RepoStore.files[0].files[0].name).toBe('.gitkeep');
|
||||
});
|
||||
|
||||
it('creates multiple trees when entryName has slashes', () => {
|
||||
eventHub.$emit('createNewEntry', 'app/test', 'tree');
|
||||
|
||||
expect(RepoStore.files.length).toBe(1);
|
||||
expect(RepoStore.files[0].name).toBe('app');
|
||||
expect(RepoStore.files[0].files[0].name).toBe('test');
|
||||
expect(RepoStore.files[0].files[0].files[0].name).toBe('.gitkeep');
|
||||
});
|
||||
|
||||
it('creates tree in existing tree', () => {
|
||||
RepoStore.files.push(RepoHelper.serializeRepoEntity('tree', {
|
||||
name: 'app',
|
||||
}));
|
||||
|
||||
eventHub.$emit('createNewEntry', 'app/test', 'tree');
|
||||
|
||||
expect(RepoStore.files.length).toBe(1);
|
||||
expect(RepoStore.files[0].name).toBe('app');
|
||||
expect(RepoStore.files[0].tempFile).toBeUndefined();
|
||||
expect(RepoStore.files[0].files[0].tempFile).toBeTruthy();
|
||||
expect(RepoStore.files[0].files[0].name).toBe('test');
|
||||
expect(RepoStore.files[0].files[0].files[0].name).toBe('.gitkeep');
|
||||
});
|
||||
|
||||
it('does not create new tree when already exists', () => {
|
||||
RepoStore.files.push(RepoHelper.serializeRepoEntity('tree', {
|
||||
name: 'app',
|
||||
}));
|
||||
|
||||
eventHub.$emit('createNewEntry', 'app', 'tree');
|
||||
|
||||
expect(RepoStore.files.length).toBe(1);
|
||||
expect(RepoStore.files[0].name).toBe('app');
|
||||
expect(RepoStore.files[0].tempFile).toBeUndefined();
|
||||
expect(RepoStore.files[0].files.length).toBe(0);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
import Vue from 'vue';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import store from '~/repo/stores';
|
||||
import modal from '~/repo/components/new_dropdown/modal.vue';
|
||||
import eventHub from '~/repo/event_hub';
|
||||
import createComponent from '../../../helpers/vue_mount_component_helper';
|
||||
import { createComponentWithStore } from '../../../helpers/vue_mount_component_helper';
|
||||
import { file, resetStore } from '../../helpers';
|
||||
|
||||
describe('new file modal component', () => {
|
||||
const Component = Vue.extend(modal);
|
||||
|
@ -11,18 +11,17 @@ describe('new file modal component', () => {
|
|||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
|
||||
RepoStore.files = [];
|
||||
RepoStore.openedFiles = [];
|
||||
RepoStore.setViewToPreview();
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
['tree', 'blob'].forEach((type) => {
|
||||
describe(type, () => {
|
||||
beforeEach(() => {
|
||||
vm = createComponent(Component, {
|
||||
vm = createComponentWithStore(Component, store, {
|
||||
type,
|
||||
currentPath: RepoStore.path,
|
||||
});
|
||||
}).$mount();
|
||||
|
||||
vm.entryName = 'testing';
|
||||
});
|
||||
|
||||
it(`sets modal title as ${type}`, () => {
|
||||
|
@ -42,35 +41,156 @@ describe('new file modal component', () => {
|
|||
|
||||
expect(vm.$el.querySelector('.label-light').textContent.trim()).toBe(`${title} name`);
|
||||
});
|
||||
|
||||
describe('createEntryInStore', () => {
|
||||
it('calls createTempEntry', () => {
|
||||
spyOn(vm, 'createTempEntry');
|
||||
|
||||
vm.createEntryInStore();
|
||||
|
||||
expect(vm.createTempEntry).toHaveBeenCalledWith({
|
||||
name: 'testing',
|
||||
type,
|
||||
});
|
||||
});
|
||||
|
||||
it('sets editMode to true', (done) => {
|
||||
vm.createEntryInStore();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(vm.$store.state.editMode).toBeTruthy();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('toggles blob view', (done) => {
|
||||
vm.createEntryInStore();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(vm.$store.state.currentBlobView).toBe('repo-editor');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('opens newly created file', (done) => {
|
||||
vm.createEntryInStore();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(vm.$store.state.openFiles.length).toBe(1);
|
||||
expect(vm.$store.state.openFiles[0].name).toBe(type === 'blob' ? 'testing' : '.gitkeep');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it(`creates ${type} in the current stores path`, (done) => {
|
||||
vm.$store.state.path = 'app';
|
||||
|
||||
vm.createEntryInStore();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(vm.$store.state.tree[0].path).toBe('app/testing');
|
||||
expect(vm.$store.state.tree[0].name).toBe('testing');
|
||||
|
||||
if (type === 'tree') {
|
||||
expect(vm.$store.state.tree[0].tree.length).toBe(1);
|
||||
}
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
if (type === 'blob') {
|
||||
it('creates new file', (done) => {
|
||||
vm.createEntryInStore();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(vm.$store.state.tree.length).toBe(1);
|
||||
expect(vm.$store.state.tree[0].name).toBe('testing');
|
||||
expect(vm.$store.state.tree[0].type).toBe('blob');
|
||||
expect(vm.$store.state.tree[0].tempFile).toBeTruthy();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('does not create temp file when file already exists', (done) => {
|
||||
vm.$store.state.tree.push(file('testing', '1', type));
|
||||
|
||||
vm.createEntryInStore();
|
||||
|
||||
setTimeout(() => {
|
||||
expect(vm.$store.state.tree.length).toBe(1);
|
||||
expect(vm.$store.state.tree[0].name).toBe('testing');
|
||||
expect(vm.$store.state.tree[0].type).toBe('blob');
|
||||
expect(vm.$store.state.tree[0].tempFile).toBeFalsy();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
it('creates new tree', () => {
|
||||
vm.createEntryInStore();
|
||||
|
||||
expect(vm.$store.state.tree.length).toBe(1);
|
||||
expect(vm.$store.state.tree[0].name).toBe('testing');
|
||||
expect(vm.$store.state.tree[0].type).toBe('tree');
|
||||
expect(vm.$store.state.tree[0].tempFile).toBeTruthy();
|
||||
expect(vm.$store.state.tree[0].tree.length).toBe(1);
|
||||
expect(vm.$store.state.tree[0].tree[0].name).toBe('.gitkeep');
|
||||
});
|
||||
|
||||
it('creates multiple trees when entryName has slashes', () => {
|
||||
vm.entryName = 'app/test';
|
||||
vm.createEntryInStore();
|
||||
|
||||
expect(vm.$store.state.tree.length).toBe(1);
|
||||
expect(vm.$store.state.tree[0].name).toBe('app');
|
||||
expect(vm.$store.state.tree[0].tree[0].name).toBe('test');
|
||||
expect(vm.$store.state.tree[0].tree[0].tree[0].name).toBe('.gitkeep');
|
||||
});
|
||||
|
||||
it('creates tree in existing tree', () => {
|
||||
vm.$store.state.tree.push(file('app', '1', 'tree'));
|
||||
|
||||
vm.entryName = 'app/test';
|
||||
vm.createEntryInStore();
|
||||
|
||||
expect(vm.$store.state.tree.length).toBe(1);
|
||||
expect(vm.$store.state.tree[0].name).toBe('app');
|
||||
expect(vm.$store.state.tree[0].tempFile).toBeFalsy();
|
||||
expect(vm.$store.state.tree[0].tree[0].tempFile).toBeTruthy();
|
||||
expect(vm.$store.state.tree[0].tree[0].name).toBe('test');
|
||||
expect(vm.$store.state.tree[0].tree[0].tree[0].name).toBe('.gitkeep');
|
||||
});
|
||||
|
||||
it('does not create new tree when already exists', () => {
|
||||
vm.$store.state.tree.push(file('app', '1', 'tree'));
|
||||
|
||||
vm.entryName = 'app';
|
||||
vm.createEntryInStore();
|
||||
|
||||
expect(vm.$store.state.tree.length).toBe(1);
|
||||
expect(vm.$store.state.tree[0].name).toBe('app');
|
||||
expect(vm.$store.state.tree[0].tempFile).toBeFalsy();
|
||||
expect(vm.$store.state.tree[0].tree.length).toBe(0);
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('focuses field on mount', () => {
|
||||
document.body.innerHTML += '<div class="js-test"></div>';
|
||||
|
||||
vm = createComponent(Component, {
|
||||
vm = createComponentWithStore(Component, store, {
|
||||
type: 'tree',
|
||||
currentPath: RepoStore.path,
|
||||
}, '.js-test');
|
||||
}).$mount('.js-test');
|
||||
|
||||
expect(document.activeElement).toBe(vm.$refs.fieldName);
|
||||
|
||||
vm.$el.remove();
|
||||
});
|
||||
|
||||
describe('createEntryInStore', () => {
|
||||
it('emits createNewEntry event', () => {
|
||||
spyOn(eventHub, '$emit');
|
||||
|
||||
vm = createComponent(Component, {
|
||||
type: 'tree',
|
||||
currentPath: RepoStore.path,
|
||||
});
|
||||
vm.entryName = 'testing';
|
||||
|
||||
vm.createEntryInStore();
|
||||
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('createNewEntry', 'testing', 'tree');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,56 +1,43 @@
|
|||
import Vue from 'vue';
|
||||
import store from '~/repo/stores';
|
||||
import service from '~/repo/services';
|
||||
import repoCommitSection from '~/repo/components/repo_commit_section.vue';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import RepoService from '~/repo/services/repo_service';
|
||||
import getSetTimeoutPromise from '../../helpers/set_timeout_promise_helper';
|
||||
import { file, resetStore } from '../helpers';
|
||||
|
||||
describe('RepoCommitSection', () => {
|
||||
const branch = 'master';
|
||||
const projectUrl = 'projectUrl';
|
||||
let changedFiles;
|
||||
let openedFiles;
|
||||
let vm;
|
||||
|
||||
RepoStore.projectUrl = projectUrl;
|
||||
|
||||
function createComponent(el) {
|
||||
function createComponent() {
|
||||
const RepoCommitSection = Vue.extend(repoCommitSection);
|
||||
|
||||
return new RepoCommitSection().$mount(el);
|
||||
const comp = new RepoCommitSection({
|
||||
store,
|
||||
}).$mount();
|
||||
|
||||
comp.$store.state.currentBranch = 'master';
|
||||
comp.$store.state.openFiles = [file(), file()];
|
||||
comp.$store.state.openFiles.forEach(f => Object.assign(f, {
|
||||
changed: true,
|
||||
content: 'testing',
|
||||
}));
|
||||
|
||||
return comp.$mount();
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
// Create a copy for each test because these can get modified directly
|
||||
changedFiles = [{
|
||||
id: 0,
|
||||
changed: true,
|
||||
url: `/namespace/${projectUrl}/blob/${branch}/dir/file0.ext`,
|
||||
path: 'dir/file0.ext',
|
||||
newContent: 'a',
|
||||
}, {
|
||||
id: 1,
|
||||
changed: true,
|
||||
url: `/namespace/${projectUrl}/blob/${branch}/dir/file1.ext`,
|
||||
path: 'dir/file1.ext',
|
||||
newContent: 'b',
|
||||
}];
|
||||
openedFiles = changedFiles.concat([{
|
||||
id: 2,
|
||||
url: `/namespace/${projectUrl}/blob/${branch}/dir/file2.ext`,
|
||||
path: 'dir/file2.ext',
|
||||
changed: false,
|
||||
}]);
|
||||
vm = createComponent();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
it('renders a commit section', () => {
|
||||
RepoStore.isCommitable = true;
|
||||
RepoStore.currentBranch = branch;
|
||||
RepoStore.targetBranch = branch;
|
||||
RepoStore.openedFiles = openedFiles;
|
||||
|
||||
const vm = createComponent();
|
||||
const changedFileElements = [...vm.$el.querySelectorAll('.changed-files > li')];
|
||||
const commitMessage = vm.$el.querySelector('#commit-message');
|
||||
const submitCommit = vm.$refs.submitCommit;
|
||||
const submitCommit = vm.$el.querySelector('.btn');
|
||||
const targetBranch = vm.$el.querySelector('.target-branch');
|
||||
|
||||
expect(vm.$el.querySelector(':scope > form')).toBeTruthy();
|
||||
|
@ -58,160 +45,70 @@ describe('RepoCommitSection', () => {
|
|||
expect(changedFileElements.length).toEqual(2);
|
||||
|
||||
changedFileElements.forEach((changedFile, i) => {
|
||||
expect(changedFile.textContent.trim()).toEqual(changedFiles[i].path);
|
||||
expect(changedFile.textContent.trim()).toEqual(vm.$store.getters.changedFiles[i].path);
|
||||
});
|
||||
|
||||
expect(commitMessage.tagName).toEqual('TEXTAREA');
|
||||
expect(commitMessage.name).toEqual('commit-message');
|
||||
expect(submitCommit.type).toEqual('submit');
|
||||
expect(submitCommit.disabled).toBeTruthy();
|
||||
expect(submitCommit.querySelector('.fa-spinner.fa-spin')).toBeFalsy();
|
||||
expect(vm.$el.querySelector('.commit-summary').textContent.trim()).toEqual('Commit 2 files');
|
||||
expect(targetBranch.querySelector(':scope > label').textContent.trim()).toEqual('Target branch');
|
||||
expect(targetBranch.querySelector('.help-block').textContent.trim()).toEqual(branch);
|
||||
});
|
||||
|
||||
it('does not render if not isCommitable', () => {
|
||||
RepoStore.isCommitable = false;
|
||||
RepoStore.openedFiles = [{
|
||||
id: 0,
|
||||
changed: true,
|
||||
}];
|
||||
|
||||
const vm = createComponent();
|
||||
|
||||
expect(vm.$el.innerHTML).toBeFalsy();
|
||||
});
|
||||
|
||||
it('does not render if no changedFiles', () => {
|
||||
RepoStore.isCommitable = true;
|
||||
RepoStore.openedFiles = [];
|
||||
|
||||
const vm = createComponent();
|
||||
|
||||
expect(vm.$el.innerHTML).toBeFalsy();
|
||||
expect(targetBranch.querySelector('.help-block').textContent.trim()).toEqual('master');
|
||||
});
|
||||
|
||||
describe('when submitting', () => {
|
||||
let el;
|
||||
let vm;
|
||||
const projectId = 'projectId';
|
||||
const commitMessage = 'commitMessage';
|
||||
let changedFiles;
|
||||
|
||||
beforeEach((done) => {
|
||||
RepoStore.isCommitable = true;
|
||||
RepoStore.currentBranch = branch;
|
||||
RepoStore.targetBranch = branch;
|
||||
RepoStore.openedFiles = openedFiles;
|
||||
RepoStore.projectId = projectId;
|
||||
beforeEach(() => {
|
||||
vm.commitMessage = 'testing';
|
||||
changedFiles = JSON.parse(JSON.stringify(vm.$store.getters.changedFiles));
|
||||
|
||||
// We need to append to body to get form `submit` events working
|
||||
// Otherwise we run into, "Form submission canceled because the form is not connected"
|
||||
// See https://html.spec.whatwg.org/multipage/form-control-infrastructure.html#form-submission-algorithm
|
||||
el = document.createElement('div');
|
||||
document.body.appendChild(el);
|
||||
|
||||
vm = createComponent(el);
|
||||
vm.commitMessage = commitMessage;
|
||||
|
||||
spyOn(vm, 'tryCommit').and.callThrough();
|
||||
spyOn(vm, 'redirectToNewMr').and.stub();
|
||||
spyOn(vm, 'redirectToBranch').and.stub();
|
||||
spyOn(RepoService, 'commitFiles').and.returnValue(Promise.resolve());
|
||||
spyOn(RepoService, 'getBranch').and.returnValue(Promise.resolve({
|
||||
commit: {
|
||||
id: 1,
|
||||
short_id: 1,
|
||||
},
|
||||
spyOn(service, 'commit').and.returnValue(Promise.resolve({
|
||||
short_id: '1',
|
||||
stats: {},
|
||||
}));
|
||||
|
||||
// Wait for the vm data to be in place
|
||||
Vue.nextTick(() => {
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
el.remove();
|
||||
RepoStore.openedFiles = [];
|
||||
});
|
||||
|
||||
it('shows commit message', () => {
|
||||
const commitMessageEl = vm.$el.querySelector('#commit-message');
|
||||
expect(commitMessageEl.value).toBe(commitMessage);
|
||||
});
|
||||
|
||||
it('allows you to submit', () => {
|
||||
const submitCommit = vm.$refs.submitCommit;
|
||||
expect(submitCommit.disabled).toBeFalsy();
|
||||
expect(vm.$el.querySelector('.btn').disabled).toBeTruthy();
|
||||
});
|
||||
|
||||
it('shows commit submit and summary if commitMessage and spinner if submitCommitsLoading', (done) => {
|
||||
const submitCommit = vm.$refs.submitCommit;
|
||||
submitCommit.click();
|
||||
it('submits commit', (done) => {
|
||||
vm.makeCommit();
|
||||
|
||||
// Wait for the branch check to finish
|
||||
getSetTimeoutPromise()
|
||||
.then(() => Vue.nextTick())
|
||||
.then(() => {
|
||||
expect(vm.tryCommit).toHaveBeenCalled();
|
||||
expect(submitCommit.querySelector('.js-commit-loading-icon')).toBeTruthy();
|
||||
expect(vm.redirectToBranch).toHaveBeenCalled();
|
||||
const args = service.commit.calls.allArgs()[0];
|
||||
const { commit_message, actions, branch: payloadBranch } = args[1];
|
||||
|
||||
const args = RepoService.commitFiles.calls.allArgs()[0];
|
||||
const { commit_message, actions, branch: payloadBranch } = args[0];
|
||||
|
||||
expect(commit_message).toBe(commitMessage);
|
||||
expect(commit_message).toBe('testing');
|
||||
expect(actions.length).toEqual(2);
|
||||
expect(payloadBranch).toEqual(branch);
|
||||
expect(payloadBranch).toEqual('master');
|
||||
expect(actions[0].action).toEqual('update');
|
||||
expect(actions[1].action).toEqual('update');
|
||||
expect(actions[0].content).toEqual(openedFiles[0].newContent);
|
||||
expect(actions[1].content).toEqual(openedFiles[1].newContent);
|
||||
expect(actions[0].file_path).toEqual(openedFiles[0].path);
|
||||
expect(actions[1].file_path).toEqual(openedFiles[1].path);
|
||||
expect(actions[0].content).toEqual(changedFiles[0].content);
|
||||
expect(actions[1].content).toEqual(changedFiles[1].content);
|
||||
expect(actions[0].file_path).toEqual(changedFiles[0].path);
|
||||
expect(actions[1].file_path).toEqual(changedFiles[1].path);
|
||||
})
|
||||
.then(done)
|
||||
.catch(done.fail);
|
||||
});
|
||||
|
||||
it('redirects to MR creation page if start new MR checkbox checked', (done) => {
|
||||
spyOn(gl.utils, 'visitUrl');
|
||||
vm.startNewMR = true;
|
||||
|
||||
Vue.nextTick()
|
||||
vm.makeCommit();
|
||||
|
||||
getSetTimeoutPromise()
|
||||
.then(() => Vue.nextTick())
|
||||
.then(() => {
|
||||
const submitCommit = vm.$refs.submitCommit;
|
||||
submitCommit.click();
|
||||
})
|
||||
// Wait for the branch check to finish
|
||||
.then(() => getSetTimeoutPromise())
|
||||
.then(() => {
|
||||
expect(vm.redirectToNewMr).toHaveBeenCalled();
|
||||
expect(gl.utils.visitUrl).toHaveBeenCalled();
|
||||
})
|
||||
.then(done)
|
||||
.catch(done.fail);
|
||||
});
|
||||
});
|
||||
|
||||
describe('methods', () => {
|
||||
describe('resetCommitState', () => {
|
||||
it('should reset store vars and scroll to top', () => {
|
||||
const vm = {
|
||||
submitCommitsLoading: true,
|
||||
changedFiles: new Array(10),
|
||||
openedFiles: new Array(3),
|
||||
commitMessage: 'commitMessage',
|
||||
editMode: true,
|
||||
};
|
||||
|
||||
repoCommitSection.methods.resetCommitState.call(vm);
|
||||
|
||||
expect(vm.submitCommitsLoading).toEqual(false);
|
||||
expect(vm.changedFiles).toEqual([]);
|
||||
expect(vm.commitMessage).toEqual('');
|
||||
expect(vm.editMode).toEqual(false);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,45 +1,78 @@
|
|||
import Vue from 'vue';
|
||||
import store from '~/repo/stores';
|
||||
import repoEditButton from '~/repo/components/repo_edit_button.vue';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import { file, resetStore } from '../helpers';
|
||||
|
||||
describe('RepoEditButton', () => {
|
||||
function createComponent() {
|
||||
let vm;
|
||||
|
||||
beforeEach(() => {
|
||||
const f = file();
|
||||
const RepoEditButton = Vue.extend(repoEditButton);
|
||||
|
||||
return new RepoEditButton().$mount();
|
||||
}
|
||||
vm = new RepoEditButton({
|
||||
store,
|
||||
});
|
||||
|
||||
f.active = true;
|
||||
f.changed = true;
|
||||
vm.$store.dispatch('setInitialData', {
|
||||
canCommit: true,
|
||||
onTopOfBranch: true,
|
||||
});
|
||||
vm.$store.state.openFiles.push(f);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
RepoStore.openedFiles = [];
|
||||
vm.$destroy();
|
||||
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
it('renders an edit button that toggles the view state', (done) => {
|
||||
RepoStore.isCommitable = true;
|
||||
RepoStore.changedFiles = [];
|
||||
RepoStore.binary = false;
|
||||
RepoStore.openedFiles = [{}, {}];
|
||||
it('renders an edit button', () => {
|
||||
vm.$mount();
|
||||
|
||||
const vm = createComponent();
|
||||
expect(vm.$el.querySelector('.btn')).not.toBeNull();
|
||||
expect(vm.$el.querySelector('.btn').textContent.trim()).toBe('Edit');
|
||||
});
|
||||
|
||||
expect(vm.$el.tagName).toEqual('BUTTON');
|
||||
expect(vm.$el.textContent).toMatch('Edit');
|
||||
it('renders edit button with cancel text', () => {
|
||||
vm.$store.state.editMode = true;
|
||||
|
||||
spyOn(vm, 'editCancelClicked').and.callThrough();
|
||||
vm.$mount();
|
||||
|
||||
vm.$el.click();
|
||||
expect(vm.$el.querySelector('.btn')).not.toBeNull();
|
||||
expect(vm.$el.querySelector('.btn').textContent.trim()).toBe('Cancel edit');
|
||||
});
|
||||
|
||||
Vue.nextTick(() => {
|
||||
expect(vm.editCancelClicked).toHaveBeenCalled();
|
||||
expect(vm.$el.textContent).toMatch('Cancel edit');
|
||||
done();
|
||||
it('toggles edit mode on click', () => {
|
||||
vm.$mount();
|
||||
|
||||
vm.$el.querySelector('.btn').click();
|
||||
|
||||
expect(vm.$el.querySelector('.btn').textContent.trim()).toBe('Cancel edit');
|
||||
});
|
||||
|
||||
describe('discardPopupOpen', () => {
|
||||
beforeEach(() => {
|
||||
vm.$store.state.discardPopupOpen = 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();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it('does not render if not isCommitable', () => {
|
||||
RepoStore.isCommitable = false;
|
||||
|
||||
const vm = createComponent();
|
||||
|
||||
expect(vm.$el.innerHTML).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,52 +1,46 @@
|
|||
import Vue from 'vue';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import store from '~/repo/stores';
|
||||
import repoEditor from '~/repo/components/repo_editor.vue';
|
||||
import { file, resetStore } from '../helpers';
|
||||
|
||||
describe('RepoEditor', () => {
|
||||
let vm;
|
||||
|
||||
beforeEach(() => {
|
||||
const f = file();
|
||||
const RepoEditor = Vue.extend(repoEditor);
|
||||
|
||||
this.vm = new RepoEditor().$mount();
|
||||
vm = new RepoEditor({
|
||||
store,
|
||||
});
|
||||
|
||||
f.active = true;
|
||||
f.tempFile = true;
|
||||
vm.$store.state.openFiles.push(f);
|
||||
vm.monaco = true;
|
||||
|
||||
vm.$mount();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
RepoStore.openedFiles = [];
|
||||
vm.$destroy();
|
||||
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
it('renders an ide container', (done) => {
|
||||
this.vm.openedFiles = ['idiidid'];
|
||||
this.vm.binary = false;
|
||||
|
||||
Vue.nextTick(() => {
|
||||
expect(this.vm.shouldHideEditor).toBe(false);
|
||||
expect(this.vm.$el.id).toEqual('ide');
|
||||
expect(this.vm.$el.tagName).toBe('DIV');
|
||||
expect(vm.shouldHideEditor).toBeFalsy();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('when there are no open files', () => {
|
||||
it('does not render the ide', (done) => {
|
||||
this.vm.openedFiles = [];
|
||||
|
||||
Vue.nextTick(() => {
|
||||
expect(this.vm.shouldHideEditor).toBe(true);
|
||||
expect(this.vm.$el.tagName).not.toBeDefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('when open file is binary and not raw', () => {
|
||||
it('does not render the IDE', (done) => {
|
||||
this.vm.binary = true;
|
||||
this.vm.activeFile = {
|
||||
raw: false,
|
||||
};
|
||||
vm.$store.getters.activeFile.binary = true;
|
||||
|
||||
Vue.nextTick(() => {
|
||||
expect(this.vm.shouldHideEditor).toBe(true);
|
||||
expect(this.vm.$el.tagName).not.toBeDefined();
|
||||
expect(vm.shouldHideEditor).toBeTruthy();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,72 +1,49 @@
|
|||
import Vue from 'vue';
|
||||
import store from '~/repo/stores';
|
||||
import repoFileButtons from '~/repo/components/repo_file_buttons.vue';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import { file, resetStore } from '../helpers';
|
||||
|
||||
describe('RepoFileButtons', () => {
|
||||
const activeFile = {
|
||||
extension: 'md',
|
||||
url: 'url',
|
||||
raw_path: 'raw_path',
|
||||
blame_path: 'blame_path',
|
||||
commits_path: 'commits_path',
|
||||
permalink: 'permalink',
|
||||
};
|
||||
const activeFile = file();
|
||||
let vm;
|
||||
|
||||
function createComponent() {
|
||||
const RepoFileButtons = Vue.extend(repoFileButtons);
|
||||
|
||||
return new RepoFileButtons().$mount();
|
||||
activeFile.rawPath = 'test';
|
||||
activeFile.blamePath = 'test';
|
||||
activeFile.commitsPath = 'test';
|
||||
activeFile.active = true;
|
||||
store.state.openFiles.push(activeFile);
|
||||
|
||||
return new RepoFileButtons({
|
||||
store,
|
||||
}).$mount();
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
RepoStore.openedFiles = [];
|
||||
vm.$destroy();
|
||||
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
it('renders Raw, Blame, History, Permalink and Preview toggle', () => {
|
||||
const activeFileLabel = 'activeFileLabel';
|
||||
RepoStore.openedFiles = new Array(1);
|
||||
RepoStore.activeFile = activeFile;
|
||||
RepoStore.activeFileLabel = activeFileLabel;
|
||||
RepoStore.editMode = true;
|
||||
RepoStore.binary = false;
|
||||
it('renders Raw, Blame, History, Permalink and Preview toggle', (done) => {
|
||||
vm = createComponent();
|
||||
|
||||
const vm = createComponent();
|
||||
const raw = vm.$el.querySelector('.raw');
|
||||
const blame = vm.$el.querySelector('.blame');
|
||||
const history = vm.$el.querySelector('.history');
|
||||
vm.$nextTick(() => {
|
||||
const raw = vm.$el.querySelector('.raw');
|
||||
const blame = vm.$el.querySelector('.blame');
|
||||
const history = vm.$el.querySelector('.history');
|
||||
|
||||
expect(raw.href).toMatch(`/${activeFile.raw_path}`);
|
||||
expect(raw.textContent.trim()).toEqual('Raw');
|
||||
expect(blame.href).toMatch(`/${activeFile.blame_path}`);
|
||||
expect(blame.textContent.trim()).toEqual('Blame');
|
||||
expect(history.href).toMatch(`/${activeFile.commits_path}`);
|
||||
expect(history.textContent.trim()).toEqual('History');
|
||||
expect(vm.$el.querySelector('.permalink').textContent.trim()).toEqual('Permalink');
|
||||
expect(vm.$el.querySelector('.preview').textContent.trim()).toEqual(activeFileLabel);
|
||||
});
|
||||
expect(raw.href).toMatch(`/${activeFile.rawPath}`);
|
||||
expect(raw.textContent.trim()).toEqual('Raw');
|
||||
expect(blame.href).toMatch(`/${activeFile.blamePath}`);
|
||||
expect(blame.textContent.trim()).toEqual('Blame');
|
||||
expect(history.href).toMatch(`/${activeFile.commitsPath}`);
|
||||
expect(history.textContent.trim()).toEqual('History');
|
||||
expect(vm.$el.querySelector('.permalink').textContent.trim()).toEqual('Permalink');
|
||||
|
||||
it('triggers rawPreviewToggle on preview click', () => {
|
||||
RepoStore.openedFiles = new Array(1);
|
||||
RepoStore.activeFile = activeFile;
|
||||
RepoStore.editMode = true;
|
||||
|
||||
const vm = createComponent();
|
||||
const preview = vm.$el.querySelector('.preview');
|
||||
|
||||
spyOn(vm, 'rawPreviewToggle');
|
||||
|
||||
preview.click();
|
||||
|
||||
expect(vm.rawPreviewToggle).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('does not render preview toggle if not canPreview', () => {
|
||||
activeFile.extension = 'js';
|
||||
RepoStore.openedFiles = new Array(1);
|
||||
RepoStore.activeFile = activeFile;
|
||||
|
||||
const vm = createComponent();
|
||||
|
||||
expect(vm.$el.querySelector('.preview')).toBeFalsy();
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,32 +1,28 @@
|
|||
import Vue from 'vue';
|
||||
import store from '~/repo/stores';
|
||||
import repoFile from '~/repo/components/repo_file.vue';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import eventHub from '~/repo/event_hub';
|
||||
import { file } from '../mock_data';
|
||||
import { file, resetStore } from '../helpers';
|
||||
|
||||
describe('RepoFile', () => {
|
||||
const updated = 'updated';
|
||||
const otherFile = {
|
||||
id: 'test',
|
||||
html: '<p class="file-content">html</p>',
|
||||
pageTitle: 'otherpageTitle',
|
||||
};
|
||||
|
||||
function createComponent(propsData) {
|
||||
const RepoFile = Vue.extend(repoFile);
|
||||
|
||||
return new RepoFile({
|
||||
store,
|
||||
propsData,
|
||||
}).$mount();
|
||||
}
|
||||
|
||||
beforeEach(() => {
|
||||
RepoStore.openedFiles = [];
|
||||
afterEach(() => {
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
it('renders link, icon, name and last commit details', () => {
|
||||
const RepoFile = Vue.extend(repoFile);
|
||||
const vm = new RepoFile({
|
||||
store,
|
||||
propsData: {
|
||||
file: file(),
|
||||
},
|
||||
|
@ -54,12 +50,6 @@ describe('RepoFile', () => {
|
|||
expect(vm.$el.querySelector('.fa-spin.fa-spinner')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('sets the document title correctly', () => {
|
||||
RepoStore.setActiveFiles(otherFile);
|
||||
|
||||
expect(document.title.trim()).toEqual(otherFile.pageTitle);
|
||||
});
|
||||
|
||||
it('renders a spinner if the file is loading', () => {
|
||||
const f = file();
|
||||
f.loading = true;
|
||||
|
@ -71,27 +61,30 @@ describe('RepoFile', () => {
|
|||
expect(vm.$el.querySelector('.fa-spin.fa-spinner').style.marginLeft).toEqual(`${vm.file.level * 16}px`);
|
||||
});
|
||||
|
||||
it('does not render commit message and datetime if mini', () => {
|
||||
RepoStore.openedFiles.push(file());
|
||||
|
||||
it('does not render commit message and datetime if mini', (done) => {
|
||||
const vm = createComponent({
|
||||
file: file(),
|
||||
});
|
||||
vm.$store.state.openFiles.push(vm.file);
|
||||
|
||||
expect(vm.$el.querySelector('.commit-message')).toBeFalsy();
|
||||
expect(vm.$el.querySelector('.commit-update')).toBeFalsy();
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.$el.querySelector('.commit-message')).toBeFalsy();
|
||||
expect(vm.$el.querySelector('.commit-update')).toBeFalsy();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('fires linkClicked when the link is clicked', () => {
|
||||
it('fires clickedTreeRow when the link is clicked', () => {
|
||||
const vm = createComponent({
|
||||
file: file(),
|
||||
});
|
||||
|
||||
spyOn(vm, 'linkClicked');
|
||||
spyOn(vm, 'clickedTreeRow');
|
||||
|
||||
vm.$el.click();
|
||||
|
||||
expect(vm.linkClicked).toHaveBeenCalledWith(vm.file);
|
||||
expect(vm.clickedTreeRow).toHaveBeenCalledWith(vm.file);
|
||||
});
|
||||
|
||||
describe('submodule', () => {
|
||||
|
@ -119,20 +112,4 @@ describe('RepoFile', () => {
|
|||
expect(vm.$el.querySelector('td').textContent.replace(/\s+/g, ' ')).toContain('submodule name @ 12345678');
|
||||
});
|
||||
});
|
||||
|
||||
describe('methods', () => {
|
||||
describe('linkClicked', () => {
|
||||
it('$emits fileNameClicked with file obj', () => {
|
||||
spyOn(eventHub, '$emit');
|
||||
|
||||
const vm = createComponent({
|
||||
file: file(),
|
||||
});
|
||||
|
||||
vm.linkClicked(vm.file);
|
||||
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('fileNameClicked', vm.file);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
import Vue from 'vue';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import store from '~/repo/stores';
|
||||
import repoLoadingFile from '~/repo/components/repo_loading_file.vue';
|
||||
import { resetStore } from '../helpers';
|
||||
|
||||
describe('RepoLoadingFile', () => {
|
||||
function createComponent(propsData) {
|
||||
let vm;
|
||||
|
||||
function createComponent() {
|
||||
const RepoLoadingFile = Vue.extend(repoLoadingFile);
|
||||
|
||||
return new RepoLoadingFile({
|
||||
propsData,
|
||||
store,
|
||||
}).$mount();
|
||||
}
|
||||
|
||||
|
@ -30,33 +33,30 @@ describe('RepoLoadingFile', () => {
|
|||
}
|
||||
|
||||
afterEach(() => {
|
||||
RepoStore.openedFiles = [];
|
||||
vm.$destroy();
|
||||
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
it('renders 3 columns of animated LoC', () => {
|
||||
const vm = createComponent({
|
||||
loading: {
|
||||
tree: true,
|
||||
},
|
||||
hasFiles: false,
|
||||
});
|
||||
vm = createComponent();
|
||||
const columns = [...vm.$el.querySelectorAll('td')];
|
||||
|
||||
expect(columns.length).toEqual(3);
|
||||
assertColumns(columns);
|
||||
});
|
||||
|
||||
it('renders 1 column of animated LoC if isMini', () => {
|
||||
RepoStore.openedFiles = new Array(1);
|
||||
const vm = createComponent({
|
||||
loading: {
|
||||
tree: true,
|
||||
},
|
||||
hasFiles: false,
|
||||
});
|
||||
const columns = [...vm.$el.querySelectorAll('td')];
|
||||
it('renders 1 column of animated LoC if isMini', (done) => {
|
||||
vm = createComponent();
|
||||
vm.$store.state.openFiles.push('test');
|
||||
|
||||
expect(columns.length).toEqual(1);
|
||||
assertColumns(columns);
|
||||
vm.$nextTick(() => {
|
||||
const columns = [...vm.$el.querySelectorAll('td')];
|
||||
|
||||
expect(columns.length).toEqual(1);
|
||||
assertColumns(columns);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,47 +1,45 @@
|
|||
import Vue from 'vue';
|
||||
import store from '~/repo/stores';
|
||||
import repoPrevDirectory from '~/repo/components/repo_prev_directory.vue';
|
||||
import eventHub from '~/repo/event_hub';
|
||||
import { resetStore } from '../helpers';
|
||||
|
||||
describe('RepoPrevDirectory', () => {
|
||||
function createComponent(propsData) {
|
||||
let vm;
|
||||
const parentLink = 'parent';
|
||||
function createComponent() {
|
||||
const RepoPrevDirectory = Vue.extend(repoPrevDirectory);
|
||||
|
||||
return new RepoPrevDirectory({
|
||||
propsData,
|
||||
}).$mount();
|
||||
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 prevUrl = 'prevUrl';
|
||||
const vm = createComponent({
|
||||
prevUrl,
|
||||
});
|
||||
const link = vm.$el.querySelector('a');
|
||||
|
||||
spyOn(vm, 'linkClicked');
|
||||
|
||||
expect(link.href).toMatch(`/${prevUrl}`);
|
||||
expect(link.href).toMatch(`/${parentLink}`);
|
||||
expect(link.textContent).toEqual('...');
|
||||
|
||||
link.click();
|
||||
|
||||
expect(vm.linkClicked).toHaveBeenCalledWith(prevUrl);
|
||||
});
|
||||
|
||||
describe('methods', () => {
|
||||
describe('linkClicked', () => {
|
||||
it('$emits linkclicked with prevUrl', () => {
|
||||
const prevUrl = 'prevUrl';
|
||||
const vm = createComponent({
|
||||
prevUrl,
|
||||
});
|
||||
it('clicking row triggers getTreeData', () => {
|
||||
spyOn(vm, 'getTreeData');
|
||||
|
||||
spyOn(eventHub, '$emit');
|
||||
vm.$el.querySelector('td').click();
|
||||
|
||||
vm.linkClicked(prevUrl);
|
||||
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('goToPreviousDirectoryClicked', prevUrl);
|
||||
});
|
||||
});
|
||||
expect(vm.getTreeData).toHaveBeenCalledWith({ endpoint: parentLink });
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,23 +1,37 @@
|
|||
import Vue from 'vue';
|
||||
import store from '~/repo/stores';
|
||||
import repoPreview from '~/repo/components/repo_preview.vue';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import { file, resetStore } from '../helpers';
|
||||
|
||||
describe('RepoPreview', () => {
|
||||
let vm;
|
||||
|
||||
function createComponent() {
|
||||
const f = file();
|
||||
const RepoPreview = Vue.extend(repoPreview);
|
||||
|
||||
return new RepoPreview().$mount();
|
||||
const comp = new RepoPreview({
|
||||
store,
|
||||
});
|
||||
|
||||
f.active = true;
|
||||
f.html = 'test';
|
||||
|
||||
comp.$store.state.openFiles.push(f);
|
||||
|
||||
return comp.$mount();
|
||||
}
|
||||
|
||||
it('renders a div with the activeFile html', () => {
|
||||
const activeFile = {
|
||||
html: '<p class="file-content">html</p>',
|
||||
};
|
||||
RepoStore.activeFile = activeFile;
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
|
||||
const vm = createComponent();
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
it('renders a div with the activeFile html', () => {
|
||||
vm = createComponent();
|
||||
|
||||
expect(vm.$el.tagName).toEqual('DIV');
|
||||
expect(vm.$el.innerHTML).toContain(activeFile.html);
|
||||
expect(vm.$el.innerHTML).toContain('test');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,32 +1,31 @@
|
|||
import Vue from 'vue';
|
||||
import Helper from '~/repo/helpers/repo_helper';
|
||||
import RepoService from '~/repo/services/repo_service';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import store from '~/repo/stores';
|
||||
import repoSidebar from '~/repo/components/repo_sidebar.vue';
|
||||
import { file } from '../mock_data';
|
||||
import { file, resetStore } from '../helpers';
|
||||
|
||||
describe('RepoSidebar', () => {
|
||||
let vm;
|
||||
|
||||
function createComponent() {
|
||||
beforeEach(() => {
|
||||
const RepoSidebar = Vue.extend(repoSidebar);
|
||||
|
||||
return new RepoSidebar().$mount();
|
||||
}
|
||||
vm = new RepoSidebar({
|
||||
store,
|
||||
});
|
||||
|
||||
vm.$store.state.isRoot = true;
|
||||
vm.$store.state.tree.push(file());
|
||||
|
||||
vm.$mount();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
|
||||
RepoStore.files = [];
|
||||
RepoStore.openedFiles = [];
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
it('renders a sidebar', () => {
|
||||
RepoStore.files = [file()];
|
||||
RepoStore.openedFiles = [];
|
||||
RepoStore.isRoot = true;
|
||||
|
||||
vm = createComponent();
|
||||
const thead = vm.$el.querySelector('thead');
|
||||
const tbody = vm.$el.querySelector('tbody');
|
||||
|
||||
|
@ -41,139 +40,36 @@ describe('RepoSidebar', () => {
|
|||
expect(tbody.querySelector('.file')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('does not render a thead, renders repo-file-options and sets sidebar-mini class if isMini', () => {
|
||||
RepoStore.openedFiles = [{
|
||||
id: 0,
|
||||
}];
|
||||
vm = createComponent();
|
||||
it('does not render a thead, renders repo-file-options and sets sidebar-mini class if isMini', (done) => {
|
||||
vm.$store.state.openFiles.push(vm.$store.state.tree[0]);
|
||||
|
||||
expect(vm.$el.classList.contains('sidebar-mini')).toBeTruthy();
|
||||
expect(vm.$el.querySelector('thead')).toBeTruthy();
|
||||
expect(vm.$el.querySelector('thead .repo-file-options')).toBeTruthy();
|
||||
});
|
||||
Vue.nextTick(() => {
|
||||
expect(vm.$el.classList.contains('sidebar-mini')).toBeTruthy();
|
||||
expect(vm.$el.querySelector('thead')).toBeTruthy();
|
||||
expect(vm.$el.querySelector('thead .repo-file-options')).toBeTruthy();
|
||||
|
||||
it('renders 5 loading files if tree is loading and not hasFiles', () => {
|
||||
RepoStore.loading.tree = true;
|
||||
RepoStore.files = [];
|
||||
vm = createComponent();
|
||||
|
||||
expect(vm.$el.querySelectorAll('tbody .loading-file').length).toEqual(5);
|
||||
});
|
||||
|
||||
it('renders a prev directory if is not root', () => {
|
||||
RepoStore.files = [file()];
|
||||
RepoStore.isRoot = false;
|
||||
RepoStore.loading.tree = false;
|
||||
vm = createComponent();
|
||||
|
||||
expect(vm.$el.querySelector('tbody .prev-directory')).toBeTruthy();
|
||||
});
|
||||
|
||||
describe('flattendFiles', () => {
|
||||
it('returns a flattend array of files', () => {
|
||||
const f = file();
|
||||
f.files.push(file('testing 123'));
|
||||
const files = [f, file()];
|
||||
vm = createComponent();
|
||||
vm.files = files;
|
||||
|
||||
expect(vm.flattendFiles.length).toBe(3);
|
||||
expect(vm.flattendFiles[1].name).toBe('testing 123');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('methods', () => {
|
||||
describe('fileClicked', () => {
|
||||
it('should fetch data for new file', () => {
|
||||
spyOn(Helper, 'getContent').and.callThrough();
|
||||
RepoStore.files = [file()];
|
||||
RepoStore.isRoot = true;
|
||||
vm = createComponent();
|
||||
it('renders 5 loading files if tree is loading', (done) => {
|
||||
vm.$store.state.tree = [];
|
||||
vm.$store.state.loading = true;
|
||||
|
||||
vm.fileClicked(RepoStore.files[0]);
|
||||
Vue.nextTick(() => {
|
||||
expect(vm.$el.querySelectorAll('tbody .loading-file').length).toEqual(5);
|
||||
|
||||
expect(Helper.getContent).toHaveBeenCalledWith(RepoStore.files[0]);
|
||||
});
|
||||
|
||||
it('should not fetch data for already opened files', () => {
|
||||
const f = file();
|
||||
spyOn(Helper, 'getFileFromPath').and.returnValue(f);
|
||||
spyOn(RepoStore, 'setActiveFiles');
|
||||
vm = createComponent();
|
||||
vm.fileClicked(f);
|
||||
|
||||
expect(RepoStore.setActiveFiles).toHaveBeenCalledWith(f);
|
||||
});
|
||||
|
||||
it('should hide files in directory if already open', () => {
|
||||
spyOn(Helper, 'setDirectoryToClosed').and.callThrough();
|
||||
const f = file();
|
||||
f.opened = true;
|
||||
f.type = 'tree';
|
||||
RepoStore.files = [f];
|
||||
vm = createComponent();
|
||||
|
||||
vm.fileClicked(RepoStore.files[0]);
|
||||
|
||||
expect(Helper.setDirectoryToClosed).toHaveBeenCalledWith(RepoStore.files[0]);
|
||||
});
|
||||
|
||||
describe('submodule', () => {
|
||||
it('opens submodule project URL', () => {
|
||||
spyOn(gl.utils, 'visitUrl');
|
||||
|
||||
const f = file();
|
||||
f.type = 'submodule';
|
||||
|
||||
vm = createComponent();
|
||||
|
||||
vm.fileClicked(f);
|
||||
|
||||
expect(gl.utils.visitUrl).toHaveBeenCalledWith('url');
|
||||
});
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
describe('goToPreviousDirectoryClicked', () => {
|
||||
it('should hide files in directory if already open', () => {
|
||||
const prevUrl = 'foo/bar';
|
||||
vm = createComponent();
|
||||
it('renders a prev directory if is not root', (done) => {
|
||||
vm.$store.state.isRoot = false;
|
||||
|
||||
vm.goToPreviousDirectoryClicked(prevUrl);
|
||||
Vue.nextTick(() => {
|
||||
expect(vm.$el.querySelector('tbody .prev-directory')).toBeTruthy();
|
||||
|
||||
expect(RepoService.url).toEqual(prevUrl);
|
||||
});
|
||||
});
|
||||
|
||||
describe('back button', () => {
|
||||
beforeEach(() => {
|
||||
const f = file();
|
||||
const file2 = Object.assign({}, file());
|
||||
file2.url = 'test';
|
||||
RepoStore.files = [f, file2];
|
||||
RepoStore.openedFiles = [];
|
||||
RepoStore.isRoot = true;
|
||||
|
||||
vm = createComponent();
|
||||
});
|
||||
|
||||
it('render previous file when using back button', () => {
|
||||
spyOn(Helper, 'getContent').and.callThrough();
|
||||
|
||||
vm.fileClicked(RepoStore.files[1]);
|
||||
expect(Helper.getContent).toHaveBeenCalledWith(RepoStore.files[1]);
|
||||
|
||||
history.pushState({
|
||||
key: Math.random(),
|
||||
}, '', RepoStore.files[1].url);
|
||||
const popEvent = document.createEvent('Event');
|
||||
popEvent.initEvent('popstate', true, true);
|
||||
window.dispatchEvent(popEvent);
|
||||
|
||||
expect(Helper.getContent.calls.mostRecent().args[0].url).toContain(RepoStore.files[1].url);
|
||||
|
||||
window.history.pushState({}, null, '/');
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
import Vue from 'vue';
|
||||
import store from '~/repo/stores';
|
||||
import repo from '~/repo/components/repo.vue';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import Service from '~/repo/services/repo_service';
|
||||
import eventHub from '~/repo/event_hub';
|
||||
import createComponent from '../../helpers/vue_mount_component_helper';
|
||||
import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
|
||||
import { file, resetStore } from '../helpers';
|
||||
|
||||
describe('repo component', () => {
|
||||
let vm;
|
||||
|
@ -11,86 +10,26 @@ describe('repo component', () => {
|
|||
beforeEach(() => {
|
||||
const Component = Vue.extend(repo);
|
||||
|
||||
RepoStore.currentBranch = 'master';
|
||||
|
||||
vm = createComponent(Component);
|
||||
vm = createComponentWithStore(Component, store).$mount();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
|
||||
RepoStore.currentBranch = '';
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
describe('createNewBranch', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(history, 'pushState');
|
||||
});
|
||||
it('does not render panel right when no files open', () => {
|
||||
expect(vm.$el.querySelector('.panel-right')).toBeNull();
|
||||
});
|
||||
|
||||
describe('success', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(Service, 'createBranch').and.returnValue(Promise.resolve({
|
||||
data: {
|
||||
name: 'test',
|
||||
},
|
||||
}));
|
||||
});
|
||||
it('renders panel right when files are open', (done) => {
|
||||
vm.$store.state.tree.push(file());
|
||||
|
||||
it('calls createBranch with branchName', () => {
|
||||
eventHub.$emit('createNewBranch', 'test');
|
||||
Vue.nextTick(() => {
|
||||
expect(vm.$el.querySelector('.panel-right')).toBeNull();
|
||||
|
||||
expect(Service.createBranch).toHaveBeenCalledWith({
|
||||
branch: 'test',
|
||||
ref: RepoStore.currentBranch,
|
||||
});
|
||||
});
|
||||
|
||||
it('pushes new history state', (done) => {
|
||||
RepoStore.currentBranch = 'master';
|
||||
|
||||
spyOn(vm, 'getCurrentLocation').and.returnValue('http://test.com/master');
|
||||
|
||||
eventHub.$emit('createNewBranch', 'test');
|
||||
|
||||
setTimeout(() => {
|
||||
expect(history.pushState).toHaveBeenCalledWith(jasmine.anything(), '', 'http://test.com/test');
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('updates stores currentBranch', (done) => {
|
||||
eventHub.$emit('createNewBranch', 'test');
|
||||
|
||||
setTimeout(() => {
|
||||
expect(RepoStore.currentBranch).toBe('test');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('failure', () => {
|
||||
beforeEach(() => {
|
||||
spyOn(Service, 'createBranch').and.returnValue(Promise.reject({
|
||||
response: {
|
||||
data: {
|
||||
message: 'test',
|
||||
},
|
||||
},
|
||||
}));
|
||||
});
|
||||
|
||||
it('emits createNewBranchError event', (done) => {
|
||||
spyOn(eventHub, '$emit').and.callThrough();
|
||||
|
||||
eventHub.$emit('createNewBranch', 'test');
|
||||
|
||||
setTimeout(() => {
|
||||
expect(eventHub.$emit).toHaveBeenCalledWith('createNewBranchError', 'test');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,46 +1,61 @@
|
|||
import Vue from 'vue';
|
||||
import store from '~/repo/stores';
|
||||
import repoTab from '~/repo/components/repo_tab.vue';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import { file, resetStore } from '../helpers';
|
||||
|
||||
describe('RepoTab', () => {
|
||||
function createComponent(propsData) {
|
||||
const RepoTab = Vue.extend(repoTab);
|
||||
|
||||
return new RepoTab({
|
||||
store,
|
||||
propsData,
|
||||
}).$mount();
|
||||
}
|
||||
|
||||
it('renders a close link and a name link', () => {
|
||||
const tab = {
|
||||
url: 'url',
|
||||
name: 'name',
|
||||
};
|
||||
const vm = createComponent({
|
||||
tab,
|
||||
});
|
||||
const close = vm.$el.querySelector('.close-btn');
|
||||
const name = vm.$el.querySelector(`a[title="${tab.url}"]`);
|
||||
afterEach(() => {
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
spyOn(vm, 'closeTab');
|
||||
spyOn(vm, 'tabClicked');
|
||||
it('renders a close link and a name link', () => {
|
||||
const vm = createComponent({
|
||||
tab: file(),
|
||||
});
|
||||
vm.$store.state.openFiles.push(vm.tab);
|
||||
const close = vm.$el.querySelector('.close-btn');
|
||||
const name = vm.$el.querySelector(`a[title="${vm.tab.url}"]`);
|
||||
|
||||
expect(close.querySelector('.fa-times')).toBeTruthy();
|
||||
expect(name.textContent.trim()).toEqual(tab.name);
|
||||
expect(name.textContent.trim()).toEqual(vm.tab.name);
|
||||
});
|
||||
|
||||
close.click();
|
||||
name.click();
|
||||
it('calls setFileActive when clicking tab', () => {
|
||||
const vm = createComponent({
|
||||
tab: file(),
|
||||
});
|
||||
|
||||
expect(vm.closeTab).toHaveBeenCalledWith(tab);
|
||||
expect(vm.tabClicked).toHaveBeenCalledWith(tab);
|
||||
spyOn(vm, 'setFileActive');
|
||||
|
||||
vm.$el.click();
|
||||
|
||||
expect(vm.setFileActive).toHaveBeenCalledWith(vm.tab);
|
||||
});
|
||||
|
||||
it('calls closeFile when clicking close button', () => {
|
||||
const vm = createComponent({
|
||||
tab: file(),
|
||||
});
|
||||
|
||||
spyOn(vm, 'closeFile');
|
||||
|
||||
vm.$el.querySelector('.close-btn').click();
|
||||
|
||||
expect(vm.closeFile).toHaveBeenCalledWith({ file: vm.tab });
|
||||
});
|
||||
|
||||
it('renders an fa-circle icon if tab is changed', () => {
|
||||
const tab = {
|
||||
url: 'url',
|
||||
name: 'name',
|
||||
changed: true,
|
||||
};
|
||||
const tab = file();
|
||||
tab.changed = true;
|
||||
const vm = createComponent({
|
||||
tab,
|
||||
});
|
||||
|
@ -50,38 +65,41 @@ describe('RepoTab', () => {
|
|||
|
||||
describe('methods', () => {
|
||||
describe('closeTab', () => {
|
||||
it('returns undefined and does not $emit if file is changed', () => {
|
||||
const tab = {
|
||||
url: 'url',
|
||||
name: 'name',
|
||||
changed: true,
|
||||
};
|
||||
it('does not close tab if is changed', (done) => {
|
||||
const tab = file();
|
||||
tab.changed = true;
|
||||
tab.opened = true;
|
||||
const vm = createComponent({
|
||||
tab,
|
||||
});
|
||||
|
||||
spyOn(RepoStore, 'removeFromOpenedFiles');
|
||||
vm.$store.state.openFiles.push(tab);
|
||||
vm.$store.dispatch('setFileActive', tab);
|
||||
|
||||
vm.$el.querySelector('.close-btn').click();
|
||||
|
||||
expect(RepoStore.removeFromOpenedFiles).not.toHaveBeenCalled();
|
||||
vm.$nextTick(() => {
|
||||
expect(tab.opened).toBeTruthy();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('$emits tabclosed event with file obj', () => {
|
||||
const tab = {
|
||||
url: 'url',
|
||||
name: 'name',
|
||||
changed: false,
|
||||
};
|
||||
it('closes tab when clicking close btn', (done) => {
|
||||
const tab = file('lose');
|
||||
tab.opened = true;
|
||||
const vm = createComponent({
|
||||
tab,
|
||||
});
|
||||
|
||||
spyOn(RepoStore, 'removeFromOpenedFiles');
|
||||
vm.$store.state.openFiles.push(tab);
|
||||
vm.$store.dispatch('setFileActive', tab);
|
||||
|
||||
vm.$el.querySelector('.close-btn').click();
|
||||
|
||||
expect(RepoStore.removeFromOpenedFiles).toHaveBeenCalledWith(tab);
|
||||
vm.$nextTick(() => {
|
||||
expect(tab.opened).toBeFalsy();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -1,35 +1,37 @@
|
|||
import Vue from 'vue';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import store from '~/repo/stores';
|
||||
import repoTabs from '~/repo/components/repo_tabs.vue';
|
||||
import { file, resetStore } from '../helpers';
|
||||
|
||||
describe('RepoTabs', () => {
|
||||
const openedFiles = [{
|
||||
id: 0,
|
||||
active: true,
|
||||
}, {
|
||||
id: 1,
|
||||
}];
|
||||
const openedFiles = [file(), file()];
|
||||
|
||||
function createComponent() {
|
||||
const RepoTabs = Vue.extend(repoTabs);
|
||||
|
||||
return new RepoTabs().$mount();
|
||||
return new RepoTabs({
|
||||
store,
|
||||
}).$mount();
|
||||
}
|
||||
|
||||
afterEach(() => {
|
||||
RepoStore.openedFiles = [];
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
it('renders a list of tabs', () => {
|
||||
RepoStore.openedFiles = openedFiles;
|
||||
|
||||
it('renders a list of tabs', (done) => {
|
||||
const vm = createComponent();
|
||||
const tabs = [...vm.$el.querySelectorAll(':scope > li')];
|
||||
openedFiles[0].active = true;
|
||||
vm.$store.state.openFiles = openedFiles;
|
||||
|
||||
expect(vm.$el.id).toEqual('tabs');
|
||||
expect(tabs.length).toEqual(3);
|
||||
expect(tabs[0].classList.contains('active')).toBeTruthy();
|
||||
expect(tabs[1].classList.contains('active')).toBeFalsy();
|
||||
expect(tabs[2].classList.contains('tabs-divider')).toBeTruthy();
|
||||
vm.$nextTick(() => {
|
||||
const tabs = [...vm.$el.querySelectorAll(':scope > li')];
|
||||
|
||||
expect(tabs.length).toEqual(3);
|
||||
expect(tabs[0].classList.contains('active')).toBeTruthy();
|
||||
expect(tabs[1].classList.contains('active')).toBeFalsy();
|
||||
expect(tabs[2].classList.contains('tabs-divider')).toBeTruthy();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
20
spec/javascripts/repo/helpers.js
Normal file
20
spec/javascripts/repo/helpers.js
Normal file
|
@ -0,0 +1,20 @@
|
|||
import { decorateData } from '~/repo/stores/utils';
|
||||
import state from '~/repo/stores/state';
|
||||
|
||||
export const resetStore = (store) => {
|
||||
store.replaceState(state());
|
||||
};
|
||||
|
||||
export const file = (name = 'name', id = name, type = '') => decorateData({
|
||||
id,
|
||||
type,
|
||||
icon: 'icon',
|
||||
url: 'url',
|
||||
name,
|
||||
path: name,
|
||||
last_commit: {
|
||||
id: '123',
|
||||
message: 'test',
|
||||
committed_date: new Date().toISOString(),
|
||||
},
|
||||
});
|
|
@ -1,14 +0,0 @@
|
|||
import RepoHelper from '~/repo/helpers/repo_helper';
|
||||
|
||||
// eslint-disable-next-line import/prefer-default-export
|
||||
export const file = (name = 'name', id = name) => RepoHelper.serializeRepoEntity('blob', {
|
||||
id,
|
||||
icon: 'icon',
|
||||
url: 'url',
|
||||
name,
|
||||
last_commit: {
|
||||
id: '123',
|
||||
message: 'test',
|
||||
committed_date: new Date().toISOString(),
|
||||
},
|
||||
});
|
|
@ -1,171 +0,0 @@
|
|||
import axios from 'axios';
|
||||
import RepoService from '~/repo/services/repo_service';
|
||||
import RepoStore from '~/repo/stores/repo_store';
|
||||
import Api from '~/api';
|
||||
|
||||
describe('RepoService', () => {
|
||||
it('has default json format param', () => {
|
||||
expect(RepoService.options.params.format).toBe('json');
|
||||
});
|
||||
|
||||
describe('buildParams', () => {
|
||||
let newParams;
|
||||
const url = 'url';
|
||||
|
||||
beforeEach(() => {
|
||||
newParams = {};
|
||||
|
||||
spyOn(Object, 'assign').and.returnValue(newParams);
|
||||
});
|
||||
|
||||
it('clones params', () => {
|
||||
const params = RepoService.buildParams(url);
|
||||
|
||||
expect(Object.assign).toHaveBeenCalledWith({}, RepoService.options.params);
|
||||
|
||||
expect(params).toBe(newParams);
|
||||
});
|
||||
|
||||
it('sets and returns viewer params to richif urlIsRichBlob is true', () => {
|
||||
spyOn(RepoService, 'urlIsRichBlob').and.returnValue(true);
|
||||
|
||||
const params = RepoService.buildParams(url);
|
||||
|
||||
expect(params.viewer).toEqual('rich');
|
||||
});
|
||||
|
||||
it('returns params urlIsRichBlob is false', () => {
|
||||
spyOn(RepoService, 'urlIsRichBlob').and.returnValue(false);
|
||||
|
||||
const params = RepoService.buildParams(url);
|
||||
|
||||
expect(params.viewer).toBeUndefined();
|
||||
});
|
||||
|
||||
it('calls urlIsRichBlob with the objects url prop if no url arg is provided', () => {
|
||||
spyOn(RepoService, 'urlIsRichBlob');
|
||||
RepoService.url = url;
|
||||
|
||||
RepoService.buildParams();
|
||||
|
||||
expect(RepoService.urlIsRichBlob).toHaveBeenCalledWith(url);
|
||||
});
|
||||
});
|
||||
|
||||
describe('urlIsRichBlob', () => {
|
||||
it('returns true for md extension', () => {
|
||||
const isRichBlob = RepoService.urlIsRichBlob('url.md');
|
||||
|
||||
expect(isRichBlob).toBeTruthy();
|
||||
});
|
||||
|
||||
it('returns false for js extension', () => {
|
||||
const isRichBlob = RepoService.urlIsRichBlob('url.js');
|
||||
|
||||
expect(isRichBlob).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe('getContent', () => {
|
||||
const params = {};
|
||||
const url = 'url';
|
||||
const requestPromise = Promise.resolve();
|
||||
|
||||
beforeEach(() => {
|
||||
spyOn(RepoService, 'buildParams').and.returnValue(params);
|
||||
spyOn(axios, 'get').and.returnValue(requestPromise);
|
||||
});
|
||||
|
||||
it('calls buildParams and axios.get', () => {
|
||||
const request = RepoService.getContent(url);
|
||||
|
||||
expect(RepoService.buildParams).toHaveBeenCalledWith(url);
|
||||
expect(axios.get).toHaveBeenCalledWith(url, {
|
||||
params,
|
||||
});
|
||||
expect(request).toBe(requestPromise);
|
||||
});
|
||||
|
||||
it('uses object url prop if no url arg is provided', () => {
|
||||
RepoService.url = url;
|
||||
|
||||
RepoService.getContent();
|
||||
|
||||
expect(axios.get).toHaveBeenCalledWith(url, {
|
||||
params,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('getBase64Content', () => {
|
||||
const url = 'url';
|
||||
const response = { data: 'data' };
|
||||
|
||||
beforeEach(() => {
|
||||
spyOn(RepoService, 'bufferToBase64');
|
||||
spyOn(axios, 'get').and.returnValue(Promise.resolve(response));
|
||||
});
|
||||
|
||||
it('calls axios.get and bufferToBase64 on completion', (done) => {
|
||||
const request = RepoService.getBase64Content(url);
|
||||
|
||||
expect(axios.get).toHaveBeenCalledWith(url, {
|
||||
responseType: 'arraybuffer',
|
||||
});
|
||||
expect(request).toEqual(jasmine.any(Promise));
|
||||
|
||||
request.then(() => {
|
||||
expect(RepoService.bufferToBase64).toHaveBeenCalledWith(response.data);
|
||||
done();
|
||||
}).catch(done.fail);
|
||||
});
|
||||
});
|
||||
|
||||
describe('commitFiles', () => {
|
||||
it('calls commitMultiple and .then commitFlash', (done) => {
|
||||
const projectId = 'projectId';
|
||||
const payload = {};
|
||||
RepoStore.projectId = projectId;
|
||||
|
||||
spyOn(Api, 'commitMultiple').and.returnValue(Promise.resolve());
|
||||
spyOn(RepoService, 'commitFlash');
|
||||
|
||||
const apiPromise = RepoService.commitFiles(payload);
|
||||
|
||||
expect(Api.commitMultiple).toHaveBeenCalledWith(projectId, payload);
|
||||
|
||||
apiPromise.then(() => {
|
||||
expect(RepoService.commitFlash).toHaveBeenCalled();
|
||||
done();
|
||||
}).catch(done.fail);
|
||||
});
|
||||
});
|
||||
|
||||
describe('commitFlash', () => {
|
||||
it('calls Flash with data.message', () => {
|
||||
const data = {
|
||||
message: 'message',
|
||||
};
|
||||
spyOn(window, 'Flash');
|
||||
|
||||
RepoService.commitFlash(data);
|
||||
|
||||
expect(window.Flash).toHaveBeenCalledWith(data.message);
|
||||
});
|
||||
|
||||
it('calls Flash with success string if short_id and stats', () => {
|
||||
const data = {
|
||||
short_id: 'short_id',
|
||||
stats: {
|
||||
additions: '4',
|
||||
deletions: '5',
|
||||
},
|
||||
};
|
||||
spyOn(window, 'Flash');
|
||||
|
||||
RepoService.commitFlash(data);
|
||||
|
||||
expect(window.Flash).toHaveBeenCalledWith(`Your changes have been committed. Commit ${data.short_id} with ${data.stats.additions} additions, ${data.stats.deletions} deletions.`, 'notice');
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue