Merge branch 'ce-xanf-migrate-clientside-spec-to-jest' into 'master'
Resolve "Migrate spec/javascripts/ide/components/preview/clientside_spec.js to Jest" See merge request gitlab-org/gitlab-ce!32294
This commit is contained in:
commit
914af2f516
2 changed files with 318 additions and 363 deletions
318
spec/frontend/ide/components/preview/clientside_spec.js
Normal file
318
spec/frontend/ide/components/preview/clientside_spec.js
Normal file
|
@ -0,0 +1,318 @@
|
|||
import Vuex from 'vuex';
|
||||
import { GlLoadingIcon } from '@gitlab/ui';
|
||||
import { shallowMount, createLocalVue } from '@vue/test-utils';
|
||||
import smooshpack from 'smooshpack';
|
||||
import Clientside from '~/ide/components/preview/clientside.vue';
|
||||
|
||||
jest.mock('smooshpack', () => ({
|
||||
Manager: jest.fn(),
|
||||
}));
|
||||
|
||||
const localVue = createLocalVue();
|
||||
localVue.use(Vuex);
|
||||
|
||||
const dummyPackageJson = () => ({
|
||||
raw: JSON.stringify({
|
||||
main: 'index.js',
|
||||
}),
|
||||
});
|
||||
|
||||
describe('IDE clientside preview', () => {
|
||||
let wrapper;
|
||||
let store;
|
||||
const storeActions = {
|
||||
getFileData: jest.fn().mockReturnValue(Promise.resolve({})),
|
||||
getRawFileData: jest.fn().mockReturnValue(Promise.resolve('')),
|
||||
};
|
||||
|
||||
const waitForCalls = () => new Promise(setImmediate);
|
||||
|
||||
const createComponent = ({ state, getters } = {}) => {
|
||||
store = new Vuex.Store({
|
||||
state: {
|
||||
entries: {},
|
||||
links: {},
|
||||
...state,
|
||||
},
|
||||
getters: {
|
||||
packageJson: () => '',
|
||||
currentProject: () => ({
|
||||
visibility: 'public',
|
||||
}),
|
||||
...getters,
|
||||
},
|
||||
actions: storeActions,
|
||||
});
|
||||
|
||||
wrapper = shallowMount(Clientside, {
|
||||
sync: false,
|
||||
store,
|
||||
localVue,
|
||||
});
|
||||
};
|
||||
|
||||
beforeAll(() => {
|
||||
jest.useFakeTimers();
|
||||
});
|
||||
|
||||
afterAll(() => {
|
||||
jest.useRealTimers();
|
||||
});
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
wrapper.destroy();
|
||||
});
|
||||
|
||||
describe('without main entry', () => {
|
||||
it('creates sandpack manager', () => {
|
||||
createComponent();
|
||||
expect(smooshpack.Manager).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
describe('with main entry', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({ getters: { packageJson: dummyPackageJson } });
|
||||
return wrapper.vm.initPreview();
|
||||
});
|
||||
|
||||
it('creates sandpack manager', () => {
|
||||
expect(smooshpack.Manager).toHaveBeenCalledWith(
|
||||
'#ide-preview',
|
||||
{
|
||||
files: {},
|
||||
entry: '/index.js',
|
||||
showOpenInCodeSandbox: true,
|
||||
},
|
||||
{
|
||||
fileResolver: {
|
||||
isFile: expect.any(Function),
|
||||
readFile: expect.any(Function),
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('computed', () => {
|
||||
describe('normalizedEntries', () => {
|
||||
it('returns flattened list of blobs with content', () => {
|
||||
createComponent({
|
||||
state: {
|
||||
entries: {
|
||||
'index.js': { type: 'blob', raw: 'test' },
|
||||
'index2.js': { type: 'blob', content: 'content' },
|
||||
tree: { type: 'tree' },
|
||||
empty: { type: 'blob' },
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
expect(wrapper.vm.normalizedEntries).toEqual({
|
||||
'/index.js': {
|
||||
code: 'test',
|
||||
},
|
||||
'/index2.js': {
|
||||
code: 'content',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mainEntry', () => {
|
||||
it('returns false when package.json is empty', () => {
|
||||
createComponent();
|
||||
expect(wrapper.vm.mainEntry).toBe(false);
|
||||
});
|
||||
|
||||
it('returns main key from package.json', () => {
|
||||
createComponent({ getters: { packageJson: dummyPackageJson } });
|
||||
expect(wrapper.vm.mainEntry).toBe('index.js');
|
||||
});
|
||||
});
|
||||
|
||||
describe('showPreview', () => {
|
||||
it('returns false if no mainEntry', () => {
|
||||
createComponent();
|
||||
expect(wrapper.vm.showPreview).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false if loading and mainEntry exists', () => {
|
||||
createComponent({ getters: { packageJson: dummyPackageJson } });
|
||||
wrapper.setData({ loading: true });
|
||||
|
||||
expect(wrapper.vm.showPreview).toBe(false);
|
||||
});
|
||||
|
||||
it('returns true if not loading and mainEntry exists', () => {
|
||||
createComponent({ getters: { packageJson: dummyPackageJson } });
|
||||
wrapper.setData({ loading: false });
|
||||
|
||||
expect(wrapper.vm.showPreview).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('showEmptyState', () => {
|
||||
it('returns true if no mainEntry exists', () => {
|
||||
createComponent();
|
||||
wrapper.setData({ loading: false });
|
||||
expect(wrapper.vm.showEmptyState).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false if loading', () => {
|
||||
createComponent();
|
||||
wrapper.setData({ loading: true });
|
||||
|
||||
expect(wrapper.vm.showEmptyState).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false if not loading and mainEntry exists', () => {
|
||||
createComponent({ getters: { packageJson: dummyPackageJson } });
|
||||
wrapper.setData({ loading: false });
|
||||
|
||||
expect(wrapper.vm.showEmptyState).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('showOpenInCodeSandbox', () => {
|
||||
it('returns true when visiblity is public', () => {
|
||||
createComponent({ getters: { currentProject: () => ({ visibility: 'public' }) } });
|
||||
|
||||
expect(wrapper.vm.showOpenInCodeSandbox).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false when visiblity is private', () => {
|
||||
createComponent({ getters: { currentProject: () => ({ visibility: 'private' }) } });
|
||||
|
||||
expect(wrapper.vm.showOpenInCodeSandbox).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('sandboxOpts', () => {
|
||||
beforeEach(() => {
|
||||
createComponent({
|
||||
state: {
|
||||
entries: {
|
||||
'index.js': { type: 'blob', raw: 'test' },
|
||||
'package.json': dummyPackageJson(),
|
||||
},
|
||||
},
|
||||
getters: {
|
||||
packageJson: dummyPackageJson,
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('returns sandbox options', () => {
|
||||
expect(wrapper.vm.sandboxOpts).toEqual({
|
||||
files: {
|
||||
'/index.js': {
|
||||
code: 'test',
|
||||
},
|
||||
'/package.json': {
|
||||
code: '{"main":"index.js"}',
|
||||
},
|
||||
},
|
||||
entry: '/index.js',
|
||||
showOpenInCodeSandbox: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('methods', () => {
|
||||
describe('loadFileContent', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
return wrapper.vm.loadFileContent('package.json');
|
||||
});
|
||||
|
||||
it('calls getFileData', () => {
|
||||
expect(storeActions.getFileData).toHaveBeenCalledWith(
|
||||
expect.any(Object),
|
||||
{
|
||||
path: 'package.json',
|
||||
makeFileActive: false,
|
||||
},
|
||||
undefined, // vuex callback
|
||||
);
|
||||
});
|
||||
|
||||
it('calls getRawFileData', () => {
|
||||
expect(storeActions.getRawFileData).toHaveBeenCalledWith(
|
||||
expect.any(Object),
|
||||
{
|
||||
path: 'package.json',
|
||||
},
|
||||
undefined, // vuex callback
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', () => {
|
||||
beforeEach(() => {
|
||||
createComponent();
|
||||
wrapper.setData({ sandpackReady: true });
|
||||
});
|
||||
|
||||
it('initializes manager if manager is empty', () => {
|
||||
createComponent({ getters: { packageJson: dummyPackageJson } });
|
||||
wrapper.setData({ sandpackReady: true });
|
||||
wrapper.vm.update();
|
||||
|
||||
jest.advanceTimersByTime(250);
|
||||
|
||||
return waitForCalls().then(() => {
|
||||
expect(smooshpack.Manager).toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
it('calls updatePreview', () => {
|
||||
wrapper.setData({
|
||||
manager: {
|
||||
listener: jest.fn(),
|
||||
updatePreview: jest.fn(),
|
||||
},
|
||||
});
|
||||
wrapper.vm.update();
|
||||
|
||||
jest.advanceTimersByTime(250);
|
||||
expect(wrapper.vm.manager.updatePreview).toHaveBeenCalledWith(wrapper.vm.sandboxOpts);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('template', () => {
|
||||
it('renders ide-preview element when showPreview is true', () => {
|
||||
createComponent({ getters: { packageJson: dummyPackageJson } });
|
||||
wrapper.setData({ loading: false });
|
||||
|
||||
return wrapper.vm.$nextTick(() => {
|
||||
expect(wrapper.find('#ide-preview').exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders empty state', () => {
|
||||
createComponent();
|
||||
wrapper.setData({ loading: false });
|
||||
|
||||
return wrapper.vm.$nextTick(() => {
|
||||
expect(wrapper.text()).toContain(
|
||||
'Preview your web application using Web IDE client-side evaluation.',
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
it('renders loading icon', () => {
|
||||
createComponent();
|
||||
wrapper.setData({ loading: true });
|
||||
|
||||
return wrapper.vm.$nextTick(() => {
|
||||
expect(wrapper.find(GlLoadingIcon).exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,363 +0,0 @@
|
|||
import Vue from 'vue';
|
||||
import { createComponentWithStore } from 'spec/helpers/vue_mount_component_helper';
|
||||
import { createStore } from '~/ide/stores';
|
||||
import Clientside from '~/ide/components/preview/clientside.vue';
|
||||
import timeoutPromise from 'spec/helpers/set_timeout_promise_helper';
|
||||
import { resetStore, file } from '../../helpers';
|
||||
|
||||
describe('IDE clientside preview', () => {
|
||||
let vm;
|
||||
let Component;
|
||||
|
||||
beforeAll(() => {
|
||||
Component = Vue.extend(Clientside);
|
||||
});
|
||||
|
||||
beforeEach(done => {
|
||||
const store = createStore();
|
||||
|
||||
Vue.set(store.state.entries, 'package.json', {
|
||||
...file('package.json'),
|
||||
});
|
||||
Vue.set(store.state, 'currentProjectId', 'gitlab-ce');
|
||||
Vue.set(store.state.projects, 'gitlab-ce', {
|
||||
visibility: 'public',
|
||||
});
|
||||
|
||||
vm = createComponentWithStore(Component, store);
|
||||
|
||||
spyOn(vm, 'getFileData').and.returnValue(Promise.resolve());
|
||||
spyOn(vm, 'getRawFileData').and.returnValue(Promise.resolve(''));
|
||||
spyOn(vm, 'initManager');
|
||||
|
||||
vm.$mount();
|
||||
|
||||
timeoutPromise()
|
||||
.then(() => vm.$nextTick())
|
||||
.then(done)
|
||||
.catch(done.fail);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
vm.$destroy();
|
||||
resetStore(vm.$store);
|
||||
});
|
||||
|
||||
describe('without main entry', () => {
|
||||
it('creates sandpack manager', () => {
|
||||
expect(vm.initManager).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
describe('with main entry', () => {
|
||||
beforeEach(done => {
|
||||
Vue.set(
|
||||
vm.$store.state.entries['package.json'],
|
||||
'raw',
|
||||
JSON.stringify({
|
||||
main: 'index.js',
|
||||
}),
|
||||
);
|
||||
|
||||
vm.$nextTick()
|
||||
.then(() => vm.initPreview())
|
||||
.then(vm.$nextTick)
|
||||
.then(done)
|
||||
.catch(done.fail);
|
||||
});
|
||||
|
||||
it('creates sandpack manager', () => {
|
||||
expect(vm.initManager).toHaveBeenCalledWith(
|
||||
'#ide-preview',
|
||||
{
|
||||
files: jasmine.any(Object),
|
||||
entry: '/index.js',
|
||||
showOpenInCodeSandbox: true,
|
||||
},
|
||||
{
|
||||
fileResolver: {
|
||||
isFile: jasmine.any(Function),
|
||||
readFile: jasmine.any(Function),
|
||||
},
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('computed', () => {
|
||||
describe('normalizedEntries', () => {
|
||||
beforeEach(done => {
|
||||
vm.$store.state.entries['index.js'] = {
|
||||
...file('index.js'),
|
||||
type: 'blob',
|
||||
raw: 'test',
|
||||
};
|
||||
vm.$store.state.entries['index2.js'] = {
|
||||
...file('index2.js'),
|
||||
type: 'blob',
|
||||
content: 'content',
|
||||
};
|
||||
vm.$store.state.entries.tree = {
|
||||
...file('tree'),
|
||||
type: 'tree',
|
||||
};
|
||||
vm.$store.state.entries.empty = {
|
||||
...file('empty'),
|
||||
type: 'blob',
|
||||
};
|
||||
|
||||
vm.$nextTick(done);
|
||||
});
|
||||
|
||||
it('returns flattened list of blobs with content', () => {
|
||||
expect(vm.normalizedEntries).toEqual({
|
||||
'/index.js': {
|
||||
code: 'test',
|
||||
},
|
||||
'/index2.js': {
|
||||
code: 'content',
|
||||
},
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('mainEntry', () => {
|
||||
it('returns false when package.json is empty', () => {
|
||||
expect(vm.mainEntry).toBe(false);
|
||||
});
|
||||
|
||||
it('returns main key from package.json', done => {
|
||||
Vue.set(
|
||||
vm.$store.state.entries['package.json'],
|
||||
'raw',
|
||||
JSON.stringify({
|
||||
main: 'index.js',
|
||||
}),
|
||||
);
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.mainEntry).toBe('index.js');
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('showPreview', () => {
|
||||
it('returns false if no mainEntry', () => {
|
||||
expect(vm.showPreview).toBe(false);
|
||||
});
|
||||
|
||||
it('returns false if loading', done => {
|
||||
Vue.set(
|
||||
vm.$store.state.entries['package.json'],
|
||||
'raw',
|
||||
JSON.stringify({
|
||||
main: 'index.js',
|
||||
}),
|
||||
);
|
||||
vm.loading = true;
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.showPreview).toBe(false);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('returns true if not loading and mainEntry exists', done => {
|
||||
Vue.set(
|
||||
vm.$store.state.entries['package.json'],
|
||||
'raw',
|
||||
JSON.stringify({
|
||||
main: 'index.js',
|
||||
}),
|
||||
);
|
||||
vm.loading = false;
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.showPreview).toBe(true);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('showEmptyState', () => {
|
||||
it('returns true if no mainEnry exists', () => {
|
||||
expect(vm.showEmptyState).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false if loading', done => {
|
||||
Vue.set(
|
||||
vm.$store.state.entries['package.json'],
|
||||
'raw',
|
||||
JSON.stringify({
|
||||
main: 'index.js',
|
||||
}),
|
||||
);
|
||||
vm.loading = true;
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.showEmptyState).toBe(false);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('returns false if not loading and mainEntry exists', done => {
|
||||
Vue.set(
|
||||
vm.$store.state.entries['package.json'],
|
||||
'raw',
|
||||
JSON.stringify({
|
||||
main: 'index.js',
|
||||
}),
|
||||
);
|
||||
vm.loading = false;
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.showEmptyState).toBe(false);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('showOpenInCodeSandbox', () => {
|
||||
it('returns true when visiblity is public', () => {
|
||||
expect(vm.showOpenInCodeSandbox).toBe(true);
|
||||
});
|
||||
|
||||
it('returns false when visiblity is private', done => {
|
||||
vm.$store.state.projects['gitlab-ce'].visibility = 'private';
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.showOpenInCodeSandbox).toBe(false);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('sandboxOpts', () => {
|
||||
beforeEach(done => {
|
||||
vm.$store.state.entries['index.js'] = {
|
||||
...file('index.js'),
|
||||
type: 'blob',
|
||||
raw: 'test',
|
||||
};
|
||||
Vue.set(
|
||||
vm.$store.state.entries['package.json'],
|
||||
'raw',
|
||||
JSON.stringify({
|
||||
main: 'index.js',
|
||||
}),
|
||||
);
|
||||
|
||||
vm.$nextTick(done);
|
||||
});
|
||||
|
||||
it('returns sandbox options', () => {
|
||||
expect(vm.sandboxOpts).toEqual({
|
||||
files: {
|
||||
'/index.js': {
|
||||
code: 'test',
|
||||
},
|
||||
'/package.json': {
|
||||
code: '{"main":"index.js"}',
|
||||
},
|
||||
},
|
||||
entry: '/index.js',
|
||||
showOpenInCodeSandbox: true,
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('methods', () => {
|
||||
describe('loadFileContent', () => {
|
||||
it('calls getFileData', () => {
|
||||
expect(vm.getFileData).toHaveBeenCalledWith({
|
||||
path: 'package.json',
|
||||
makeFileActive: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('calls getRawFileData', () => {
|
||||
expect(vm.getRawFileData).toHaveBeenCalledWith({ path: 'package.json' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('update', () => {
|
||||
beforeEach(() => {
|
||||
jasmine.clock().install();
|
||||
|
||||
vm.sandpackReady = true;
|
||||
vm.manager.updatePreview = jasmine.createSpy('updatePreview');
|
||||
vm.manager.listener = jasmine.createSpy('updatePreview');
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
jasmine.clock().uninstall();
|
||||
});
|
||||
|
||||
it('calls initPreview if manager is empty', () => {
|
||||
spyOn(vm, 'initPreview');
|
||||
vm.manager = {};
|
||||
|
||||
vm.update();
|
||||
|
||||
jasmine.clock().tick(250);
|
||||
|
||||
expect(vm.initPreview).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('calls updatePreview', () => {
|
||||
vm.update();
|
||||
|
||||
jasmine.clock().tick(250);
|
||||
|
||||
expect(vm.manager.updatePreview).toHaveBeenCalledWith(vm.sandboxOpts);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('template', () => {
|
||||
it('renders ide-preview element when showPreview is true', done => {
|
||||
Vue.set(
|
||||
vm.$store.state.entries['package.json'],
|
||||
'raw',
|
||||
JSON.stringify({
|
||||
main: 'index.js',
|
||||
}),
|
||||
);
|
||||
vm.loading = false;
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.$el.querySelector('#ide-preview')).not.toBe(null);
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders empty state', done => {
|
||||
vm.loading = false;
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.$el.textContent).toContain(
|
||||
'Preview your web application using Web IDE client-side evaluation.',
|
||||
);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
it('renders loading icon', done => {
|
||||
vm.loading = true;
|
||||
|
||||
vm.$nextTick(() => {
|
||||
expect(vm.$el.querySelector('.loading-container')).not.toBe(null);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
Loading…
Reference in a new issue