diff options
Diffstat (limited to 'spec/frontend/clusters_list/components/agents_spec.js')
-rw-r--r-- | spec/frontend/clusters_list/components/agents_spec.js | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/spec/frontend/clusters_list/components/agents_spec.js b/spec/frontend/clusters_list/components/agents_spec.js new file mode 100644 index 00000000000..54d5ae94172 --- /dev/null +++ b/spec/frontend/clusters_list/components/agents_spec.js @@ -0,0 +1,246 @@ +import { GlAlert, GlKeysetPagination, GlLoadingIcon } from '@gitlab/ui'; +import { createLocalVue, shallowMount } from '@vue/test-utils'; +import VueApollo from 'vue-apollo'; +import AgentEmptyState from '~/clusters_list/components/agent_empty_state.vue'; +import AgentTable from '~/clusters_list/components/agent_table.vue'; +import Agents from '~/clusters_list/components/agents.vue'; +import { ACTIVE_CONNECTION_TIME } from '~/clusters_list/constants'; +import getAgentsQuery from '~/clusters_list/graphql/queries/get_agents.query.graphql'; +import createMockApollo from 'helpers/mock_apollo_helper'; + +const localVue = createLocalVue(); +localVue.use(VueApollo); + +describe('Agents', () => { + let wrapper; + + const propsData = { + defaultBranchName: 'default', + }; + const provideData = { + projectPath: 'path/to/project', + kasAddress: 'kas.example.com', + }; + + const createWrapper = ({ agents = [], pageInfo = null, trees = [] }) => { + const provide = provideData; + const apolloQueryResponse = { + data: { + project: { + clusterAgents: { nodes: agents, pageInfo, tokens: { nodes: [] } }, + repository: { tree: { trees: { nodes: trees, pageInfo } } }, + }, + }, + }; + + const apolloProvider = createMockApollo([ + [getAgentsQuery, jest.fn().mockResolvedValue(apolloQueryResponse, provide)], + ]); + + wrapper = shallowMount(Agents, { + localVue, + apolloProvider, + propsData, + provide: provideData, + }); + + return wrapper.vm.$nextTick(); + }; + + const findAgentTable = () => wrapper.find(AgentTable); + const findEmptyState = () => wrapper.find(AgentEmptyState); + const findPaginationButtons = () => wrapper.find(GlKeysetPagination); + + afterEach(() => { + if (wrapper) { + wrapper.destroy(); + wrapper = null; + } + }); + + describe('when there is a list of agents', () => { + let testDate = new Date(); + const agents = [ + { + id: '1', + name: 'agent-1', + webPath: '/agent-1', + tokens: null, + }, + { + id: '2', + name: 'agent-2', + webPath: '/agent-2', + tokens: { + nodes: [ + { + lastUsedAt: testDate, + }, + ], + }, + }, + ]; + + const trees = [ + { + name: 'agent-2', + path: '.gitlab/agents/agent-2', + webPath: '/project/path/.gitlab/agents/agent-2', + }, + ]; + + const expectedAgentsList = [ + { + id: '1', + name: 'agent-1', + webPath: '/agent-1', + configFolder: undefined, + status: 'unused', + lastContact: null, + tokens: null, + }, + { + id: '2', + name: 'agent-2', + configFolder: { + name: 'agent-2', + path: '.gitlab/agents/agent-2', + webPath: '/project/path/.gitlab/agents/agent-2', + }, + webPath: '/agent-2', + status: 'active', + lastContact: new Date(testDate).getTime(), + tokens: { + nodes: [ + { + lastUsedAt: testDate, + }, + ], + }, + }, + ]; + + beforeEach(() => { + return createWrapper({ agents, trees }); + }); + + it('should render agent table', () => { + expect(findAgentTable().exists()).toBe(true); + expect(findEmptyState().exists()).toBe(false); + }); + + it('should pass agent and folder info to table component', () => { + expect(findAgentTable().props('agents')).toMatchObject(expectedAgentsList); + }); + + describe('when the agent has recently connected tokens', () => { + it('should set agent status to active', () => { + expect(findAgentTable().props('agents')).toMatchObject(expectedAgentsList); + }); + }); + + describe('when the agent has tokens connected more then 8 minutes ago', () => { + const now = new Date(); + testDate = new Date(now.getTime() - ACTIVE_CONNECTION_TIME); + it('should set agent status to inactive', () => { + expect(findAgentTable().props('agents')).toMatchObject(expectedAgentsList); + }); + }); + + describe('when the agent has no connected tokens', () => { + testDate = null; + it('should set agent status to unused', () => { + expect(findAgentTable().props('agents')).toMatchObject(expectedAgentsList); + }); + }); + + it('should not render pagination buttons when there are no additional pages', () => { + expect(findPaginationButtons().exists()).toBe(false); + }); + + describe('when the list has additional pages', () => { + const pageInfo = { + hasNextPage: true, + hasPreviousPage: false, + startCursor: 'prev', + endCursor: 'next', + }; + + beforeEach(() => { + return createWrapper({ + agents, + pageInfo, + }); + }); + + it('should render pagination buttons', () => { + expect(findPaginationButtons().exists()).toBe(true); + }); + + it('should pass pageInfo to the pagination component', () => { + expect(findPaginationButtons().props()).toMatchObject(pageInfo); + }); + }); + }); + + describe('when the agent list is empty', () => { + beforeEach(() => { + return createWrapper({ agents: [] }); + }); + + it('should render empty state', () => { + expect(findAgentTable().exists()).toBe(false); + expect(findEmptyState().exists()).toBe(true); + }); + }); + + describe('when the agent configurations are present', () => { + const trees = [ + { + name: 'agent-1', + path: '.gitlab/agents/agent-1', + webPath: '/project/path/.gitlab/agents/agent-1', + }, + ]; + + beforeEach(() => { + return createWrapper({ agents: [], trees }); + }); + + it('should pass the correct hasConfigurations boolean value to empty state component', () => { + expect(findEmptyState().props('hasConfigurations')).toEqual(true); + }); + }); + + describe('when agents query has errored', () => { + beforeEach(() => { + return createWrapper({ agents: null }); + }); + + it('displays an alert message', () => { + expect(wrapper.find(GlAlert).exists()).toBe(true); + }); + }); + + describe('when agents query is loading', () => { + const mocks = { + $apollo: { + queries: { + agents: { + loading: true, + }, + }, + }, + }; + + beforeEach(() => { + wrapper = shallowMount(Agents, { mocks, propsData, provide: provideData }); + + return wrapper.vm.$nextTick(); + }); + + it('displays a loading icon', () => { + expect(wrapper.find(GlLoadingIcon).exists()).toBe(true); + }); + }); +}); |