diff options
Diffstat (limited to 'spec/frontend/clusters_list/components/install_agent_modal_spec.js')
-rw-r--r-- | spec/frontend/clusters_list/components/install_agent_modal_spec.js | 265 |
1 files changed, 179 insertions, 86 deletions
diff --git a/spec/frontend/clusters_list/components/install_agent_modal_spec.js b/spec/frontend/clusters_list/components/install_agent_modal_spec.js index 6c2ea45b99b..4d1429c9e50 100644 --- a/spec/frontend/clusters_list/components/install_agent_modal_spec.js +++ b/spec/frontend/clusters_list/components/install_agent_modal_spec.js @@ -1,10 +1,21 @@ import { GlAlert, GlButton, GlFormInputGroup } from '@gitlab/ui'; -import { createLocalVue, shallowMount } from '@vue/test-utils'; +import { createLocalVue } from '@vue/test-utils'; import VueApollo from 'vue-apollo'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import { mockTracking } from 'helpers/tracking_helper'; import AvailableAgentsDropdown from '~/clusters_list/components/available_agents_dropdown.vue'; import InstallAgentModal from '~/clusters_list/components/install_agent_modal.vue'; -import { I18N_INSTALL_AGENT_MODAL, MAX_LIST_COUNT } from '~/clusters_list/constants'; +import { + I18N_AGENT_MODAL, + MAX_LIST_COUNT, + EVENT_LABEL_MODAL, + EVENT_ACTIONS_OPEN, + EVENT_ACTIONS_SELECT, + MODAL_TYPE_EMPTY, + MODAL_TYPE_REGISTER, +} from '~/clusters_list/constants'; import getAgentsQuery from '~/clusters_list/graphql/queries/get_agents.query.graphql'; +import getAgentConfigurations from '~/clusters_list/graphql/queries/agent_configurations.query.graphql'; import createAgentMutation from '~/clusters_list/graphql/mutations/create_agent.mutation.graphql'; import createAgentTokenMutation from '~/clusters_list/graphql/mutations/create_agent_token.mutation.graphql'; import createMockApollo from 'helpers/mock_apollo_helper'; @@ -23,14 +34,28 @@ const localVue = createLocalVue(); localVue.use(VueApollo); const projectPath = 'path/to/project'; +const kasAddress = 'kas.example.com'; +const kasEnabled = true; +const emptyStateImage = 'path/to/image'; const defaultBranchName = 'default'; const maxAgents = MAX_LIST_COUNT; describe('InstallAgentModal', () => { let wrapper; let apolloProvider; + let trackingSpy; + + const configurations = [{ agentName: 'agent-name' }]; + const apolloQueryResponse = { + data: { + project: { + id: '1', + clusterAgents: { nodes: [] }, + agentConfigurations: { nodes: configurations }, + }, + }, + }; - const i18n = I18N_INSTALL_AGENT_MODAL; const findModal = () => wrapper.findComponent(ModalStub); const findAgentDropdown = () => findModal().findComponent(AvailableAgentsDropdown); const findAlert = () => findModal().findComponent(GlAlert); @@ -40,6 +65,8 @@ describe('InstallAgentModal', () => { .wrappers.find((button) => button.props('variant') === variant); const findActionButton = () => findButtonByVariant('confirm'); const findCancelButton = () => findButtonByVariant('default'); + const findSecondaryButton = () => wrapper.findByTestId('agent-secondary-button'); + const findImage = () => wrapper.findByRole('img', { alt: I18N_AGENT_MODAL.empty_state.altText }); const expectDisabledAttribute = (element, disabled) => { if (disabled) { @@ -52,7 +79,9 @@ describe('InstallAgentModal', () => { const createWrapper = () => { const provide = { projectPath, - kasAddress: 'kas.example.com', + kasAddress, + kasEnabled, + emptyStateImage, }; const propsData = { @@ -60,7 +89,7 @@ describe('InstallAgentModal', () => { maxAgents, }; - wrapper = shallowMount(InstallAgentModal, { + wrapper = shallowMountExtended(InstallAgentModal, { attachTo: document.body, stubs: { GlModal: ModalStub, @@ -85,10 +114,12 @@ describe('InstallAgentModal', () => { }); }; - const mockSelectedAgentResponse = () => { + const mockSelectedAgentResponse = async () => { createWrapper(); writeQuery(); + await wrapper.vm.$nextTick(); + wrapper.vm.setAgentName('agent-name'); findActionButton().vm.$emit('click'); @@ -96,120 +127,182 @@ describe('InstallAgentModal', () => { }; beforeEach(() => { + apolloProvider = createMockApollo([ + [getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryResponse)], + ]); createWrapper(); + trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn); }); afterEach(() => { wrapper.destroy(); - wrapper = null; apolloProvider = null; }); - describe('initial state', () => { - it('renders the dropdown for available agents', () => { - expect(findAgentDropdown().isVisible()).toBe(true); - expect(findModal().text()).not.toContain(i18n.basicInstallTitle); - expect(findModal().findComponent(GlFormInputGroup).exists()).toBe(false); - expect(findModal().findComponent(GlAlert).exists()).toBe(false); - expect(findModal().findComponent(CodeBlock).exists()).toBe(false); - }); + describe('when agent configurations are present', () => { + const i18n = I18N_AGENT_MODAL.agent_registration; - it('renders a cancel button', () => { - expect(findCancelButton().isVisible()).toBe(true); - expectDisabledAttribute(findCancelButton(), false); - }); + describe('initial state', () => { + it('renders the dropdown for available agents', () => { + expect(findAgentDropdown().isVisible()).toBe(true); + expect(findModal().text()).not.toContain(i18n.basicInstallTitle); + expect(findModal().findComponent(GlFormInputGroup).exists()).toBe(false); + expect(findModal().findComponent(GlAlert).exists()).toBe(false); + expect(findModal().findComponent(CodeBlock).exists()).toBe(false); + }); - it('renders a disabled next button', () => { - expect(findActionButton().isVisible()).toBe(true); - expect(findActionButton().text()).toBe(i18n.registerAgentButton); - expectDisabledAttribute(findActionButton(), true); - }); - }); + it('renders a cancel button', () => { + expect(findCancelButton().isVisible()).toBe(true); + expectDisabledAttribute(findCancelButton(), false); + }); - describe('an agent is selected', () => { - beforeEach(() => { - findAgentDropdown().vm.$emit('agentSelected'); - }); + it('renders a disabled next button', () => { + expect(findActionButton().isVisible()).toBe(true); + expect(findActionButton().text()).toBe(i18n.registerAgentButton); + expectDisabledAttribute(findActionButton(), true); + }); - it('enables the next button', () => { - expect(findActionButton().isVisible()).toBe(true); - expectDisabledAttribute(findActionButton(), false); + it('sends the event with the modalType', () => { + findModal().vm.$emit('show'); + expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTIONS_OPEN, { + label: EVENT_LABEL_MODAL, + property: MODAL_TYPE_REGISTER, + }); + }); }); - }); - describe('registering an agent', () => { - const createAgentHandler = jest.fn().mockResolvedValue(createAgentResponse); - const createAgentTokenHandler = jest.fn().mockResolvedValue(createAgentTokenResponse); + describe('an agent is selected', () => { + beforeEach(() => { + findAgentDropdown().vm.$emit('agentSelected'); + }); - beforeEach(() => { - apolloProvider = createMockApollo([ - [createAgentMutation, createAgentHandler], - [createAgentTokenMutation, createAgentTokenHandler], - ]); + it('enables the next button', () => { + expect(findActionButton().isVisible()).toBe(true); + expectDisabledAttribute(findActionButton(), false); + }); - return mockSelectedAgentResponse(apolloProvider); + it('sends the correct tracking event', () => { + expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTIONS_SELECT, { + label: EVENT_LABEL_MODAL, + }); + }); }); - it('creates an agent and token', () => { - expect(createAgentHandler).toHaveBeenCalledWith({ - input: { name: 'agent-name', projectPath }, - }); + describe('registering an agent', () => { + const createAgentHandler = jest.fn().mockResolvedValue(createAgentResponse); + const createAgentTokenHandler = jest.fn().mockResolvedValue(createAgentTokenResponse); - expect(createAgentTokenHandler).toHaveBeenCalledWith({ - input: { clusterAgentId: 'agent-id', name: 'agent-name' }, + beforeEach(() => { + apolloProvider = createMockApollo([ + [getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryResponse)], + [createAgentMutation, createAgentHandler], + [createAgentTokenMutation, createAgentTokenHandler], + ]); + + return mockSelectedAgentResponse(); }); - }); - it('renders a close button', () => { - expect(findActionButton().isVisible()).toBe(true); - expect(findActionButton().text()).toBe(i18n.close); - expectDisabledAttribute(findActionButton(), false); - }); + it('creates an agent and token', () => { + expect(createAgentHandler).toHaveBeenCalledWith({ + input: { name: 'agent-name', projectPath }, + }); - it('shows agent instructions', () => { - const modalText = findModal().text(); - expect(modalText).toContain(i18n.basicInstallTitle); - expect(modalText).toContain(i18n.basicInstallBody); + expect(createAgentTokenHandler).toHaveBeenCalledWith({ + input: { clusterAgentId: 'agent-id', name: 'agent-name' }, + }); + }); - const token = findModal().findComponent(GlFormInputGroup); - expect(token.props('value')).toBe('mock-agent-token'); + it('renders a close button', () => { + expect(findActionButton().isVisible()).toBe(true); + expect(findActionButton().text()).toBe(i18n.close); + expectDisabledAttribute(findActionButton(), false); + }); - const alert = findModal().findComponent(GlAlert); - expect(alert.props('title')).toBe(i18n.tokenSingleUseWarningTitle); + it('shows agent instructions', () => { + const modalText = findModal().text(); + expect(modalText).toContain(i18n.basicInstallTitle); + expect(modalText).toContain(i18n.basicInstallBody); - const code = findModal().findComponent(CodeBlock).props('code'); - expect(code).toContain('--agent-token=mock-agent-token'); - expect(code).toContain('--kas-address=kas.example.com'); - }); + const token = findModal().findComponent(GlFormInputGroup); + expect(token.props('value')).toBe('mock-agent-token'); - describe('error creating agent', () => { - beforeEach(() => { - apolloProvider = createMockApollo([ - [createAgentMutation, jest.fn().mockResolvedValue(createAgentErrorResponse)], - ]); + const alert = findModal().findComponent(GlAlert); + expect(alert.props('title')).toBe(i18n.tokenSingleUseWarningTitle); - return mockSelectedAgentResponse(); + const code = findModal().findComponent(CodeBlock).props('code'); + expect(code).toContain('--agent-token=mock-agent-token'); + expect(code).toContain('--kas-address=kas.example.com'); + }); + + describe('error creating agent', () => { + beforeEach(() => { + apolloProvider = createMockApollo([ + [getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryResponse)], + [createAgentMutation, jest.fn().mockResolvedValue(createAgentErrorResponse)], + ]); + + return mockSelectedAgentResponse(); + }); + + it('displays the error message', () => { + expect(findAlert().text()).toBe( + createAgentErrorResponse.data.createClusterAgent.errors[0], + ); + }); }); - it('displays the error message', () => { - expect(findAlert().text()).toBe(createAgentErrorResponse.data.createClusterAgent.errors[0]); + describe('error creating token', () => { + beforeEach(() => { + apolloProvider = createMockApollo([ + [getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryResponse)], + [createAgentMutation, jest.fn().mockResolvedValue(createAgentResponse)], + [createAgentTokenMutation, jest.fn().mockResolvedValue(createAgentTokenErrorResponse)], + ]); + + return mockSelectedAgentResponse(); + }); + + it('displays the error message', async () => { + expect(findAlert().text()).toBe( + createAgentTokenErrorResponse.data.clusterAgentTokenCreate.errors[0], + ); + }); }); }); + }); - describe('error creating token', () => { - beforeEach(() => { - apolloProvider = createMockApollo([ - [createAgentMutation, jest.fn().mockResolvedValue(createAgentResponse)], - [createAgentTokenMutation, jest.fn().mockResolvedValue(createAgentTokenErrorResponse)], - ]); + describe('when there are no agent configurations present', () => { + const i18n = I18N_AGENT_MODAL.empty_state; + const apolloQueryEmptyResponse = { + data: { + project: { + clusterAgents: { nodes: [] }, + agentConfigurations: { nodes: [] }, + }, + }, + }; - return mockSelectedAgentResponse(); - }); + beforeEach(() => { + apolloProvider = createMockApollo([ + [getAgentConfigurations, jest.fn().mockResolvedValue(apolloQueryEmptyResponse)], + ]); + createWrapper(); + }); + + it('renders empty state image', () => { + expect(findImage().attributes('src')).toBe(emptyStateImage); + }); + + it('renders a secondary button', () => { + expect(findSecondaryButton().isVisible()).toBe(true); + expect(findSecondaryButton().text()).toBe(i18n.secondaryButton); + }); - it('displays the error message', () => { - expect(findAlert().text()).toBe( - createAgentTokenErrorResponse.data.clusterAgentTokenCreate.errors[0], - ); + it('sends the event with the modalType', () => { + findModal().vm.$emit('show'); + expect(trackingSpy).toHaveBeenCalledWith(undefined, EVENT_ACTIONS_OPEN, { + label: EVENT_LABEL_MODAL, + property: MODAL_TYPE_EMPTY, }); }); }); |