diff options
Diffstat (limited to 'spec/frontend/clusters/clusters_bundle_spec.js')
-rw-r--r-- | spec/frontend/clusters/clusters_bundle_spec.js | 376 |
1 files changed, 376 insertions, 0 deletions
diff --git a/spec/frontend/clusters/clusters_bundle_spec.js b/spec/frontend/clusters/clusters_bundle_spec.js new file mode 100644 index 00000000000..eea7bd87257 --- /dev/null +++ b/spec/frontend/clusters/clusters_bundle_spec.js @@ -0,0 +1,376 @@ +import Clusters from '~/clusters/clusters_bundle'; +import { + REQUEST_SUBMITTED, + REQUEST_FAILURE, + APPLICATION_STATUS, + INGRESS_DOMAIN_SUFFIX, +} from '~/clusters/constants'; +import MockAdapter from 'axios-mock-adapter'; +import axios from '~/lib/utils/axios_utils'; +import { loadHTMLFixture } from 'helpers/fixtures'; +import { setTestTimeout } from 'helpers/timeout'; +import $ from 'jquery'; + +describe('Clusters', () => { + setTestTimeout(500); + + let cluster; + let mock; + + const mockGetClusterStatusRequest = () => { + const { statusPath } = document.querySelector('.js-edit-cluster-form').dataset; + + mock = new MockAdapter(axios); + + mock.onGet(statusPath).reply(200); + }; + + beforeEach(() => { + loadHTMLFixture('clusters/show_cluster.html'); + }); + + beforeEach(() => { + mockGetClusterStatusRequest(); + }); + + beforeEach(() => { + cluster = new Clusters(); + }); + + afterEach(() => { + cluster.destroy(); + mock.restore(); + }); + + describe('toggle', () => { + it('should update the button and the input field on click', done => { + const toggleButton = document.querySelector( + '.js-cluster-enable-toggle-area .js-project-feature-toggle', + ); + const toggleInput = document.querySelector( + '.js-cluster-enable-toggle-area .js-project-feature-toggle-input', + ); + + $(toggleInput).one('trigger-change', () => { + expect(toggleButton.classList).not.toContain('is-checked'); + expect(toggleInput.getAttribute('value')).toEqual('false'); + done(); + }); + + toggleButton.click(); + }); + }); + + describe('showToken', () => { + it('should update token field type', () => { + cluster.showTokenButton.click(); + + expect(cluster.tokenField.getAttribute('type')).toEqual('text'); + + cluster.showTokenButton.click(); + + expect(cluster.tokenField.getAttribute('type')).toEqual('password'); + }); + + it('should update show token button text', () => { + cluster.showTokenButton.click(); + + expect(cluster.showTokenButton.textContent).toEqual('Hide'); + + cluster.showTokenButton.click(); + + expect(cluster.showTokenButton.textContent).toEqual('Show'); + }); + }); + + describe('checkForNewInstalls', () => { + const INITIAL_APP_MAP = { + helm: { status: null, title: 'Helm Tiller' }, + ingress: { status: null, title: 'Ingress' }, + runner: { status: null, title: 'GitLab Runner' }, + }; + + it('does not show alert when things transition from initial null state to something', () => { + cluster.checkForNewInstalls(INITIAL_APP_MAP, { + ...INITIAL_APP_MAP, + helm: { status: APPLICATION_STATUS.INSTALLABLE, title: 'Helm Tiller' }, + }); + + const flashMessage = document.querySelector('.js-cluster-application-notice .flash-text'); + + expect(flashMessage).toBeNull(); + }); + + it('shows an alert when something gets newly installed', () => { + cluster.checkForNewInstalls( + { + ...INITIAL_APP_MAP, + helm: { status: APPLICATION_STATUS.INSTALLING, title: 'Helm Tiller' }, + }, + { + ...INITIAL_APP_MAP, + helm: { status: APPLICATION_STATUS.INSTALLED, title: 'Helm Tiller' }, + }, + ); + + const flashMessage = document.querySelector('.js-cluster-application-notice .flash-text'); + + expect(flashMessage).not.toBeNull(); + expect(flashMessage.textContent.trim()).toEqual( + 'Helm Tiller was successfully installed on your Kubernetes cluster', + ); + }); + + it('shows an alert when multiple things gets newly installed', () => { + cluster.checkForNewInstalls( + { + ...INITIAL_APP_MAP, + helm: { status: APPLICATION_STATUS.INSTALLING, title: 'Helm Tiller' }, + ingress: { status: APPLICATION_STATUS.INSTALLABLE, title: 'Ingress' }, + }, + { + ...INITIAL_APP_MAP, + helm: { status: APPLICATION_STATUS.INSTALLED, title: 'Helm Tiller' }, + ingress: { status: APPLICATION_STATUS.INSTALLED, title: 'Ingress' }, + }, + ); + + const flashMessage = document.querySelector('.js-cluster-application-notice .flash-text'); + + expect(flashMessage).not.toBeNull(); + expect(flashMessage.textContent.trim()).toEqual( + 'Helm Tiller, Ingress was successfully installed on your Kubernetes cluster', + ); + }); + }); + + describe('updateContainer', () => { + describe('when creating cluster', () => { + it('should show the creating container', () => { + cluster.updateContainer(null, 'creating'); + + expect(cluster.creatingContainer.classList.contains('hidden')).toBeFalsy(); + + expect(cluster.successContainer.classList.contains('hidden')).toBeTruthy(); + + expect(cluster.errorContainer.classList.contains('hidden')).toBeTruthy(); + }); + + it('should continue to show `creating` banner with subsequent updates of the same status', () => { + cluster.updateContainer('creating', 'creating'); + + expect(cluster.creatingContainer.classList.contains('hidden')).toBeFalsy(); + + expect(cluster.successContainer.classList.contains('hidden')).toBeTruthy(); + + expect(cluster.errorContainer.classList.contains('hidden')).toBeTruthy(); + }); + }); + + describe('when cluster is created', () => { + it('should show the success container and fresh the page', () => { + cluster.updateContainer(null, 'created'); + + expect(cluster.creatingContainer.classList.contains('hidden')).toBeTruthy(); + + expect(cluster.successContainer.classList.contains('hidden')).toBeFalsy(); + + expect(cluster.errorContainer.classList.contains('hidden')).toBeTruthy(); + }); + + it('should not show a banner when status is already `created`', () => { + cluster.updateContainer('created', 'created'); + + expect(cluster.creatingContainer.classList.contains('hidden')).toBeTruthy(); + + expect(cluster.successContainer.classList.contains('hidden')).toBeTruthy(); + + expect(cluster.errorContainer.classList.contains('hidden')).toBeTruthy(); + }); + }); + + describe('when cluster has error', () => { + it('should show the error container', () => { + cluster.updateContainer(null, 'errored', 'this is an error'); + + expect(cluster.creatingContainer.classList.contains('hidden')).toBeTruthy(); + + expect(cluster.successContainer.classList.contains('hidden')).toBeTruthy(); + + expect(cluster.errorContainer.classList.contains('hidden')).toBeFalsy(); + + expect(cluster.errorReasonContainer.textContent).toContain('this is an error'); + }); + + it('should show `error` banner when previously `creating`', () => { + cluster.updateContainer('creating', 'errored'); + + expect(cluster.creatingContainer.classList.contains('hidden')).toBeTruthy(); + + expect(cluster.successContainer.classList.contains('hidden')).toBeTruthy(); + + expect(cluster.errorContainer.classList.contains('hidden')).toBeFalsy(); + }); + }); + }); + + describe('installApplication', () => { + it('tries to install helm', () => { + jest.spyOn(cluster.service, 'installApplication').mockResolvedValueOnce(); + + expect(cluster.store.state.applications.helm.requestStatus).toEqual(null); + + cluster.installApplication({ id: 'helm' }); + + expect(cluster.store.state.applications.helm.requestStatus).toEqual(REQUEST_SUBMITTED); + expect(cluster.store.state.applications.helm.requestReason).toEqual(null); + expect(cluster.service.installApplication).toHaveBeenCalledWith('helm', undefined); + }); + + it('tries to install ingress', () => { + jest.spyOn(cluster.service, 'installApplication').mockResolvedValueOnce(); + + expect(cluster.store.state.applications.ingress.requestStatus).toEqual(null); + + cluster.installApplication({ id: 'ingress' }); + + expect(cluster.store.state.applications.ingress.requestStatus).toEqual(REQUEST_SUBMITTED); + expect(cluster.store.state.applications.ingress.requestReason).toEqual(null); + expect(cluster.service.installApplication).toHaveBeenCalledWith('ingress', undefined); + }); + + it('tries to install runner', () => { + jest.spyOn(cluster.service, 'installApplication').mockResolvedValueOnce(); + + expect(cluster.store.state.applications.runner.requestStatus).toEqual(null); + + cluster.installApplication({ id: 'runner' }); + + expect(cluster.store.state.applications.runner.requestStatus).toEqual(REQUEST_SUBMITTED); + expect(cluster.store.state.applications.runner.requestReason).toEqual(null); + expect(cluster.service.installApplication).toHaveBeenCalledWith('runner', undefined); + }); + + it('tries to install jupyter', () => { + jest.spyOn(cluster.service, 'installApplication').mockResolvedValueOnce(); + + expect(cluster.store.state.applications.jupyter.requestStatus).toEqual(null); + cluster.installApplication({ + id: 'jupyter', + params: { hostname: cluster.store.state.applications.jupyter.hostname }, + }); + + expect(cluster.store.state.applications.jupyter.requestStatus).toEqual(REQUEST_SUBMITTED); + expect(cluster.store.state.applications.jupyter.requestReason).toEqual(null); + expect(cluster.service.installApplication).toHaveBeenCalledWith('jupyter', { + hostname: cluster.store.state.applications.jupyter.hostname, + }); + }); + + it('sets error request status when the request fails', () => { + jest + .spyOn(cluster.service, 'installApplication') + .mockRejectedValueOnce(new Error('STUBBED ERROR')); + + expect(cluster.store.state.applications.helm.requestStatus).toEqual(null); + + const promise = cluster.installApplication({ id: 'helm' }); + + expect(cluster.store.state.applications.helm.requestStatus).toEqual(REQUEST_SUBMITTED); + expect(cluster.store.state.applications.helm.requestReason).toEqual(null); + expect(cluster.service.installApplication).toHaveBeenCalled(); + + return promise.then(() => { + expect(cluster.store.state.applications.helm.requestStatus).toEqual(REQUEST_FAILURE); + expect(cluster.store.state.applications.helm.requestReason).toBeDefined(); + }); + }); + }); + + describe('handleSuccess', () => { + beforeEach(() => { + jest.spyOn(cluster.store, 'updateStateFromServer').mockReturnThis(); + jest.spyOn(cluster, 'toggleIngressDomainHelpText').mockReturnThis(); + jest.spyOn(cluster, 'checkForNewInstalls').mockReturnThis(); + jest.spyOn(cluster, 'updateContainer').mockReturnThis(); + + cluster.handleSuccess({ data: {} }); + }); + + it('updates clusters store', () => { + expect(cluster.store.updateStateFromServer).toHaveBeenCalled(); + }); + + it('checks for new installable apps', () => { + expect(cluster.checkForNewInstalls).toHaveBeenCalled(); + }); + + it('toggles ingress domain help text', () => { + expect(cluster.toggleIngressDomainHelpText).toHaveBeenCalled(); + }); + + it('updates message containers', () => { + expect(cluster.updateContainer).toHaveBeenCalled(); + }); + }); + + describe('toggleIngressDomainHelpText', () => { + const { INSTALLED, INSTALLABLE, NOT_INSTALLABLE } = APPLICATION_STATUS; + let ingressPreviousState; + let ingressNewState; + + beforeEach(() => { + ingressPreviousState = { status: INSTALLABLE }; + ingressNewState = { status: INSTALLED, externalIp: '127.0.0.1' }; + }); + + describe(`when ingress application new status is ${INSTALLED}`, () => { + beforeEach(() => { + ingressNewState.status = INSTALLED; + cluster.toggleIngressDomainHelpText(ingressPreviousState, ingressNewState); + }); + + it('displays custom domain help text', () => { + expect(cluster.ingressDomainHelpText.classList.contains('hide')).toEqual(false); + }); + + it('updates ingress external ip address', () => { + expect(cluster.ingressDomainSnippet.textContent).toEqual( + `${ingressNewState.externalIp}${INGRESS_DOMAIN_SUFFIX}`, + ); + }); + }); + + describe(`when ingress application new status is different from ${INSTALLED}`, () => { + it('hides custom domain help text', () => { + ingressNewState.status = NOT_INSTALLABLE; + cluster.ingressDomainHelpText.classList.remove('hide'); + + cluster.toggleIngressDomainHelpText(ingressPreviousState, ingressNewState); + + expect(cluster.ingressDomainHelpText.classList.contains('hide')).toEqual(true); + }); + }); + + describe('when ingress application new status and old status are the same', () => { + it('does not display custom domain help text', () => { + ingressPreviousState.status = INSTALLED; + ingressNewState.status = ingressPreviousState.status; + + cluster.toggleIngressDomainHelpText(ingressPreviousState, ingressNewState); + + expect(cluster.ingressDomainHelpText.classList.contains('hide')).toEqual(true); + }); + }); + + describe(`when ingress new status is ${INSTALLED} and there isn’t an ip assigned`, () => { + it('does not display custom domain help text', () => { + ingressNewState.externalIp = null; + + cluster.toggleIngressDomainHelpText(ingressPreviousState, ingressNewState); + + expect(cluster.ingressDomainHelpText.classList.contains('hide')).toEqual(true); + }); + }); + }); +}); |