+
diff --git a/app/assets/javascripts/ide/ide_router.js b/app/assets/javascripts/ide/ide_router.js
index b52618f4fde5785c8f1869e94ca09e6b0b3c54d4..cc8dbb942d8562c468828b6ab79e38d08fdeef44 100644
--- a/app/assets/javascripts/ide/ide_router.js
+++ b/app/assets/javascripts/ide/ide_router.js
@@ -95,14 +95,6 @@ router.beforeEach((to, from, next) => {
}
})
.catch(e => {
- flash(
- 'Error while loading the branch files. Please try again.',
- 'alert',
- document,
- null,
- false,
- true,
- );
throw e;
});
} else if (to.params.mrid) {
diff --git a/app/assets/javascripts/ide/services/index.js b/app/assets/javascripts/ide/services/index.js
index da9de25302aa76fd8776bbfb6e098f00fee93767..5e64206714106e83af7e0d07a78881f1d659179f 100644
--- a/app/assets/javascripts/ide/services/index.js
+++ b/app/assets/javascripts/ide/services/index.js
@@ -1,5 +1,6 @@
import Vue from 'vue';
import VueResource from 'vue-resource';
+import axios from '~/lib/utils/axios_utils';
import Api from '~/api';
Vue.use(VueResource);
@@ -69,11 +70,7 @@ export default {
},
getFiles(projectUrl, branchId) {
const url = `${projectUrl}/files/${branchId}`;
- return Vue.http.get(url, {
- params: {
- format: 'json',
- },
- });
+ return axios.get(url, { params: { format: 'json' } });
},
lastCommitPipelines({ getters }) {
const commitSha = getters.lastCommit.id;
diff --git a/app/assets/javascripts/ide/stores/actions.js b/app/assets/javascripts/ide/stores/actions.js
index 3dc365eaead64d75f40c81efe06c948995d54d5a..5e91fa915ff1a327020a71484e394dfd7ab23798 100644
--- a/app/assets/javascripts/ide/stores/actions.js
+++ b/app/assets/javascripts/ide/stores/actions.js
@@ -175,6 +175,9 @@ export const setRightPane = ({ commit }, view) => {
export const setLinks = ({ commit }, links) => commit(types.SET_LINKS, links);
+export const setErrorMessage = ({ commit }, errorMessage) =>
+ commit(types.SET_ERROR_MESSAGE, errorMessage);
+
export * from './actions/tree';
export * from './actions/file';
export * from './actions/project';
diff --git a/app/assets/javascripts/ide/stores/actions/project.js b/app/assets/javascripts/ide/stores/actions/project.js
index 0b99bce4a8e1e12c803ec6bbb008e60b6466eb42..ab5cd8e474267f2c3a70afc1e57ada58bdaef687 100644
--- a/app/assets/javascripts/ide/stores/actions/project.js
+++ b/app/assets/javascripts/ide/stores/actions/project.js
@@ -1,7 +1,10 @@
+import _ from 'underscore';
import flash from '~/flash';
-import { __ } from '~/locale';
+import { __, sprintf } from '~/locale';
import service from '../../services';
+import api from '../../../api';
import * as types from '../mutation_types';
+import router from '../../ide_router';
export const getProjectData = ({ commit, state }, { namespace, projectId, force = false } = {}) =>
new Promise((resolve, reject) => {
@@ -32,7 +35,10 @@ export const getProjectData = ({ commit, state }, { namespace, projectId, force
}
});
-export const getBranchData = ({ commit, state }, { projectId, branchId, force = false } = {}) =>
+export const getBranchData = (
+ { commit, dispatch, state },
+ { projectId, branchId, force = false } = {},
+) =>
new Promise((resolve, reject) => {
if (
typeof state.projects[`${projectId}`] === 'undefined' ||
@@ -51,15 +57,19 @@ export const getBranchData = ({ commit, state }, { projectId, branchId, force =
commit(types.SET_BRANCH_WORKING_REFERENCE, { projectId, branchId, reference: id });
resolve(data);
})
- .catch(() => {
- flash(
- __('Error loading branch data. Please try again.'),
- 'alert',
- document,
- null,
- false,
- true,
- );
+ .catch(e => {
+ if (e.response.status === 404) {
+ dispatch('showBranchNotFoundError', branchId);
+ } else {
+ flash(
+ __('Error loading branch data. Please try again.'),
+ 'alert',
+ document,
+ null,
+ false,
+ true,
+ );
+ }
reject(new Error(`Branch not loaded - ${projectId}/${branchId}`));
});
} else {
@@ -80,3 +90,37 @@ export const refreshLastCommitData = ({ commit }, { projectId, branchId } = {})
.catch(() => {
flash(__('Error loading last commit.'), 'alert', document, null, false, true);
});
+
+export const createNewBranchFromDefault = ({ state, dispatch, getters }, branch) =>
+ api
+ .createBranch(state.currentProjectId, {
+ ref: getters.currentProject.default_branch,
+ branch,
+ })
+ .then(() => {
+ dispatch('setErrorMessage', null);
+ router.push(`${router.currentRoute.path}?${Date.now()}`);
+ })
+ .catch(() => {
+ dispatch('setErrorMessage', {
+ text: __('An error occured creating the new branch.'),
+ action: 'createNewBranchFromDefault',
+ actionText: __('Please try again'),
+ actionPayload: branch,
+ });
+ });
+
+export const showBranchNotFoundError = ({ dispatch }, branchId) => {
+ dispatch('setErrorMessage', {
+ text: sprintf(
+ __("Branch %{branchName} was not found in this project's repository."),
+ {
+ branchName: `${_.escape(branchId)}`,
+ },
+ false,
+ ),
+ action: 'createNewBranchFromDefault',
+ actionText: __('Create branch'),
+ actionPayload: branchId,
+ });
+};
diff --git a/app/assets/javascripts/ide/stores/actions/tree.js b/app/assets/javascripts/ide/stores/actions/tree.js
index 2fbc9990fa258819cf5af40b5af284fc0eaae3db..dcdd900fc7eb2c5af0284680908d9cfbc9090f19 100644
--- a/app/assets/javascripts/ide/stores/actions/tree.js
+++ b/app/assets/javascripts/ide/stores/actions/tree.js
@@ -1,5 +1,6 @@
import { normalizeHeaders } from '~/lib/utils/common_utils';
import flash from '~/flash';
+import { __ } from '../../../locale';
import service from '../../services';
import * as types from '../mutation_types';
import { findEntry } from '../utils';
@@ -62,16 +63,19 @@ export const getLastCommitData = ({ state, commit, dispatch }, tree = state) =>
.catch(() => flash('Error fetching log data.', 'alert', document, null, false, true));
};
-export const getFiles = ({ state, commit }, { projectId, branchId } = {}) =>
+export const getFiles = ({ state, commit, dispatch }, { projectId, branchId } = {}) =>
new Promise((resolve, reject) => {
- if (!state.trees[`${projectId}/${branchId}`]) {
+ if (
+ !state.trees[`${projectId}/${branchId}`] ||
+ (state.trees[`${projectId}/${branchId}`].tree &&
+ state.trees[`${projectId}/${branchId}`].tree.length === 0)
+ ) {
const selectedProject = state.projects[projectId];
commit(types.CREATE_TREE, { treePath: `${projectId}/${branchId}` });
service
.getFiles(selectedProject.web_url, branchId)
- .then(res => res.json())
- .then(data => {
+ .then(({ data }) => {
const worker = new FilesDecoratorWorker();
worker.addEventListener('message', e => {
const { entries, treeList } = e.data;
@@ -99,7 +103,18 @@ export const getFiles = ({ state, commit }, { projectId, branchId } = {}) =>
});
})
.catch(e => {
- flash('Error loading tree data. Please try again.', 'alert', document, null, false, true);
+ if (e.response.status === 404) {
+ dispatch('showBranchNotFoundError', branchId);
+ } else {
+ flash(
+ __('Error loading tree data. Please try again.'),
+ 'alert',
+ document,
+ null,
+ false,
+ true,
+ );
+ }
reject(e);
});
} else {
diff --git a/app/assets/javascripts/ide/stores/mutation_types.js b/app/assets/javascripts/ide/stores/mutation_types.js
index fda606dbf01022826ef48893ca432f6a08c897b8..555802e18118b6909ca63536add155271db8b23c 100644
--- a/app/assets/javascripts/ide/stores/mutation_types.js
+++ b/app/assets/javascripts/ide/stores/mutation_types.js
@@ -72,3 +72,5 @@ export const SET_RIGHT_PANE = 'SET_RIGHT_PANE';
export const CLEAR_PROJECTS = 'CLEAR_PROJECTS';
export const RESET_OPEN_FILES = 'RESET_OPEN_FILES';
+
+export const SET_ERROR_MESSAGE = 'SET_ERROR_MESSAGE';
diff --git a/app/assets/javascripts/ide/stores/mutations.js b/app/assets/javascripts/ide/stores/mutations.js
index 48f1da4eccf698f58a5bef79f0bef89600229300..702be2140e22a7d1b1c6d52ee5964c76a5a07565 100644
--- a/app/assets/javascripts/ide/stores/mutations.js
+++ b/app/assets/javascripts/ide/stores/mutations.js
@@ -163,6 +163,9 @@ export default {
[types.RESET_OPEN_FILES](state) {
Object.assign(state, { openFiles: [] });
},
+ [types.SET_ERROR_MESSAGE](state, errorMessage) {
+ Object.assign(state, { errorMessage });
+ },
...projectMutations,
...mergeRequestMutation,
...fileMutations,
diff --git a/app/assets/javascripts/ide/stores/state.js b/app/assets/javascripts/ide/stores/state.js
index 4aac46960754250bbc570ccbeb00978b28b127c0..be229b2c723be3333f0a073ed7ee1837b9d62155 100644
--- a/app/assets/javascripts/ide/stores/state.js
+++ b/app/assets/javascripts/ide/stores/state.js
@@ -25,4 +25,5 @@ export default () => ({
fileFindVisible: false,
rightPane: null,
links: {},
+ errorMessage: null,
});
diff --git a/app/assets/stylesheets/framework/flash.scss b/app/assets/stylesheets/framework/flash.scss
index a6e324036ae4320787da24d66451731bd4fae0f1..e4bcb92876d08cecb17f214750df82cb34ec28c0 100644
--- a/app/assets/stylesheets/framework/flash.scss
+++ b/app/assets/stylesheets/framework/flash.scss
@@ -42,7 +42,7 @@
display: inline-block;
}
- a.flash-action {
+ .flash-action {
margin-left: 5px;
text-decoration: none;
font-weight: $gl-font-weight-normal;
diff --git a/spec/javascripts/api_spec.js b/spec/javascripts/api_spec.js
index e843511622117e8869ae61f63e41c0ee23c344fc..c53b6da4b480efcea8e327274ea52d8c8ca7f2af 100644
--- a/spec/javascripts/api_spec.js
+++ b/spec/javascripts/api_spec.js
@@ -362,4 +362,29 @@ describe('Api', () => {
.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);
+ });
+ });
});
diff --git a/spec/javascripts/ide/components/error_message_spec.js b/spec/javascripts/ide/components/error_message_spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..70d13a6ceb290dbeac3e43c5a6b59fd7ba85f4e6
--- /dev/null
+++ b/spec/javascripts/ide/components/error_message_spec.js
@@ -0,0 +1,104 @@
+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();
+ });
+ });
+ });
+});
diff --git a/spec/javascripts/ide/components/ide_spec.js b/spec/javascripts/ide/components/ide_spec.js
index 045a60e56a04bed6498257bbb8c832f15764aa3a..708c9fe69af3beb135463d45e4d049842f4842f8 100644
--- a/spec/javascripts/ide/components/ide_spec.js
+++ b/spec/javascripts/ide/components/ide_spec.js
@@ -114,4 +114,18 @@ describe('ide component', () => {
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();
+ });
+ });
});
diff --git a/spec/javascripts/ide/stores/actions/project_spec.js b/spec/javascripts/ide/stores/actions/project_spec.js
index d71fc0e035eed3affd593f8b7e42186b761c255c..c1f9fc4f148da8015b5bc967993682a35264e0cb 100644
--- a/spec/javascripts/ide/stores/actions/project_spec.js
+++ b/spec/javascripts/ide/stores/actions/project_spec.js
@@ -1,15 +1,32 @@
-import { refreshLastCommitData } from '~/ide/stores/actions';
+import MockAdapter from 'axios-mock-adapter';
+import axios from '~/lib/utils/axios_utils';
+import {
+ refreshLastCommitData,
+ showBranchNotFoundError,
+ createNewBranchFromDefault,
+ getBranchData,
+} from '~/ide/stores/actions';
import store from '~/ide/stores';
import service from '~/ide/services';
+import api from '~/api';
+import router from '~/ide/ide_router';
import { resetStore } from '../../helpers';
import testAction from '../../../helpers/vuex_action_helper';
describe('IDE store project actions', () => {
+ let mock;
+
beforeEach(() => {
- store.state.projects['abc/def'] = {};
+ mock = new MockAdapter(axios);
+
+ store.state.projects['abc/def'] = {
+ branches: {},
+ };
});
afterEach(() => {
+ mock.restore();
+
resetStore(store);
});
@@ -80,4 +97,138 @@ describe('IDE store project actions', () => {
);
});
});
+
+ describe('showBranchNotFoundError', () => {
+ it('dispatches setErrorMessage', done => {
+ testAction(
+ showBranchNotFoundError,
+ 'master',
+ null,
+ [],
+ [
+ {
+ type: 'setErrorMessage',
+ payload: {
+ text: "Branch master was not found in this project's repository.",
+ action: 'createNewBranchFromDefault',
+ actionText: 'Create branch',
+ actionPayload: 'master',
+ },
+ },
+ ],
+ done,
+ );
+ });
+ });
+
+ describe('createNewBranchFromDefault', () => {
+ it('calls API', done => {
+ spyOn(api, 'createBranch').and.returnValue(Promise.resolve());
+ spyOn(router, 'push');
+
+ createNewBranchFromDefault(
+ {
+ state: {
+ currentProjectId: 'project-path',
+ },
+ getters: {
+ currentProject: {
+ default_branch: 'master',
+ },
+ },
+ dispatch() {},
+ },
+ 'new-branch-name',
+ )
+ .then(() => {
+ expect(api.createBranch).toHaveBeenCalledWith('project-path', {
+ ref: 'master',
+ branch: 'new-branch-name',
+ });
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('clears error message', done => {
+ const dispatchSpy = jasmine.createSpy('dispatch');
+ spyOn(api, 'createBranch').and.returnValue(Promise.resolve());
+ spyOn(router, 'push');
+
+ createNewBranchFromDefault(
+ {
+ state: {
+ currentProjectId: 'project-path',
+ },
+ getters: {
+ currentProject: {
+ default_branch: 'master',
+ },
+ },
+ dispatch: dispatchSpy,
+ },
+ 'new-branch-name',
+ )
+ .then(() => {
+ expect(dispatchSpy).toHaveBeenCalledWith('setErrorMessage', null);
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+
+ it('reloads window', done => {
+ spyOn(api, 'createBranch').and.returnValue(Promise.resolve());
+ spyOn(router, 'push');
+
+ createNewBranchFromDefault(
+ {
+ state: {
+ currentProjectId: 'project-path',
+ },
+ getters: {
+ currentProject: {
+ default_branch: 'master',
+ },
+ },
+ dispatch() {},
+ },
+ 'new-branch-name',
+ )
+ .then(() => {
+ expect(router.push).toHaveBeenCalled();
+ })
+ .then(done)
+ .catch(done.fail);
+ });
+ });
+
+ 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();
+ });
+ });
+ });
+ });
});
diff --git a/spec/javascripts/ide/stores/actions/tree_spec.js b/spec/javascripts/ide/stores/actions/tree_spec.js
index cefed9ddb4335c99522808c8299447ef56bab26c..612a439cfbf5f6f85566c25389fc78bfe11e7c71 100644
--- a/spec/javascripts/ide/stores/actions/tree_spec.js
+++ b/spec/javascripts/ide/stores/actions/tree_spec.js
@@ -1,7 +1,9 @@
+import MockAdapter from 'axios-mock-adapter';
import Vue from 'vue';
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 axios from '~/lib/utils/axios_utils';
import store from '~/ide/stores';
import service from '~/ide/services';
import router from '~/ide/ide_router';
@@ -9,6 +11,7 @@ import { file, resetStore, createEntriesFromPaths } from '../../helpers';
describe('Multi-file store tree actions', () => {
let projectTree;
+ let mock;
const basicCallParameters = {
endpoint: 'rootEndpoint',
@@ -20,6 +23,8 @@ describe('Multi-file store tree actions', () => {
beforeEach(() => {
spyOn(router, 'push');
+ mock = new MockAdapter(axios);
+
store.state.currentProjectId = 'abcproject';
store.state.currentBranchId = 'master';
store.state.projects.abcproject = {
@@ -33,49 +38,85 @@ describe('Multi-file store tree actions', () => {
});
afterEach(() => {
+ mock.restore();
resetStore(store);
});
describe('getFiles', () => {
- beforeEach(() => {
- spyOn(service, 'getFiles').and.returnValue(
- Promise.resolve({
- json: () =>
- Promise.resolve([
- 'file.txt',
- 'folder/fileinfolder.js',
- 'folder/subfolder/fileinsubfolder.js',
- ]),
- }),
- );
+ describe('success', () => {
+ beforeEach(() => {
+ spyOn(service, 'getFiles').and.callThrough();
+
+ mock
+ .onGet(/(.*)/)
+ .replyOnce(200, [
+ '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 => {
- store
- .dispatch('getFiles', basicCallParameters)
- .then(() => {
- expect(service.getFiles).toHaveBeenCalledWith('', 'master');
+ describe('error', () => {
+ it('dispatches branch not found actions when response is 404', done => {
+ const dispatch = jasmine.createSpy('dispatchSpy');
- done();
- })
- .catch(done.fail);
- });
+ store.state.projects = {
+ 'abc/def': {
+ web_url: `${gl.TEST_HOST}/files`,
+ },
+ };
- 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');
+ mock.onGet(/(.*)/).replyOnce(404);
- done();
- })
- .catch(done.fail);
+ getFiles(
+ {
+ 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', () => {
{ type: types.SET_TREE_OPEN, payload: 'grandparent/parent' },
{ type: types.SET_TREE_OPEN, payload: 'grandparent' },
],
- [
- { type: 'showTreeEntry' },
- ],
+ [{ type: 'showTreeEntry' }],
done,
);
});
diff --git a/spec/javascripts/ide/stores/actions_spec.js b/spec/javascripts/ide/stores/actions_spec.js
index 062c3497623a41d1378a247200f0003f5d86502e..8b665a6d79e381f8a8f4f9f5d06b7e9abee3a524 100644
--- a/spec/javascripts/ide/stores/actions_spec.js
+++ b/spec/javascripts/ide/stores/actions_spec.js
@@ -6,6 +6,7 @@ import actions, {
setEmptyStateSvgs,
updateActivityBarView,
updateTempFlagForEntry,
+ setErrorMessage,
} from '~/ide/stores/actions';
import store from '~/ide/stores';
import * as types from '~/ide/stores/mutation_types';
@@ -443,4 +444,17 @@ describe('Multi-file store actions', () => {
);
});
});
+
+ describe('setErrorMessage', () => {
+ it('commis error messsage', done => {
+ testAction(
+ setErrorMessage,
+ 'error',
+ null,
+ [{ type: types.SET_ERROR_MESSAGE, payload: 'error' }],
+ [],
+ done,
+ );
+ });
+ });
});
diff --git a/spec/javascripts/ide/stores/mutations_spec.js b/spec/javascripts/ide/stores/mutations_spec.js
index 972713c5ad2b67bde93ff1d5e19ade17c7c06dbc..98016f593aaf183c80a61214075d4ea9a48a24bd 100644
--- a/spec/javascripts/ide/stores/mutations_spec.js
+++ b/spec/javascripts/ide/stores/mutations_spec.js
@@ -148,4 +148,12 @@ describe('Multi-file store mutations', () => {
expect(localState.unusedSeal).toBe(false);
});
});
+
+ describe('SET_ERROR_MESSAGE', () => {
+ it('updates error message', () => {
+ mutations.SET_ERROR_MESSAGE(localState, 'error');
+
+ expect(localState.errorMessage).toBe('error');
+ });
+ });
});