Commit 5c483fd8 authored by Phil Hughes's avatar Phil Hughes

specs

parent 093e43a0
import Vue from 'vue'; import Vue from 'vue';
import VueResource from 'vue-resource'; import VueResource from 'vue-resource';
import axios from '~/lib/utils/axios_utils';
import Api from '~/api'; import Api from '~/api';
Vue.use(VueResource); Vue.use(VueResource);
...@@ -69,11 +70,7 @@ export default { ...@@ -69,11 +70,7 @@ export default {
}, },
getFiles(projectUrl, branchId) { getFiles(projectUrl, branchId) {
const url = `${projectUrl}/files/${branchId}`; const url = `${projectUrl}/files/${branchId}`;
return Vue.http.get(url, { return axios.get(url, { params: { format: 'json' } });
params: {
format: 'json',
},
});
}, },
lastCommitPipelines({ getters }) { lastCommitPipelines({ getters }) {
const commitSha = getters.lastCommit.id; const commitSha = getters.lastCommit.id;
......
...@@ -70,8 +70,7 @@ export const getFiles = ({ state, commit, dispatch }, { projectId, branchId } = ...@@ -70,8 +70,7 @@ export const getFiles = ({ state, commit, dispatch }, { projectId, branchId } =
service service
.getFiles(selectedProject.web_url, branchId) .getFiles(selectedProject.web_url, branchId)
.then(res => res.json()) .then(({ data }) => {
.then(data => {
const worker = new FilesDecoratorWorker(); const worker = new FilesDecoratorWorker();
worker.addEventListener('message', e => { worker.addEventListener('message', e => {
const { entries, treeList } = e.data; const { entries, treeList } = e.data;
......
...@@ -362,4 +362,29 @@ describe('Api', () => { ...@@ -362,4 +362,29 @@ describe('Api', () => {
.catch(done.fail); .catch(done.fail);
}); });
}); });
describe('createBranch', () => {
it('creates new branch', done => {
const ref = 'master';
const branch = 'new-branch-name';
const dummyProjectPath = 'gitlab-org/gitlab-ce';
const expectedUrl = `${dummyUrlRoot}/api/${dummyApiVersion}/projects/${encodeURIComponent(
dummyProjectPath,
)}/repository/branches`;
spyOn(axios, 'post').and.callThrough();
mock.onPost(expectedUrl).replyOnce(200, {
name: branch,
});
Api.createBranch(dummyProjectPath, { ref, branch })
.then(({ data }) => {
expect(data.name).toBe(branch);
expect(axios.post).toHaveBeenCalledWith(expectedUrl, { ref, branch });
})
.then(done)
.catch(done.fail);
});
});
}); });
import Vue from 'vue';
import store from '~/ide/stores';
import ErrorMessage from '~/ide/components/error_message.vue';
import { createComponentWithStore } from '../../helpers/vue_mount_component_helper';
import { resetStore } from '../helpers';
describe('IDE error message component', () => {
const Component = Vue.extend(ErrorMessage);
let vm;
beforeEach(() => {
vm = createComponentWithStore(Component, store, {
message: {
text: 'error message',
action: null,
actionText: null,
},
}).$mount();
});
afterEach(() => {
vm.$destroy();
resetStore(vm.$store);
});
it('renders error message', () => {
expect(vm.$el.textContent).toContain('error message');
});
it('clears error message on click', () => {
spyOn(vm, 'setErrorMessage');
vm.$el.click();
expect(vm.setErrorMessage).toHaveBeenCalledWith(null);
});
describe('with action', () => {
beforeEach(done => {
vm.message.action = 'testAction';
vm.message.actionText = 'test action';
vm.message.actionPayload = 'testActionPayload';
spyOn(vm.$store, 'dispatch').and.returnValue(Promise.resolve());
vm.$nextTick(done);
});
it('renders action button', () => {
expect(vm.$el.querySelector('.flash-action')).not.toBe(null);
expect(vm.$el.textContent).toContain('test action');
});
it('does not clear error message on click', () => {
spyOn(vm, 'setErrorMessage');
vm.$el.click();
expect(vm.setErrorMessage).not.toHaveBeenCalled();
});
it('dispatches action', done => {
vm.$el.querySelector('.flash-action').click();
vm.$nextTick(() => {
expect(vm.$store.dispatch).toHaveBeenCalledWith('testAction', 'testActionPayload');
done();
});
});
it('does not dispatch action when already loading', () => {
vm.isLoading = true;
vm.$el.querySelector('.flash-action').click();
expect(vm.$store.dispatch).not.toHaveBeenCalledWith();
});
it('resets isLoading after click', done => {
vm.$el.querySelector('.flash-action').click();
expect(vm.isLoading).toBe(true);
vm.$nextTick(() => {
expect(vm.isLoading).toBe(false);
done();
});
});
it('shows loading icon when isLoading is true', done => {
expect(vm.$el.querySelector('.loading-container').style.display).not.toBe('');
vm.isLoading = true;
vm.$nextTick(() => {
expect(vm.$el.querySelector('.loading-container').style.display).toBe('');
done();
});
});
});
});
...@@ -114,4 +114,18 @@ describe('ide component', () => { ...@@ -114,4 +114,18 @@ describe('ide component', () => {
expect(vm.mousetrapStopCallback(null, document.querySelector('.inputarea'), 't')).toBe(true); expect(vm.mousetrapStopCallback(null, document.querySelector('.inputarea'), 't')).toBe(true);
}); });
}); });
it('shows error message when set', done => {
expect(vm.$el.querySelector('.flash-container')).toBe(null);
vm.$store.state.errorMessage = {
text: 'error',
};
vm.$nextTick(() => {
expect(vm.$el.querySelector('.flash-container')).not.toBe(null);
done();
});
});
}); });
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import { import {
refreshLastCommitData, refreshLastCommitData,
showBranchNotFoundError, showBranchNotFoundError,
createNewBranchFromDefault, createNewBranchFromDefault,
getBranchData,
} from '~/ide/stores/actions'; } from '~/ide/stores/actions';
import store from '~/ide/stores'; import store from '~/ide/stores';
import projectActions from '~/ide/stores/actions/project'; import projectActions from '~/ide/stores/actions/project';
...@@ -11,11 +14,19 @@ import { resetStore } from '../../helpers'; ...@@ -11,11 +14,19 @@ import { resetStore } from '../../helpers';
import testAction from '../../../helpers/vuex_action_helper'; import testAction from '../../../helpers/vuex_action_helper';
describe('IDE store project actions', () => { describe('IDE store project actions', () => {
let mock;
beforeEach(() => { beforeEach(() => {
store.state.projects['abc/def'] = {}; mock = new MockAdapter(axios);
store.state.projects['abc/def'] = {
branches: {},
};
}); });
afterEach(() => { afterEach(() => {
mock.restore();
resetStore(store); resetStore(store);
}); });
...@@ -164,4 +175,34 @@ describe('IDE store project actions', () => { ...@@ -164,4 +175,34 @@ describe('IDE store project actions', () => {
}); });
}); });
}); });
describe('getBranchData', () => {
describe('error', () => {
it('dispatches branch not found action when response is 404', done => {
const dispatch = jasmine.createSpy('dispatchSpy');
mock.onGet(/(.*)/).replyOnce(404);
getBranchData(
{
commit() {},
dispatch,
state: store.state,
},
{
projectId: 'abc/def',
branchId: 'master-testing',
},
)
.then(done.fail)
.catch(() => {
expect(dispatch.calls.argsFor(0)).toEqual([
'showBranchNotFoundError',
'master-testing',
]);
done();
});
});
});
});
}); });
import MockAdapter from 'axios-mock-adapter';
import Vue from 'vue'; import Vue from 'vue';
import testAction from 'spec/helpers/vuex_action_helper'; import testAction from 'spec/helpers/vuex_action_helper';
import { showTreeEntry } from '~/ide/stores/actions/tree'; import { showTreeEntry, getFiles } from '~/ide/stores/actions/tree';
import * as types from '~/ide/stores/mutation_types'; import * as types from '~/ide/stores/mutation_types';
import axios from '~/lib/utils/axios_utils';
import store from '~/ide/stores'; import store from '~/ide/stores';
import service from '~/ide/services'; import service from '~/ide/services';
import router from '~/ide/ide_router'; import router from '~/ide/ide_router';
...@@ -9,6 +11,7 @@ import { file, resetStore, createEntriesFromPaths } from '../../helpers'; ...@@ -9,6 +11,7 @@ import { file, resetStore, createEntriesFromPaths } from '../../helpers';
describe('Multi-file store tree actions', () => { describe('Multi-file store tree actions', () => {
let projectTree; let projectTree;
let mock;
const basicCallParameters = { const basicCallParameters = {
endpoint: 'rootEndpoint', endpoint: 'rootEndpoint',
...@@ -20,6 +23,8 @@ describe('Multi-file store tree actions', () => { ...@@ -20,6 +23,8 @@ describe('Multi-file store tree actions', () => {
beforeEach(() => { beforeEach(() => {
spyOn(router, 'push'); spyOn(router, 'push');
mock = new MockAdapter(axios);
store.state.currentProjectId = 'abcproject'; store.state.currentProjectId = 'abcproject';
store.state.currentBranchId = 'master'; store.state.currentBranchId = 'master';
store.state.projects.abcproject = { store.state.projects.abcproject = {
...@@ -33,49 +38,85 @@ describe('Multi-file store tree actions', () => { ...@@ -33,49 +38,85 @@ describe('Multi-file store tree actions', () => {
}); });
afterEach(() => { afterEach(() => {
mock.restore();
resetStore(store); resetStore(store);
}); });
describe('getFiles', () => { describe('getFiles', () => {
beforeEach(() => { describe('success', () => {
spyOn(service, 'getFiles').and.returnValue( beforeEach(() => {
Promise.resolve({ spyOn(service, 'getFiles').and.callThrough();
json: () =>
Promise.resolve([ mock
'file.txt', .onGet(/(.*)/)
'folder/fileinfolder.js', .replyOnce(200, [
'folder/subfolder/fileinsubfolder.js', 'file.txt',
]), 'folder/fileinfolder.js',
}), 'folder/subfolder/fileinsubfolder.js',
); ]);
});
it('calls service getFiles', done => {
store
.dispatch('getFiles', basicCallParameters)
.then(() => {
expect(service.getFiles).toHaveBeenCalledWith('', 'master');
done();
})
.catch(done.fail);
});
it('adds data into tree', done => {
store
.dispatch('getFiles', basicCallParameters)
.then(() => {
projectTree = store.state.trees['abcproject/master'];
expect(projectTree.tree.length).toBe(2);
expect(projectTree.tree[0].type).toBe('tree');
expect(projectTree.tree[0].tree[1].name).toBe('fileinfolder.js');
expect(projectTree.tree[1].type).toBe('blob');
expect(projectTree.tree[0].tree[0].tree[0].type).toBe('blob');
expect(projectTree.tree[0].tree[0].tree[0].name).toBe('fileinsubfolder.js');
done();
})
.catch(done.fail);
});
}); });
it('calls service getFiles', done => { describe('error', () => {
store it('dispatches branch not found actions when response is 404', done => {
.dispatch('getFiles', basicCallParameters) const dispatch = jasmine.createSpy('dispatchSpy');
.then(() => {
expect(service.getFiles).toHaveBeenCalledWith('', 'master');
done(); store.state.projects = {
}) 'abc/def': {
.catch(done.fail); web_url: `${gl.TEST_HOST}/files`,
}); },
};
it('adds data into tree', done => { mock.onGet(/(.*)/).replyOnce(404);
store
.dispatch('getFiles', basicCallParameters)
.then(() => {
projectTree = store.state.trees['abcproject/master'];
expect(projectTree.tree.length).toBe(2);
expect(projectTree.tree[0].type).toBe('tree');
expect(projectTree.tree[0].tree[1].name).toBe('fileinfolder.js');
expect(projectTree.tree[1].type).toBe('blob');
expect(projectTree.tree[0].tree[0].tree[0].type).toBe('blob');
expect(projectTree.tree[0].tree[0].tree[0].name).toBe('fileinsubfolder.js');
done(); getFiles(
}) {
.catch(done.fail); commit() {},
dispatch,
state: store.state,
},
{
projectId: 'abc/def',
branchId: 'master-testing',
},
)
.then(done.fail)
.catch(() => {
expect(dispatch.calls.argsFor(0)).toEqual([
'showBranchNotFoundError',
'master-testing',
]);
done();
});
});
}); });
}); });
...@@ -122,9 +163,7 @@ describe('Multi-file store tree actions', () => { ...@@ -122,9 +163,7 @@ describe('Multi-file store tree actions', () => {
{ type: types.SET_TREE_OPEN, payload: 'grandparent/parent' }, { type: types.SET_TREE_OPEN, payload: 'grandparent/parent' },
{ type: types.SET_TREE_OPEN, payload: 'grandparent' }, { type: types.SET_TREE_OPEN, payload: 'grandparent' },
], ],
[ [{ type: 'showTreeEntry' }],
{ type: 'showTreeEntry' },
],
done, done,
); );
}); });
......
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