added specs for file actions

in this it also removes Vue Resource from the IDE, axios is nicer to test
This commit is contained in:
Phil Hughes 2018-06-28 15:09:21 +01:00
parent d255fd4f46
commit fa8c82c7ec
No known key found for this signature in database
GPG Key ID: 32245528C52E0F9F
5 changed files with 205 additions and 155 deletions

View File

@ -1,16 +1,11 @@
import Vue from 'vue';
import VueResource from 'vue-resource';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import Api from '~/api'; import Api from '~/api';
Vue.use(VueResource);
export default { export default {
getTreeData(endpoint) {
return Vue.http.get(endpoint, { params: { format: 'json' } });
},
getFileData(endpoint) { getFileData(endpoint) {
return Vue.http.get(endpoint, { params: { format: 'json', viewer: 'none' } }); return axios.get(endpoint, {
params: { format: 'json', viewer: 'none' },
});
}, },
getRawFileData(file) { getRawFileData(file) {
if (file.tempFile) { if (file.tempFile) {
@ -21,7 +16,11 @@ export default {
return Promise.resolve(file.raw); return Promise.resolve(file.raw);
} }
return Vue.http.get(file.rawPath, { params: { format: 'json' } }).then(res => res.text()); return axios
.get(file.rawPath, {
params: { format: 'json' },
})
.then(({ data }) => data);
}, },
getBaseRawFileData(file, sha) { getBaseRawFileData(file, sha) {
if (file.tempFile) { if (file.tempFile) {
@ -32,11 +31,11 @@ export default {
return Promise.resolve(file.baseRaw); return Promise.resolve(file.baseRaw);
} }
return Vue.http return axios
.get(file.rawPath.replace(`/raw/${file.branchId}/${file.path}`, `/raw/${sha}/${file.path}`), { .get(file.rawPath.replace(`/raw/${file.branchId}/${file.path}`, `/raw/${sha}/${file.path}`), {
params: { format: 'json' }, params: { format: 'json' },
}) })
.then(res => res.text()); .then(({ data }) => data);
}, },
getProjectData(namespace, project) { getProjectData(namespace, project) {
return Api.project(`${namespace}/${project}`); return Api.project(`${namespace}/${project}`);
@ -53,21 +52,9 @@ export default {
getBranchData(projectId, currentBranchId) { getBranchData(projectId, currentBranchId) {
return Api.branchSingle(projectId, currentBranchId); return Api.branchSingle(projectId, currentBranchId);
}, },
createBranch(projectId, payload) {
const url = Api.buildUrl(Api.createBranchPath).replace(':id', projectId);
return Vue.http.post(url, payload);
},
commit(projectId, payload) { commit(projectId, payload) {
return Api.commitMultiple(projectId, payload); return Api.commitMultiple(projectId, payload);
}, },
getTreeLastCommit(endpoint) {
return Vue.http.get(endpoint, {
params: {
format: 'json',
},
});
},
getFiles(projectUrl, branchId) { getFiles(projectUrl, branchId) {
const url = `${projectUrl}/files/${branchId}`; const url = `${projectUrl}/files/${branchId}`;
return axios.get(url, { params: { format: 'json' } }); return axios.get(url, { params: { format: 'json' } });

View File

@ -66,13 +66,9 @@ export const getFileData = ({ state, commit, dispatch }, { path, makeFileActive
.getFileData( .getFileData(
`${gon.relative_url_root ? gon.relative_url_root : ''}${file.url.replace('/-/', '/')}`, `${gon.relative_url_root ? gon.relative_url_root : ''}${file.url.replace('/-/', '/')}`,
) )
.then(res => { .then(({ data, headers }) => {
const pageTitle = decodeURI(normalizeHeaders(res.headers)['PAGE-TITLE']); setPageTitle(decodeURI(headers['page-title']));
setPageTitle(pageTitle);
return res.json();
})
.then(data => {
commit(types.SET_FILE_DATA, { data, file }); commit(types.SET_FILE_DATA, { data, file });
commit(types.TOGGLE_FILE_OPEN, path); commit(types.TOGGLE_FILE_OPEN, path);
if (makeFileActive) dispatch('setFileActive', path); if (makeFileActive) dispatch('setFileActive', path);

View File

@ -68,23 +68,6 @@ describe('RepoCommitSection', () => {
vm.$mount(); vm.$mount();
spyOn(service, 'getTreeData').and.returnValue(
Promise.resolve({
headers: {
'page-title': 'test',
},
json: () =>
Promise.resolve({
last_commit_path: 'last_commit_path',
parent_tree_url: 'parent_tree_url',
path: '/',
trees: [{ name: 'tree' }],
blobs: [{ name: 'blob' }],
submodules: [{ name: 'submodule' }],
}),
}),
);
Vue.nextTick(done); Vue.nextTick(done);
}); });

View File

@ -1,5 +1,8 @@
import Vue from 'vue'; import Vue from 'vue';
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import store from '~/ide/stores'; import store from '~/ide/stores';
import { getFileData, getRawFileData } from '~/ide/stores/actions/file';
import * as actions from '~/ide/stores/actions/file'; import * as actions from '~/ide/stores/actions/file';
import * as types from '~/ide/stores/mutation_types'; import * as types from '~/ide/stores/mutation_types';
import service from '~/ide/services'; import service from '~/ide/services';
@ -9,11 +12,16 @@ import { file, resetStore } from '../../helpers';
import testAction from '../../../helpers/vuex_action_helper'; import testAction from '../../../helpers/vuex_action_helper';
describe('IDE store file actions', () => { describe('IDE store file actions', () => {
let mock;
beforeEach(() => { beforeEach(() => {
mock = new MockAdapter(axios);
spyOn(router, 'push'); spyOn(router, 'push');
}); });
afterEach(() => { afterEach(() => {
mock.restore();
resetStore(store); resetStore(store);
}); });
@ -183,94 +191,131 @@ describe('IDE store file actions', () => {
let localFile; let localFile;
beforeEach(() => { beforeEach(() => {
spyOn(service, 'getFileData').and.returnValue( spyOn(service, 'getFileData').and.callThrough();
Promise.resolve({
headers: {
'page-title': 'testing getFileData',
},
json: () =>
Promise.resolve({
blame_path: 'blame_path',
commits_path: 'commits_path',
permalink: 'permalink',
raw_path: 'raw_path',
binary: false,
html: '123',
render_error: '',
}),
}),
);
localFile = file(`newCreate-${Math.random()}`); localFile = file(`newCreate-${Math.random()}`);
localFile.url = 'getFileDataURL'; localFile.url = `${gl.TEST_HOST}/getFileDataURL`;
store.state.entries[localFile.path] = localFile; store.state.entries[localFile.path] = localFile;
}); });
it('calls the service', done => { describe('success', () => {
store beforeEach(() => {
.dispatch('getFileData', { path: localFile.path }) mock.onGet(`${gl.TEST_HOST}/getFileDataURL`).replyOnce(
.then(() => { 200,
expect(service.getFileData).toHaveBeenCalledWith('getFileDataURL'); {
blame_path: 'blame_path',
commits_path: 'commits_path',
permalink: 'permalink',
raw_path: 'raw_path',
binary: false,
html: '123',
render_error: '',
},
{
'page-title': 'testing getFileData',
},
);
});
done(); it('calls the service', done => {
}) store
.catch(done.fail); .dispatch('getFileData', { path: localFile.path })
.then(() => {
expect(service.getFileData).toHaveBeenCalledWith(`${gl.TEST_HOST}/getFileDataURL`);
done();
})
.catch(done.fail);
});
it('sets the file data', done => {
store
.dispatch('getFileData', { path: localFile.path })
.then(() => {
expect(localFile.blamePath).toBe('blame_path');
done();
})
.catch(done.fail);
});
it('sets document title', done => {
store
.dispatch('getFileData', { path: localFile.path })
.then(() => {
expect(document.title).toBe('testing getFileData');
done();
})
.catch(done.fail);
});
it('sets the file as active', done => {
store
.dispatch('getFileData', { path: localFile.path })
.then(() => {
expect(localFile.active).toBeTruthy();
done();
})
.catch(done.fail);
});
it('sets the file not as active if we pass makeFileActive false', done => {
store
.dispatch('getFileData', { path: localFile.path, makeFileActive: false })
.then(() => {
expect(localFile.active).toBeFalsy();
done();
})
.catch(done.fail);
});
it('adds the file to open files', done => {
store
.dispatch('getFileData', { path: localFile.path })
.then(() => {
expect(store.state.openFiles.length).toBe(1);
expect(store.state.openFiles[0].name).toBe(localFile.name);
done();
})
.catch(done.fail);
});
}); });
it('sets the file data', done => { describe('error', () => {
store beforeEach(() => {
.dispatch('getFileData', { path: localFile.path }) mock.onGet(`${gl.TEST_HOST}/getFileDataURL`).networkError();
.then(() => { });
expect(localFile.blamePath).toBe('blame_path');
done(); it('dispatches error action', done => {
}) const dispatch = jasmine.createSpy('dispatch');
.catch(done.fail);
});
it('sets document title', done => { getFileData(
store {
.dispatch('getFileData', { path: localFile.path }) state: store.state,
.then(() => { commit() {},
expect(document.title).toBe('testing getFileData'); dispatch,
},
{ path: localFile.path },
)
.then(() => {
expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
text: 'An error occured whilst loading the file.',
action: jasmine.any(Function),
actionText: 'Please try again',
actionPayload: {
path: localFile.path,
makeFileActive: true,
},
});
done(); done();
}) })
.catch(done.fail); .catch(done.fail);
}); });
it('sets the file as active', done => {
store
.dispatch('getFileData', { path: localFile.path })
.then(() => {
expect(localFile.active).toBeTruthy();
done();
})
.catch(done.fail);
});
it('sets the file not as active if we pass makeFileActive false', done => {
store
.dispatch('getFileData', { path: localFile.path, makeFileActive: false })
.then(() => {
expect(localFile.active).toBeFalsy();
done();
})
.catch(done.fail);
});
it('adds the file to open files', done => {
store
.dispatch('getFileData', { path: localFile.path })
.then(() => {
expect(store.state.openFiles.length).toBe(1);
expect(store.state.openFiles[0].name).toBe(localFile.name);
done();
})
.catch(done.fail);
}); });
}); });
@ -278,48 +323,87 @@ describe('IDE store file actions', () => {
let tmpFile; let tmpFile;
beforeEach(() => { beforeEach(() => {
spyOn(service, 'getRawFileData').and.returnValue(Promise.resolve('raw')); spyOn(service, 'getRawFileData').and.callThrough();
tmpFile = file('tmpFile'); tmpFile = file('tmpFile');
store.state.entries[tmpFile.path] = tmpFile; store.state.entries[tmpFile.path] = tmpFile;
}); });
it('calls getRawFileData service method', done => { describe('success', () => {
store beforeEach(() => {
.dispatch('getRawFileData', { path: tmpFile.path }) mock.onGet(/(.*)/).replyOnce(200, 'raw');
.then(() => { });
expect(service.getRawFileData).toHaveBeenCalledWith(tmpFile);
done(); it('calls getRawFileData service method', done => {
}) store
.catch(done.fail); .dispatch('getRawFileData', { path: tmpFile.path })
.then(() => {
expect(service.getRawFileData).toHaveBeenCalledWith(tmpFile);
done();
})
.catch(done.fail);
});
it('updates file raw data', done => {
store
.dispatch('getRawFileData', { path: tmpFile.path })
.then(() => {
expect(tmpFile.raw).toBe('raw');
done();
})
.catch(done.fail);
});
it('calls also getBaseRawFileData service method', done => {
spyOn(service, 'getBaseRawFileData').and.returnValue(Promise.resolve('baseraw'));
tmpFile.mrChange = { new_file: false };
store
.dispatch('getRawFileData', { path: tmpFile.path, baseSha: 'SHA' })
.then(() => {
expect(service.getBaseRawFileData).toHaveBeenCalledWith(tmpFile, 'SHA');
expect(tmpFile.baseRaw).toBe('baseraw');
done();
})
.catch(done.fail);
});
}); });
it('updates file raw data', done => { describe('error', () => {
store beforeEach(() => {
.dispatch('getRawFileData', { path: tmpFile.path }) mock.onGet(/(.*)/).networkError();
.then(() => { });
expect(tmpFile.raw).toBe('raw');
done(); it('dispatches error action', done => {
}) const dispatch = jasmine.createSpy('dispatch');
.catch(done.fail);
});
it('calls also getBaseRawFileData service method', done => { getRawFileData(
spyOn(service, 'getBaseRawFileData').and.returnValue(Promise.resolve('baseraw')); {
state: store.state,
commit() {},
dispatch,
},
{ path: tmpFile.path, baseSha: tmpFile.baseSha },
)
.then(done.fail)
.catch(() => {
expect(dispatch).toHaveBeenCalledWith('setErrorMessage', {
text: 'An error occured whilst loading the file content.',
action: jasmine.any(Function),
actionText: 'Please try again',
actionPayload: {
path: tmpFile.path,
baseSha: tmpFile.baseSha,
},
});
tmpFile.mrChange = { new_file: false }; done();
});
store });
.dispatch('getRawFileData', { path: tmpFile.path, baseSha: 'SHA' })
.then(() => {
expect(service.getBaseRawFileData).toHaveBeenCalledWith(tmpFile, 'SHA');
expect(tmpFile.baseRaw).toBe('baseraw');
done();
})
.catch(done.fail);
}); });
}); });

View File

@ -110,7 +110,7 @@ describe('IDE store project actions', () => {
type: 'setErrorMessage', type: 'setErrorMessage',
payload: { payload: {
text: "Branch <strong>master</strong> was not found in this project's repository.", text: "Branch <strong>master</strong> was not found in this project's repository.",
action: 'createNewBranchFromDefault', action: jasmine.any(Function),
actionText: 'Create branch', actionText: 'Create branch',
actionPayload: 'master', actionPayload: 'master',
}, },