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:
Diffstat (limited to 'spec/frontend/clusters/agents')
-rw-r--r--spec/frontend/clusters/agents/components/agent_integration_status_row_spec.js96
-rw-r--r--spec/frontend/clusters/agents/components/integration_status_spec.js111
-rw-r--r--spec/frontend/clusters/agents/components/show_spec.js6
3 files changed, 213 insertions, 0 deletions
diff --git a/spec/frontend/clusters/agents/components/agent_integration_status_row_spec.js b/spec/frontend/clusters/agents/components/agent_integration_status_row_spec.js
new file mode 100644
index 00000000000..2af64191a88
--- /dev/null
+++ b/spec/frontend/clusters/agents/components/agent_integration_status_row_spec.js
@@ -0,0 +1,96 @@
+import { GlLink, GlIcon, GlBadge } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import AgentIntegrationStatusRow from '~/clusters/agents/components/agent_integration_status_row.vue';
+
+const defaultProps = {
+ text: 'Default integration status',
+};
+
+describe('IntegrationStatus', () => {
+ let wrapper;
+
+ const createWrapper = ({ props = {}, glFeatures = {} } = {}) => {
+ wrapper = shallowMount(AgentIntegrationStatusRow, {
+ propsData: {
+ ...defaultProps,
+ ...props,
+ },
+ provide: {
+ glFeatures,
+ },
+ });
+ };
+
+ const findLink = () => wrapper.findComponent(GlLink);
+ const findIcon = () => wrapper.findComponent(GlIcon);
+ const findBadge = () => wrapper.findComponent(GlBadge);
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ describe('icon', () => {
+ const icon = 'status-success';
+ const iconClass = 'text-success-500';
+ it.each`
+ props | iconName | iconClassName
+ ${{ icon, iconClass }} | ${icon} | ${iconClass}
+ ${{ icon }} | ${icon} | ${'text-info'}
+ ${{ iconClass }} | ${'information'} | ${iconClass}
+ ${null} | ${'information'} | ${'text-info'}
+ `('displays correct icon when props are $props', ({ props, iconName, iconClassName }) => {
+ createWrapper({ props });
+
+ expect(findIcon().props('name')).toBe(iconName);
+ expect(findIcon().attributes('class')).toContain(iconClassName);
+ });
+ });
+
+ describe('helpUrl', () => {
+ it('displays a link with the correct help url when provided in props', () => {
+ const props = {
+ helpUrl: 'help-page-path',
+ };
+ createWrapper({ props });
+
+ expect(findLink().attributes('href')).toBe(props.helpUrl);
+ expect(findLink().text()).toBe(defaultProps.text);
+ });
+
+ it("displays the text without a link when it's not provided", () => {
+ createWrapper();
+
+ expect(findLink().exists()).toBe(false);
+ expect(wrapper.text()).toBe(defaultProps.text);
+ });
+ });
+
+ describe('badge', () => {
+ it('does not display premium feature badge when featureName is not provided', () => {
+ createWrapper();
+
+ expect(findBadge().exists()).toBe(false);
+ });
+
+ it('does not display premium feature badge when featureName is provided and is available for the project', () => {
+ const props = { featureName: 'feature' };
+ const glFeatures = { feature: true };
+ createWrapper({ props, glFeatures });
+
+ expect(findBadge().exists()).toBe(false);
+ });
+
+ it('displays premium feature badge when featureName is provided and is not available for the project', () => {
+ const props = { featureName: 'feature' };
+ const glFeatures = { feature: false };
+ createWrapper({ props, glFeatures });
+
+ expect(findBadge().props()).toMatchObject({
+ icon: 'license',
+ variant: 'tier',
+ size: 'md',
+ });
+ expect(findBadge().text()).toBe(wrapper.vm.$options.i18n.premiumTitle);
+ });
+ });
+});
diff --git a/spec/frontend/clusters/agents/components/integration_status_spec.js b/spec/frontend/clusters/agents/components/integration_status_spec.js
new file mode 100644
index 00000000000..36f0e622452
--- /dev/null
+++ b/spec/frontend/clusters/agents/components/integration_status_spec.js
@@ -0,0 +1,111 @@
+import { GlCollapse, GlButton, GlIcon } from '@gitlab/ui';
+import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
+import IntegrationStatus from '~/clusters/agents/components/integration_status.vue';
+import AgentIntegrationStatusRow from '~/clusters/agents/components/agent_integration_status_row.vue';
+import { ACTIVE_CONNECTION_TIME } from '~/clusters_list/constants';
+import {
+ INTEGRATION_STATUS_VALID_TOKEN,
+ INTEGRATION_STATUS_NO_TOKEN,
+ INTEGRATION_STATUS_RESTRICTED_CI_CD,
+} from '~/clusters/agents/constants';
+
+const connectedTimeNow = new Date();
+const connectedTimeInactive = new Date(connectedTimeNow.getTime() - ACTIVE_CONNECTION_TIME);
+
+describe('IntegrationStatus', () => {
+ let wrapper;
+
+ const createWrapper = (tokens = []) => {
+ wrapper = shallowMountExtended(IntegrationStatus, {
+ propsData: { tokens },
+ });
+ };
+
+ const findCollapseButton = () => wrapper.findComponent(GlButton);
+ const findCollapse = () => wrapper.findComponent(GlCollapse);
+ const findStatusIcon = () => wrapper.findComponent(GlIcon);
+ const findAgentStatus = () => wrapper.findByTestId('agent-status');
+ const findAgentIntegrationStatusRows = () => wrapper.findAllComponents(AgentIntegrationStatusRow);
+
+ afterEach(() => {
+ wrapper.destroy();
+ });
+
+ it.each`
+ lastUsedAt | status | iconName
+ ${null} | ${'Never connected'} | ${'status-neutral'}
+ ${connectedTimeNow} | ${'Connected'} | ${'status-success'}
+ ${connectedTimeInactive} | ${'Not connected'} | ${'status-alert'}
+ `(
+ 'displays correct text and icon when agent connection status is "$status"',
+ ({ lastUsedAt, status, iconName }) => {
+ const tokens = [{ lastUsedAt }];
+ createWrapper(tokens);
+
+ expect(findStatusIcon().props('name')).toBe(iconName);
+ expect(findAgentStatus().text()).toBe(status);
+ },
+ );
+
+ describe('default', () => {
+ beforeEach(() => {
+ createWrapper();
+ });
+
+ it('shows the collapse toggle button', () => {
+ expect(findCollapseButton().text()).toBe(wrapper.vm.$options.i18n.title);
+ expect(findCollapseButton().attributes()).toMatchObject({
+ variant: 'link',
+ icon: 'chevron-right',
+ size: 'small',
+ });
+ });
+
+ it('sets collapse component as invisible by default', () => {
+ expect(findCollapse().props('visible')).toBeUndefined();
+ });
+ });
+
+ describe('when user clicks collapse toggle', () => {
+ beforeEach(() => {
+ createWrapper();
+ findCollapseButton().vm.$emit('click');
+ });
+
+ it('changes the collapse button icon', () => {
+ expect(findCollapseButton().props('icon')).toBe('chevron-down');
+ });
+
+ it('sets collapse component as visible', () => {
+ expect(findCollapse().attributes('visible')).toBe('true');
+ });
+ });
+
+ describe('integration status details', () => {
+ it.each`
+ agentStatus | tokens | integrationStatuses
+ ${'active'} | ${[{ lastUsedAt: connectedTimeNow }]} | ${[INTEGRATION_STATUS_VALID_TOKEN, INTEGRATION_STATUS_RESTRICTED_CI_CD]}
+ ${'inactive'} | ${[{ lastUsedAt: connectedTimeInactive }]} | ${[INTEGRATION_STATUS_RESTRICTED_CI_CD]}
+ ${'inactive'} | ${[]} | ${[INTEGRATION_STATUS_NO_TOKEN, INTEGRATION_STATUS_RESTRICTED_CI_CD]}
+ ${'unused'} | ${[{ lastUsedAt: null }]} | ${[INTEGRATION_STATUS_RESTRICTED_CI_CD]}
+ ${'unused'} | ${[]} | ${[INTEGRATION_STATUS_NO_TOKEN, INTEGRATION_STATUS_RESTRICTED_CI_CD]}
+ `(
+ 'displays AgentIntegrationStatusRow component with correct properties when agent status is $agentStatus and agent has $tokens.length tokens',
+ ({ tokens, integrationStatuses }) => {
+ createWrapper(tokens);
+
+ expect(findAgentIntegrationStatusRows().length).toBe(integrationStatuses.length);
+
+ integrationStatuses.forEach((integrationStatus, index) => {
+ expect(findAgentIntegrationStatusRows().at(index).props()).toMatchObject({
+ icon: integrationStatus.icon,
+ iconClass: integrationStatus.iconClass,
+ text: integrationStatus.text,
+ helpUrl: integrationStatus.helpUrl || null,
+ featureName: integrationStatus.featureName || null,
+ });
+ });
+ },
+ );
+ });
+});
diff --git a/spec/frontend/clusters/agents/components/show_spec.js b/spec/frontend/clusters/agents/components/show_spec.js
index f2f073544e3..efa85136b17 100644
--- a/spec/frontend/clusters/agents/components/show_spec.js
+++ b/spec/frontend/clusters/agents/components/show_spec.js
@@ -6,6 +6,7 @@ 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 IntegrationStatus from '~/clusters/agents/components/integration_status.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';
@@ -76,6 +77,7 @@ describe('ClusterAgentShow', () => {
const findTokenCount = () => wrapper.findByTestId('cluster-agent-token-count').text();
const findEESecurityTabSlot = () => wrapper.findByTestId('ee-security-tab');
const findActivity = () => wrapper.findComponent(ActivityEvents);
+ const findIntegrationStatus = () => wrapper.findComponent(IntegrationStatus);
afterEach(() => {
wrapper.destroy();
@@ -107,6 +109,10 @@ describe('ClusterAgentShow', () => {
expect(findCreatedText()).toMatchInterpolatedText('Created by user-1 2 days ago');
});
+ it('displays agent integration status section', () => {
+ expect(findIntegrationStatus().exists()).toBe(true);
+ });
+
it('displays token count', () => {
expect(findTokenCount()).toMatchInterpolatedText(
`${ClusterAgentShow.i18n.tokens} ${defaultClusterAgent.tokens.count}`,