Commit f3891d9d authored by Himanshu Kapoor's avatar Himanshu Kapoor

Web IDE: Port Web Terminal from EE to Core

Move Web terminal code from EE to core.
parent e5dadb8e
<script> <script>
import Vue from 'vue';
import { mapActions, mapGetters, mapState } from 'vuex'; import { mapActions, mapGetters, mapState } from 'vuex';
import { GlDeprecatedButton, GlLoadingIcon } from '@gitlab/ui'; import { GlDeprecatedButton, GlLoadingIcon } from '@gitlab/ui';
import { __ } from '~/locale'; import { __ } from '~/locale';
...@@ -27,15 +26,9 @@ export default { ...@@ -27,15 +26,9 @@ export default {
CommitEditorHeader, CommitEditorHeader,
GlDeprecatedButton, GlDeprecatedButton,
GlLoadingIcon, GlLoadingIcon,
RightPane,
}, },
mixins: [glFeatureFlagsMixin()], mixins: [glFeatureFlagsMixin()],
props: {
rightPaneComponent: {
type: Vue.Component,
required: false,
default: () => RightPane,
},
},
computed: { computed: {
...mapState([ ...mapState([
'openFiles', 'openFiles',
...@@ -160,7 +153,7 @@ export default { ...@@ -160,7 +153,7 @@ export default {
</div> </div>
</template> </template>
</div> </div>
<component :is="rightPaneComponent" v-if="currentProjectId" /> <right-pane v-if="currentProjectId" />
</div> </div>
<ide-status-bar /> <ide-status-bar />
<new-modal ref="newModal" /> <new-modal ref="newModal" />
......
<script> <script>
/* eslint-disable @gitlab/vue-require-i18n-strings */ /* eslint-disable @gitlab/vue-require-i18n-strings */
import { mapActions, mapState, mapGetters } from 'vuex'; import { mapActions, mapState, mapGetters } from 'vuex';
import IdeStatusList from 'ee_else_ce/ide/components/ide_status_list.vue'; import IdeStatusList from './ide_status_list.vue';
import IdeStatusMr from './ide_status_mr.vue'; import IdeStatusMr from './ide_status_mr.vue';
import icon from '~/vue_shared/components/icon.vue'; import icon from '~/vue_shared/components/icon.vue';
import tooltip from '~/vue_shared/directives/tooltip'; import tooltip from '~/vue_shared/directives/tooltip';
......
<script> <script>
import { mapGetters } from 'vuex'; import { mapGetters } from 'vuex';
import TerminalSyncStatusSafe from './terminal_sync/terminal_sync_status_safe.vue';
export default { export default {
components: {
TerminalSyncStatusSafe,
},
computed: { computed: {
...mapGetters(['activeFile']), ...mapGetters(['activeFile']),
}, },
...@@ -18,6 +22,6 @@ export default { ...@@ -18,6 +22,6 @@ export default {
</div> </div>
<div class="ide-status-file">{{ activeFile.fileLanguage }}</div> <div class="ide-status-file">{{ activeFile.fileLanguage }}</div>
</template> </template>
<slot></slot> <terminal-sync-status-safe />
</div> </div>
</template> </template>
...@@ -7,6 +7,7 @@ import { rightSidebarViews, SIDEBAR_INIT_WIDTH, SIDEBAR_NAV_WIDTH } from '../../ ...@@ -7,6 +7,7 @@ import { rightSidebarViews, SIDEBAR_INIT_WIDTH, SIDEBAR_NAV_WIDTH } from '../../
import PipelinesList from '../pipelines/list.vue'; import PipelinesList from '../pipelines/list.vue';
import JobsDetail from '../jobs/detail.vue'; import JobsDetail from '../jobs/detail.vue';
import Clientside from '../preview/clientside.vue'; import Clientside from '../preview/clientside.vue';
import TerminalView from '../terminal/view.vue';
// Need to add the width of the nav buttons since the resizable container contains those as well // Need to add the width of the nav buttons since the resizable container contains those as well
const WIDTH = SIDEBAR_INIT_WIDTH + SIDEBAR_NAV_WIDTH; const WIDTH = SIDEBAR_INIT_WIDTH + SIDEBAR_NAV_WIDTH;
...@@ -17,14 +18,8 @@ export default { ...@@ -17,14 +18,8 @@ export default {
CollapsibleSidebar, CollapsibleSidebar,
ResizablePanel, ResizablePanel,
}, },
props: {
extensionTabs: {
type: Array,
required: false,
default: () => [],
},
},
computed: { computed: {
...mapState('terminal', { isTerminalVisible: 'isVisible' }),
...mapState(['currentMergeRequestId', 'clientsidePreviewEnabled']), ...mapState(['currentMergeRequestId', 'clientsidePreviewEnabled']),
...mapGetters(['packageJson']), ...mapGetters(['packageJson']),
...mapState('rightPane', ['isOpen']), ...mapState('rightPane', ['isOpen']),
...@@ -48,7 +43,12 @@ export default { ...@@ -48,7 +43,12 @@ export default {
views: [{ component: Clientside, ...rightSidebarViews.clientSidePreview }], views: [{ component: Clientside, ...rightSidebarViews.clientSidePreview }],
icon: 'live-preview', icon: 'live-preview',
}, },
...this.extensionTabs, {
show: this.isTerminalVisible,
title: __('Terminal'),
views: [{ component: TerminalView, ...rightSidebarViews.terminal }],
icon: 'terminal',
},
]; ];
}, },
}, },
......
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
import { mapActions, mapState } from 'vuex'; import { mapActions, mapState } from 'vuex';
import { __ } from '~/locale'; import { __ } from '~/locale';
import Terminal from './terminal.vue'; import Terminal from './terminal.vue';
import { isEndingStatus } from '../../utils'; import { isEndingStatus } from '../../stores/modules/terminal/utils';
export default { export default {
components: { components: {
......
...@@ -4,8 +4,8 @@ import { GlLoadingIcon } from '@gitlab/ui'; ...@@ -4,8 +4,8 @@ import { GlLoadingIcon } from '@gitlab/ui';
import { __ } from '~/locale'; import { __ } from '~/locale';
import GLTerminal from '~/terminal/terminal'; import GLTerminal from '~/terminal/terminal';
import TerminalControls from './terminal_controls.vue'; import TerminalControls from './terminal_controls.vue';
import { RUNNING, STOPPING } from '../../constants'; import { RUNNING, STOPPING } from '../../stores/modules/terminal/constants';
import { isStartingStatus } from '../../utils'; import { isStartingStatus } from '../../stores/modules/terminal/utils';
export default { export default {
components: { components: {
......
...@@ -7,7 +7,7 @@ import { ...@@ -7,7 +7,7 @@ import {
MSG_TERMINAL_SYNC_CONNECTING, MSG_TERMINAL_SYNC_CONNECTING,
MSG_TERMINAL_SYNC_UPLOADING, MSG_TERMINAL_SYNC_UPLOADING,
MSG_TERMINAL_SYNC_RUNNING, MSG_TERMINAL_SYNC_RUNNING,
} from '../../messages'; } from '../../stores/modules/terminal_sync/messages';
export default { export default {
components: { components: {
......
...@@ -57,6 +57,7 @@ export const rightSidebarViews = { ...@@ -57,6 +57,7 @@ export const rightSidebarViews = {
jobsDetail: { name: 'jobs-detail', keepAlive: false }, jobsDetail: { name: 'jobs-detail', keepAlive: false },
mergeRequestInfo: { name: 'merge-request-info', keepAlive: true }, mergeRequestInfo: { name: 'merge-request-info', keepAlive: true },
clientSidePreview: { name: 'clientside', keepAlive: false }, clientSidePreview: { name: 'clientside', keepAlive: false },
terminal: { name: 'terminal', keepAlive: true },
}; };
export const stageKeys = { export const stageKeys = {
......
...@@ -2,7 +2,7 @@ import Api from '~/api'; ...@@ -2,7 +2,7 @@ import Api from '~/api';
import httpStatus from '~/lib/utils/http_status'; import httpStatus from '~/lib/utils/http_status';
import * as types from '../mutation_types'; import * as types from '../mutation_types';
import * as messages from '../messages'; import * as messages from '../messages';
import { CHECK_CONFIG, CHECK_RUNNERS, RETRY_RUNNERS_INTERVAL } from '../../../../constants'; import { CHECK_CONFIG, CHECK_RUNNERS, RETRY_RUNNERS_INTERVAL } from '../constants';
import * as terminalService from '../../../../services/terminals'; import * as terminalService from '../../../../services/terminals';
export const requestConfigCheck = ({ commit }) => { export const requestConfigCheck = ({ commit }) => {
......
...@@ -4,7 +4,7 @@ import flash from '~/flash'; ...@@ -4,7 +4,7 @@ import flash from '~/flash';
import * as types from '../mutation_types'; import * as types from '../mutation_types';
import * as messages from '../messages'; import * as messages from '../messages';
import * as terminalService from '../../../../services/terminals'; import * as terminalService from '../../../../services/terminals';
import { STARTING, STOPPING, STOPPED } from '../../../../constants'; import { STARTING, STOPPING, STOPPED } from '../constants';
export const requestStartSession = ({ commit }) => { export const requestStartSession = ({ commit }) => {
commit(types.SET_SESSION_STATUS, STARTING); commit(types.SET_SESSION_STATUS, STARTING);
......
...@@ -2,7 +2,7 @@ import axios from '~/lib/utils/axios_utils'; ...@@ -2,7 +2,7 @@ import axios from '~/lib/utils/axios_utils';
import flash from '~/flash'; import flash from '~/flash';
import * as types from '../mutation_types'; import * as types from '../mutation_types';
import * as messages from '../messages'; import * as messages from '../messages';
import { isEndingStatus } from '../../../../utils'; import { isEndingStatus } from '../utils';
export const pollSessionStatus = ({ state, dispatch, commit }) => { export const pollSessionStatus = ({ state, dispatch, commit }) => {
dispatch('stopPollingSessionStatus'); dispatch('stopPollingSessionStatus');
......
import { CHECK_CONFIG, CHECK_RUNNERS } from '../../../constants'; import { CHECK_CONFIG, CHECK_RUNNERS } from './constants';
export default () => ({ export default () => ({
checks: { checks: {
......
import { debounce } from 'lodash'; import { debounce } from 'lodash';
import eventHub from '~/ide/eventhub'; import eventHub from '~/ide/eventhub';
import terminalSyncModule from '../modules/terminal_sync'; import terminalSyncModule from '../modules/terminal_sync';
import { isEndingStatus, isRunningStatus } from '../../utils'; import { isEndingStatus, isRunningStatus } from '../modules/terminal/utils';
const UPLOAD_DEBOUNCE = 200; const UPLOAD_DEBOUNCE = 200;
......
import { startIde } from '~/ide/index'; import { startIde } from '~/ide/index';
import extendStore from '~/ide/stores/extend';
startIde(); startIde({ extendStore });
...@@ -887,6 +887,7 @@ $ide-commit-header-height: 48px; ...@@ -887,6 +887,7 @@ $ide-commit-header-height: 48px;
padding-bottom: 0; padding-bottom: 0;
} }
.ide-right-sidebar-terminal,
.ide-right-sidebar-clientside { .ide-right-sidebar-clientside {
padding: 0; padding: 0;
} }
...@@ -1154,3 +1155,22 @@ $ide-commit-header-height: 48px; ...@@ -1154,3 +1155,22 @@ $ide-commit-header-height: 48px;
fill: var(--ide-text-color-secondary, $gl-text-color-secondary); fill: var(--ide-text-color-secondary, $gl-text-color-secondary);
} }
} }
.ide-terminal {
@include ide-trace-view();
.terminal-wrapper {
background: $black;
color: $gray-darkest;
overflow: hidden;
}
.xterm {
height: 100%;
padding: $grid-size;
}
.xterm-viewport {
overflow-y: auto;
}
}
<script>
import Ide from '~/ide/components/ide.vue';
import EERightPane from './panes/right.vue';
export default {
// name: 'EEIde' is a false positive: https://gitlab.com/gitlab-org/frontend/eslint-plugin-i18n/issues/25
// eslint-disable-next-line @gitlab/require-i18n-strings
name: 'EEIde',
components: {
Ide,
},
EERightPane,
};
</script>
<template>
<ide :right-pane-component="$options.EERightPane" />
</template>
<script>
import IdeStatusList from '~/ide/components/ide_status_list.vue';
import TerminalSyncStatusSafe from './terminal_sync/terminal_sync_status_safe.vue';
export default {
components: {
IdeStatusList,
TerminalSyncStatusSafe,
},
};
</script>
<template>
<ide-status-list>
<terminal-sync-status-safe />
</ide-status-list>
</template>
<script>
import { mapState } from 'vuex';
import { __ } from '~/locale';
import RightPane from '~/ide/components/panes/right.vue';
import TerminalView from '../terminal/view.vue';
export default {
name: 'EERightPane',
components: {
RightPane,
},
computed: {
...mapState('terminal', {
isTerminalVisible: 'isVisible',
}),
extensionTabs() {
return [
{
show: this.isTerminalVisible,
title: __('Terminal'),
views: [{ name: 'terminal', keepAlive: true, component: TerminalView }],
icon: 'terminal',
},
];
},
},
};
</script>
<template>
<right-pane :extension-tabs="extensionTabs" />
</template>
import EEIde from 'ee/ide/components/ide.vue';
import extendStore from 'ee/ide/stores/extend';
import { startIde } from '~/ide/index';
startIde({
extendStore,
rootComponent: EEIde,
});
...@@ -3,5 +3,4 @@ ...@@ -3,5 +3,4 @@
*/ */
@import '../components/**/*'; @import '../components/**/*';
@import '../framework/**/*'; @import '../framework/**/*';
@import '../page_bundles/**/*';
@import '../pages/**/*'; @import '../pages/**/*';
@import 'page_bundles/ide_mixins';
.ide-right-sidebar {
.multi-file-commit-panel-inner.ide-right-sidebar-terminal {
padding: 0;
}
}
.ide-terminal {
@include ide-trace-view();
.terminal-wrapper {
background: $black;
color: $gray-darkest;
overflow: hidden;
}
.xterm {
height: 100%;
padding: $grid-size;
}
.xterm-viewport {
overflow-y: auto;
}
}
import Vuex from 'vuex';
import { mount, createLocalVue } from '@vue/test-utils';
import TerminalSyncStatusSafe from 'ee/ide/components/terminal_sync/terminal_sync_status_safe.vue';
import IdeStatusList from 'ee/ide/components/ide_status_list.vue';
import { createStore } from '~/ide/stores';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('ee/ide/components/ide_status_list', () => {
let store;
let wrapper;
const createComponent = () => {
store = createStore();
wrapper = mount(IdeStatusList, {
localVue,
store,
});
};
afterEach(() => {
wrapper.destroy();
});
it('renders terminal sync status', () => {
createComponent();
expect(wrapper.find(TerminalSyncStatusSafe).exists()).toBe(true);
});
});
import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex';
import EERightPane from 'ee/ide/components/panes/right.vue';
import RightPane from '~/ide/components/panes/right.vue';
const localVue = createLocalVue();
localVue.use(Vuex);
describe('IDE EERightPane', () => {
let wrapper;
let terminalState;
const factory = () => {
const store = new Vuex.Store({
modules: {
terminal: {
namespaced: true,
state: terminalState,
},
},
});
wrapper = shallowMount(EERightPane, { localVue, store });
};
beforeEach(() => {
terminalState = {};
});
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
it('adds terminal tab', () => {
terminalState.isVisible = true;
factory();
expect(wrapper.find(RightPane).props('extensionTabs')).toEqual([
expect.objectContaining({
show: true,
title: 'Terminal',
}),
]);
});
it('hides terminal tab when not visible', () => {
terminalState.isVisible = false;
factory();
expect(wrapper.find(RightPane).props('extensionTabs')).toEqual([
expect.objectContaining({
show: false,
title: 'Terminal',
}),
]);
});
});
...@@ -20,11 +20,11 @@ module QA ...@@ -20,11 +20,11 @@ module QA
element :terminal_tab_button, %q(:data-qa-selector="`${tab.title.toLowerCase()}_tab_button`") # rubocop:disable QA/ElementWithPattern element :terminal_tab_button, %q(:data-qa-selector="`${tab.title.toLowerCase()}_tab_button`") # rubocop:disable QA/ElementWithPattern
end end
view 'ee/app/assets/javascripts/ide/components/terminal/empty_state.vue' do view 'app/assets/javascripts/ide/components/terminal/empty_state.vue' do
element :start_web_terminal_button element :start_web_terminal_button
end end
view 'ee/app/assets/javascripts/ide/components/terminal/terminal.vue' do view 'app/assets/javascripts/ide/components/terminal/terminal.vue' do
element :loading_container element :loading_container
element :terminal_screen element :terminal_screen
end end
......
...@@ -20,7 +20,7 @@ const TEST_CURRENT_INDEX = 1; ...@@ -20,7 +20,7 @@ const TEST_CURRENT_INDEX = 1;
const TEST_CURRENT_VIEW = TEST_TABS[TEST_CURRENT_INDEX].views[1].name; const TEST_CURRENT_VIEW = TEST_TABS[TEST_CURRENT_INDEX].views[1].name;
const TEST_OPEN_VIEW = TEST_TABS[TEST_CURRENT_INDEX].views[0]; const TEST_OPEN_VIEW = TEST_TABS[TEST_CURRENT_INDEX].views[0];
describe('~/ide/components/ide_sidebar_nav', () => { describe('ide/components/ide_sidebar_nav', () => {
let wrapper; let wrapper;
const createComponent = (props = {}) => { const createComponent = (props = {}) => {
......
import Vue from 'vue'; import Vue from 'vue';
import { createComponentWithStore } from 'helpers/vue_mount_component_helper'; import { createComponentWithStore } from 'helpers/vue_mount_component_helper';
import store from '~/ide/stores'; import { createStore } from '~/ide/stores';
import ide from '~/ide/components/ide.vue'; import ide from '~/ide/components/ide.vue';
import { file, resetStore } from '../helpers'; import { file, resetStore } from '../helpers';
import { projectData } from '../mock_data'; import { projectData } from '../mock_data';
import extendStore from '~/ide/stores/extend';
let store;
function bootstrap(projData) { function bootstrap(projData) {
store = createStore();
extendStore(store, document.createElement('div'));
const Component = Vue.extend(ide); const Component = Vue.extend(ide);
store.state.currentProjectId = 'abcproject'; store.state.currentProjectId = 'abcproject';
......
import Vuex from 'vuex'; import Vuex from 'vuex';
import { createLocalVue, shallowMount } from '@vue/test-utils'; import { createLocalVue, shallowMount } from '@vue/test-utils';
import IdeStatusList from '~/ide/components/ide_status_list.vue'; import IdeStatusList from '~/ide/components/ide_status_list.vue';
import TerminalSyncStatusSafe from '~/ide/components/terminal_sync/terminal_sync_status_safe.vue';
const TEST_FILE = { const TEST_FILE = {
name: 'lorem.md', name: 'lorem.md',
...@@ -78,13 +79,9 @@ describe('ide/components/ide_status_list', () => { ...@@ -78,13 +79,9 @@ describe('ide/components/ide_status_list', () => {
}); });
}); });
it('adds slot as child of list', () => { it('renders terminal sync status', () => {
createComponent({ createComponent();
slots: {
default: ['<div class="js-test">Hello</div>', '<div class="js-test">World</div>'],
},
});
expect(wrapper.find('.ide-status-list').findAll('.js-test').length).toEqual(2); expect(wrapper.find(TerminalSyncStatusSafe).exists()).toBe(true);
}); });
}); });
...@@ -5,6 +5,7 @@ import { createStore } from '~/ide/stores'; ...@@ -5,6 +5,7 @@ import { createStore } from '~/ide/stores';
import RightPane from '~/ide/components/panes/right.vue'; import RightPane from '~/ide/components/panes/right.vue';
import CollapsibleSidebar from '~/ide/components/panes/collapsible_sidebar.vue'; import CollapsibleSidebar from '~/ide/components/panes/collapsible_sidebar.vue';
import { rightSidebarViews } from '~/ide/constants'; import { rightSidebarViews } from '~/ide/constants';
import extendStore from '~/ide/stores/extend';
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
...@@ -14,6 +15,8 @@ describe('ide/components/panes/right.vue', () => { ...@@ -14,6 +15,8 @@ describe('ide/components/panes/right.vue', () => {
let store; let store;
const createComponent = props => { const createComponent = props => {
extendStore(store, document.createElement('div'));
wrapper = shallowMount(RightPane, { wrapper = shallowMount(RightPane, {
localVue, localVue,
store, store,
...@@ -32,26 +35,6 @@ describe('ide/components/panes/right.vue', () => { ...@@ -32,26 +35,6 @@ describe('ide/components/panes/right.vue', () => {
wrapper = null; wrapper = null;
}); });
it('allows tabs to be added via extensionTabs prop', () => {
createComponent({
extensionTabs: [
{
show: true,
title: 'FakeTab',
},
],
});
expect(wrapper.find(CollapsibleSidebar).props('extensionTabs')).toEqual(
expect.arrayContaining([
expect.objectContaining({
show: true,
title: 'FakeTab',
}),
]),
);
});
describe('pipelines tab', () => { describe('pipelines tab', () => {
it('is always shown', () => { it('is always shown', () => {
createComponent(); createComponent();
...@@ -99,4 +82,38 @@ describe('ide/components/panes/right.vue', () => { ...@@ -99,4 +82,38 @@ describe('ide/components/panes/right.vue', () => {
); );
}); });
}); });
describe('terminal tab', () => {
beforeEach(() => {
createComponent();
});
it('adds terminal tab', () => {
store.state.terminal.isVisible = true;
return wrapper.vm.$nextTick().then(() => {
expect(wrapper.find(CollapsibleSidebar).props('extensionTabs')).toEqual(
expect.arrayContaining([
expect.objectContaining({
show: true,
title: 'Terminal',
}),
]),
);
});
});
it('hides terminal tab when not visible', () => {
store.state.terminal.isVisible = false;
expect(wrapper.find(CollapsibleSidebar).props('extensionTabs')).toEqual(
expect.arrayContaining([
expect.objectContaining({
show: false,
title: 'Terminal',
}),
]),
);
});
});
}); });
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import { TEST_HOST } from 'spec/test_constants'; import { TEST_HOST } from 'spec/test_constants';
import TerminalEmptyState from 'ee/ide/components/terminal/empty_state.vue'; import TerminalEmptyState from '~/ide/components/terminal/empty_state.vue';
const TEST_HELP_PATH = `${TEST_HOST}/help/test`; const TEST_HELP_PATH = `${TEST_HOST}/help/test`;
const TEST_PATH = `${TEST_HOST}/home.png`; const TEST_PATH = `${TEST_HOST}/home.png`;
const TEST_HTML_MESSAGE = 'lorem <strong>ipsum</strong>'; const TEST_HTML_MESSAGE = 'lorem <strong>ipsum</strong>';
describe('EE IDE TerminalEmptyState', () => { describe('IDE TerminalEmptyState', () => {
let wrapper; let wrapper;
const factory = (options = {}) => { const factory = (options = {}) => {
......
import { createLocalVue, shallowMount } from '@vue/test-utils'; import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex'; import Vuex from 'vuex';
import TerminalSession from 'ee/ide/components/terminal/session.vue'; import TerminalSession from '~/ide/components/terminal/session.vue';
import Terminal from 'ee/ide/components/terminal/terminal.vue'; import Terminal from '~/ide/components/terminal/terminal.vue';
import { STARTING, PENDING, RUNNING, STOPPING, STOPPED } from 'ee/ide/constants'; import {
STARTING,
PENDING,
RUNNING,
STOPPING,
STOPPED,
} from '~/ide/stores/modules/terminal/constants';
const TEST_TERMINAL_PATH = 'terminal/path'; const TEST_TERMINAL_PATH = 'terminal/path';
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
describe('EE IDE TerminalSession', () => { describe('IDE TerminalSession', () => {
let wrapper; let wrapper;
let actions; let actions;
let state; let state;
......
import { shallowMount } from '@vue/test-utils'; import { shallowMount } from '@vue/test-utils';
import TerminalControls from 'ee/ide/components/terminal/terminal_controls.vue'; import TerminalControls from '~/ide/components/terminal/terminal_controls.vue';
import ScrollButton from '~/ide/components/jobs/detail/scroll_button.vue'; import ScrollButton from '~/ide/components/jobs/detail/scroll_button.vue';
describe('EE IDE TerminalControls', () => { describe('IDE TerminalControls', () => {
let wrapper; let wrapper;
let buttons; let buttons;
......
import { createLocalVue, shallowMount } from '@vue/test-utils'; import { createLocalVue, shallowMount } from '@vue/test-utils';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import Terminal from 'ee/ide/components/terminal/terminal.vue'; import Terminal from '~/ide/components/terminal/terminal.vue';
import TerminalControls from 'ee/ide/components/terminal/terminal_controls.vue'; import TerminalControls from '~/ide/components/terminal/terminal_controls.vue';
import { STARTING, PENDING, RUNNING, STOPPING, STOPPED } from 'ee/ide/constants'; import {
STARTING,
PENDING,
RUNNING,
STOPPING,
STOPPED,
} from '~/ide/stores/modules/terminal/constants';
import GLTerminal from '~/terminal/terminal'; import GLTerminal from '~/terminal/terminal';
const TEST_TERMINAL_PATH = 'terminal/path'; const TEST_TERMINAL_PATH = 'terminal/path';
...@@ -21,7 +27,7 @@ jest.mock('~/terminal/terminal', () => ...@@ -21,7 +27,7 @@ jest.mock('~/terminal/terminal', () =>
})), })),
); );
describe('EE IDE Terminal', () => { describe('IDE Terminal', () => {
let wrapper; let wrapper;
let state; let state;
......
import { shallowMount, createLocalVue } from '@vue/test-utils'; import { shallowMount, createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { TEST_HOST } from 'spec/test_constants'; import { TEST_HOST } from 'spec/test_constants';
import TerminalEmptyState from 'ee/ide/components/terminal/empty_state.vue'; import TerminalEmptyState from '~/ide/components/terminal/empty_state.vue';
import TerminalView from 'ee/ide/components/terminal/view.vue'; import TerminalView from '~/ide/components/terminal/view.vue';
import TerminalSession from 'ee/ide/components/terminal/session.vue'; import TerminalSession from '~/ide/components/terminal/session.vue';
const TEST_HELP_PATH = `${TEST_HOST}/help`; const TEST_HELP_PATH = `${TEST_HOST}/help`;
const TEST_SVG_PATH = `${TEST_HOST}/illustration.svg`; const TEST_SVG_PATH = `${TEST_HOST}/illustration.svg`;
...@@ -11,7 +11,7 @@ const TEST_SVG_PATH = `${TEST_HOST}/illustration.svg`; ...@@ -11,7 +11,7 @@ const TEST_SVG_PATH = `${TEST_HOST}/illustration.svg`;
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
describe('EE IDE TerminalView', () => { describe('IDE TerminalView', () => {
let state; let state;
let actions; let actions;
let getters; let getters;
......
import Vuex from 'vuex'; import Vuex from 'vuex';
import { createLocalVue, shallowMount } from '@vue/test-utils'; import { createLocalVue, shallowMount } from '@vue/test-utils';
import TerminalSyncStatus from 'ee/ide/components/terminal_sync/terminal_sync_status.vue'; import TerminalSyncStatus from '~/ide/components/terminal_sync/terminal_sync_status.vue';
import TerminalSyncStatusSafe from 'ee/ide/components/terminal_sync/terminal_sync_status_safe.vue'; import TerminalSyncStatusSafe from '~/ide/components/terminal_sync/terminal_sync_status_safe.vue';
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
describe('ee/ide/components/terminal_sync/terminal_sync_status_safe', () => { describe('ide/components/terminal_sync/terminal_sync_status_safe', () => {
let store; let store;
let wrapper; let wrapper;
......
import Vuex from 'vuex'; import Vuex from 'vuex';
import { createLocalVue, shallowMount } from '@vue/test-utils'; import { createLocalVue, shallowMount } from '@vue/test-utils';
import { GlLoadingIcon } from '@gitlab/ui'; import { GlLoadingIcon } from '@gitlab/ui';
import TerminalSyncStatus from 'ee/ide/components/terminal_sync/terminal_sync_status.vue'; import TerminalSyncStatus from '~/ide/components/terminal_sync/terminal_sync_status.vue';
import { import {
MSG_TERMINAL_SYNC_CONNECTING, MSG_TERMINAL_SYNC_CONNECTING,
MSG_TERMINAL_SYNC_UPLOADING, MSG_TERMINAL_SYNC_UPLOADING,
MSG_TERMINAL_SYNC_RUNNING, MSG_TERMINAL_SYNC_RUNNING,
} from 'ee/ide/messages'; } from '~/ide/stores/modules/terminal_sync/messages';
import Icon from '~/vue_shared/components/icon.vue'; import Icon from '~/vue_shared/components/icon.vue';
const TEST_MESSAGE = 'lorem ipsum dolar sit'; const TEST_MESSAGE = 'lorem ipsum dolar sit';
...@@ -15,7 +15,7 @@ const START_LOADING = 'START_LOADING'; ...@@ -15,7 +15,7 @@ const START_LOADING = 'START_LOADING';
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
describe('ee/ide/components/terminal_sync/terminal_sync_status', () => { describe('ide/components/terminal_sync/terminal_sync_status', () => {
let moduleState; let moduleState;
let store; let store;
let wrapper; let wrapper;
......
import createDiff from 'ee/ide/lib/create_diff'; import createDiff from '~/ide/lib/create_diff';
import createFileDiff from 'ee/ide/lib/create_file_diff'; import createFileDiff from '~/ide/lib/create_file_diff';
import { commitActionTypes } from '~/ide/constants'; import { commitActionTypes } from '~/ide/constants';
import { import {
createNewFile, createNewFile,
...@@ -24,7 +24,7 @@ const LINES = TEXT.trim().split('\n'); ...@@ -24,7 +24,7 @@ const LINES = TEXT.trim().split('\n');
const joinDiffs = (...patches) => patches.join(''); const joinDiffs = (...patches) => patches.join('');
describe('EE IDE lib/create_diff', () => { describe('IDE lib/create_diff', () => {
it('with created files, generates patch', () => { it('with created files, generates patch', () => {
const changedFiles = [createNewFile(PATH_FOO, TEXT), createNewFile(PATH_BAR, '')]; const changedFiles = [createNewFile(PATH_FOO, TEXT), createNewFile(PATH_BAR, '')];
const result = createDiff({ changedFiles }); const result = createDiff({ changedFiles });
......
import createFileDiff from 'ee/ide/lib/create_file_diff'; import createFileDiff from '~/ide/lib/create_file_diff';
import { commitActionTypes } from '~/ide/constants'; import { commitActionTypes } from '~/ide/constants';
import { import {
createUpdatedFile, createUpdatedFile,
...@@ -27,7 +27,7 @@ const mapLines = (content, mapFn) => ...@@ -27,7 +27,7 @@ const mapLines = (content, mapFn) =>
.map(mapFn) .map(mapFn)
.join('\n'); .join('\n');
describe('EE IDE lib/create_file_diff', () => { describe('IDE lib/create_file_diff', () => {
it('returns empty string with "garbage" action', () => { it('returns empty string with "garbage" action', () => {
const result = createFileDiff(createNewFile(PATH, ''), 'garbage'); const result = createFileDiff(createNewFile(PATH, ''), 'garbage');
......
import createDiff from 'ee/ide/lib/create_diff'; import createDiff from '~/ide/lib/create_diff';
import { import {
canConnect, canConnect,
createMirror, createMirror,
...@@ -6,10 +6,10 @@ import { ...@@ -6,10 +6,10 @@ import {
PROTOCOL, PROTOCOL,
MSG_CONNECTION_ERROR, MSG_CONNECTION_ERROR,
SERVICE_DELAY, SERVICE_DELAY,
} from 'ee/ide/lib/mirror'; } from '~/ide/lib/mirror';
import { getWebSocketUrl } from '~/lib/utils/url_utility'; import { getWebSocketUrl } from '~/lib/utils/url_utility';
jest.mock('ee/ide/lib/create_diff', () => jest.fn()); jest.mock('~/ide/lib/create_diff', () => jest.fn());
const TEST_PATH = '/project/ide/proxy/path'; const TEST_PATH = '/project/ide/proxy/path';
const TEST_DIFF = { const TEST_DIFF = {
...@@ -38,7 +38,7 @@ const buildUploadMessage = ({ toDelete, patch }) => ...@@ -38,7 +38,7 @@ const buildUploadMessage = ({ toDelete, patch }) =>
payload: { diff: patch, delete_files: toDelete }, payload: { diff: patch, delete_files: toDelete },
}); });
describe('ee/ide/lib/mirror', () => { describe('ide/lib/mirror', () => {
describe('canConnect', () => { describe('canConnect', () => {
it('can connect if the session has the expected service', () => { it('can connect if the session has the expected service', () => {
const result = canConnect({ services: ['test1', SERVICE_NAME, 'test2'] }); const result = canConnect({ services: ['test1', SERVICE_NAME, 'test2'] });
......
import extendStore from 'ee/ide/stores/extend'; import extendStore from '~/ide/stores/extend';
import terminalPlugin from 'ee/ide/stores/plugins/terminal'; import terminalPlugin from '~/ide/stores/plugins/terminal';
import terminalSyncPlugin from 'ee/ide/stores/plugins/terminal_sync'; import terminalSyncPlugin from '~/ide/stores/plugins/terminal_sync';
jest.mock('ee/ide/stores/plugins/terminal', () => jest.fn()); jest.mock('~/ide/stores/plugins/terminal', () => jest.fn());
jest.mock('ee/ide/stores/plugins/terminal_sync', () => jest.fn()); jest.mock('~/ide/stores/plugins/terminal_sync', () => jest.fn());
describe('ee/ide/stores/extend', () => { describe('ide/stores/extend', () => {
let prevGon; let prevGon;
let store; let store;
let el; let el;
......
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import testAction from 'helpers/vuex_action_helper'; import testAction from 'helpers/vuex_action_helper';
import { TEST_HOST } from 'spec/test_constants'; import { TEST_HOST } from 'spec/test_constants';
import { CHECK_CONFIG, CHECK_RUNNERS, RETRY_RUNNERS_INTERVAL } from 'ee/ide/constants'; import {
import * as mutationTypes from 'ee/ide/stores/modules/terminal/mutation_types'; CHECK_CONFIG,
import * as messages from 'ee/ide/stores/modules/terminal/messages'; CHECK_RUNNERS,
import * as actions from 'ee/ide/stores/modules/terminal/actions/checks'; RETRY_RUNNERS_INTERVAL,
} from '~/ide/stores/modules/terminal/constants';
import * as mutationTypes from '~/ide/stores/modules/terminal/mutation_types';
import * as messages from '~/ide/stores/modules/terminal/messages';
import * as actions from '~/ide/stores/modules/terminal/actions/checks';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import httpStatus from '~/lib/utils/http_status'; import httpStatus from '~/lib/utils/http_status';
...@@ -13,7 +17,7 @@ const TEST_BRANCH_ID = 'master'; ...@@ -13,7 +17,7 @@ const TEST_BRANCH_ID = 'master';
const TEST_YAML_HELP_PATH = `${TEST_HOST}/test/yaml/help`; const TEST_YAML_HELP_PATH = `${TEST_HOST}/test/yaml/help`;
const TEST_RUNNERS_HELP_PATH = `${TEST_HOST}/test/runners/help`; const TEST_RUNNERS_HELP_PATH = `${TEST_HOST}/test/runners/help`;
describe('EE IDE store terminal check actions', () => { describe('IDE store terminal check actions', () => {
let mock; let mock;
let state; let state;
let rootState; let rootState;
......
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import testAction from 'helpers/vuex_action_helper'; import testAction from 'helpers/vuex_action_helper';
import { STARTING, PENDING, STOPPING, STOPPED } from 'ee/ide/constants'; import { STARTING, PENDING, STOPPING, STOPPED } from '~/ide/stores/modules/terminal/constants';
import * as messages from 'ee/ide/stores/modules/terminal/messages'; import * as messages from '~/ide/stores/modules/terminal/messages';
import * as mutationTypes from 'ee/ide/stores/modules/terminal/mutation_types'; import * as mutationTypes from '~/ide/stores/modules/terminal/mutation_types';
import * as actions from 'ee/ide/stores/modules/terminal/actions/session_controls'; import * as actions from '~/ide/stores/modules/terminal/actions/session_controls';
import httpStatus from '~/lib/utils/http_status'; import httpStatus from '~/lib/utils/http_status';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash'; import createFlash from '~/flash';
...@@ -23,7 +23,7 @@ const TEST_SESSION = { ...@@ -23,7 +23,7 @@ const TEST_SESSION = {
services: ['test-service'], services: ['test-service'],
}; };
describe('EE IDE store terminal session controls actions', () => { describe('IDE store terminal session controls actions', () => {
let mock; let mock;
let dispatch; let dispatch;
let rootState; let rootState;
......
import MockAdapter from 'axios-mock-adapter'; import MockAdapter from 'axios-mock-adapter';
import testAction from 'helpers/vuex_action_helper'; import testAction from 'helpers/vuex_action_helper';
import { PENDING, RUNNING, STOPPING, STOPPED } from 'ee/ide/constants'; import { PENDING, RUNNING, STOPPING, STOPPED } from '~/ide/stores/modules/terminal/constants';
import * as messages from 'ee/ide/stores/modules/terminal/messages'; import * as messages from '~/ide/stores/modules/terminal/messages';
import * as mutationTypes from 'ee/ide/stores/modules/terminal/mutation_types'; import * as mutationTypes from '~/ide/stores/modules/terminal/mutation_types';
import * as actions from 'ee/ide/stores/modules/terminal/actions/session_status'; import * as actions from '~/ide/stores/modules/terminal/actions/session_status';
import axios from '~/lib/utils/axios_utils'; import axios from '~/lib/utils/axios_utils';
import createFlash from '~/flash'; import createFlash from '~/flash';
...@@ -18,7 +18,7 @@ const TEST_SESSION = { ...@@ -18,7 +18,7 @@ const TEST_SESSION = {
terminal_path: 'path/terminal', terminal_path: 'path/terminal',
}; };
describe('EE IDE store terminal session controls actions', () => { describe('IDE store terminal session controls actions', () => {
let mock; let mock;
let dispatch; let dispatch;
let commit; let commit;
......
import testAction from 'helpers/vuex_action_helper'; import testAction from 'helpers/vuex_action_helper';
import * as mutationTypes from 'ee/ide/stores/modules/terminal/mutation_types'; import * as mutationTypes from '~/ide/stores/modules/terminal/mutation_types';
import * as actions from 'ee/ide/stores/modules/terminal/actions/setup'; import * as actions from '~/ide/stores/modules/terminal/actions/setup';
describe('EE IDE store terminal setup actions', () => { describe('IDE store terminal setup actions', () => {
describe('init', () => { describe('init', () => {
it('dispatches checks', () => { it('dispatches checks', () => {
return testAction( return testAction(
......
import { CHECK_CONFIG, CHECK_RUNNERS } from 'ee/ide/constants'; import { CHECK_CONFIG, CHECK_RUNNERS } from '~/ide/stores/modules/terminal/constants';
import * as getters from 'ee/ide/stores/modules/terminal/getters'; import * as getters from '~/ide/stores/modules/terminal/getters';
describe('EE IDE store terminal getters', () => { describe('IDE store terminal getters', () => {
describe('allCheck', () => { describe('allCheck', () => {
it('is loading if one check is loading', () => { it('is loading if one check is loading', () => {
const checks = { const checks = {
......
import { escape } from 'lodash'; import { escape } from 'lodash';
import { TEST_HOST } from 'spec/test_constants'; import { TEST_HOST } from 'spec/test_constants';
import * as messages from 'ee/ide/stores/modules/terminal/messages'; import * as messages from '~/ide/stores/modules/terminal/messages';
import { sprintf } from '~/locale'; import { sprintf } from '~/locale';
import httpStatus from '~/lib/utils/http_status'; import httpStatus from '~/lib/utils/http_status';
const TEST_HELP_URL = `${TEST_HOST}/help`; const TEST_HELP_URL = `${TEST_HOST}/help`;
describe('EE IDE store terminal messages', () => { describe('IDE store terminal messages', () => {
describe('configCheckError', () => { describe('configCheckError', () => {
it('returns job error, with status UNPROCESSABLE_ENTITY', () => { it('returns job error, with status UNPROCESSABLE_ENTITY', () => {
const result = messages.configCheckError(httpStatus.UNPROCESSABLE_ENTITY, TEST_HELP_URL); const result = messages.configCheckError(httpStatus.UNPROCESSABLE_ENTITY, TEST_HELP_URL);
......
import { CHECK_CONFIG, CHECK_RUNNERS, RUNNING, STOPPING } from 'ee/ide/constants'; import {
import createState from 'ee/ide/stores/modules/terminal/state'; CHECK_CONFIG,
import * as types from 'ee/ide/stores/modules/terminal/mutation_types'; CHECK_RUNNERS,
import mutations from 'ee/ide/stores/modules/terminal/mutations'; RUNNING,
STOPPING,
describe('EE IDE store terminal mutations', () => { } from '~/ide/stores/modules/terminal/constants';
import createState from '~/ide/stores/modules/terminal/state';
import * as types from '~/ide/stores/modules/terminal/mutation_types';
import mutations from '~/ide/stores/modules/terminal/mutations';
describe('IDE store terminal mutations', () => {
let state; let state;
beforeEach(() => { beforeEach(() => {
......
import * as actions from 'ee/ide/stores/modules/terminal_sync/actions'; import * as actions from '~/ide/stores/modules/terminal_sync/actions';
import mirror, { canConnect, SERVICE_NAME } from 'ee/ide/lib/mirror'; import mirror, { canConnect, SERVICE_NAME } from '~/ide/lib/mirror';
import * as types from 'ee/ide/stores/modules/terminal_sync/mutation_types'; import * as types from '~/ide/stores/modules/terminal_sync/mutation_types';
import testAction from 'helpers/vuex_action_helper'; import testAction from 'helpers/vuex_action_helper';
jest.mock('ee/ide/lib/mirror'); jest.mock('~/ide/lib/mirror');
const TEST_SESSION = { const TEST_SESSION = {
proxyWebsocketPath: 'test/path', proxyWebsocketPath: 'test/path',
services: [SERVICE_NAME], services: [SERVICE_NAME],
}; };
describe('ee/ide/stores/modules/terminal_sync/actions', () => { describe('ide/stores/modules/terminal_sync/actions', () => {
let rootState; let rootState;
beforeEach(() => { beforeEach(() => {
......
import createState from 'ee/ide/stores/modules/terminal_sync/state'; import createState from '~/ide/stores/modules/terminal_sync/state';
import * as types from 'ee/ide/stores/modules/terminal_sync/mutation_types'; import * as types from '~/ide/stores/modules/terminal_sync/mutation_types';
import mutations from 'ee/ide/stores/modules/terminal_sync/mutations'; import mutations from '~/ide/stores/modules/terminal_sync/mutations';
const TEST_MESSAGE = 'lorem ipsum dolar sit'; const TEST_MESSAGE = 'lorem ipsum dolar sit';
describe('ee/ide/stores/modules/terminal_sync/mutations', () => { describe('ide/stores/modules/terminal_sync/mutations', () => {
let state; let state;
beforeEach(() => { beforeEach(() => {
......
import { createLocalVue } from '@vue/test-utils'; import { createLocalVue } from '@vue/test-utils';
import Vuex from 'vuex'; import Vuex from 'vuex';
import { TEST_HOST } from 'helpers/test_constants'; import { TEST_HOST } from 'helpers/test_constants';
import terminalModule from 'ee/ide/stores/modules/terminal'; import terminalModule from '~/ide/stores/modules/terminal';
import createTerminalPlugin from 'ee/ide/stores/plugins/terminal'; import createTerminalPlugin from '~/ide/stores/plugins/terminal';
import { SET_BRANCH_WORKING_REFERENCE } from '~/ide/stores/mutation_types'; import { SET_BRANCH_WORKING_REFERENCE } from '~/ide/stores/mutation_types';
const TEST_DATASET = { const TEST_DATASET = {
...@@ -14,7 +14,7 @@ const TEST_DATASET = { ...@@ -14,7 +14,7 @@ const TEST_DATASET = {
const localVue = createLocalVue(); const localVue = createLocalVue();
localVue.use(Vuex); localVue.use(Vuex);
describe('ee/ide/stores/extend', () => { describe('ide/stores/extend', () => {
let store; let store;
beforeEach(() => { beforeEach(() => {
......
import createTerminalPlugin from 'ee/ide/stores/plugins/terminal'; import createTerminalPlugin from '~/ide/stores/plugins/terminal';
import createTerminalSyncPlugin from 'ee/ide/stores/plugins/terminal_sync'; import createTerminalSyncPlugin from '~/ide/stores/plugins/terminal_sync';
import { SET_SESSION_STATUS } from 'ee/ide/stores/modules/terminal/mutation_types'; import { SET_SESSION_STATUS } from '~/ide/stores/modules/terminal/mutation_types';
import { RUNNING, STOPPING } from 'ee/ide/constants'; import { RUNNING, STOPPING } from '~/ide/stores/modules/terminal/constants';
import { createStore } from '~/ide/stores'; import { createStore } from '~/ide/stores';
import eventHub from '~/ide/eventhub'; import eventHub from '~/ide/eventhub';
jest.mock('ee/ide/lib/mirror'); jest.mock('~/ide/lib/mirror');
const ACTION_START = 'terminalSync/start'; const ACTION_START = 'terminalSync/start';
const ACTION_STOP = 'terminalSync/stop'; const ACTION_STOP = 'terminalSync/stop';
const ACTION_UPLOAD = 'terminalSync/upload'; const ACTION_UPLOAD = 'terminalSync/upload';
const FILES_CHANGE_EVENT = 'ide.files.change'; const FILES_CHANGE_EVENT = 'ide.files.change';
describe('EE IDE stores/plugins/mirror', () => { describe('IDE stores/plugins/mirror', () => {
let store; let store;
beforeEach(() => { beforeEach(() => {
......
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