diff options
Diffstat (limited to 'spec/frontend/ide/stores/modules/terminal/actions/session_controls_spec.js')
-rw-r--r-- | spec/frontend/ide/stores/modules/terminal/actions/session_controls_spec.js | 300 |
1 files changed, 300 insertions, 0 deletions
diff --git a/spec/frontend/ide/stores/modules/terminal/actions/session_controls_spec.js b/spec/frontend/ide/stores/modules/terminal/actions/session_controls_spec.js new file mode 100644 index 00000000000..4bc937b4784 --- /dev/null +++ b/spec/frontend/ide/stores/modules/terminal/actions/session_controls_spec.js @@ -0,0 +1,300 @@ +import MockAdapter from 'axios-mock-adapter'; +import testAction from 'helpers/vuex_action_helper'; +import { STARTING, PENDING, STOPPING, STOPPED } from '~/ide/stores/modules/terminal/constants'; +import * as messages from '~/ide/stores/modules/terminal/messages'; +import * as mutationTypes from '~/ide/stores/modules/terminal/mutation_types'; +import * as actions from '~/ide/stores/modules/terminal/actions/session_controls'; +import httpStatus from '~/lib/utils/http_status'; +import axios from '~/lib/utils/axios_utils'; +import createFlash from '~/flash'; + +jest.mock('~/flash'); + +const TEST_PROJECT_PATH = 'lorem/root'; +const TEST_BRANCH_ID = 'master'; +const TEST_SESSION = { + id: 7, + status: PENDING, + show_path: 'path/show', + cancel_path: 'path/cancel', + retry_path: 'path/retry', + terminal_path: 'path/terminal', + proxy_websocket_path: 'path/proxy', + services: ['test-service'], +}; + +describe('IDE store terminal session controls actions', () => { + let mock; + let dispatch; + let rootState; + let rootGetters; + + beforeEach(() => { + mock = new MockAdapter(axios); + dispatch = jest.fn().mockName('dispatch'); + rootState = { + currentBranchId: TEST_BRANCH_ID, + }; + rootGetters = { + currentProject: { + id: 7, + path_with_namespace: TEST_PROJECT_PATH, + }, + }; + }); + + afterEach(() => { + mock.restore(); + }); + + describe('requestStartSession', () => { + it('sets session status', () => { + return testAction( + actions.requestStartSession, + null, + {}, + [{ type: mutationTypes.SET_SESSION_STATUS, payload: STARTING }], + [], + ); + }); + }); + + describe('receiveStartSessionSuccess', () => { + it('sets session and starts polling status', () => { + return testAction( + actions.receiveStartSessionSuccess, + TEST_SESSION, + {}, + [ + { + type: mutationTypes.SET_SESSION, + payload: { + id: TEST_SESSION.id, + status: TEST_SESSION.status, + showPath: TEST_SESSION.show_path, + cancelPath: TEST_SESSION.cancel_path, + retryPath: TEST_SESSION.retry_path, + terminalPath: TEST_SESSION.terminal_path, + proxyWebsocketPath: TEST_SESSION.proxy_websocket_path, + services: TEST_SESSION.services, + }, + }, + ], + [{ type: 'pollSessionStatus' }], + ); + }); + }); + + describe('receiveStartSessionError', () => { + it('flashes message', () => { + actions.receiveStartSessionError({ dispatch }); + + expect(createFlash).toHaveBeenCalledWith(messages.UNEXPECTED_ERROR_STARTING); + }); + + it('sets session status', () => { + return testAction(actions.receiveStartSessionError, null, {}, [], [{ type: 'killSession' }]); + }); + }); + + describe('startSession', () => { + it('does nothing if session is already starting', () => { + const state = { + session: { status: STARTING }, + }; + + actions.startSession({ state, dispatch }); + + expect(dispatch).not.toHaveBeenCalled(); + }); + + it('dispatches request and receive on success', () => { + mock.onPost(/.*\/ide_terminals/).reply(200, TEST_SESSION); + + return testAction( + actions.startSession, + null, + { ...rootGetters, ...rootState }, + [], + [ + { type: 'requestStartSession' }, + { type: 'receiveStartSessionSuccess', payload: TEST_SESSION }, + ], + ); + }); + + it('dispatches request and receive on error', () => { + mock.onPost(/.*\/ide_terminals/).reply(400); + + return testAction( + actions.startSession, + null, + { ...rootGetters, ...rootState }, + [], + [ + { type: 'requestStartSession' }, + { type: 'receiveStartSessionError', payload: expect.any(Error) }, + ], + ); + }); + }); + + describe('requestStopSession', () => { + it('sets session status', () => { + return testAction( + actions.requestStopSession, + null, + {}, + [{ type: mutationTypes.SET_SESSION_STATUS, payload: STOPPING }], + [], + ); + }); + }); + + describe('receiveStopSessionSuccess', () => { + it('kills the session', () => { + return testAction(actions.receiveStopSessionSuccess, null, {}, [], [{ type: 'killSession' }]); + }); + }); + + describe('receiveStopSessionError', () => { + it('flashes message', () => { + actions.receiveStopSessionError({ dispatch }); + + expect(createFlash).toHaveBeenCalledWith(messages.UNEXPECTED_ERROR_STOPPING); + }); + + it('kills the session', () => { + return testAction(actions.receiveStopSessionError, null, {}, [], [{ type: 'killSession' }]); + }); + }); + + describe('stopSession', () => { + it('dispatches request and receive on success', () => { + mock.onPost(TEST_SESSION.cancel_path).reply(200, {}); + + const state = { + session: { cancelPath: TEST_SESSION.cancel_path }, + }; + + return testAction( + actions.stopSession, + null, + state, + [], + [{ type: 'requestStopSession' }, { type: 'receiveStopSessionSuccess' }], + ); + }); + + it('dispatches request and receive on error', () => { + mock.onPost(TEST_SESSION.cancel_path).reply(400); + + const state = { + session: { cancelPath: TEST_SESSION.cancel_path }, + }; + + return testAction( + actions.stopSession, + null, + state, + [], + [ + { type: 'requestStopSession' }, + { type: 'receiveStopSessionError', payload: expect.any(Error) }, + ], + ); + }); + }); + + describe('killSession', () => { + it('stops polling and sets status', () => { + return testAction( + actions.killSession, + null, + {}, + [{ type: mutationTypes.SET_SESSION_STATUS, payload: STOPPED }], + [{ type: 'stopPollingSessionStatus' }], + ); + }); + }); + + describe('restartSession', () => { + let state; + + beforeEach(() => { + state = { + session: { status: STOPPED, retryPath: 'test/retry' }, + }; + }); + + it('does nothing if current not stopped', () => { + state.session.status = STOPPING; + + actions.restartSession({ state, dispatch, rootState }); + + expect(dispatch).not.toHaveBeenCalled(); + }); + + it('dispatches startSession if retryPath is empty', () => { + state.session.retryPath = ''; + + return testAction( + actions.restartSession, + null, + { ...state, ...rootState }, + [], + [{ type: 'startSession' }], + ); + }); + + it('dispatches request and receive on success', () => { + mock + .onPost(state.session.retryPath, { branch: rootState.currentBranchId, format: 'json' }) + .reply(200, TEST_SESSION); + + return testAction( + actions.restartSession, + null, + { ...state, ...rootState }, + [], + [ + { type: 'requestStartSession' }, + { type: 'receiveStartSessionSuccess', payload: TEST_SESSION }, + ], + ); + }); + + it('dispatches request and receive on error', () => { + mock + .onPost(state.session.retryPath, { branch: rootState.currentBranchId, format: 'json' }) + .reply(400); + + return testAction( + actions.restartSession, + null, + { ...state, ...rootState }, + [], + [ + { type: 'requestStartSession' }, + { type: 'receiveStartSessionError', payload: expect.any(Error) }, + ], + ); + }); + + [httpStatus.NOT_FOUND, httpStatus.UNPROCESSABLE_ENTITY].forEach(status => { + it(`dispatches request and startSession on ${status}`, () => { + mock + .onPost(state.session.retryPath, { branch: rootState.currentBranchId, format: 'json' }) + .reply(status); + + return testAction( + actions.restartSession, + null, + { ...state, ...rootState }, + [], + [{ type: 'requestStartSession' }, { type: 'startSession' }], + ); + }); + }); + }); +}); |