debian-mirror-gitlab/spec/frontend/ide/stores/actions_spec.js

1061 lines
28 KiB
JavaScript
Raw Normal View History

2020-01-01 13:55:28 +05:30
import MockAdapter from 'axios-mock-adapter';
2021-03-08 18:12:59 +05:30
import testAction from 'helpers/vuex_action_helper';
2021-03-11 19:13:27 +05:30
import eventHub from '~/ide/eventhub';
2020-06-23 00:09:42 +05:30
import { createRouter } from '~/ide/ide_router';
2021-03-11 19:13:27 +05:30
import { createStore } from '~/ide/stores';
2020-06-23 00:09:42 +05:30
import {
2021-06-08 01:23:25 +05:30
init,
2018-10-15 14:42:47 +05:30
stageAllChanges,
unstageAllChanges,
toggleFileFinder,
setCurrentBranchId,
setEmptyStateSvgs,
updateActivityBarView,
updateTempFlagForEntry,
2018-11-08 19:23:39 +05:30
setErrorMessage,
2018-11-18 11:00:15 +05:30
deleteEntry,
renameEntry,
2019-09-04 21:01:54 +05:30
getBranchData,
2019-09-30 21:07:59 +05:30
createTempEntry,
2020-01-01 13:55:28 +05:30
discardAllChanges,
2018-10-15 14:42:47 +05:30
} from '~/ide/stores/actions';
import * as types from '~/ide/stores/mutation_types';
2021-03-11 19:13:27 +05:30
import axios from '~/lib/utils/axios_utils';
import { visitUrl } from '~/lib/utils/url_utility';
2021-01-29 00:20:46 +05:30
import { file, createTriggerRenameAction, createTriggerChangeAction } from '../helpers';
2019-12-21 20:55:43 +05:30
2020-06-23 00:09:42 +05:30
jest.mock('~/lib/utils/url_utility', () => ({
visitUrl: jest.fn(),
joinPaths: jest.requireActual('~/lib/utils/url_utility').joinPaths,
}));
2018-05-09 12:01:36 +05:30
describe('Multi-file store actions', () => {
2020-03-13 15:44:24 +05:30
let store;
2020-06-23 00:09:42 +05:30
let router;
2020-03-13 15:44:24 +05:30
2018-05-09 12:01:36 +05:30
beforeEach(() => {
2020-03-13 15:44:24 +05:30
store = createStore();
2020-06-23 00:09:42 +05:30
router = createRouter(store);
2018-05-09 12:01:36 +05:30
2020-06-23 00:09:42 +05:30
jest.spyOn(store, 'commit');
jest.spyOn(store, 'dispatch');
jest.spyOn(router, 'push').mockImplementation();
2018-05-09 12:01:36 +05:30
});
describe('redirectToUrl', () => {
2021-03-08 18:12:59 +05:30
it('calls visitUrl', (done) => {
2018-05-09 12:01:36 +05:30
store
.dispatch('redirectToUrl', 'test')
.then(() => {
2018-10-15 14:42:47 +05:30
expect(visitUrl).toHaveBeenCalledWith('test');
2018-05-09 12:01:36 +05:30
done();
})
.catch(done.fail);
});
});
2021-06-08 01:23:25 +05:30
describe('init', () => {
it('commits initial data and requests user callouts', () => {
return testAction(
init,
{ canCommit: true },
store.state,
[{ type: 'SET_INITIAL_DATA', payload: { canCommit: true } }],
[],
);
2018-05-09 12:01:36 +05:30
});
});
describe('discardAllChanges', () => {
2020-03-13 15:44:24 +05:30
const paths = ['to_discard', 'another_one_to_discard'];
2018-05-09 12:01:36 +05:30
beforeEach(() => {
2021-03-08 18:12:59 +05:30
paths.forEach((path) => {
2020-03-13 15:44:24 +05:30
const f = file(path);
f.changed = true;
2018-05-09 12:01:36 +05:30
2020-03-13 15:44:24 +05:30
store.state.openFiles.push(f);
store.state.changedFiles.push(f);
store.state.entries[f.path] = f;
});
2018-05-09 12:01:36 +05:30
});
2020-03-13 15:44:24 +05:30
it('discards all changes in file', () => {
2021-03-08 18:12:59 +05:30
const expectedCalls = paths.map((path) => ['restoreOriginalFile', path]);
2020-03-13 15:44:24 +05:30
discardAllChanges(store);
2020-06-23 00:09:42 +05:30
expect(store.dispatch.mock.calls).toEqual(expect.arrayContaining(expectedCalls));
2018-05-09 12:01:36 +05:30
});
2021-03-08 18:12:59 +05:30
it('removes all files from changedFiles state', (done) => {
2018-05-09 12:01:36 +05:30
store
.dispatch('discardAllChanges')
.then(() => {
expect(store.state.changedFiles.length).toBe(0);
2020-03-13 15:44:24 +05:30
expect(store.state.openFiles.length).toBe(2);
2018-05-09 12:01:36 +05:30
})
.then(done)
.catch(done.fail);
});
});
describe('createTempEntry', () => {
beforeEach(() => {
document.body.innerHTML += '<div class="flash-container"></div>';
store.state.currentProjectId = 'abcproject';
store.state.currentBranchId = 'mybranch';
store.state.trees['abcproject/mybranch'] = {
tree: [],
};
store.state.projects.abcproject = {
web_url: '',
};
});
afterEach(() => {
document.querySelector('.flash-container').remove();
});
describe('tree', () => {
2021-03-08 18:12:59 +05:30
it('creates temp tree', (done) => {
2018-05-09 12:01:36 +05:30
store
.dispatch('createTempEntry', {
name: 'test',
type: 'tree',
})
.then(() => {
const entry = store.state.entries.test;
expect(entry).not.toBeNull();
expect(entry.type).toBe('tree');
done();
})
.catch(done.fail);
});
2021-03-08 18:12:59 +05:30
it('creates new folder inside another tree', (done) => {
2018-05-09 12:01:36 +05:30
const tree = {
type: 'tree',
name: 'testing',
path: 'testing',
tree: [],
};
store.state.entries[tree.path] = tree;
store
.dispatch('createTempEntry', {
name: 'testing/test',
type: 'tree',
})
.then(() => {
expect(tree.tree[0].tempFile).toBeTruthy();
expect(tree.tree[0].name).toBe('test');
expect(tree.tree[0].type).toBe('tree');
done();
})
.catch(done.fail);
});
2021-03-08 18:12:59 +05:30
it('does not create new tree if already exists', (done) => {
2018-05-09 12:01:36 +05:30
const tree = {
type: 'tree',
path: 'testing',
tempFile: false,
tree: [],
};
store.state.entries[tree.path] = tree;
store
.dispatch('createTempEntry', {
name: 'testing',
type: 'tree',
})
.then(() => {
expect(store.state.entries[tree.path].tempFile).toEqual(false);
expect(document.querySelector('.flash-alert')).not.toBeNull();
done();
})
.catch(done.fail);
});
});
describe('blob', () => {
2021-03-08 18:12:59 +05:30
it('creates temp file', (done) => {
2020-03-13 15:44:24 +05:30
const name = 'test';
2018-05-09 12:01:36 +05:30
store
.dispatch('createTempEntry', {
2020-03-13 15:44:24 +05:30
name,
2018-05-09 12:01:36 +05:30
type: 'blob',
2021-03-08 18:12:59 +05:30
mimeType: 'test/mime',
2018-05-09 12:01:36 +05:30
})
2020-03-13 15:44:24 +05:30
.then(() => {
const f = store.state.entries[name];
2018-05-09 12:01:36 +05:30
expect(f.tempFile).toBeTruthy();
2021-03-08 18:12:59 +05:30
expect(f.mimeType).toBe('test/mime');
2018-10-15 14:42:47 +05:30
expect(store.state.trees['abcproject/mybranch'].tree.length).toBe(1);
2018-05-09 12:01:36 +05:30
done();
})
.catch(done.fail);
});
2021-03-08 18:12:59 +05:30
it('adds tmp file to open files', (done) => {
2020-03-13 15:44:24 +05:30
const name = 'test';
2018-05-09 12:01:36 +05:30
store
.dispatch('createTempEntry', {
2020-03-13 15:44:24 +05:30
name,
2018-05-09 12:01:36 +05:30
type: 'blob',
})
2020-03-13 15:44:24 +05:30
.then(() => {
const f = store.state.entries[name];
2018-05-09 12:01:36 +05:30
expect(store.state.openFiles.length).toBe(1);
expect(store.state.openFiles[0].name).toBe(f.name);
done();
})
.catch(done.fail);
});
2021-03-08 18:12:59 +05:30
it('adds tmp file to staged files', (done) => {
2020-03-13 15:44:24 +05:30
const name = 'test';
2018-05-09 12:01:36 +05:30
store
.dispatch('createTempEntry', {
2020-03-13 15:44:24 +05:30
name,
2018-05-09 12:01:36 +05:30
type: 'blob',
})
2020-03-13 15:44:24 +05:30
.then(() => {
2020-06-23 00:09:42 +05:30
expect(store.state.stagedFiles).toEqual([expect.objectContaining({ name })]);
2018-05-09 12:01:36 +05:30
done();
})
.catch(done.fail);
});
2020-03-13 15:44:24 +05:30
it('sets tmp file as active', () => {
2020-11-24 15:15:51 +05:30
createTempEntry(store, { name: 'test', type: 'blob' });
2020-03-13 15:44:24 +05:30
expect(store.dispatch).toHaveBeenCalledWith('setFileActive', 'test');
2018-05-09 12:01:36 +05:30
});
2021-03-08 18:12:59 +05:30
it('creates flash message if file already exists', (done) => {
2018-05-09 12:01:36 +05:30
const f = file('test', '1', 'blob');
store.state.trees['abcproject/mybranch'].tree = [f];
store.state.entries[f.path] = f;
store
.dispatch('createTempEntry', {
name: 'test',
type: 'blob',
})
.then(() => {
2020-03-13 15:44:24 +05:30
expect(document.querySelector('.flash-alert')?.textContent.trim()).toEqual(
`The name "${f.name}" is already taken in this directory.`,
);
done();
})
.catch(done.fail);
});
2018-05-09 12:01:36 +05:30
});
});
describe('scrollToTab', () => {
2021-03-08 18:12:59 +05:30
it('focuses the current active element', (done) => {
2018-05-09 12:01:36 +05:30
document.body.innerHTML +=
'<div id="tabs"><div class="active"><div class="repo-tab"></div></div></div>';
const el = document.querySelector('.repo-tab');
2020-06-23 00:09:42 +05:30
jest.spyOn(el, 'focus').mockImplementation();
2018-05-09 12:01:36 +05:30
store
.dispatch('scrollToTab')
.then(() => {
2020-06-23 00:09:42 +05:30
setImmediate(() => {
2018-05-09 12:01:36 +05:30
expect(el.focus).toHaveBeenCalled();
document.getElementById('tabs').remove();
done();
});
})
.catch(done.fail);
});
});
2020-03-13 15:44:24 +05:30
describe('stage/unstageAllChanges', () => {
let file1;
let file2;
2018-11-20 20:47:30 +05:30
2020-03-13 15:44:24 +05:30
beforeEach(() => {
file1 = { ...file('test'), content: 'changed test', raw: 'test' };
file2 = { ...file('test2'), content: 'changed test2', raw: 'test2' };
2018-10-15 14:42:47 +05:30
2020-03-13 15:44:24 +05:30
store.state.openFiles = [file1];
store.state.changedFiles = [file1];
store.state.stagedFiles = [{ ...file2, content: 'staged test' }];
store.state.entries = {
[file1.path]: { ...file1 },
[file2.path]: { ...file2 },
};
2018-10-15 14:42:47 +05:30
});
2020-03-13 15:44:24 +05:30
describe('stageAllChanges', () => {
it('adds all files from changedFiles to stagedFiles', () => {
stageAllChanges(store);
2018-11-20 20:47:30 +05:30
2020-06-23 00:09:42 +05:30
expect(store.commit.mock.calls).toEqual(
expect.arrayContaining([
[types.SET_LAST_COMMIT_MSG, ''],
[types.STAGE_CHANGE, expect.objectContaining({ path: file1.path })],
]),
);
2020-03-13 15:44:24 +05:30
});
2018-10-15 14:42:47 +05:30
2020-03-13 15:44:24 +05:30
it('opens pending tab if a change exists in that file', () => {
stageAllChanges(store);
2020-06-23 00:09:42 +05:30
expect(store.dispatch.mock.calls).toEqual([
2020-03-13 15:44:24 +05:30
[
'openPendingTab',
{ file: { ...file1, staged: true, changed: true }, keyPrefix: 'staged' },
],
]);
});
it('does not open pending tab if no change exists in that file', () => {
store.state.entries[file1.path].content = 'test';
store.state.stagedFiles = [file1];
store.state.changedFiles = [store.state.entries[file1.path]];
stageAllChanges(store);
expect(store.dispatch).not.toHaveBeenCalled();
});
});
describe('unstageAllChanges', () => {
it('removes all files from stagedFiles after unstaging', () => {
unstageAllChanges(store);
2020-06-23 00:09:42 +05:30
expect(store.commit.mock.calls).toEqual(
expect.arrayContaining([
[types.UNSTAGE_CHANGE, expect.objectContaining({ path: file2.path })],
]),
);
2020-03-13 15:44:24 +05:30
});
it('opens pending tab if a change exists in that file', () => {
unstageAllChanges(store);
2020-06-23 00:09:42 +05:30
expect(store.dispatch.mock.calls).toEqual([
2020-03-13 15:44:24 +05:30
['openPendingTab', { file: file1, keyPrefix: 'unstaged' }],
]);
});
it('does not open pending tab if no change exists in that file', () => {
store.state.entries[file1.path].content = 'test';
store.state.stagedFiles = [file1];
store.state.changedFiles = [store.state.entries[file1.path]];
unstageAllChanges(store);
expect(store.dispatch).not.toHaveBeenCalled();
});
2018-10-15 14:42:47 +05:30
});
});
2018-05-09 12:01:36 +05:30
describe('updateViewer', () => {
2021-03-08 18:12:59 +05:30
it('updates viewer state', (done) => {
2018-05-09 12:01:36 +05:30
store
.dispatch('updateViewer', 'diff')
.then(() => {
expect(store.state.viewer).toBe('diff');
})
.then(done)
.catch(done.fail);
});
});
2018-10-15 14:42:47 +05:30
describe('updateActivityBarView', () => {
2021-03-08 18:12:59 +05:30
it('commits UPDATE_ACTIVITY_BAR_VIEW', (done) => {
2018-10-15 14:42:47 +05:30
testAction(
updateActivityBarView,
'test',
{},
[{ type: 'UPDATE_ACTIVITY_BAR_VIEW', payload: 'test' }],
[],
done,
);
});
});
describe('setEmptyStateSvgs', () => {
2021-03-08 18:12:59 +05:30
it('commits setEmptyStateSvgs', (done) => {
2018-10-15 14:42:47 +05:30
testAction(
setEmptyStateSvgs,
'svg',
{},
[{ type: 'SET_EMPTY_STATE_SVGS', payload: 'svg' }],
[],
done,
);
});
});
describe('updateTempFlagForEntry', () => {
2021-03-08 18:12:59 +05:30
it('commits UPDATE_TEMP_FLAG', (done) => {
2018-10-15 14:42:47 +05:30
const f = {
...file(),
path: 'test',
tempFile: true,
};
store.state.entries[f.path] = f;
testAction(
updateTempFlagForEntry,
{ file: f, tempFile: false },
store.state,
[{ type: 'UPDATE_TEMP_FLAG', payload: { path: f.path, tempFile: false } }],
[],
done,
);
});
2021-03-08 18:12:59 +05:30
it('commits UPDATE_TEMP_FLAG and dispatches for parent', (done) => {
2018-10-15 14:42:47 +05:30
const parent = {
...file(),
path: 'testing',
};
const f = {
...file(),
path: 'test',
parentPath: 'testing',
};
store.state.entries[parent.path] = parent;
store.state.entries[f.path] = f;
testAction(
updateTempFlagForEntry,
{ file: f, tempFile: false },
store.state,
[{ type: 'UPDATE_TEMP_FLAG', payload: { path: f.path, tempFile: false } }],
[{ type: 'updateTempFlagForEntry', payload: { file: parent, tempFile: false } }],
done,
);
});
2019-12-21 20:55:43 +05:30
2021-03-08 18:12:59 +05:30
it('does not dispatch for parent, if parent does not exist', (done) => {
2019-12-21 20:55:43 +05:30
const f = {
...file(),
path: 'test',
parentPath: 'testing',
};
store.state.entries[f.path] = f;
testAction(
updateTempFlagForEntry,
{ file: f, tempFile: false },
store.state,
[{ type: 'UPDATE_TEMP_FLAG', payload: { path: f.path, tempFile: false } }],
[],
done,
);
});
2018-10-15 14:42:47 +05:30
});
describe('setCurrentBranchId', () => {
2021-03-08 18:12:59 +05:30
it('commits setCurrentBranchId', (done) => {
2018-10-15 14:42:47 +05:30
testAction(
setCurrentBranchId,
'branchId',
{},
[{ type: 'SET_CURRENT_BRANCH', payload: 'branchId' }],
[],
done,
);
});
});
describe('toggleFileFinder', () => {
2021-03-08 18:12:59 +05:30
it('commits TOGGLE_FILE_FINDER', (done) => {
2018-10-15 14:42:47 +05:30
testAction(
toggleFileFinder,
true,
null,
[{ type: 'TOGGLE_FILE_FINDER', payload: true }],
[],
done,
);
});
});
2018-11-08 19:23:39 +05:30
describe('setErrorMessage', () => {
2021-03-08 18:12:59 +05:30
it('commis error messsage', (done) => {
2018-11-08 19:23:39 +05:30
testAction(
setErrorMessage,
'error',
null,
[{ type: types.SET_ERROR_MESSAGE, payload: 'error' }],
[],
done,
);
});
});
2018-11-18 11:00:15 +05:30
describe('deleteEntry', () => {
2021-03-08 18:12:59 +05:30
it('commits entry deletion', (done) => {
2018-11-18 11:00:15 +05:30
store.state.entries.path = 'testing';
testAction(
deleteEntry,
'path',
store.state,
[{ type: types.DELETE_ENTRY, payload: 'path' }],
2021-01-29 00:20:46 +05:30
[{ type: 'stageChange', payload: 'path' }, createTriggerChangeAction()],
2019-09-30 21:07:59 +05:30
done,
);
});
2021-03-08 18:12:59 +05:30
it('does not delete a folder after it is emptied', (done) => {
2019-09-30 21:07:59 +05:30
const testFolder = {
type: 'tree',
tree: [],
};
const testEntry = {
path: 'testFolder/entry-to-delete',
parentPath: 'testFolder',
opened: false,
tree: [],
};
testFolder.tree.push(testEntry);
store.state.entries = {
testFolder,
'testFolder/entry-to-delete': testEntry,
};
testAction(
deleteEntry,
'testFolder/entry-to-delete',
store.state,
[{ type: types.DELETE_ENTRY, payload: 'testFolder/entry-to-delete' }],
[
{ type: 'stageChange', payload: 'testFolder/entry-to-delete' },
2021-01-29 00:20:46 +05:30
createTriggerChangeAction(),
2019-09-30 21:07:59 +05:30
],
2018-11-18 11:00:15 +05:30
done,
);
});
2020-03-13 15:44:24 +05:30
describe('when renamed', () => {
let testEntry;
2018-11-18 11:00:15 +05:30
2020-03-13 15:44:24 +05:30
beforeEach(() => {
testEntry = {
path: 'test',
name: 'test',
prevPath: 'test_old',
prevName: 'test_old',
prevParentPath: '',
};
store.state.entries = { test: testEntry };
});
describe('and previous does not exist', () => {
2021-03-08 18:12:59 +05:30
it('reverts the rename before deleting', (done) => {
2020-03-13 15:44:24 +05:30
testAction(
deleteEntry,
testEntry.path,
store.state,
[],
[
{
type: 'renameEntry',
payload: {
path: testEntry.path,
name: testEntry.prevName,
parentPath: testEntry.prevParentPath,
},
},
{
type: 'deleteEntry',
payload: testEntry.prevPath,
},
],
done,
);
});
});
describe('and previous exists', () => {
beforeEach(() => {
const oldEntry = {
path: testEntry.prevPath,
name: testEntry.prevName,
};
store.state.entries[oldEntry.path] = oldEntry;
});
2021-03-08 18:12:59 +05:30
it('does not revert rename before deleting', (done) => {
2020-03-13 15:44:24 +05:30
testAction(
deleteEntry,
testEntry.path,
store.state,
[{ type: types.DELETE_ENTRY, payload: testEntry.path }],
2021-01-29 00:20:46 +05:30
[{ type: 'stageChange', payload: testEntry.path }, createTriggerChangeAction()],
2020-03-13 15:44:24 +05:30
done,
);
});
2021-03-08 18:12:59 +05:30
it('when previous is deleted, it reverts rename before deleting', (done) => {
2020-03-13 15:44:24 +05:30
store.state.entries[testEntry.prevPath].deleted = true;
testAction(
deleteEntry,
testEntry.path,
store.state,
[],
[
{
type: 'renameEntry',
payload: {
path: testEntry.path,
name: testEntry.prevName,
parentPath: testEntry.prevParentPath,
},
},
{
type: 'deleteEntry',
payload: testEntry.prevPath,
},
],
done,
);
});
});
});
2019-12-21 20:55:43 +05:30
});
2018-11-18 11:00:15 +05:30
2019-12-21 20:55:43 +05:30
describe('renameEntry', () => {
describe('purging of file model cache', () => {
beforeEach(() => {
2020-06-23 00:09:42 +05:30
jest.spyOn(eventHub, '$emit').mockImplementation();
2019-12-21 20:55:43 +05:30
});
2021-03-08 18:12:59 +05:30
it('does not purge model cache for temporary entries that got renamed', (done) => {
2019-12-21 20:55:43 +05:30
Object.assign(store.state.entries, {
test: {
...file('test'),
key: 'foo-key',
type: 'blob',
tempFile: true,
2018-11-18 11:00:15 +05:30
},
2019-12-21 20:55:43 +05:30
});
2018-11-18 11:00:15 +05:30
2019-12-21 20:55:43 +05:30
store
.dispatch('renameEntry', {
path: 'test',
name: 'new',
})
.then(() => {
2020-06-23 00:09:42 +05:30
expect(eventHub.$emit.mock.calls).not.toContain('editor.update.model.dispose.foo-bar');
2019-12-21 20:55:43 +05:30
})
.then(done)
.catch(done.fail);
});
2021-03-08 18:12:59 +05:30
it('purges model cache for renamed entry', (done) => {
2019-12-21 20:55:43 +05:30
Object.assign(store.state.entries, {
test: {
...file('test'),
key: 'foo-key',
type: 'blob',
tempFile: false,
2018-11-18 11:00:15 +05:30
},
2019-12-21 20:55:43 +05:30
});
store
.dispatch('renameEntry', {
path: 'test',
name: 'new',
})
.then(() => {
expect(eventHub.$emit).toHaveBeenCalled();
expect(eventHub.$emit).toHaveBeenCalledWith(`editor.update.model.dispose.foo-key`);
})
.then(done)
.catch(done.fail);
});
});
describe('single entry', () => {
let origEntry;
let renamedEntry;
beforeEach(() => {
// Need to insert both because `testAction` doesn't actually call the mutation
origEntry = file('orig', 'orig', 'blob');
renamedEntry = {
...file('renamed', 'renamed', 'blob'),
prevKey: origEntry.key,
prevName: origEntry.name,
prevPath: origEntry.path,
};
Object.assign(store.state.entries, {
orig: origEntry,
renamed: renamedEntry,
});
});
2020-03-13 15:44:24 +05:30
it('by default renames an entry and stages it', () => {
2020-06-23 00:09:42 +05:30
const dispatch = jest.fn();
const commit = jest.fn();
2019-12-21 20:55:43 +05:30
2020-03-13 15:44:24 +05:30
renameEntry(
{ dispatch, commit, state: store.state, getters: store.getters },
2019-12-21 20:55:43 +05:30
{ path: 'orig', name: 'renamed' },
);
2020-03-13 15:44:24 +05:30
2020-06-23 00:09:42 +05:30
expect(commit.mock.calls).toEqual([
2020-03-13 15:44:24 +05:30
[types.RENAME_ENTRY, { path: 'orig', name: 'renamed', parentPath: undefined }],
2020-06-23 00:09:42 +05:30
[types.STAGE_CHANGE, expect.objectContaining({ path: 'renamed' })],
2020-03-13 15:44:24 +05:30
]);
2019-12-21 20:55:43 +05:30
});
2021-03-08 18:12:59 +05:30
it('if not changed, completely unstages and discards entry if renamed to original', (done) => {
2019-12-21 20:55:43 +05:30
testAction(
renameEntry,
{ path: 'renamed', name: 'orig' },
store.state,
[
{
type: types.RENAME_ENTRY,
payload: {
path: 'renamed',
name: 'orig',
parentPath: undefined,
},
},
{
type: types.REMOVE_FILE_FROM_STAGED_AND_CHANGED,
payload: origEntry,
},
],
2021-01-29 00:20:46 +05:30
[createTriggerRenameAction('renamed', 'orig')],
2019-12-21 20:55:43 +05:30
done,
);
});
2021-03-08 18:12:59 +05:30
it('if already in changed, does not add to change', (done) => {
2019-12-21 20:55:43 +05:30
store.state.changedFiles.push(renamedEntry);
testAction(
renameEntry,
{ path: 'orig', name: 'renamed' },
store.state,
2020-06-23 00:09:42 +05:30
[expect.objectContaining({ type: types.RENAME_ENTRY })],
2021-01-29 00:20:46 +05:30
[createTriggerRenameAction('orig', 'renamed')],
2019-12-21 20:55:43 +05:30
done,
);
});
2021-03-08 18:12:59 +05:30
it('routes to the renamed file if the original file has been opened', (done) => {
2020-11-24 15:15:51 +05:30
store.state.currentProjectId = 'test/test';
store.state.currentBranchId = 'master';
2019-12-21 20:55:43 +05:30
Object.assign(store.state.entries.orig, {
opened: true,
});
store
.dispatch('renameEntry', {
path: 'orig',
name: 'renamed',
})
.then(() => {
2020-06-23 00:09:42 +05:30
expect(router.push.mock.calls).toHaveLength(1);
2020-11-24 15:15:51 +05:30
expect(router.push).toHaveBeenCalledWith(`/project/test/test/tree/master/-/renamed/`);
2019-12-21 20:55:43 +05:30
})
.then(done)
.catch(done.fail);
});
});
describe('folder', () => {
let folder;
let file1;
let file2;
beforeEach(() => {
folder = file('folder', 'folder', 'tree');
file1 = file('file-1', 'file-1', 'blob', folder);
file2 = file('file-2', 'file-2', 'blob', folder);
folder.tree = [file1, file2];
Object.assign(store.state.entries, {
[folder.path]: folder,
[file1.path]: file1,
[file2.path]: file2,
});
});
2021-03-08 18:12:59 +05:30
it('updates entries in a folder correctly, when folder is renamed', (done) => {
2019-12-21 20:55:43 +05:30
store
.dispatch('renameEntry', {
path: 'folder',
name: 'new-folder',
})
.then(() => {
const keys = Object.keys(store.state.entries);
expect(keys.length).toBe(3);
expect(keys.indexOf('new-folder')).toBe(0);
expect(keys.indexOf('new-folder/file-1')).toBe(1);
expect(keys.indexOf('new-folder/file-2')).toBe(2);
})
.then(done)
.catch(done.fail);
});
2021-03-08 18:12:59 +05:30
it('discards renaming of an entry if the root folder is renamed back to a previous name', (done) => {
2019-12-21 20:55:43 +05:30
const rootFolder = file('old-folder', 'old-folder', 'tree');
const testEntry = file('test', 'test', 'blob', rootFolder);
Object.assign(store.state, {
entries: {
'old-folder': {
...rootFolder,
tree: [testEntry],
2019-07-07 11:18:12 +05:30
},
2019-12-21 20:55:43 +05:30
'old-folder/test': testEntry,
2019-07-07 11:18:12 +05:30
},
2019-12-21 20:55:43 +05:30
});
store
.dispatch('renameEntry', {
path: 'old-folder',
name: 'new-folder',
})
.then(() => {
const { entries } = store.state;
expect(Object.keys(entries).length).toBe(2);
expect(entries['old-folder']).toBeUndefined();
expect(entries['old-folder/test']).toBeUndefined();
expect(entries['new-folder']).toBeDefined();
expect(entries['new-folder/test']).toEqual(
2020-06-23 00:09:42 +05:30
expect.objectContaining({
2019-12-21 20:55:43 +05:30
path: 'new-folder/test',
name: 'test',
prevPath: 'old-folder/test',
prevName: 'test',
}),
);
})
.then(() =>
store.dispatch('renameEntry', {
path: 'new-folder',
name: 'old-folder',
}),
)
.then(() => {
const { entries } = store.state;
expect(Object.keys(entries).length).toBe(2);
expect(entries['new-folder']).toBeUndefined();
expect(entries['new-folder/test']).toBeUndefined();
expect(entries['old-folder']).toBeDefined();
expect(entries['old-folder/test']).toEqual(
2020-06-23 00:09:42 +05:30
expect.objectContaining({
2019-12-21 20:55:43 +05:30
path: 'old-folder/test',
name: 'test',
prevPath: undefined,
prevName: undefined,
}),
);
})
.then(done)
.catch(done.fail);
});
2020-03-13 15:44:24 +05:30
describe('with file in directory', () => {
const parentPath = 'original-dir';
const newParentPath = 'new-dir';
const fileName = 'test.md';
const filePath = `${parentPath}/${fileName}`;
let rootDir;
beforeEach(() => {
const parentEntry = file(parentPath, parentPath, 'tree');
const fileEntry = file(filePath, filePath, 'blob', parentEntry);
rootDir = {
tree: [],
};
Object.assign(store.state, {
entries: {
[parentPath]: {
...parentEntry,
tree: [fileEntry],
},
[filePath]: fileEntry,
},
trees: {
'/': rootDir,
},
});
});
2021-03-08 18:12:59 +05:30
it('creates new directory', (done) => {
2020-03-13 15:44:24 +05:30
expect(store.state.entries[newParentPath]).toBeUndefined();
store
.dispatch('renameEntry', { path: filePath, name: fileName, parentPath: newParentPath })
.then(() => {
expect(store.state.entries[newParentPath]).toEqual(
2020-06-23 00:09:42 +05:30
expect.objectContaining({
2020-03-13 15:44:24 +05:30
path: newParentPath,
type: 'tree',
2020-06-23 00:09:42 +05:30
tree: expect.arrayContaining([
2020-03-13 15:44:24 +05:30
store.state.entries[`${newParentPath}/${fileName}`],
]),
}),
);
})
.then(done)
.catch(done.fail);
});
describe('when new directory exists', () => {
let newDir;
beforeEach(() => {
newDir = file(newParentPath, newParentPath, 'tree');
store.state.entries[newDir.path] = newDir;
rootDir.tree.push(newDir);
});
2021-03-08 18:12:59 +05:30
it('inserts in new directory', (done) => {
2020-03-13 15:44:24 +05:30
expect(newDir.tree).toEqual([]);
store
.dispatch('renameEntry', {
path: filePath,
name: fileName,
parentPath: newParentPath,
})
.then(() => {
expect(newDir.tree).toEqual([store.state.entries[`${newParentPath}/${fileName}`]]);
})
.then(done)
.catch(done.fail);
});
2021-03-08 18:12:59 +05:30
it('when new directory is deleted, it undeletes it', (done) => {
2020-03-13 15:44:24 +05:30
store.dispatch('deleteEntry', newParentPath);
expect(store.state.entries[newParentPath].deleted).toBe(true);
2021-03-08 18:12:59 +05:30
expect(rootDir.tree.some((x) => x.path === newParentPath)).toBe(false);
2020-03-13 15:44:24 +05:30
store
.dispatch('renameEntry', {
path: filePath,
name: fileName,
parentPath: newParentPath,
})
.then(() => {
expect(store.state.entries[newParentPath].deleted).toBe(false);
2021-03-08 18:12:59 +05:30
expect(rootDir.tree.some((x) => x.path === newParentPath)).toBe(true);
2020-03-13 15:44:24 +05:30
})
.then(done)
.catch(done.fail);
});
});
});
2018-11-18 11:00:15 +05:30
});
});
2019-09-04 21:01:54 +05:30
describe('getBranchData', () => {
let mock;
beforeEach(() => {
mock = new MockAdapter(axios);
});
afterEach(() => {
mock.restore();
});
describe('error', () => {
let dispatch;
2020-03-13 15:44:24 +05:30
let callParams;
2019-09-04 21:01:54 +05:30
beforeEach(() => {
2020-03-13 15:44:24 +05:30
callParams = [
{
commit() {},
state: store.state,
},
{
projectId: 'abc/def',
branchId: 'master-testing',
},
];
2020-06-23 00:09:42 +05:30
dispatch = jest.fn();
2019-09-04 21:01:54 +05:30
document.body.innerHTML += '<div class="flash-container"></div>';
});
afterEach(() => {
document.querySelector('.flash-container').remove();
});
2021-03-08 18:12:59 +05:30
it('passes the error further unchanged without dispatching any action when response is 404', (done) => {
2019-09-04 21:01:54 +05:30
mock.onGet(/(.*)/).replyOnce(404);
getBranchData(...callParams)
.then(done.fail)
2021-03-08 18:12:59 +05:30
.catch((e) => {
2020-06-23 00:09:42 +05:30
expect(dispatch.mock.calls).toHaveLength(0);
2019-09-04 21:01:54 +05:30
expect(e.response.status).toEqual(404);
expect(document.querySelector('.flash-alert')).toBeNull();
done();
});
});
2021-03-08 18:12:59 +05:30
it('does not pass the error further and flashes an alert if error is not 404', (done) => {
2019-09-04 21:01:54 +05:30
mock.onGet(/(.*)/).replyOnce(418);
getBranchData(...callParams)
.then(done.fail)
2021-03-08 18:12:59 +05:30
.catch((e) => {
2020-06-23 00:09:42 +05:30
expect(dispatch.mock.calls).toHaveLength(0);
2019-09-04 21:01:54 +05:30
expect(e.response).toBeUndefined();
expect(document.querySelector('.flash-alert')).not.toBeNull();
done();
});
});
});
});
2018-05-09 12:01:36 +05:30
});