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/ci/runner/components')
-rw-r--r--spec/frontend/ci/runner/components/cells/runner_summary_cell_spec.js (renamed from spec/frontend/ci/runner/components/cells/runner_stacked_summary_cell_spec.js)29
-rw-r--r--spec/frontend/ci/runner/components/runner_filtered_search_bar_spec.js3
-rw-r--r--spec/frontend/ci/runner/components/runner_job_status_badge_spec.js51
-rw-r--r--spec/frontend/ci/runner/components/runner_list_spec.js15
-rw-r--r--spec/frontend/ci/runner/components/runner_status_badge_spec.js4
-rw-r--r--spec/frontend/ci/runner/components/search_tokens/tag_token_spec.js4
-rw-r--r--spec/frontend/ci/runner/components/stat/runner_stats_spec.js53
7 files changed, 133 insertions, 26 deletions
diff --git a/spec/frontend/ci/runner/components/cells/runner_stacked_summary_cell_spec.js b/spec/frontend/ci/runner/components/cells/runner_summary_cell_spec.js
index 4aa354f9b62..10280c77303 100644
--- a/spec/frontend/ci/runner/components/cells/runner_stacked_summary_cell_spec.js
+++ b/spec/frontend/ci/runner/components/cells/runner_summary_cell_spec.js
@@ -1,12 +1,18 @@
import { __ } from '~/locale';
import { mountExtended } from 'helpers/vue_test_utils_helper';
-import RunnerStackedSummaryCell from '~/ci/runner/components/cells/runner_stacked_summary_cell.vue';
+import RunnerSummaryCell from '~/ci/runner/components/cells/runner_summary_cell.vue';
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
import RunnerTags from '~/ci/runner/components/runner_tags.vue';
+import RunnerJobStatusBadge from '~/ci/runner/components/runner_job_status_badge.vue';
import RunnerSummaryField from '~/ci/runner/components/cells/runner_summary_field.vue';
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
-import { INSTANCE_TYPE, I18N_INSTANCE_TYPE, PROJECT_TYPE } from '~/ci/runner/constants';
+import {
+ INSTANCE_TYPE,
+ I18N_INSTANCE_TYPE,
+ PROJECT_TYPE,
+ I18N_NO_DESCRIPTION,
+} from '~/ci/runner/constants';
import { allRunnersData } from '../../mock_data';
@@ -16,13 +22,14 @@ describe('RunnerTypeCell', () => {
let wrapper;
const findLockIcon = () => wrapper.findByTestId('lock-icon');
+ const findRunnerJobStatusBadge = () => wrapper.findComponent(RunnerJobStatusBadge);
const findRunnerTags = () => wrapper.findComponent(RunnerTags);
const findRunnerSummaryField = (icon) =>
wrapper.findAllComponents(RunnerSummaryField).filter((w) => w.props('icon') === icon)
.wrappers[0];
const createComponent = (runner, options) => {
- wrapper = mountExtended(RunnerStackedSummaryCell, {
+ wrapper = mountExtended(RunnerSummaryCell, {
propsData: {
runner: {
...mockRunner,
@@ -80,6 +87,18 @@ describe('RunnerTypeCell', () => {
expect(wrapper.text()).toContain(mockRunner.description);
});
+ it('Displays the no runner description', () => {
+ createComponent({
+ description: null,
+ });
+
+ expect(wrapper.text()).toContain(I18N_NO_DESCRIPTION);
+ });
+
+ it('Displays job execution status', () => {
+ expect(findRunnerJobStatusBadge().props('jobStatus')).toBe(mockRunner.jobExecutionStatus);
+ });
+
it('Displays last contact', () => {
createComponent({
contactedAt: '2022-01-02',
@@ -147,14 +166,14 @@ describe('RunnerTypeCell', () => {
expect(findRunnerTags().props('tagList')).toEqual(['shell', 'linux']);
});
- it('Displays a custom slot', () => {
+ it.each(['runner-name', 'runner-job-status-badge'])('Displays a custom "%s" slot', (slotName) => {
const slotContent = 'My custom runner name';
createComponent(
{},
{
slots: {
- 'runner-name': slotContent,
+ [slotName]: slotContent,
},
},
);
diff --git a/spec/frontend/ci/runner/components/runner_filtered_search_bar_spec.js b/spec/frontend/ci/runner/components/runner_filtered_search_bar_spec.js
index 496c144083e..408750e646f 100644
--- a/spec/frontend/ci/runner/components/runner_filtered_search_bar_spec.js
+++ b/spec/frontend/ci/runner/components/runner_filtered_search_bar_spec.js
@@ -13,6 +13,7 @@ import {
DEFAULT_SORT,
CONTACTED_DESC,
} from '~/ci/runner/constants';
+import { FILTERED_SEARCH_TERM } from '~/vue_shared/components/filtered_search_bar/constants';
import FilteredSearch from '~/vue_shared/components/filtered_search_bar/filtered_search_bar_root.vue';
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
@@ -34,7 +35,7 @@ describe('RunnerList', () => {
const mockOtherSort = CONTACTED_DESC;
const mockFilters = [
{ type: PARAM_KEY_STATUS, value: { data: STATUS_ONLINE, operator: '=' } },
- { type: 'filtered-search-term', value: { data: '' } },
+ { type: FILTERED_SEARCH_TERM, value: { data: '' } },
];
const expectToHaveLastEmittedInput = (value) => {
diff --git a/spec/frontend/ci/runner/components/runner_job_status_badge_spec.js b/spec/frontend/ci/runner/components/runner_job_status_badge_spec.js
new file mode 100644
index 00000000000..015bebf40e3
--- /dev/null
+++ b/spec/frontend/ci/runner/components/runner_job_status_badge_spec.js
@@ -0,0 +1,51 @@
+import { GlBadge } from '@gitlab/ui';
+import { shallowMount } from '@vue/test-utils';
+import RunnerJobStatusBadge from '~/ci/runner/components/runner_job_status_badge.vue';
+import {
+ I18N_JOB_STATUS_RUNNING,
+ I18N_JOB_STATUS_IDLE,
+ JOB_STATUS_RUNNING,
+ JOB_STATUS_IDLE,
+} from '~/ci/runner/constants';
+
+describe('RunnerTypeBadge', () => {
+ let wrapper;
+
+ const findBadge = () => wrapper.findComponent(GlBadge);
+
+ const createComponent = ({ props, ...options } = {}) => {
+ wrapper = shallowMount(RunnerJobStatusBadge, {
+ propsData: {
+ ...props,
+ },
+ ...options,
+ });
+ };
+
+ it.each`
+ jobStatus | classes | text
+ ${JOB_STATUS_RUNNING} | ${['gl-mr-3', 'gl-bg-transparent!', 'gl-text-blue-600!', 'gl-border', 'gl-border-blue-600!']} | ${I18N_JOB_STATUS_RUNNING}
+ ${JOB_STATUS_IDLE} | ${['gl-mr-3', 'gl-bg-transparent!', 'gl-text-gray-700!', 'gl-border', 'gl-border-gray-500!']} | ${I18N_JOB_STATUS_IDLE}
+ `(
+ 'renders $jobStatus job status with "$text" text and styles',
+ ({ jobStatus, classes, text }) => {
+ createComponent({ props: { jobStatus } });
+
+ expect(findBadge().props()).toMatchObject({ size: 'sm', variant: 'muted' });
+ expect(findBadge().classes().sort()).toEqual(classes.sort());
+ expect(findBadge().text()).toBe(text);
+ },
+ );
+
+ it('does not render an unknown status', () => {
+ createComponent({ props: { jobStatus: 'UNKNOWN_STATUS' } });
+
+ expect(wrapper.html()).toBe('');
+ });
+
+ it('adds arbitrary attributes', () => {
+ createComponent({ props: { jobStatus: JOB_STATUS_RUNNING }, attrs: { href: '/url' } });
+
+ expect(findBadge().attributes('href')).toBe('/url');
+ });
+});
diff --git a/spec/frontend/ci/runner/components/runner_list_spec.js b/spec/frontend/ci/runner/components/runner_list_spec.js
index d53a0ce8f4f..1267d045623 100644
--- a/spec/frontend/ci/runner/components/runner_list_spec.js
+++ b/spec/frontend/ci/runner/components/runner_list_spec.js
@@ -188,6 +188,21 @@ describe('RunnerList', () => {
expect(findCell({ fieldKey: 'summary' }).text()).toContain(`Summary: ${mockRunners[0].id}`);
});
+ it('Render #runner-job-status-badge slot in "summary" cell', () => {
+ createComponent(
+ {
+ scopedSlots: {
+ 'runner-job-status-badge': ({ runner }) => `Job status ${runner.jobExecutionStatus}`,
+ },
+ },
+ mountExtended,
+ );
+
+ expect(findCell({ fieldKey: 'summary' }).text()).toContain(
+ `Job status ${mockRunners[0].jobExecutionStatus}`,
+ );
+ });
+
it('Render #runner-actions-cell slot in "actions" cell', () => {
createComponent(
{
diff --git a/spec/frontend/ci/runner/components/runner_status_badge_spec.js b/spec/frontend/ci/runner/components/runner_status_badge_spec.js
index 7d3064c2aef..45b410df2d4 100644
--- a/spec/frontend/ci/runner/components/runner_status_badge_spec.js
+++ b/spec/frontend/ci/runner/components/runner_status_badge_spec.js
@@ -37,12 +37,12 @@ describe('RunnerTypeBadge', () => {
};
beforeEach(() => {
- jest.useFakeTimers('modern');
+ jest.useFakeTimers({ legacyFakeTimers: false });
jest.setSystemTime(new Date('2021-01-01T00:00:00Z'));
});
afterEach(() => {
- jest.useFakeTimers('legacy');
+ jest.useFakeTimers({ legacyFakeTimers: true });
wrapper.destroy();
});
diff --git a/spec/frontend/ci/runner/components/search_tokens/tag_token_spec.js b/spec/frontend/ci/runner/components/search_tokens/tag_token_spec.js
index d3c7ea50f9d..3dce5a509ca 100644
--- a/spec/frontend/ci/runner/components/search_tokens/tag_token_spec.js
+++ b/spec/frontend/ci/runner/components/search_tokens/tag_token_spec.js
@@ -7,7 +7,7 @@ import { createAlert } from '~/flash';
import axios from '~/lib/utils/axios_utils';
import TagToken, { TAG_SUGGESTIONS_PATH } from '~/ci/runner/components/search_tokens/tag_token.vue';
-import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
+import { OPERATORS_IS } from '~/vue_shared/components/filtered_search_bar/constants';
import { getRecentlyUsedSuggestions } from '~/vue_shared/components/filtered_search_bar/filtered_search_utils';
jest.mock('~/flash');
@@ -42,7 +42,7 @@ const mockTagTokenConfig = {
type: 'tag',
token: TagToken,
recentSuggestionsStorageKey: mockStorageKey,
- operators: OPERATOR_IS_ONLY,
+ operators: OPERATORS_IS,
};
describe('TagToken', () => {
diff --git a/spec/frontend/ci/runner/components/stat/runner_stats_spec.js b/spec/frontend/ci/runner/components/stat/runner_stats_spec.js
index daebf3df050..3d45674d106 100644
--- a/spec/frontend/ci/runner/components/stat/runner_stats_spec.js
+++ b/spec/frontend/ci/runner/components/stat/runner_stats_spec.js
@@ -16,6 +16,23 @@ describe('RunnerStats', () => {
const findSingleStats = () => wrapper.findAllComponents(RunnerSingleStat);
+ const RunnerCountStub = {
+ props: ['variables'],
+ render() {
+ // return a count for each status
+ const mockCounts = {
+ undefined: 6, // no status returns "all"
+ [STATUS_ONLINE]: 3,
+ [STATUS_OFFLINE]: 2,
+ [STATUS_STALE]: 1,
+ };
+
+ return this.$scopedSlots.default({
+ count: mockCounts[this.variables.status],
+ });
+ },
+ };
+
const createComponent = ({ props = {}, mountFn = shallowMount, ...options } = {}) => {
wrapper = mountFn(RunnerStats, {
propsData: {
@@ -23,6 +40,9 @@ describe('RunnerStats', () => {
variables: {},
...props,
},
+ stubs: {
+ RunnerCount: RunnerCountStub,
+ },
...options,
});
};
@@ -32,24 +52,8 @@ describe('RunnerStats', () => {
});
it('Displays all the stats', () => {
- const mockCounts = {
- [STATUS_ONLINE]: 3,
- [STATUS_OFFLINE]: 2,
- [STATUS_STALE]: 1,
- };
-
createComponent({
mountFn: mount,
- stubs: {
- RunnerCount: {
- props: ['variables'],
- render() {
- return this.$scopedSlots.default({
- count: mockCounts[this.variables.status],
- });
- },
- },
- },
});
const text = wrapper.text();
@@ -78,4 +82,21 @@ describe('RunnerStats', () => {
expect(stat.props('variables')).toMatchObject(mockVariables);
});
});
+
+ it('Does not display counts when total is 0', () => {
+ createComponent({
+ mountFn: mount,
+ stubs: {
+ RunnerCount: {
+ render() {
+ return this.$scopedSlots.default({
+ count: 0,
+ });
+ },
+ },
+ },
+ });
+
+ expect(wrapper.html()).toBe('');
+ });
});