Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-12-20 16:37:47 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-12-20 16:37:47 +0300
commitaee0a117a889461ce8ced6fcf73207fe017f1d99 (patch)
tree891d9ef189227a8445d83f35c1b0fc99573f4380 /spec/frontend/clusters
parent8d46af3258650d305f53b819eabf7ab18d22f59e (diff)
Add latest changes from gitlab-org/gitlab@14-6-stable-eev14.6.0-rc42
Diffstat (limited to 'spec/frontend/clusters')
-rw-r--r--spec/frontend/clusters/agents/components/activity_events_list_spec.js102
-rw-r--r--spec/frontend/clusters/agents/components/activity_history_item_spec.js56
-rw-r--r--spec/frontend/clusters/agents/components/show_spec.js10
-rw-r--r--spec/frontend/clusters/mock_data.js165
4 files changed, 332 insertions, 1 deletions
diff --git a/spec/frontend/clusters/agents/components/activity_events_list_spec.js b/spec/frontend/clusters/agents/components/activity_events_list_spec.js
new file mode 100644
index 00000000000..4abbd77dfb7
--- /dev/null
+++ b/spec/frontend/clusters/agents/components/activity_events_list_spec.js
@@ -0,0 +1,102 @@
+import { GlLoadingIcon, GlAlert, GlEmptyState } from '@gitlab/ui';
+import Vue from 'vue';
+import VueApollo from 'vue-apollo';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import { useFakeDate } from 'helpers/fake_date';
+import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
+import ActivityEvents from '~/clusters/agents/components/activity_events_list.vue';
+import ActivityHistoryItem from '~/clusters/agents/components/activity_history_item.vue';
+import getAgentActivityEventsQuery from '~/clusters/agents/graphql/queries/get_agent_activity_events.query.graphql';
+import { mockResponse, mockEmptyResponse } from '../../mock_data';
+
+const activityEmptyStateImage = '/path/to/image';
+const projectPath = 'path/to/project';
+const agentName = 'cluster-agent';
+
+Vue.use(VueApollo);
+
+describe('ActivityEvents', () => {
+ let wrapper;
+ useFakeDate([2021, 12, 3]);
+
+ const provideData = {
+ agentName,
+ projectPath,
+ activityEmptyStateImage,
+ };
+
+ const createWrapper = ({ queryResponse = null } = {}) => {
+ const agentEventsQueryResponse = queryResponse || jest.fn().mockResolvedValue(mockResponse);
+ const apolloProvider = createMockApollo([
+ [getAgentActivityEventsQuery, agentEventsQueryResponse],
+ ]);
+
+ wrapper = shallowMountExtended(ActivityEvents, {
+ apolloProvider,
+ provide: provideData,
+ });
+ };
+
+ const findLoadingIcon = () => wrapper.findComponent(GlLoadingIcon);
+ const findAlert = () => wrapper.findComponent(GlAlert);
+ const findEmptyState = () => wrapper.findComponent(GlEmptyState);
+ const findAllActivityHistoryItems = () => wrapper.findAllComponents(ActivityHistoryItem);
+ const findSectionTitle = (at) => wrapper.findAllByTestId('activity-section-title').at(at);
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('while the agentEvents query is loading', () => {
+ it('displays a loading icon', async () => {
+ createWrapper();
+
+ expect(findLoadingIcon().exists()).toBe(true);
+ await waitForPromises();
+ expect(findLoadingIcon().exists()).toBe(false);
+ });
+ });
+
+ describe('when the agentEvents query has errored', () => {
+ beforeEach(() => {
+ createWrapper({ queryResponse: jest.fn().mockRejectedValue() });
+ return waitForPromises();
+ });
+
+ it('displays an alert message', () => {
+ expect(findAlert().exists()).toBe(true);
+ });
+ });
+
+ describe('when there are no agentEvents', () => {
+ beforeEach(() => {
+ createWrapper({ queryResponse: jest.fn().mockResolvedValue(mockEmptyResponse) });
+ });
+
+ it('displays an empty state with the correct illustration', () => {
+ expect(findEmptyState().exists()).toBe(true);
+ expect(findEmptyState().props('svgPath')).toBe(activityEmptyStateImage);
+ });
+ });
+
+ describe('when the agentEvents are present', () => {
+ const length = mockResponse.data?.project?.clusterAgent?.activityEvents?.nodes?.length;
+
+ beforeEach(() => {
+ createWrapper();
+ });
+ it('renders an activity-history-item components for every event', () => {
+ expect(findAllActivityHistoryItems()).toHaveLength(length);
+ });
+
+ it.each`
+ recordedAt | date | lineNumber
+ ${'2021-12-03T01:06:56Z'} | ${'Today'} | ${0}
+ ${'2021-12-02T19:26:56Z'} | ${'Yesterday'} | ${1}
+ ${'2021-11-22T19:26:56Z'} | ${'2021-11-22'} | ${2}
+ `('renders correct titles for different days', ({ date, lineNumber }) => {
+ expect(findSectionTitle(lineNumber).text()).toBe(date);
+ });
+ });
+});
diff --git a/spec/frontend/clusters/agents/components/activity_history_item_spec.js b/spec/frontend/clusters/agents/components/activity_history_item_spec.js
new file mode 100644
index 00000000000..100a280d0cc
--- /dev/null
+++ b/spec/frontend/clusters/agents/components/activity_history_item_spec.js
@@ -0,0 +1,56 @@
+import { GlSprintf } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import { sprintf } from '~/locale';
+import HistoryItem from '~/vue_shared/components/registry/history_item.vue';
+import TimeAgoTooltip from '~/vue_shared/components/time_ago_tooltip.vue';
+import ActivityHistoryItem from '~/clusters/agents/components/activity_history_item.vue';
+import { EVENT_DETAILS, DEFAULT_ICON } from '~/clusters/agents/constants';
+import { mockAgentHistoryActivityItems } from '../../mock_data';
+
+const agentName = 'cluster-agent';
+
+describe('ActivityHistoryItem', () => {
+ let wrapper;
+
+ const createWrapper = ({ event = {} }) => {
+ wrapper = shallowMount(ActivityHistoryItem, {
+ propsData: { event },
+ stubs: {
+ HistoryItem,
+ GlSprintf,
+ },
+ });
+ };
+
+ const findHistoryItem = () => wrapper.findComponent(HistoryItem);
+ const findTimeAgo = () => wrapper.find(TimeAgoTooltip);
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe.each`
+ kind | icon | title | lineNumber
+ ${'token_created'} | ${EVENT_DETAILS.token_created.eventTypeIcon} | ${sprintf(EVENT_DETAILS.token_created.title, { tokenName: agentName })} | ${0}
+ ${'token_revoked'} | ${EVENT_DETAILS.token_revoked.eventTypeIcon} | ${sprintf(EVENT_DETAILS.token_revoked.title, { tokenName: agentName })} | ${1}
+ ${'agent_connected'} | ${EVENT_DETAILS.agent_connected.eventTypeIcon} | ${sprintf(EVENT_DETAILS.agent_connected.title, { titleIcon: '' })} | ${2}
+ ${'agent_disconnected'} | ${EVENT_DETAILS.agent_disconnected.eventTypeIcon} | ${sprintf(EVENT_DETAILS.agent_disconnected.title, { titleIcon: '' })} | ${3}
+ ${'agent_connected'} | ${EVENT_DETAILS.agent_connected.eventTypeIcon} | ${sprintf(EVENT_DETAILS.agent_connected.title, { titleIcon: '' })} | ${4}
+ ${'unknown_agent'} | ${DEFAULT_ICON} | ${'unknown_agent Event occurred'} | ${5}
+ `('when the event type is $kind event', ({ icon, title, lineNumber }) => {
+ beforeEach(() => {
+ const event = mockAgentHistoryActivityItems[lineNumber];
+ createWrapper({ event });
+ });
+ it('renders the correct icon', () => {
+ expect(findHistoryItem().props('icon')).toBe(icon);
+ });
+ it('renders the correct title', () => {
+ expect(findHistoryItem().text()).toContain(title);
+ });
+ it('renders the correct time-ago tooltip', () => {
+ const activityEvents = mockAgentHistoryActivityItems;
+ expect(findTimeAgo().props('time')).toBe(activityEvents[lineNumber].recordedAt);
+ });
+ });
+});
diff --git a/spec/frontend/clusters/agents/components/show_spec.js b/spec/frontend/clusters/agents/components/show_spec.js
index c502e7d813e..d5a8117f48c 100644
--- a/spec/frontend/clusters/agents/components/show_spec.js
+++ b/spec/frontend/clusters/agents/components/show_spec.js
@@ -5,6 +5,7 @@ import VueApollo from 'vue-apollo';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import ClusterAgentShow from '~/clusters/agents/components/show.vue';
import TokenTable from '~/clusters/agents/components/token_table.vue';
+import ActivityEvents from '~/clusters/agents/components/activity_events_list.vue';
import getAgentQuery from '~/clusters/agents/graphql/queries/get_cluster_agent.query.graphql';
import { useFakeDate } from 'helpers/fake_date';
import createMockApollo from 'helpers/mock_apollo_helper';
@@ -27,6 +28,7 @@ describe('ClusterAgentShow', () => {
id: '1',
createdAt: '2021-02-13T00:00:00Z',
createdByUser: {
+ id: 'user-1',
name: 'user-1',
},
name: 'token-1',
@@ -39,7 +41,8 @@ describe('ClusterAgentShow', () => {
const createWrapper = ({ clusterAgent, queryResponse = null }) => {
const agentQueryResponse =
- queryResponse || jest.fn().mockResolvedValue({ data: { project: { clusterAgent } } });
+ queryResponse ||
+ jest.fn().mockResolvedValue({ data: { project: { id: 'project-1', clusterAgent } } });
const apolloProvider = createMockApollo([[getAgentQuery, agentQueryResponse]]);
wrapper = extendedWrapper(
@@ -70,6 +73,7 @@ describe('ClusterAgentShow', () => {
const findPaginationButtons = () => wrapper.findComponent(GlKeysetPagination);
const findTokenCount = () => wrapper.findByTestId('cluster-agent-token-count').text();
const findEESecurityTabSlot = () => wrapper.findByTestId('ee-security-tab');
+ const findActivity = () => wrapper.findComponent(ActivityEvents);
afterEach(() => {
wrapper.destroy();
@@ -101,6 +105,10 @@ describe('ClusterAgentShow', () => {
it('should not render pagination buttons when there are no additional pages', () => {
expect(findPaginationButtons().exists()).toBe(false);
});
+
+ it('renders activity events list', () => {
+ expect(findActivity().exists()).toBe(true);
+ });
});
describe('when create user is unknown', () => {
diff --git a/spec/frontend/clusters/mock_data.js b/spec/frontend/clusters/mock_data.js
new file mode 100644
index 00000000000..75306ca0295
--- /dev/null
+++ b/spec/frontend/clusters/mock_data.js
@@ -0,0 +1,165 @@
+const user = {
+ id: 1,
+ name: 'Administrator',
+ username: 'root',
+ webUrl: 'http://172.31.0.1:3000/root',
+};
+
+const agentToken = {
+ id: 1,
+ name: 'cluster-agent',
+};
+
+export const defaultActivityEvent = {
+ kind: 'unknown_agent',
+ level: 'info',
+ recordedAt: '2021-11-22T19:26:56Z',
+ agentToken,
+ user,
+};
+
+export const mockAgentActivityEvents = [
+ {
+ kind: 'token_created',
+ level: 'info',
+ recordedAt: '2021-12-03T01:06:56Z',
+ agentToken,
+ user,
+ },
+
+ {
+ kind: 'token_revoked',
+ level: 'info',
+ recordedAt: '2021-12-03T00:26:56Z',
+ agentToken,
+ user,
+ },
+
+ {
+ kind: 'agent_connected',
+ level: 'info',
+ recordedAt: '2021-12-02T19:26:56Z',
+ agentToken,
+ user,
+ },
+
+ {
+ kind: 'agent_disconnected',
+ level: 'info',
+ recordedAt: '2021-12-02T19:26:56Z',
+ agentToken,
+ user,
+ },
+
+ {
+ kind: 'agent_connected',
+ level: 'info',
+ recordedAt: '2021-11-22T19:26:56Z',
+ agentToken,
+ user,
+ },
+
+ {
+ kind: 'unknown_agent',
+ level: 'info',
+ recordedAt: '2021-11-22T19:26:56Z',
+ agentToken,
+ user,
+ },
+];
+
+export const mockResponse = {
+ data: {
+ project: {
+ id: 'project-1',
+ clusterAgent: {
+ id: 'cluster-agent',
+ activityEvents: {
+ nodes: mockAgentActivityEvents,
+ },
+ },
+ },
+ },
+};
+
+export const mockEmptyResponse = {
+ data: {
+ project: {
+ id: 'project-1',
+ clusterAgent: {
+ id: 'cluster-agent',
+ activityEvents: {
+ nodes: [],
+ },
+ },
+ },
+ },
+};
+
+export const mockAgentHistoryActivityItems = [
+ {
+ kind: 'token_created',
+ level: 'info',
+ recordedAt: '2021-12-03T01:06:56Z',
+ agentToken,
+ user,
+ eventTypeIcon: 'token',
+ title: 'cluster-agent created',
+ body: 'Token created by Administrator',
+ },
+
+ {
+ kind: 'token_revoked',
+ level: 'info',
+ recordedAt: '2021-12-03T00:26:56Z',
+ agentToken,
+ user,
+ eventTypeIcon: 'token',
+ title: 'cluster-agent revoked',
+ body: 'Token revoked by Administrator',
+ },
+
+ {
+ kind: 'agent_connected',
+ level: 'info',
+ recordedAt: '2021-12-02T19:26:56Z',
+ agentToken,
+ user,
+ eventTypeIcon: 'connected',
+ title: 'Connected',
+ body: 'Agent Connected',
+ },
+
+ {
+ kind: 'agent_disconnected',
+ level: 'info',
+ recordedAt: '2021-12-02T19:26:56Z',
+ agentToken,
+ user,
+ eventTypeIcon: 'connected',
+ title: 'Not connected',
+ body: 'Agent Not connected',
+ },
+
+ {
+ kind: 'agent_connected',
+ level: 'info',
+ recordedAt: '2021-11-22T19:26:56Z',
+ agentToken,
+ user,
+ eventTypeIcon: 'connected',
+ title: 'Connected',
+ body: 'Agent Connected',
+ },
+
+ {
+ kind: 'unknown_agent',
+ level: 'info',
+ recordedAt: '2021-11-22T19:26:56Z',
+ agentToken,
+ user,
+ eventTypeIcon: 'token',
+ title: 'unknown_agent',
+ body: 'Event occurred',
+ },
+];