Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
6d706d5dc0
commit
a7ad649614
|
@ -277,6 +277,7 @@ export default {
|
||||||
v-model="variable.key"
|
v-model="variable.key"
|
||||||
:token-list="$options.tokenList"
|
:token-list="$options.tokenList"
|
||||||
:label-text="__('Key')"
|
:label-text="__('Key')"
|
||||||
|
data-testid="pipeline-form-ci-variable-key"
|
||||||
data-qa-selector="ci_variable_key_field"
|
data-qa-selector="ci_variable_key_field"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -293,6 +294,7 @@ export default {
|
||||||
:state="variableValidationState"
|
:state="variableValidationState"
|
||||||
rows="3"
|
rows="3"
|
||||||
max-rows="6"
|
max-rows="6"
|
||||||
|
data-testid="pipeline-form-ci-variable-value"
|
||||||
data-qa-selector="ci_variable_value_field"
|
data-qa-selector="ci_variable_value_field"
|
||||||
class="gl-font-monospace!"
|
class="gl-font-monospace!"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -255,6 +255,7 @@ export default {
|
||||||
v-model="key"
|
v-model="key"
|
||||||
:token-list="$options.tokenList"
|
:token-list="$options.tokenList"
|
||||||
:label-text="__('Key')"
|
:label-text="__('Key')"
|
||||||
|
data-testid="pipeline-form-ci-variable-key"
|
||||||
data-qa-selector="ci_variable_key_field"
|
data-qa-selector="ci_variable_key_field"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -271,6 +272,7 @@ export default {
|
||||||
:state="variableValidationState"
|
:state="variableValidationState"
|
||||||
rows="3"
|
rows="3"
|
||||||
max-rows="6"
|
max-rows="6"
|
||||||
|
data-testid="pipeline-form-ci-variable-value"
|
||||||
data-qa-selector="ci_variable_value_field"
|
data-qa-selector="ci_variable_value_field"
|
||||||
class="gl-font-monospace!"
|
class="gl-font-monospace!"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -163,7 +163,6 @@ export default {
|
||||||
v-gl-modal="'configure-feature-flags'"
|
v-gl-modal="'configure-feature-flags'"
|
||||||
variant="confirm"
|
variant="confirm"
|
||||||
category="secondary"
|
category="secondary"
|
||||||
data-qa-selector="configure_feature_flags_button"
|
|
||||||
data-testid="ff-configure-button"
|
data-testid="ff-configure-button"
|
||||||
class="gl-mb-3"
|
class="gl-mb-3"
|
||||||
>
|
>
|
||||||
|
|
|
@ -142,9 +142,16 @@ export const dayInQuarter = (date, quarter) => {
|
||||||
|
|
||||||
export const millisecondsPerDay = 1000 * 60 * 60 * 24;
|
export const millisecondsPerDay = 1000 * 60 * 60 * 24;
|
||||||
|
|
||||||
export const getDayDifference = (a, b) => {
|
/**
|
||||||
const date1 = Date.UTC(a.getFullYear(), a.getMonth(), a.getDate());
|
* Calculates the number of days between 2 specified dates, excluding the current date
|
||||||
const date2 = Date.UTC(b.getFullYear(), b.getMonth(), b.getDate());
|
*
|
||||||
|
* @param {Date} startDate the earlier date that we will substract from the end date
|
||||||
|
* @param {Date} endDate the last date in the range
|
||||||
|
* @return {Number} number of days in between
|
||||||
|
*/
|
||||||
|
export const getDayDifference = (startDate, endDate) => {
|
||||||
|
const date1 = Date.UTC(startDate.getFullYear(), startDate.getMonth(), startDate.getDate());
|
||||||
|
const date2 = Date.UTC(endDate.getFullYear(), endDate.getMonth(), endDate.getDate());
|
||||||
|
|
||||||
return Math.floor((date2 - date1) / millisecondsPerDay);
|
return Math.floor((date2 - date1) / millisecondsPerDay);
|
||||||
};
|
};
|
||||||
|
|
|
@ -88,7 +88,8 @@ export default {
|
||||||
:action-primary="actionPrimary"
|
:action-primary="actionPrimary"
|
||||||
:title="actionText"
|
:title="actionText"
|
||||||
:visible="removeMemberModalVisible"
|
:visible="removeMemberModalVisible"
|
||||||
data-qa-selector="remove_member_modal_content"
|
data-qa-selector="remove_member_modal"
|
||||||
|
data-testid="remove-member-modal-content"
|
||||||
@primary="submitForm"
|
@primary="submitForm"
|
||||||
@hide="hideRemoveMemberModal"
|
@hide="hideRemoveMemberModal"
|
||||||
>
|
>
|
||||||
|
|
|
@ -391,7 +391,11 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div class="prometheus-graphs" data-qa-selector="prometheus_graphs">
|
<div
|
||||||
|
class="prometheus-graphs"
|
||||||
|
data-qa-selector="prometheus_graphs_content"
|
||||||
|
data-testid="prometheus-graphs"
|
||||||
|
>
|
||||||
<div>
|
<div>
|
||||||
<gl-alert
|
<gl-alert
|
||||||
v-if="!isDeprecationNoticeDismissed"
|
v-if="!isDeprecationNoticeDismissed"
|
||||||
|
|
|
@ -189,6 +189,7 @@ export default {
|
||||||
ref="monitorEnvironmentsDropdown"
|
ref="monitorEnvironmentsDropdown"
|
||||||
class="flex-grow-1"
|
class="flex-grow-1"
|
||||||
data-qa-selector="environments_dropdown"
|
data-qa-selector="environments_dropdown"
|
||||||
|
data-testid="environments-dropdown"
|
||||||
toggle-class="dropdown-menu-toggle"
|
toggle-class="dropdown-menu-toggle"
|
||||||
menu-class="monitor-environment-dropdown-menu"
|
menu-class="monitor-environment-dropdown-menu"
|
||||||
:text="environmentDropdownText"
|
:text="environmentDropdownText"
|
||||||
|
|
|
@ -59,6 +59,7 @@ export default {
|
||||||
<resolve-discussion-button
|
<resolve-discussion-button
|
||||||
v-if="discussion.resolvable"
|
v-if="discussion.resolvable"
|
||||||
data-qa-selector="resolve_discussion_button"
|
data-qa-selector="resolve_discussion_button"
|
||||||
|
data-testid="resolve-discussion-button"
|
||||||
:is-resolving="isResolving"
|
:is-resolving="isResolving"
|
||||||
:button-title="resolveButtonTitle"
|
:button-title="resolveButtonTitle"
|
||||||
@onClick="$emit('resolve')"
|
@onClick="$emit('resolve')"
|
||||||
|
|
|
@ -98,7 +98,7 @@ export default {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<div data-qa-selector="packages-table">
|
<div data-testid="packages-table">
|
||||||
<packages-list-row
|
<packages-list-row
|
||||||
v-for="packageEntity in list"
|
v-for="packageEntity in list"
|
||||||
:key="packageEntity.id"
|
:key="packageEntity.id"
|
||||||
|
|
|
@ -78,7 +78,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<list-item data-qa-selector="package_row" :disabled="disabledRow">
|
<list-item data-testid="package-row" :disabled="disabledRow">
|
||||||
<template #left-primary>
|
<template #left-primary>
|
||||||
<div class="gl-display-flex gl-align-items-center gl-mr-3 gl-min-w-0">
|
<div class="gl-display-flex gl-align-items-center gl-mr-3 gl-min-w-0">
|
||||||
<gl-link
|
<gl-link
|
||||||
|
|
|
@ -90,7 +90,7 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<list-item data-qa-selector="package_row">
|
<list-item data-testid="package-row">
|
||||||
<template #left-primary>
|
<template #left-primary>
|
||||||
<div class="gl-display-flex gl-align-items-center gl-mr-3 gl-min-w-0">
|
<div class="gl-display-flex gl-align-items-center gl-mr-3 gl-min-w-0">
|
||||||
<router-link
|
<router-link
|
||||||
|
|
|
@ -151,7 +151,7 @@ export default {
|
||||||
@primaryAction="showConfirmationModal"
|
@primaryAction="showConfirmationModal"
|
||||||
>{{ $options.i18n.errorMessageBodyAlert }}</gl-alert
|
>{{ $options.i18n.errorMessageBodyAlert }}</gl-alert
|
||||||
>
|
>
|
||||||
<div data-qa-selector="packages-table">
|
<div data-testid="packages-table">
|
||||||
<packages-list-row
|
<packages-list-row
|
||||||
v-for="packageEntity in list"
|
v-for="packageEntity in list"
|
||||||
:key="packageEntity.id"
|
:key="packageEntity.id"
|
||||||
|
|
|
@ -87,7 +87,7 @@ export default {
|
||||||
v-else-if="!loadingContentFailed && !isLoadingContent"
|
v-else-if="!loadingContentFailed && !isLoadingContent"
|
||||||
ref="content"
|
ref="content"
|
||||||
data-qa-selector="wiki_page_content"
|
data-qa-selector="wiki_page_content"
|
||||||
data-testid="wiki_page_content"
|
data-testid="wiki-page-content"
|
||||||
class="js-wiki-page-content md"
|
class="js-wiki-page-content md"
|
||||||
v-html="content /* eslint-disable-line vue/no-v-html */"
|
v-html="content /* eslint-disable-line vue/no-v-html */"
|
||||||
></div>
|
></div>
|
||||||
|
|
|
@ -244,7 +244,7 @@ export default {
|
||||||
/><span class="position-relative">{{ fullPath }}</span>
|
/><span class="position-relative">{{ fullPath }}</span>
|
||||||
</component>
|
</component>
|
||||||
<!-- eslint-disable @gitlab/vue-require-i18n-strings -->
|
<!-- eslint-disable @gitlab/vue-require-i18n-strings -->
|
||||||
<gl-badge v-if="lfsOid" variant="muted" size="sm" class="ml-1" data-qa-selector="label-lfs"
|
<gl-badge v-if="lfsOid" variant="muted" size="sm" class="ml-1" data-testid="label-lfs"
|
||||||
>LFS</gl-badge
|
>LFS</gl-badge
|
||||||
>
|
>
|
||||||
<!-- eslint-enable @gitlab/vue-require-i18n-strings -->
|
<!-- eslint-enable @gitlab/vue-require-i18n-strings -->
|
||||||
|
|
|
@ -32,17 +32,14 @@ export default {
|
||||||
<div>
|
<div>
|
||||||
<runner-status-badge
|
<runner-status-badge
|
||||||
:runner="runner"
|
:runner="runner"
|
||||||
size="sm"
|
|
||||||
class="gl-display-inline-block gl-max-w-full gl-text-truncate"
|
class="gl-display-inline-block gl-max-w-full gl-text-truncate"
|
||||||
/>
|
/>
|
||||||
<runner-upgrade-status-badge
|
<runner-upgrade-status-badge
|
||||||
:runner="runner"
|
:runner="runner"
|
||||||
size="sm"
|
|
||||||
class="gl-display-inline-block gl-max-w-full gl-text-truncate"
|
class="gl-display-inline-block gl-max-w-full gl-text-truncate"
|
||||||
/>
|
/>
|
||||||
<runner-paused-badge
|
<runner-paused-badge
|
||||||
v-if="paused"
|
v-if="paused"
|
||||||
size="sm"
|
|
||||||
class="gl-display-inline-block gl-max-w-full gl-text-truncate"
|
class="gl-display-inline-block gl-max-w-full gl-text-truncate"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -57,7 +57,7 @@ export default {
|
||||||
:title="$options.i18n.I18N_LOCKED_RUNNER_DESCRIPTION"
|
:title="$options.i18n.I18N_LOCKED_RUNNER_DESCRIPTION"
|
||||||
name="lock"
|
name="lock"
|
||||||
/>
|
/>
|
||||||
<runner-type-badge class="gl-ml-2" :type="runnerType" size="sm" />
|
<runner-type-badge class="gl-ml-2 gl-vertical-align-middle" :type="runnerType" size="sm" />
|
||||||
|
|
||||||
<tooltip-on-truncate class="gl-display-block gl-text-truncate" :title="description">
|
<tooltip-on-truncate class="gl-display-block gl-text-truncate" :title="description">
|
||||||
{{ description }}
|
{{ description }}
|
||||||
|
|
|
@ -38,11 +38,12 @@ export default {
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="gl-display-flex gl-align-items-center gl-py-5 gl-border-b-1 gl-border-b-solid gl-border-b-gray-100"
|
class="gl-display-flex gl-justify-content-space-between gl-align-items-center gl-gap-3 gl-flex-wrap gl-py-5 gl-border-b-1 gl-border-b-solid gl-border-b-gray-100"
|
||||||
>
|
>
|
||||||
<div>
|
<div class="gl-display-flex gl-align-items-flex-start gl-gap-3 gl-flex-wrap">
|
||||||
<runner-status-badge :runner="runner" />
|
<runner-status-badge :runner="runner" />
|
||||||
<runner-type-badge v-if="runner" :type="runner.runnerType" />
|
<runner-type-badge v-if="runner" :type="runner.runnerType" />
|
||||||
|
<span>
|
||||||
<template v-if="runner.createdAt">
|
<template v-if="runner.createdAt">
|
||||||
<gl-sprintf :message="__('%{runner} created %{timeago}')">
|
<gl-sprintf :message="__('%{runner} created %{timeago}')">
|
||||||
<template #runner>
|
<template #runner>
|
||||||
|
@ -62,7 +63,8 @@ export default {
|
||||||
<template v-else>
|
<template v-else>
|
||||||
<strong>{{ heading }}</strong>
|
<strong>{{ heading }}</strong>
|
||||||
</template>
|
</template>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="gl-ml-auto gl-flex-shrink-0"><slot name="actions"></slot></div>
|
<div class="gl-display-flex gl-gap-3 gl-flex-wrap"><slot name="actions"></slot></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -14,7 +14,7 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<span class="gl-font-weight-bold"
|
<span class="gl-font-weight-bold gl-vertical-align-middle"
|
||||||
>#{{ getIdFromGraphQLId(runner.id) }} ({{ runner.shortSha }})</span
|
>#{{ getIdFromGraphQLId(runner.id) }} ({{ runner.shortSha }})</span
|
||||||
>
|
>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
|
import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
|
||||||
import { I18N_PAUSED_DESCRIPTION } from '../constants';
|
import { I18N_PAUSED, I18N_PAUSED_DESCRIPTION } from '../constants';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
@ -9,11 +9,17 @@ export default {
|
||||||
directives: {
|
directives: {
|
||||||
GlTooltip: GlTooltipDirective,
|
GlTooltip: GlTooltipDirective,
|
||||||
},
|
},
|
||||||
|
I18N_PAUSED,
|
||||||
I18N_PAUSED_DESCRIPTION,
|
I18N_PAUSED_DESCRIPTION,
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<gl-badge v-gl-tooltip="$options.I18N_PAUSED_DESCRIPTION" variant="danger" v-bind="$attrs">
|
<gl-badge
|
||||||
{{ s__('Runners|paused') }}
|
v-gl-tooltip="$options.I18N_PAUSED_DESCRIPTION"
|
||||||
|
variant="warning"
|
||||||
|
icon="status-paused"
|
||||||
|
v-bind="$attrs"
|
||||||
|
>
|
||||||
|
{{ $options.I18N_PAUSED }}
|
||||||
</gl-badge>
|
</gl-badge>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,8 +1,12 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
|
import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
|
||||||
import { __, s__, sprintf } from '~/locale';
|
import { __, sprintf } from '~/locale';
|
||||||
import { getTimeago } from '~/lib/utils/datetime_utility';
|
import { getTimeago } from '~/lib/utils/datetime_utility';
|
||||||
import {
|
import {
|
||||||
|
I18N_STATUS_ONLINE,
|
||||||
|
I18N_STATUS_NEVER_CONTACTED,
|
||||||
|
I18N_STATUS_OFFLINE,
|
||||||
|
I18N_STATUS_STALE,
|
||||||
I18N_ONLINE_TIMEAGO_TOOLTIP,
|
I18N_ONLINE_TIMEAGO_TOOLTIP,
|
||||||
I18N_NEVER_CONTACTED_TOOLTIP,
|
I18N_NEVER_CONTACTED_TOOLTIP,
|
||||||
I18N_OFFLINE_TIMEAGO_TOOLTIP,
|
I18N_OFFLINE_TIMEAGO_TOOLTIP,
|
||||||
|
@ -39,26 +43,30 @@ export default {
|
||||||
switch (this.runner?.status) {
|
switch (this.runner?.status) {
|
||||||
case STATUS_ONLINE:
|
case STATUS_ONLINE:
|
||||||
return {
|
return {
|
||||||
|
icon: 'status-active',
|
||||||
variant: 'success',
|
variant: 'success',
|
||||||
label: s__('Runners|online'),
|
label: I18N_STATUS_ONLINE,
|
||||||
tooltip: this.timeAgoTooltip(I18N_ONLINE_TIMEAGO_TOOLTIP),
|
tooltip: this.timeAgoTooltip(I18N_ONLINE_TIMEAGO_TOOLTIP),
|
||||||
};
|
};
|
||||||
case STATUS_NEVER_CONTACTED:
|
case STATUS_NEVER_CONTACTED:
|
||||||
return {
|
return {
|
||||||
|
icon: 'time-out',
|
||||||
variant: 'muted',
|
variant: 'muted',
|
||||||
label: s__('Runners|never contacted'),
|
label: I18N_STATUS_NEVER_CONTACTED,
|
||||||
tooltip: I18N_NEVER_CONTACTED_TOOLTIP,
|
tooltip: I18N_NEVER_CONTACTED_TOOLTIP,
|
||||||
};
|
};
|
||||||
case STATUS_OFFLINE:
|
case STATUS_OFFLINE:
|
||||||
return {
|
return {
|
||||||
|
icon: 'time-out',
|
||||||
variant: 'muted',
|
variant: 'muted',
|
||||||
label: s__('Runners|offline'),
|
label: I18N_STATUS_OFFLINE,
|
||||||
tooltip: this.timeAgoTooltip(I18N_OFFLINE_TIMEAGO_TOOLTIP),
|
tooltip: this.timeAgoTooltip(I18N_OFFLINE_TIMEAGO_TOOLTIP),
|
||||||
};
|
};
|
||||||
case STATUS_STALE:
|
case STATUS_STALE:
|
||||||
return {
|
return {
|
||||||
|
icon: 'time-out',
|
||||||
variant: 'warning',
|
variant: 'warning',
|
||||||
label: s__('Runners|stale'),
|
label: I18N_STATUS_STALE,
|
||||||
// runner may have contacted (or not) and be stale: consider both cases.
|
// runner may have contacted (or not) and be stale: consider both cases.
|
||||||
tooltip: this.runner.contactedAt
|
tooltip: this.runner.contactedAt
|
||||||
? this.timeAgoTooltip(I18N_STALE_TIMEAGO_TOOLTIP)
|
? this.timeAgoTooltip(I18N_STALE_TIMEAGO_TOOLTIP)
|
||||||
|
@ -77,7 +85,13 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<gl-badge v-if="badge" v-gl-tooltip="badge.tooltip" :variant="badge.variant" v-bind="$attrs">
|
<gl-badge
|
||||||
|
v-if="badge"
|
||||||
|
v-gl-tooltip="badge.tooltip"
|
||||||
|
:variant="badge.variant"
|
||||||
|
:icon="badge.icon"
|
||||||
|
v-bind="$attrs"
|
||||||
|
>
|
||||||
{{ badge.label }}
|
{{ badge.label }}
|
||||||
</gl-badge>
|
</gl-badge>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,26 +1,31 @@
|
||||||
<script>
|
<script>
|
||||||
import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
|
import { GlBadge, GlTooltipDirective } from '@gitlab/ui';
|
||||||
import { s__ } from '~/locale';
|
|
||||||
import {
|
import {
|
||||||
INSTANCE_TYPE,
|
INSTANCE_TYPE,
|
||||||
GROUP_TYPE,
|
GROUP_TYPE,
|
||||||
PROJECT_TYPE,
|
PROJECT_TYPE,
|
||||||
|
I18N_INSTANCE_TYPE,
|
||||||
I18N_INSTANCE_RUNNER_DESCRIPTION,
|
I18N_INSTANCE_RUNNER_DESCRIPTION,
|
||||||
|
I18N_GROUP_TYPE,
|
||||||
I18N_GROUP_RUNNER_DESCRIPTION,
|
I18N_GROUP_RUNNER_DESCRIPTION,
|
||||||
|
I18N_PROJECT_TYPE,
|
||||||
I18N_PROJECT_RUNNER_DESCRIPTION,
|
I18N_PROJECT_RUNNER_DESCRIPTION,
|
||||||
} from '../constants';
|
} from '../constants';
|
||||||
|
|
||||||
const BADGE_DATA = {
|
const BADGE_DATA = {
|
||||||
[INSTANCE_TYPE]: {
|
[INSTANCE_TYPE]: {
|
||||||
text: s__('Runners|shared'),
|
icon: 'users',
|
||||||
|
text: I18N_INSTANCE_TYPE,
|
||||||
tooltip: I18N_INSTANCE_RUNNER_DESCRIPTION,
|
tooltip: I18N_INSTANCE_RUNNER_DESCRIPTION,
|
||||||
},
|
},
|
||||||
[GROUP_TYPE]: {
|
[GROUP_TYPE]: {
|
||||||
text: s__('Runners|group'),
|
icon: 'group',
|
||||||
|
text: I18N_GROUP_TYPE,
|
||||||
tooltip: I18N_GROUP_RUNNER_DESCRIPTION,
|
tooltip: I18N_GROUP_RUNNER_DESCRIPTION,
|
||||||
},
|
},
|
||||||
[PROJECT_TYPE]: {
|
[PROJECT_TYPE]: {
|
||||||
text: s__('Runners|specific'),
|
icon: 'project',
|
||||||
|
text: I18N_PROJECT_TYPE,
|
||||||
tooltip: I18N_PROJECT_RUNNER_DESCRIPTION,
|
tooltip: I18N_PROJECT_RUNNER_DESCRIPTION,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -50,7 +55,13 @@ export default {
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
<template>
|
<template>
|
||||||
<gl-badge v-if="badge" v-gl-tooltip="badge.tooltip" variant="info" v-bind="$attrs">
|
<gl-badge
|
||||||
|
v-if="badge"
|
||||||
|
v-gl-tooltip="badge.tooltip"
|
||||||
|
variant="muted"
|
||||||
|
:icon="badge.icon"
|
||||||
|
v-bind="$attrs"
|
||||||
|
>
|
||||||
{{ badge.text }}
|
{{ badge.text }}
|
||||||
</gl-badge>
|
</gl-badge>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { __, s__ } from '~/locale';
|
import { __ } from '~/locale';
|
||||||
import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
|
import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
|
||||||
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
|
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
|
||||||
import { PARAM_KEY_PAUSED } from '../../constants';
|
import { PARAM_KEY_PAUSED, I18N_PAUSED } from '../../constants';
|
||||||
|
|
||||||
const options = [
|
const options = [
|
||||||
{ value: 'true', title: __('Yes') },
|
{ value: 'true', title: __('Yes') },
|
||||||
|
@ -10,7 +10,7 @@ const options = [
|
||||||
|
|
||||||
export const pausedTokenConfig = {
|
export const pausedTokenConfig = {
|
||||||
icon: 'pause',
|
icon: 'pause',
|
||||||
title: s__('Runners|Paused'),
|
title: I18N_PAUSED,
|
||||||
type: PARAM_KEY_PAUSED,
|
type: PARAM_KEY_PAUSED,
|
||||||
token: BaseToken,
|
token: BaseToken,
|
||||||
unique: true,
|
unique: true,
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
import { __, s__ } from '~/locale';
|
import { __ } from '~/locale';
|
||||||
import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
|
import { OPERATOR_IS_ONLY } from '~/vue_shared/components/filtered_search_bar/constants';
|
||||||
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
|
import BaseToken from '~/vue_shared/components/filtered_search_bar/tokens/base_token.vue';
|
||||||
import {
|
import {
|
||||||
|
I18N_STATUS_ONLINE,
|
||||||
|
I18N_STATUS_NEVER_CONTACTED,
|
||||||
|
I18N_STATUS_OFFLINE,
|
||||||
|
I18N_STATUS_STALE,
|
||||||
STATUS_ONLINE,
|
STATUS_ONLINE,
|
||||||
STATUS_OFFLINE,
|
STATUS_OFFLINE,
|
||||||
STATUS_NEVER_CONTACTED,
|
STATUS_NEVER_CONTACTED,
|
||||||
|
@ -10,10 +14,10 @@ import {
|
||||||
} from '../../constants';
|
} from '../../constants';
|
||||||
|
|
||||||
const options = [
|
const options = [
|
||||||
{ value: STATUS_ONLINE, title: s__('Runners|Online') },
|
{ value: STATUS_ONLINE, title: I18N_STATUS_ONLINE },
|
||||||
{ value: STATUS_OFFLINE, title: s__('Runners|Offline') },
|
{ value: STATUS_OFFLINE, title: I18N_STATUS_OFFLINE },
|
||||||
{ value: STATUS_NEVER_CONTACTED, title: s__('Runners|Never contacted') },
|
{ value: STATUS_NEVER_CONTACTED, title: I18N_STATUS_NEVER_CONTACTED },
|
||||||
{ value: STATUS_STALE, title: s__('Runners|Stale') },
|
{ value: STATUS_STALE, title: I18N_STATUS_STALE },
|
||||||
];
|
];
|
||||||
|
|
||||||
export const statusTokenConfig = {
|
export const statusTokenConfig = {
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
<script>
|
<script>
|
||||||
import { s__ } from '~/locale';
|
|
||||||
import RunnerSingleStat from '~/runner/components/stat/runner_single_stat.vue';
|
import RunnerSingleStat from '~/runner/components/stat/runner_single_stat.vue';
|
||||||
import { STATUS_ONLINE, STATUS_OFFLINE, STATUS_STALE } from '../../constants';
|
import {
|
||||||
|
I18N_STATUS_ONLINE,
|
||||||
|
I18N_STATUS_OFFLINE,
|
||||||
|
I18N_STATUS_STALE,
|
||||||
|
STATUS_ONLINE,
|
||||||
|
STATUS_OFFLINE,
|
||||||
|
STATUS_STALE,
|
||||||
|
} from '../../constants';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {
|
components: {
|
||||||
|
@ -29,7 +35,7 @@ export default {
|
||||||
skip: this.statusCountSkip(STATUS_ONLINE),
|
skip: this.statusCountSkip(STATUS_ONLINE),
|
||||||
variables: { ...this.variables, status: STATUS_ONLINE },
|
variables: { ...this.variables, status: STATUS_ONLINE },
|
||||||
variant: 'success',
|
variant: 'success',
|
||||||
title: s__('Runners|Online'),
|
title: I18N_STATUS_ONLINE,
|
||||||
metaIcon: 'status-active',
|
metaIcon: 'status-active',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -39,7 +45,7 @@ export default {
|
||||||
skip: this.statusCountSkip(STATUS_OFFLINE),
|
skip: this.statusCountSkip(STATUS_OFFLINE),
|
||||||
variables: { ...this.variables, status: STATUS_OFFLINE },
|
variables: { ...this.variables, status: STATUS_OFFLINE },
|
||||||
variant: 'muted',
|
variant: 'muted',
|
||||||
title: s__('Runners|Offline'),
|
title: I18N_STATUS_OFFLINE,
|
||||||
metaIcon: 'status-waiting',
|
metaIcon: 'status-waiting',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -49,7 +55,7 @@ export default {
|
||||||
skip: this.statusCountSkip(STATUS_STALE),
|
skip: this.statusCountSkip(STATUS_STALE),
|
||||||
variables: { ...this.variables, status: STATUS_STALE },
|
variables: { ...this.variables, status: STATUS_STALE },
|
||||||
variant: 'warning',
|
variant: 'warning',
|
||||||
title: s__('Runners|Stale'),
|
title: I18N_STATUS_STALE,
|
||||||
metaIcon: 'time-out',
|
metaIcon: 'time-out',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -23,6 +23,12 @@ export const I18N_GROUP_RUNNER_DESCRIPTION = s__(
|
||||||
);
|
);
|
||||||
export const I18N_PROJECT_RUNNER_DESCRIPTION = s__('Runners|Associated with one or more projects');
|
export const I18N_PROJECT_RUNNER_DESCRIPTION = s__('Runners|Associated with one or more projects');
|
||||||
|
|
||||||
|
// Status
|
||||||
|
export const I18N_STATUS_ONLINE = s__('Runners|Online');
|
||||||
|
export const I18N_STATUS_NEVER_CONTACTED = s__('Runners|Never contacted');
|
||||||
|
export const I18N_STATUS_OFFLINE = s__('Runners|Offline');
|
||||||
|
export const I18N_STATUS_STALE = s__('Runners|Stale');
|
||||||
|
|
||||||
// Status help popover
|
// Status help popover
|
||||||
export const I18N_STATUS_POPOVER_TITLE = s__('Runners|Runner statuses');
|
export const I18N_STATUS_POPOVER_TITLE = s__('Runners|Runner statuses');
|
||||||
|
|
||||||
|
@ -62,6 +68,7 @@ export const I18N_STALE_NEVER_CONTACTED_TOOLTIP = s__(
|
||||||
export const I18N_EDIT = __('Edit');
|
export const I18N_EDIT = __('Edit');
|
||||||
|
|
||||||
export const I18N_PAUSE = __('Pause');
|
export const I18N_PAUSE = __('Pause');
|
||||||
|
export const I18N_PAUSED = s__('Runners|Paused');
|
||||||
export const I18N_PAUSE_TOOLTIP = s__('Runners|Pause from accepting jobs');
|
export const I18N_PAUSE_TOOLTIP = s__('Runners|Pause from accepting jobs');
|
||||||
export const I18N_PAUSED_DESCRIPTION = s__('Runners|Not accepting jobs');
|
export const I18N_PAUSED_DESCRIPTION = s__('Runners|Not accepting jobs');
|
||||||
|
|
||||||
|
@ -94,7 +101,7 @@ export const I18N_NO_JOBS_FOUND = s__('Runners|This runner has not run any jobs.
|
||||||
|
|
||||||
// Styles
|
// Styles
|
||||||
|
|
||||||
export const RUNNER_TAG_BADGE_VARIANT = 'neutral';
|
export const RUNNER_TAG_BADGE_VARIANT = 'info';
|
||||||
export const RUNNER_TAG_BG_CLASS = 'gl-bg-blue-100';
|
export const RUNNER_TAG_BG_CLASS = 'gl-bg-blue-100';
|
||||||
|
|
||||||
// Filtered search parameter names
|
// Filtered search parameter names
|
||||||
|
|
|
@ -16,7 +16,7 @@ export default {
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<copyable-field
|
<copyable-field
|
||||||
data-qa-selector="copy-forward-email"
|
data-testid="copy-forward-email"
|
||||||
:name="s__('RightSidebar|Issue email')"
|
:name="s__('RightSidebar|Issue email')"
|
||||||
:clipboard-tooltip-text="s__('RightSidebar|Copy email address')"
|
:clipboard-tooltip-text="s__('RightSidebar|Copy email address')"
|
||||||
:value="issueEmailAddress"
|
:value="issueEmailAddress"
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
.js-wiki-page-content.md.gl-pt-2{ data: { qa_selector: 'wiki_page_content', testid: 'wiki_page_content', tracking_context: wiki_page_tracking_context(@page).to_json } }
|
.js-wiki-page-content.md.gl-pt-2{ data: { qa_selector: 'wiki_page_content', testid: 'wiki-page-content', tracking_context: wiki_page_tracking_context(@page).to_json } }
|
||||||
= render_wiki_content(@page)
|
= render_wiki_content(@page)
|
||||||
|
|
|
@ -9,6 +9,6 @@
|
||||||
.gl-mt-5.gl-mb-3
|
.gl-mt-5.gl-mb-3
|
||||||
.gl-display-flex.gl-justify-content-space-between
|
.gl-display-flex.gl-justify-content-space-between
|
||||||
%h2.gl-mt-0.gl-mb-5{ data: { qa_selector: 'wiki_page_title', testid: 'wiki_page_title' } }= @page ? @page.human_title : _('Failed to retrieve page')
|
%h2.gl-mt-0.gl-mb-5{ data: { qa_selector: 'wiki_page_title', testid: 'wiki_page_title' } }= @page ? @page.human_title : _('Failed to retrieve page')
|
||||||
.js-wiki-page-content.md.gl-pt-2{ data: { qa_selector: 'wiki_page_content', testid: 'wiki_page_content' } }
|
.js-wiki-page-content.md.gl-pt-2{ data: { qa_selector: 'wiki_page_content', testid: 'wiki-page-content' } }
|
||||||
= _('The page could not be displayed because it timed out.')
|
= _('The page could not be displayed because it timed out.')
|
||||||
= html_escape(_('You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}')) % { linkStart: "<a href=\"#{git_access_url}\">".html_safe, linkEnd: '</a>'.html_safe, cloneIcon: sprite_icon('download', css_class: 'gl-mr-2').html_safe }
|
= html_escape(_('You can view the source or %{linkStart}%{cloneIcon} clone the repository%{linkEnd}')) % { linkStart: "<a href=\"#{git_access_url}\">".html_safe, linkEnd: '</a>'.html_safe, cloneIcon: sprite_icon('download', css_class: 'gl-mr-2').html_safe }
|
||||||
|
|
|
@ -27,6 +27,6 @@
|
||||||
- if can?(current_user, :create_wiki, @wiki.container) && @page.latest? && @valid_encoding
|
- if can?(current_user, :create_wiki, @wiki.container) && @page.latest? && @valid_encoding
|
||||||
= link_to sprite_icon('pencil', css_class: 'gl-icon'), wiki_page_path(@wiki, @page, action: :edit), title: 'Edit', role: "button", class: 'btn gl-button btn-icon btn-default js-wiki-edit', data: { qa_selector: 'edit_page_button', testid: 'wiki_edit_button' }
|
= link_to sprite_icon('pencil', css_class: 'gl-icon'), wiki_page_path(@wiki, @page, action: :edit), title: 'Edit', role: "button", class: 'btn gl-button btn-icon btn-default js-wiki-edit', data: { qa_selector: 'edit_page_button', testid: 'wiki_edit_button' }
|
||||||
|
|
||||||
.js-async-wiki-page-content.md.gl-pt-2{ data: { qa_selector: 'wiki_page_content', testid: 'wiki_page_content', tracking_context: wiki_page_tracking_context(@page).to_json, get_wiki_content_url: wiki_page_render_api_endpoint(@page) } }
|
.js-async-wiki-page-content.md.gl-pt-2{ data: { qa_selector: 'wiki_page_content', testid: 'wiki-page-content', tracking_context: wiki_page_tracking_context(@page).to_json, get_wiki_content_url: wiki_page_render_api_endpoint(@page) } }
|
||||||
|
|
||||||
= render 'shared/wikis/sidebar'
|
= render 'shared/wikis/sidebar'
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
name: cache_issue_sums
|
name: cache_issue_sums
|
||||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95048
|
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95048
|
||||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/365940
|
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/365940
|
||||||
milestone: '15.3'
|
milestone: '15.4'
|
||||||
type: development
|
type: development
|
||||||
group: group::product planning
|
group: group::product planning
|
||||||
default_enabled: false
|
default_enabled: false
|
||||||
|
|
|
@ -81,7 +81,6 @@ module Gitlab
|
||||||
# @param expires_in [ActiveSupport::Duration, Integer] an expiry time for the cache entry
|
# @param expires_in [ActiveSupport::Duration, Integer] an expiry time for the cache entry
|
||||||
# @return [Array<String>]
|
# @return [Array<String>]
|
||||||
def cached_collection(collection, presenter:, presenter_args:, context:, expires_in:)
|
def cached_collection(collection, presenter:, presenter_args:, context:, expires_in:)
|
||||||
total_count = collection.size
|
|
||||||
misses = 0
|
misses = 0
|
||||||
|
|
||||||
json = fetch_multi(presenter, collection, context: context, expires_in: expires_in) do |obj|
|
json = fetch_multi(presenter, collection, context: context, expires_in: expires_in) do |obj|
|
||||||
|
@ -92,7 +91,7 @@ module Gitlab
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
increment_cache_metric(render_type: :collection, total_count: total_count, miss_count: misses)
|
increment_cache_metric(render_type: :collection, total_count: collection.length, miss_count: misses)
|
||||||
|
|
||||||
json.values
|
json.values
|
||||||
end
|
end
|
||||||
|
|
|
@ -34251,15 +34251,6 @@ msgstr ""
|
||||||
msgid "Runners|group"
|
msgid "Runners|group"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Runners|never contacted"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Runners|offline"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Runners|online"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Runners|paused"
|
msgid "Runners|paused"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
@ -34269,15 +34260,6 @@ msgstr ""
|
||||||
msgid "Runners|specific"
|
msgid "Runners|specific"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
msgid "Runners|stale"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Runners|upgrade available"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Runners|upgrade recommended"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
msgid "Runner|Owner"
|
msgid "Runner|Owner"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ module QA
|
||||||
include Page::Component::MembersFilter
|
include Page::Component::MembersFilter
|
||||||
|
|
||||||
view 'app/assets/javascripts/members/components/modals/remove_member_modal.vue' do
|
view 'app/assets/javascripts/members/components/modals/remove_member_modal.vue' do
|
||||||
element :remove_member_modal_content
|
element :remove_member_modal
|
||||||
end
|
end
|
||||||
|
|
||||||
view 'app/assets/javascripts/pages/groups/group_members/index.js' do
|
view 'app/assets/javascripts/pages/groups/group_members/index.js' do
|
||||||
|
@ -45,7 +45,7 @@ module QA
|
||||||
click_element :delete_member_button
|
click_element :delete_member_button
|
||||||
end
|
end
|
||||||
|
|
||||||
within_element(:remove_member_modal_content) do
|
within_element(:remove_member_modal) do
|
||||||
click_button("Remove member")
|
click_button("Remove member")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -10,7 +10,7 @@ module QA
|
||||||
LOADING_MESSAGE = 'Waiting for performance data'
|
LOADING_MESSAGE = 'Waiting for performance data'
|
||||||
|
|
||||||
view 'app/assets/javascripts/monitoring/components/dashboard.vue' do
|
view 'app/assets/javascripts/monitoring/components/dashboard.vue' do
|
||||||
element :prometheus_graphs
|
element :prometheus_graphs_content
|
||||||
end
|
end
|
||||||
|
|
||||||
view 'app/assets/javascripts/monitoring/components/dashboard_header.vue' do
|
view 'app/assets/javascripts/monitoring/components/dashboard_header.vue' do
|
||||||
|
@ -54,7 +54,7 @@ module QA
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_metrics?
|
def has_metrics?
|
||||||
within_element :prometheus_graphs do
|
within_element :prometheus_graphs_content do
|
||||||
has_text?(EXPECTED_TITLE)
|
has_text?(EXPECTED_TITLE)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -102,7 +102,7 @@ module QA
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_custom_metric?(metric)
|
def has_custom_metric?(metric)
|
||||||
within_element :prometheus_graphs do
|
within_element :prometheus_graphs_content do
|
||||||
has_text?(metric)
|
has_text?(metric)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -114,7 +114,7 @@ module QA
|
||||||
end
|
end
|
||||||
|
|
||||||
def has_template_metric?(metric)
|
def has_template_metric?(metric)
|
||||||
within_element :prometheus_graphs do
|
within_element :prometheus_graphs_content do
|
||||||
has_text?(metric)
|
has_text?(metric)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -6,12 +6,10 @@ module QA
|
||||||
module Packages
|
module Packages
|
||||||
class Index < QA::Page::Base
|
class Index < QA::Page::Base
|
||||||
view 'app/assets/javascripts/packages_and_registries/package_registry/components/list/package_list_row.vue' do
|
view 'app/assets/javascripts/packages_and_registries/package_registry/components/list/package_list_row.vue' do
|
||||||
element :package_row
|
|
||||||
element :package_link
|
element :package_link
|
||||||
end
|
end
|
||||||
|
|
||||||
view 'app/assets/javascripts/packages_and_registries/infrastructure_registry/shared/package_list_row.vue' do
|
view 'app/assets/javascripts/packages_and_registries/infrastructure_registry/shared/package_list_row.vue' do
|
||||||
element :package_row
|
|
||||||
element :package_link
|
element :package_link
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -263,22 +263,6 @@ module QA
|
||||||
ENV['GITLAB_QA_PASSWORD_6']
|
ENV['GITLAB_QA_PASSWORD_6']
|
||||||
end
|
end
|
||||||
|
|
||||||
def gitlab_qa_1p_email
|
|
||||||
ENV['GITLAB_QA_1P_EMAIL']
|
|
||||||
end
|
|
||||||
|
|
||||||
def gitlab_qa_1p_password
|
|
||||||
ENV['GITLAB_QA_1P_PASSWORD']
|
|
||||||
end
|
|
||||||
|
|
||||||
def gitlab_qa_1p_secret
|
|
||||||
ENV['GITLAB_QA_1P_SECRET']
|
|
||||||
end
|
|
||||||
|
|
||||||
def gitlab_qa_1p_github_uuid
|
|
||||||
ENV['GITLAB_QA_1P_GITHUB_UUID']
|
|
||||||
end
|
|
||||||
|
|
||||||
def jira_admin_username
|
def jira_admin_username
|
||||||
ENV['JIRA_ADMIN_USERNAME']
|
ENV['JIRA_ADMIN_USERNAME']
|
||||||
end
|
end
|
||||||
|
|
|
@ -50,7 +50,7 @@ RSpec.describe "Admin Runners" do
|
||||||
|
|
||||||
it 'shows an instance badge' do
|
it 'shows an instance badge' do
|
||||||
within_runner_row(instance_runner.id) do
|
within_runner_row(instance_runner.id) do
|
||||||
expect(page).to have_selector '.badge', text: 'shared'
|
expect(page).to have_selector '.badge', text: 'Instance'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -66,9 +66,9 @@ RSpec.describe "Admin Runners" do
|
||||||
|
|
||||||
it 'has all necessary texts' do
|
it 'has all necessary texts' do
|
||||||
expect(page).to have_text "Register an instance runner"
|
expect(page).to have_text "Register an instance runner"
|
||||||
expect(page).to have_text "Online 1"
|
expect(page).to have_text "#{s_('Runners|Online')} 1"
|
||||||
expect(page).to have_text "Offline 2"
|
expect(page).to have_text "#{s_('Runners|Offline')} 2"
|
||||||
expect(page).to have_text "Stale 1"
|
expect(page).to have_text "#{s_('Runners|Stale')} 1"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ RSpec.describe "Admin Runners" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows paused runners' do
|
it 'shows paused runners' do
|
||||||
input_filtered_search_filter_is_only('Paused', 'Yes')
|
input_filtered_search_filter_is_only(s_('Runners|Paused'), 'Yes')
|
||||||
|
|
||||||
expect(page).to have_link('All 1')
|
expect(page).to have_link('All 1')
|
||||||
|
|
||||||
|
@ -154,7 +154,7 @@ RSpec.describe "Admin Runners" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows active runners' do
|
it 'shows active runners' do
|
||||||
input_filtered_search_filter_is_only('Paused', 'No')
|
input_filtered_search_filter_is_only(s_('Runners|Paused'), 'No')
|
||||||
|
|
||||||
expect(page).to have_link('All 1')
|
expect(page).to have_link('All 1')
|
||||||
|
|
||||||
|
@ -186,7 +186,7 @@ RSpec.describe "Admin Runners" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows correct runner when status matches' do
|
it 'shows correct runner when status matches' do
|
||||||
input_filtered_search_filter_is_only('Status', 'Online')
|
input_filtered_search_filter_is_only('Status', s_('Runners|Online'))
|
||||||
|
|
||||||
expect(page).to have_link('All 2')
|
expect(page).to have_link('All 2')
|
||||||
|
|
||||||
|
@ -197,7 +197,7 @@ RSpec.describe "Admin Runners" do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows correct runner when status is selected and search term is entered' do
|
it 'shows correct runner when status is selected and search term is entered' do
|
||||||
input_filtered_search_filter_is_only('Status', 'Online')
|
input_filtered_search_filter_is_only('Status', s_('Runners|Online'))
|
||||||
input_filtered_search_keys('runner-1')
|
input_filtered_search_keys('runner-1')
|
||||||
|
|
||||||
expect(page).to have_link('All 1')
|
expect(page).to have_link('All 1')
|
||||||
|
@ -220,7 +220,7 @@ RSpec.describe "Admin Runners" do
|
||||||
expect(page).to have_content 'runner-never-contacted'
|
expect(page).to have_content 'runner-never-contacted'
|
||||||
|
|
||||||
within_runner_row(never_contacted.id) do
|
within_runner_row(never_contacted.id) do
|
||||||
expect(page).to have_selector '.badge', text: 'never contacted'
|
expect(page).to have_selector '.badge', text: s_('Runners|Never contacted')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -308,7 +308,7 @@ RSpec.describe "Admin Runners" do
|
||||||
|
|
||||||
visit admin_runners_path
|
visit admin_runners_path
|
||||||
|
|
||||||
input_filtered_search_filter_is_only('Paused', 'No')
|
input_filtered_search_filter_is_only(s_('Runners|Paused'), 'No')
|
||||||
|
|
||||||
expect(page).to have_content 'runner-project'
|
expect(page).to have_content 'runner-project'
|
||||||
expect(page).to have_content 'runner-group'
|
expect(page).to have_content 'runner-group'
|
||||||
|
@ -535,6 +535,36 @@ RSpec.describe "Admin Runners" do
|
||||||
let(:runner_page_path) { admin_runner_path(project_runner) }
|
let(:runner_page_path) { admin_runner_path(project_runner) }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'breadcrumbs' do
|
||||||
|
it 'contains the current runner id and token' do
|
||||||
|
page.within '[data-testid="breadcrumb-links"]' do
|
||||||
|
expect(page).to have_link("##{project_runner.id} (#{project_runner.short_sha})")
|
||||||
|
expect(page.find('[data-testid="breadcrumb-current-link"]')).to have_content("Edit")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe 'runner header', :js do
|
||||||
|
it 'contains the runner status, type and id' do
|
||||||
|
expect(page).to have_content("#{s_('Runners|Never contacted')} Project Runner ##{project_runner.id} created")
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when a runner is updated', :js do
|
||||||
|
before do
|
||||||
|
click_on _('Save changes')
|
||||||
|
wait_for_requests
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'show success alert' do
|
||||||
|
expect(page.find('[data-testid="alert-success"]')).to have_content('saved')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'redirects to runner page' do
|
||||||
|
expect(current_url).to match(admin_runner_path(project_runner))
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe 'projects' do
|
describe 'projects' do
|
||||||
it 'contains project names' do
|
it 'contains project names' do
|
||||||
expect(page).to have_content(project1.full_name)
|
expect(page).to have_content(project1.full_name)
|
||||||
|
|
|
@ -3,14 +3,10 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe 'Commit > User view commits' do
|
RSpec.describe 'Commit > User view commits' do
|
||||||
let_it_be(:project) { create(:project, :public, :repository) }
|
let_it_be(:user) { create(:user) }
|
||||||
let_it_be(:user) { project.creator }
|
let_it_be(:group) { create(:group, :public) }
|
||||||
|
|
||||||
before do
|
shared_examples 'can view commits' do
|
||||||
visit project_commits_path(project)
|
|
||||||
end
|
|
||||||
|
|
||||||
describe 'Commits List' do
|
|
||||||
it 'displays the correct number of commits per day in the header' do
|
it 'displays the correct number of commits per day in the header' do
|
||||||
expect(first('.js-commit-header').find('.commits-count').text).to eq('1 commit')
|
expect(first('.js-commit-header').find('.commits-count').text).to eq('1 commit')
|
||||||
end
|
end
|
||||||
|
@ -19,4 +15,51 @@ RSpec.describe 'Commit > User view commits' do
|
||||||
expect(page).to have_selector('#commits-list > li:nth-child(2) > ul', count: 1)
|
expect(page).to have_selector('#commits-list > li:nth-child(2) > ul', count: 1)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'Commits List' do
|
||||||
|
context 'when project is public' do
|
||||||
|
let(:project) { create(:project, :public, :repository, group: group) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
visit project_commits_path(project)
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'can view commits'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when project is public with private repository' do
|
||||||
|
let(:project) { create(:project, :public, :repository, :repository_private, group: group) }
|
||||||
|
|
||||||
|
context 'and user is an inherited member from the group' do
|
||||||
|
context 'and user is a guest' do
|
||||||
|
before do
|
||||||
|
group.add_guest(user)
|
||||||
|
sign_in(user)
|
||||||
|
visit project_commits_path(project)
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'can view commits'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when project is private' do
|
||||||
|
let(:project) { create(:project, :private, :repository, group: group) }
|
||||||
|
|
||||||
|
context 'and user is an inherited member from the group' do
|
||||||
|
context 'and user is a guest' do
|
||||||
|
before do
|
||||||
|
group.add_guest(user)
|
||||||
|
sign_in(user)
|
||||||
|
visit project_commits_path(project)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'renders not found' do
|
||||||
|
expect(page).to have_title('Not Found')
|
||||||
|
expect(page).to have_content('Page Not Found')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -61,7 +61,7 @@ RSpec.describe "Group Runners" do
|
||||||
|
|
||||||
it 'shows a group badge' do
|
it 'shows a group badge' do
|
||||||
within_runner_row(group_runner.id) do
|
within_runner_row(group_runner.id) do
|
||||||
expect(page).to have_selector '.badge', text: 'group'
|
expect(page).to have_selector '.badge', text: s_('Runners|Group')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -101,9 +101,9 @@ RSpec.describe "Group Runners" do
|
||||||
let(:runner) { project_runner }
|
let(:runner) { project_runner }
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows a project (specific) badge' do
|
it 'shows a project badge' do
|
||||||
within_runner_row(project_runner.id) do
|
within_runner_row(project_runner.id) do
|
||||||
expect(page).to have_selector '.badge', text: 'specific'
|
expect(page).to have_selector '.badge', text: s_('Runners|Project')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -137,7 +137,7 @@ RSpec.describe "Group Runners" do
|
||||||
focus_filtered_search
|
focus_filtered_search
|
||||||
|
|
||||||
page.within(search_bar_selector) do
|
page.within(search_bar_selector) do
|
||||||
expect(page).to have_link('Paused')
|
expect(page).to have_link(s_('Runners|Paused'))
|
||||||
expect(page).to have_content('Status')
|
expect(page).to have_content('Status')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -39,7 +39,7 @@ RSpec.describe 'Resolving all open threads in a merge request from an issue', :j
|
||||||
|
|
||||||
context 'resolving the thread' do
|
context 'resolving the thread' do
|
||||||
before do
|
before do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
find('button[data-testid="resolve-discussion-button"]').click
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'hides the link for creating a new issue' do
|
it 'hides the link for creating a new issue' do
|
||||||
|
|
|
@ -35,7 +35,7 @@ RSpec.describe 'Resolve an open thread in a merge request by creating an issue',
|
||||||
|
|
||||||
context 'resolving the thread' do
|
context 'resolving the thread' do
|
||||||
before do
|
before do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
find('button[data-testid="resolve-discussion-button"]').click
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'hides the link for creating a new issue' do
|
it 'hides the link for creating a new issue' do
|
||||||
|
|
|
@ -302,7 +302,9 @@ RSpec.describe 'Issue Sidebar' do
|
||||||
|
|
||||||
context 'sidebar', :js do
|
context 'sidebar', :js do
|
||||||
it 'finds issue copy forwarding email' do
|
it 'finds issue copy forwarding email' do
|
||||||
expect(find('[data-qa-selector="copy-forward-email"]').text).to eq "Issue email: #{issue.creatable_note_email_address(user)}" # rubocop:disable QA/SelectorUsage
|
expect(
|
||||||
|
find('[data-testid="copy-forward-email"]').text
|
||||||
|
).to eq "Issue email: #{issue.creatable_note_email_address(user)}"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -338,7 +340,7 @@ RSpec.describe 'Issue Sidebar' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'does not find issue email' do
|
it 'does not find issue email' do
|
||||||
expect(page).not_to have_selector('[data-qa-selector="copy-forward-email"]') # rubocop:disable QA/SelectorUsage
|
expect(page).not_to have_selector('[data-testid="copy-forward-email"]')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -66,7 +66,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'allows user to mark thread as resolved' do
|
it 'allows user to mark thread as resolved' do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
find('button[data-testid="resolve-discussion-button"]').click
|
||||||
end
|
end
|
||||||
|
|
||||||
expect(page).to have_selector('.discussion-body', visible: false)
|
expect(page).to have_selector('.discussion-body', visible: false)
|
||||||
|
@ -82,7 +82,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'allows user to unresolve thread' do
|
it 'allows user to unresolve thread' do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
find('button[data-testid="resolve-discussion-button"]').click
|
||||||
click_button 'Unresolve thread'
|
click_button 'Unresolve thread'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
describe 'resolved thread' do
|
describe 'resolved thread' do
|
||||||
before do
|
before do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
find('button[data-testid="resolve-discussion-button"]').click
|
||||||
end
|
end
|
||||||
|
|
||||||
visit_merge_request
|
visit_merge_request
|
||||||
|
@ -194,7 +194,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'allows user to resolve from reply form without a comment' do
|
it 'allows user to resolve from reply form without a comment' do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
find('button[data-testid="resolve-discussion-button"]').click
|
||||||
end
|
end
|
||||||
|
|
||||||
page.within '.discussions-counter' do
|
page.within '.discussions-counter' do
|
||||||
|
@ -229,7 +229,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'hides jump to next button when all resolved' do
|
it 'hides jump to next button when all resolved' do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
find('button[data-testid="resolve-discussion-button"]').click
|
||||||
end
|
end
|
||||||
|
|
||||||
expect(page).to have_selector('.discussion-next-btn', visible: false)
|
expect(page).to have_selector('.discussion-next-btn', visible: false)
|
||||||
|
@ -324,7 +324,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
it 'allows user to mark all threads as resolved' do
|
it 'allows user to mark all threads as resolved' do
|
||||||
page.all('.discussion-reply-holder', count: 2).each do |reply_holder|
|
page.all('.discussion-reply-holder', count: 2).each do |reply_holder|
|
||||||
page.within reply_holder do
|
page.within reply_holder do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
find('button[data-testid="resolve-discussion-button"]').click
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -335,7 +335,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'allows user to quickly scroll to next unresolved thread' do
|
it 'allows user to quickly scroll to next unresolved thread' do
|
||||||
page.within('.discussion-reply-holder', match: :first) do
|
page.within('.discussion-reply-holder', match: :first) do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
find('button[data-testid="resolve-discussion-button"]').click
|
||||||
end
|
end
|
||||||
|
|
||||||
page.within '.discussions-counter' do
|
page.within '.discussions-counter' do
|
||||||
|
@ -406,7 +406,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'allows user to mark thread as resolved' do
|
it 'allows user to mark thread as resolved' do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
find('button[data-testid="resolve-discussion-button"]').click
|
||||||
end
|
end
|
||||||
|
|
||||||
page.within '.diff-content .note' do
|
page.within '.diff-content .note' do
|
||||||
|
@ -420,7 +420,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'allows user to unresolve thread' do
|
it 'allows user to unresolve thread' do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
find('button[data-testid="resolve-discussion-button"]').click
|
||||||
click_button 'Unresolve thread'
|
click_button 'Unresolve thread'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -447,7 +447,7 @@ RSpec.describe 'Merge request > User resolves diff notes and threads', :js do
|
||||||
|
|
||||||
it 'allows user to comment & unresolve thread' do
|
it 'allows user to comment & unresolve thread' do
|
||||||
page.within '.diff-content' do
|
page.within '.diff-content' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
find('button[data-testid="resolve-discussion-button"]').click
|
||||||
|
|
||||||
find_field('Reply…').click
|
find_field('Reply…').click
|
||||||
|
|
||||||
|
|
|
@ -30,9 +30,9 @@ RSpec.describe 'Environment > Metrics' do
|
||||||
click_link 'Monitoring'
|
click_link 'Monitoring'
|
||||||
|
|
||||||
expect(page).to have_current_path(project_metrics_dashboard_path(project, environment: environment.id))
|
expect(page).to have_current_path(project_metrics_dashboard_path(project, environment: environment.id))
|
||||||
expect(page).to have_css('[data-qa-selector="environments_dropdown"]') # rubocop:disable QA/SelectorUsage
|
expect(page).to have_css('[data-testid="environments-dropdown"]')
|
||||||
|
|
||||||
within('[data-qa-selector="environments_dropdown"]') do # rubocop:disable QA/SelectorUsage
|
within('[data-testid="environments-dropdown"]') do
|
||||||
# Click on the dropdown
|
# Click on the dropdown
|
||||||
click_on(environment.name)
|
click_on(environment.name)
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ RSpec.describe 'Environment > Metrics' do
|
||||||
visit_environment(environment)
|
visit_environment(environment)
|
||||||
click_link 'Monitoring'
|
click_link 'Monitoring'
|
||||||
|
|
||||||
expect(page).to have_css('[data-qa-selector="prometheus_graphs"]') # rubocop:disable QA/SelectorUsage
|
expect(page).to have_css('[data-testid="prometheus-graphs"]')
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'has environment selector'
|
it_behaves_like 'has environment selector'
|
||||||
|
|
|
@ -90,7 +90,7 @@ RSpec.describe 'User sees feature flag list', :js do
|
||||||
it 'shows the empty page' do
|
it 'shows the empty page' do
|
||||||
expect(page).to have_text 'Get started with feature flags'
|
expect(page).to have_text 'Get started with feature flags'
|
||||||
expect(page).to have_selector('.btn-confirm', text: 'New feature flag')
|
expect(page).to have_selector('.btn-confirm', text: 'New feature flag')
|
||||||
expect(page).to have_selector('[data-qa-selector="configure_feature_flags_button"]', text: 'Configure') # rubocop:disable QA/SelectorUsage
|
expect(page).to have_selector('[data-testid="ff-configure-button"]', text: 'Configure')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -26,7 +26,7 @@ RSpec.describe 'Projects tree', :js do
|
||||||
expect(page).to have_selector('.tree-item')
|
expect(page).to have_selector('.tree-item')
|
||||||
expect(page).to have_content('add tests for .gitattributes custom highlighting')
|
expect(page).to have_content('add tests for .gitattributes custom highlighting')
|
||||||
expect(page).not_to have_selector('[data-testid="alert-danger"]')
|
expect(page).not_to have_selector('[data-testid="alert-danger"]')
|
||||||
expect(page).not_to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS') # rubocop:disable QA/SelectorUsage
|
expect(page).not_to have_selector('[data-testid="label-lfs"]', text: 'LFS')
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'renders tree table for a subtree without errors' do
|
it 'renders tree table for a subtree without errors' do
|
||||||
|
@ -35,7 +35,7 @@ RSpec.describe 'Projects tree', :js do
|
||||||
|
|
||||||
expect(page).to have_selector('.tree-item')
|
expect(page).to have_selector('.tree-item')
|
||||||
expect(page).to have_content('add spaces in whitespace file')
|
expect(page).to have_content('add spaces in whitespace file')
|
||||||
expect(page).not_to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS') # rubocop:disable QA/SelectorUsage
|
expect(page).not_to have_selector('[data-testid="label-lfs"]', text: 'LFS')
|
||||||
expect(page).not_to have_selector('[data-testid="alert-danger"]')
|
expect(page).not_to have_selector('[data-testid="alert-danger"]')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -112,7 +112,7 @@ RSpec.describe 'Projects tree', :js do
|
||||||
it 'renders LFS badge on blob item' do
|
it 'renders LFS badge on blob item' do
|
||||||
visit project_tree_path(project, File.join('master', 'files/lfs'))
|
visit project_tree_path(project, File.join('master', 'files/lfs'))
|
||||||
|
|
||||||
expect(page).to have_selector('[data-qa-selector="label-lfs"]', text: 'LFS') # rubocop:disable QA/SelectorUsage
|
expect(page).to have_selector('[data-testid="label-lfs"]', text: 'LFS')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,8 @@
|
||||||
exports[`Dashboard template matches the default snapshot 1`] = `
|
exports[`Dashboard template matches the default snapshot 1`] = `
|
||||||
<div
|
<div
|
||||||
class="prometheus-graphs"
|
class="prometheus-graphs"
|
||||||
data-qa-selector="prometheus_graphs"
|
data-qa-selector="prometheus_graphs_content"
|
||||||
|
data-testid="prometheus-graphs"
|
||||||
environmentstate="available"
|
environmentstate="available"
|
||||||
metricsdashboardbasepath="/monitoring/monitor-project/-/metrics?environment=1"
|
metricsdashboardbasepath="/monitoring/monitor-project/-/metrics?environment=1"
|
||||||
metricsendpoint="/monitoring/monitor-project/-/environments/1/additional_metrics.json"
|
metricsendpoint="/monitoring/monitor-project/-/environments/1/additional_metrics.json"
|
||||||
|
@ -60,6 +61,7 @@ exports[`Dashboard template matches the default snapshot 1`] = `
|
||||||
clearalltext="Clear all"
|
clearalltext="Clear all"
|
||||||
clearalltextclass="gl-px-5"
|
clearalltextclass="gl-px-5"
|
||||||
data-qa-selector="environments_dropdown"
|
data-qa-selector="environments_dropdown"
|
||||||
|
data-testid="environments-dropdown"
|
||||||
headertext=""
|
headertext=""
|
||||||
hideheaderborder="true"
|
hideheaderborder="true"
|
||||||
highlighteditemstitle="Selected"
|
highlighteditemstitle="Selected"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
exports[`packages_list_row renders 1`] = `
|
exports[`packages_list_row renders 1`] = `
|
||||||
<div
|
<div
|
||||||
class="gl-display-flex gl-flex-direction-column gl-border-b-solid gl-border-t-solid gl-border-t-1 gl-border-b-1 gl-border-t-transparent gl-border-b-gray-100"
|
class="gl-display-flex gl-flex-direction-column gl-border-b-solid gl-border-t-solid gl-border-t-1 gl-border-b-1 gl-border-t-transparent gl-border-b-gray-100"
|
||||||
data-qa-selector="package_row"
|
data-testid="package-row"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="gl-display-flex gl-align-items-center gl-py-3"
|
class="gl-display-flex gl-align-items-center gl-py-3"
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
exports[`packages_list_row renders 1`] = `
|
exports[`packages_list_row renders 1`] = `
|
||||||
<div
|
<div
|
||||||
class="gl-display-flex gl-flex-direction-column gl-border-b-solid gl-border-t-solid gl-border-t-1 gl-border-b-1 gl-border-t-transparent gl-border-b-gray-100"
|
class="gl-display-flex gl-flex-direction-column gl-border-b-solid gl-border-t-solid gl-border-t-1 gl-border-b-1 gl-border-t-transparent gl-border-b-gray-100"
|
||||||
data-qa-selector="package_row"
|
data-testid="package-row"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="gl-display-flex gl-align-items-center gl-py-3"
|
class="gl-display-flex gl-align-items-center gl-py-3"
|
||||||
|
|
|
@ -38,7 +38,7 @@ describe('pages/shared/wikis/components/wiki_content', () => {
|
||||||
|
|
||||||
const findGlAlert = () => wrapper.findComponent(GlAlert);
|
const findGlAlert = () => wrapper.findComponent(GlAlert);
|
||||||
const findGlSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
|
const findGlSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader);
|
||||||
const findContent = () => wrapper.find('[data-testid="wiki_page_content"]');
|
const findContent = () => wrapper.find('[data-testid="wiki-page-content"]');
|
||||||
|
|
||||||
describe('when loading content', () => {
|
describe('when loading content', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
|
|
|
@ -33,6 +33,12 @@ import {
|
||||||
CREATED_ASC,
|
CREATED_ASC,
|
||||||
CREATED_DESC,
|
CREATED_DESC,
|
||||||
DEFAULT_SORT,
|
DEFAULT_SORT,
|
||||||
|
I18N_STATUS_ONLINE,
|
||||||
|
I18N_STATUS_OFFLINE,
|
||||||
|
I18N_STATUS_STALE,
|
||||||
|
I18N_INSTANCE_TYPE,
|
||||||
|
I18N_GROUP_TYPE,
|
||||||
|
I18N_PROJECT_TYPE,
|
||||||
INSTANCE_TYPE,
|
INSTANCE_TYPE,
|
||||||
PARAM_KEY_PAUSED,
|
PARAM_KEY_PAUSED,
|
||||||
PARAM_KEY_STATUS,
|
PARAM_KEY_STATUS,
|
||||||
|
@ -156,15 +162,16 @@ describe('AdminRunnersApp', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows the runner tabs', () => {
|
it('shows the runner tabs', () => {
|
||||||
expect(findRunnerTypeTabs().text()).toMatchInterpolatedText(
|
const tabs = findRunnerTypeTabs().text();
|
||||||
`All ${mockRunnersCount} Instance ${mockRunnersCount} Group ${mockRunnersCount} Project ${mockRunnersCount}`,
|
expect(tabs).toMatchInterpolatedText(
|
||||||
|
`All ${mockRunnersCount} ${I18N_INSTANCE_TYPE} ${mockRunnersCount} ${I18N_GROUP_TYPE} ${mockRunnersCount} ${I18N_PROJECT_TYPE} ${mockRunnersCount}`,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows the total', () => {
|
it('shows the total', () => {
|
||||||
expect(findRunnerStats().text()).toContain(`${s__('Runners|Online')} ${mockRunnersCount}`);
|
expect(findRunnerStats().text()).toContain(`${I18N_STATUS_ONLINE} ${mockRunnersCount}`);
|
||||||
expect(findRunnerStats().text()).toContain(`${s__('Runners|Offline')} ${mockRunnersCount}`);
|
expect(findRunnerStats().text()).toContain(`${I18N_STATUS_OFFLINE} ${mockRunnersCount}`);
|
||||||
expect(findRunnerStats().text()).toContain(`${s__('Runners|Stale')} ${mockRunnersCount}`);
|
expect(findRunnerStats().text()).toContain(`${I18N_STATUS_STALE} ${mockRunnersCount}`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import RunnerTags from '~/runner/components/runner_tags.vue';
|
||||||
import RunnerSummaryField from '~/runner/components/cells/runner_summary_field.vue';
|
import RunnerSummaryField from '~/runner/components/cells/runner_summary_field.vue';
|
||||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||||
|
|
||||||
import { INSTANCE_TYPE, PROJECT_TYPE } from '~/runner/constants';
|
import { INSTANCE_TYPE, I18N_INSTANCE_TYPE, PROJECT_TYPE } from '~/runner/constants';
|
||||||
|
|
||||||
import { allRunnersData } from '../../mock_data';
|
import { allRunnersData } from '../../mock_data';
|
||||||
|
|
||||||
|
@ -69,7 +69,7 @@ describe('RunnerTypeCell', () => {
|
||||||
locked: true,
|
locked: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(wrapper.text()).toContain('shared');
|
expect(wrapper.text()).toContain(I18N_INSTANCE_TYPE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Displays the runner version', () => {
|
it('Displays the runner version', () => {
|
||||||
|
|
|
@ -3,7 +3,14 @@ import RunnerStatusCell from '~/runner/components/cells/runner_status_cell.vue';
|
||||||
|
|
||||||
import RunnerStatusBadge from '~/runner/components/runner_status_badge.vue';
|
import RunnerStatusBadge from '~/runner/components/runner_status_badge.vue';
|
||||||
import RunnerPausedBadge from '~/runner/components/runner_paused_badge.vue';
|
import RunnerPausedBadge from '~/runner/components/runner_paused_badge.vue';
|
||||||
import { INSTANCE_TYPE, STATUS_ONLINE, STATUS_OFFLINE } from '~/runner/constants';
|
import {
|
||||||
|
I18N_PAUSED,
|
||||||
|
I18N_STATUS_ONLINE,
|
||||||
|
I18N_STATUS_OFFLINE,
|
||||||
|
INSTANCE_TYPE,
|
||||||
|
STATUS_ONLINE,
|
||||||
|
STATUS_OFFLINE,
|
||||||
|
} from '~/runner/constants';
|
||||||
|
|
||||||
describe('RunnerStatusCell', () => {
|
describe('RunnerStatusCell', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
|
@ -31,8 +38,8 @@ describe('RunnerStatusCell', () => {
|
||||||
it('Displays online status', () => {
|
it('Displays online status', () => {
|
||||||
createComponent();
|
createComponent();
|
||||||
|
|
||||||
expect(wrapper.text()).toMatchInterpolatedText('online');
|
expect(wrapper.text()).toContain(I18N_STATUS_ONLINE);
|
||||||
expect(findStatusBadge().text()).toBe('online');
|
expect(findStatusBadge().text()).toBe(I18N_STATUS_ONLINE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Displays offline status', () => {
|
it('Displays offline status', () => {
|
||||||
|
@ -42,8 +49,8 @@ describe('RunnerStatusCell', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(wrapper.text()).toMatchInterpolatedText('offline');
|
expect(wrapper.text()).toMatchInterpolatedText(I18N_STATUS_OFFLINE);
|
||||||
expect(findStatusBadge().text()).toBe('offline');
|
expect(findStatusBadge().text()).toBe(I18N_STATUS_OFFLINE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Displays paused status', () => {
|
it('Displays paused status', () => {
|
||||||
|
@ -54,8 +61,8 @@ describe('RunnerStatusCell', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(wrapper.text()).toMatchInterpolatedText('online paused');
|
expect(wrapper.text()).toMatchInterpolatedText(`${I18N_STATUS_ONLINE} ${I18N_PAUSED}`);
|
||||||
expect(findPausedBadge().text()).toBe('paused');
|
expect(findPausedBadge().text()).toBe(I18N_PAUSED);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Is empty when data is missing', () => {
|
it('Is empty when data is missing', () => {
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { __ } from '~/locale';
|
||||||
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
import { mountExtended } from 'helpers/vue_test_utils_helper';
|
||||||
import RunnerSummaryCell from '~/runner/components/cells/runner_summary_cell.vue';
|
import RunnerSummaryCell from '~/runner/components/cells/runner_summary_cell.vue';
|
||||||
import RunnerTags from '~/runner/components/runner_tags.vue';
|
import RunnerTags from '~/runner/components/runner_tags.vue';
|
||||||
import { INSTANCE_TYPE, PROJECT_TYPE } from '~/runner/constants';
|
import { INSTANCE_TYPE, I18N_INSTANCE_TYPE, PROJECT_TYPE } from '~/runner/constants';
|
||||||
|
|
||||||
const mockId = '1';
|
const mockId = '1';
|
||||||
const mockShortSha = '2P6oDVDm';
|
const mockShortSha = '2P6oDVDm';
|
||||||
|
@ -46,7 +46,7 @@ describe('RunnerTypeCell', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Displays the runner type', () => {
|
it('Displays the runner type', () => {
|
||||||
expect(wrapper.text()).toContain('shared');
|
expect(wrapper.text()).toContain(I18N_INSTANCE_TYPE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Does not display the locked icon', () => {
|
it('Does not display the locked icon', () => {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { GlSprintf } from '@gitlab/ui';
|
import { GlSprintf } from '@gitlab/ui';
|
||||||
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
import { mountExtended, shallowMountExtended } from 'helpers/vue_test_utils_helper';
|
||||||
import { GROUP_TYPE, STATUS_ONLINE } from '~/runner/constants';
|
import { I18N_STATUS_ONLINE, I18N_GROUP_TYPE, GROUP_TYPE, STATUS_ONLINE } from '~/runner/constants';
|
||||||
import { TYPE_CI_RUNNER } from '~/graphql_shared/constants';
|
import { TYPE_CI_RUNNER } from '~/graphql_shared/constants';
|
||||||
import { convertToGraphQLId } from '~/graphql_shared/utils';
|
import { convertToGraphQLId } from '~/graphql_shared/utils';
|
||||||
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
|
import TimeAgo from '~/vue_shared/components/time_ago_tooltip.vue';
|
||||||
|
@ -49,7 +49,7 @@ describe('RunnerHeader', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(findRunnerStatusBadge().text()).toContain('online');
|
expect(findRunnerStatusBadge().text()).toContain(I18N_STATUS_ONLINE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays the runner type', () => {
|
it('displays the runner type', () => {
|
||||||
|
@ -60,7 +60,7 @@ describe('RunnerHeader', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(findRunnerTypeBadge().text()).toContain('group');
|
expect(findRunnerTypeBadge().text()).toContain(I18N_GROUP_TYPE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays the runner id', () => {
|
it('displays the runner id', () => {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import {
|
||||||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||||
import RunnerList from '~/runner/components/runner_list.vue';
|
import RunnerList from '~/runner/components/runner_list.vue';
|
||||||
import RunnerStatusPopover from '~/runner/components/runner_status_popover.vue';
|
import RunnerStatusPopover from '~/runner/components/runner_status_popover.vue';
|
||||||
|
import { I18N_PROJECT_TYPE, I18N_STATUS_NEVER_CONTACTED } from '~/runner/constants';
|
||||||
import { allRunnersData, onlineContactTimeoutSecs, staleTimeoutSecs } from '../mock_data';
|
import { allRunnersData, onlineContactTimeoutSecs, staleTimeoutSecs } from '../mock_data';
|
||||||
|
|
||||||
const mockRunners = allRunnersData.data.runners.nodes;
|
const mockRunners = allRunnersData.data.runners.nodes;
|
||||||
|
@ -91,7 +92,7 @@ describe('RunnerList', () => {
|
||||||
createComponent({}, mountExtended);
|
createComponent({}, mountExtended);
|
||||||
|
|
||||||
// Badges
|
// Badges
|
||||||
expect(findCell({ fieldKey: 'status' }).text()).toMatchInterpolatedText('never contacted');
|
expect(findCell({ fieldKey: 'status' }).text()).toBe(I18N_STATUS_NEVER_CONTACTED);
|
||||||
|
|
||||||
// Runner summary
|
// Runner summary
|
||||||
expect(findCell({ fieldKey: 'summary' }).text()).toContain(
|
expect(findCell({ fieldKey: 'summary' }).text()).toContain(
|
||||||
|
@ -262,13 +263,15 @@ describe('RunnerList', () => {
|
||||||
const numericId = getIdFromGraphQLId(id);
|
const numericId = getIdFromGraphQLId(id);
|
||||||
|
|
||||||
// Badges
|
// Badges
|
||||||
expect(findCell({ fieldKey: 'status' }).text()).toMatchInterpolatedText('never contacted');
|
expect(findCell({ fieldKey: 'status' }).text()).toMatchInterpolatedText(
|
||||||
|
I18N_STATUS_NEVER_CONTACTED,
|
||||||
|
);
|
||||||
|
|
||||||
// Runner summary
|
// Runner summary
|
||||||
const summary = findCell({ fieldKey: 'summary' }).text();
|
const summary = findCell({ fieldKey: 'summary' }).text();
|
||||||
|
|
||||||
expect(summary).toContain(`#${numericId} (${shortSha})`);
|
expect(summary).toContain(`#${numericId} (${shortSha})`);
|
||||||
expect(summary).toContain('specific');
|
expect(summary).toContain(I18N_PROJECT_TYPE);
|
||||||
|
|
||||||
expect(summary).toContain(version);
|
expect(summary).toContain(version);
|
||||||
expect(summary).toContain(description);
|
expect(summary).toContain(description);
|
||||||
|
|
|
@ -2,6 +2,7 @@ import { GlBadge } from '@gitlab/ui';
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import RunnerStatePausedBadge from '~/runner/components/runner_paused_badge.vue';
|
import RunnerStatePausedBadge from '~/runner/components/runner_paused_badge.vue';
|
||||||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||||
|
import { I18N_PAUSED } from '~/runner/constants';
|
||||||
|
|
||||||
describe('RunnerTypeBadge', () => {
|
describe('RunnerTypeBadge', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
|
@ -29,8 +30,8 @@ describe('RunnerTypeBadge', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders paused state', () => {
|
it('renders paused state', () => {
|
||||||
expect(wrapper.text()).toBe('paused');
|
expect(wrapper.text()).toBe(I18N_PAUSED);
|
||||||
expect(findBadge().props('variant')).toBe('danger');
|
expect(findBadge().props('variant')).toBe('warning');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('renders tooltip', () => {
|
it('renders tooltip', () => {
|
||||||
|
|
|
@ -3,12 +3,16 @@ import { shallowMount } from '@vue/test-utils';
|
||||||
import RunnerStatusBadge from '~/runner/components/runner_status_badge.vue';
|
import RunnerStatusBadge from '~/runner/components/runner_status_badge.vue';
|
||||||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||||
import {
|
import {
|
||||||
|
I18N_STATUS_ONLINE,
|
||||||
|
I18N_STATUS_NEVER_CONTACTED,
|
||||||
|
I18N_STATUS_OFFLINE,
|
||||||
|
I18N_STATUS_STALE,
|
||||||
|
I18N_NEVER_CONTACTED_TOOLTIP,
|
||||||
|
I18N_STALE_NEVER_CONTACTED_TOOLTIP,
|
||||||
STATUS_ONLINE,
|
STATUS_ONLINE,
|
||||||
STATUS_OFFLINE,
|
STATUS_OFFLINE,
|
||||||
STATUS_STALE,
|
STATUS_STALE,
|
||||||
STATUS_NEVER_CONTACTED,
|
STATUS_NEVER_CONTACTED,
|
||||||
I18N_NEVER_CONTACTED_TOOLTIP,
|
|
||||||
I18N_STALE_NEVER_CONTACTED_TOOLTIP,
|
|
||||||
} from '~/runner/constants';
|
} from '~/runner/constants';
|
||||||
|
|
||||||
describe('RunnerTypeBadge', () => {
|
describe('RunnerTypeBadge', () => {
|
||||||
|
@ -46,7 +50,7 @@ describe('RunnerTypeBadge', () => {
|
||||||
it('renders online state', () => {
|
it('renders online state', () => {
|
||||||
createComponent();
|
createComponent();
|
||||||
|
|
||||||
expect(wrapper.text()).toBe('online');
|
expect(wrapper.text()).toBe(I18N_STATUS_ONLINE);
|
||||||
expect(findBadge().props('variant')).toBe('success');
|
expect(findBadge().props('variant')).toBe('success');
|
||||||
expect(getTooltip().value).toBe('Runner is online; last contact was 1 minute ago');
|
expect(getTooltip().value).toBe('Runner is online; last contact was 1 minute ago');
|
||||||
});
|
});
|
||||||
|
@ -59,7 +63,7 @@ describe('RunnerTypeBadge', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(wrapper.text()).toBe('never contacted');
|
expect(wrapper.text()).toBe(I18N_STATUS_NEVER_CONTACTED);
|
||||||
expect(findBadge().props('variant')).toBe('muted');
|
expect(findBadge().props('variant')).toBe('muted');
|
||||||
expect(getTooltip().value).toBe(I18N_NEVER_CONTACTED_TOOLTIP);
|
expect(getTooltip().value).toBe(I18N_NEVER_CONTACTED_TOOLTIP);
|
||||||
});
|
});
|
||||||
|
@ -72,7 +76,7 @@ describe('RunnerTypeBadge', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(wrapper.text()).toBe('offline');
|
expect(wrapper.text()).toBe(I18N_STATUS_OFFLINE);
|
||||||
expect(findBadge().props('variant')).toBe('muted');
|
expect(findBadge().props('variant')).toBe('muted');
|
||||||
expect(getTooltip().value).toBe('Runner is offline; last contact was 1 day ago');
|
expect(getTooltip().value).toBe('Runner is offline; last contact was 1 day ago');
|
||||||
});
|
});
|
||||||
|
@ -85,7 +89,7 @@ describe('RunnerTypeBadge', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(wrapper.text()).toBe('stale');
|
expect(wrapper.text()).toBe(I18N_STATUS_STALE);
|
||||||
expect(findBadge().props('variant')).toBe('warning');
|
expect(findBadge().props('variant')).toBe('warning');
|
||||||
expect(getTooltip().value).toBe('Runner is stale; last contact was 1 year ago');
|
expect(getTooltip().value).toBe('Runner is stale; last contact was 1 year ago');
|
||||||
});
|
});
|
||||||
|
@ -98,7 +102,7 @@ describe('RunnerTypeBadge', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(wrapper.text()).toBe('stale');
|
expect(wrapper.text()).toBe(I18N_STATUS_STALE);
|
||||||
expect(findBadge().props('variant')).toBe('warning');
|
expect(findBadge().props('variant')).toBe('warning');
|
||||||
expect(getTooltip().value).toBe(I18N_STALE_NEVER_CONTACTED_TOOLTIP);
|
expect(getTooltip().value).toBe(I18N_STALE_NEVER_CONTACTED_TOOLTIP);
|
||||||
});
|
});
|
||||||
|
@ -112,7 +116,7 @@ describe('RunnerTypeBadge', () => {
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(wrapper.text()).toBe('online');
|
expect(wrapper.text()).toBe(I18N_STATUS_ONLINE);
|
||||||
expect(getTooltip().value).toBe('Runner is online; last contact was never');
|
expect(getTooltip().value).toBe('Runner is online; last contact was never');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import { GlBadge } from '@gitlab/ui';
|
import { GlBadge } from '@gitlab/ui';
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import { nextTick } from 'vue';
|
import { nextTick } from 'vue';
|
||||||
|
|
||||||
|
import { RUNNER_TAG_BADGE_VARIANT } from '~/runner/constants';
|
||||||
import RunnerTag from '~/runner/components/runner_tag.vue';
|
import RunnerTag from '~/runner/components/runner_tag.vue';
|
||||||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||||
|
|
||||||
|
@ -48,7 +50,7 @@ describe('RunnerTag', () => {
|
||||||
it('Displays tags with correct style', () => {
|
it('Displays tags with correct style', () => {
|
||||||
expect(findBadge().props()).toMatchObject({
|
expect(findBadge().props()).toMatchObject({
|
||||||
size: 'sm',
|
size: 'sm',
|
||||||
variant: 'neutral',
|
variant: RUNNER_TAG_BADGE_VARIANT,
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,6 @@ describe('RunnerTags', () => {
|
||||||
|
|
||||||
it('Displays tags with correct style', () => {
|
it('Displays tags with correct style', () => {
|
||||||
expect(findBadge().props('size')).toBe('sm');
|
expect(findBadge().props('size')).toBe('sm');
|
||||||
expect(findBadge().props('variant')).toBe('neutral');
|
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Displays tags with md size', () => {
|
it('Displays tags with md size', () => {
|
||||||
|
|
|
@ -2,7 +2,14 @@ import { GlBadge } from '@gitlab/ui';
|
||||||
import { shallowMount } from '@vue/test-utils';
|
import { shallowMount } from '@vue/test-utils';
|
||||||
import RunnerTypeBadge from '~/runner/components/runner_type_badge.vue';
|
import RunnerTypeBadge from '~/runner/components/runner_type_badge.vue';
|
||||||
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
import { createMockDirective, getBinding } from 'helpers/vue_mock_directive';
|
||||||
import { INSTANCE_TYPE, GROUP_TYPE, PROJECT_TYPE } from '~/runner/constants';
|
import {
|
||||||
|
INSTANCE_TYPE,
|
||||||
|
GROUP_TYPE,
|
||||||
|
PROJECT_TYPE,
|
||||||
|
I18N_INSTANCE_TYPE,
|
||||||
|
I18N_GROUP_TYPE,
|
||||||
|
I18N_PROJECT_TYPE,
|
||||||
|
} from '~/runner/constants';
|
||||||
|
|
||||||
describe('RunnerTypeBadge', () => {
|
describe('RunnerTypeBadge', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
|
@ -27,9 +34,9 @@ describe('RunnerTypeBadge', () => {
|
||||||
|
|
||||||
describe.each`
|
describe.each`
|
||||||
type | text
|
type | text
|
||||||
${INSTANCE_TYPE} | ${'shared'}
|
${INSTANCE_TYPE} | ${I18N_INSTANCE_TYPE}
|
||||||
${GROUP_TYPE} | ${'group'}
|
${GROUP_TYPE} | ${I18N_GROUP_TYPE}
|
||||||
${PROJECT_TYPE} | ${'specific'}
|
${PROJECT_TYPE} | ${I18N_PROJECT_TYPE}
|
||||||
`('displays $type runner', ({ type, text }) => {
|
`('displays $type runner', ({ type, text }) => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
createComponent({ props: { type } });
|
createComponent({ props: { type } });
|
||||||
|
@ -37,7 +44,7 @@ describe('RunnerTypeBadge', () => {
|
||||||
|
|
||||||
it(`as "${text}" with an "info" variant`, () => {
|
it(`as "${text}" with an "info" variant`, () => {
|
||||||
expect(findBadge().text()).toBe(text);
|
expect(findBadge().text()).toBe(text);
|
||||||
expect(findBadge().props('variant')).toBe('info');
|
expect(findBadge().props('variant')).toBe('muted');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('with a tooltip', () => {
|
it('with a tooltip', () => {
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
import { shallowMount, mount } from '@vue/test-utils';
|
import { shallowMount, mount } from '@vue/test-utils';
|
||||||
import { s__ } from '~/locale';
|
|
||||||
import RunnerStats from '~/runner/components/stat/runner_stats.vue';
|
import RunnerStats from '~/runner/components/stat/runner_stats.vue';
|
||||||
import RunnerSingleStat from '~/runner/components/stat/runner_single_stat.vue';
|
import RunnerSingleStat from '~/runner/components/stat/runner_single_stat.vue';
|
||||||
import { INSTANCE_TYPE, STATUS_ONLINE, STATUS_OFFLINE, STATUS_STALE } from '~/runner/constants';
|
import {
|
||||||
|
I18N_STATUS_ONLINE,
|
||||||
|
I18N_STATUS_OFFLINE,
|
||||||
|
I18N_STATUS_STALE,
|
||||||
|
INSTANCE_TYPE,
|
||||||
|
STATUS_ONLINE,
|
||||||
|
STATUS_OFFLINE,
|
||||||
|
STATUS_STALE,
|
||||||
|
} from '~/runner/constants';
|
||||||
|
|
||||||
describe('RunnerStats', () => {
|
describe('RunnerStats', () => {
|
||||||
let wrapper;
|
let wrapper;
|
||||||
|
@ -46,9 +53,9 @@ describe('RunnerStats', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const text = wrapper.text();
|
const text = wrapper.text();
|
||||||
expect(text).toContain(`${s__('Runners|Online')} 3`);
|
expect(text).toContain(`${I18N_STATUS_ONLINE} 3`);
|
||||||
expect(text).toContain(`${s__('Runners|Offline')} 2`);
|
expect(text).toContain(`${I18N_STATUS_OFFLINE} 2`);
|
||||||
expect(text).toContain(`${s__('Runners|Stale')} 1`);
|
expect(text).toContain(`${I18N_STATUS_STALE} 1`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Skips query for other stats', () => {
|
it('Skips query for other stats', () => {
|
||||||
|
|
|
@ -28,6 +28,9 @@ import {
|
||||||
CREATED_ASC,
|
CREATED_ASC,
|
||||||
CREATED_DESC,
|
CREATED_DESC,
|
||||||
DEFAULT_SORT,
|
DEFAULT_SORT,
|
||||||
|
I18N_STATUS_ONLINE,
|
||||||
|
I18N_STATUS_OFFLINE,
|
||||||
|
I18N_STATUS_STALE,
|
||||||
INSTANCE_TYPE,
|
INSTANCE_TYPE,
|
||||||
GROUP_TYPE,
|
GROUP_TYPE,
|
||||||
PARAM_KEY_PAUSED,
|
PARAM_KEY_PAUSED,
|
||||||
|
@ -154,9 +157,9 @@ describe('GroupRunnersApp', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
const text = findRunnerStats().text();
|
const text = findRunnerStats().text();
|
||||||
expect(text).toContain(`${s__('Runners|Online')} ${mockGroupRunnersCount}`);
|
expect(text).toContain(`${I18N_STATUS_ONLINE} ${mockGroupRunnersCount}`);
|
||||||
expect(text).toContain(`${s__('Runners|Offline')} ${mockGroupRunnersCount}`);
|
expect(text).toContain(`${I18N_STATUS_OFFLINE} ${mockGroupRunnersCount}`);
|
||||||
expect(text).toContain(`${s__('Runners|Stale')} ${mockGroupRunnersCount}`);
|
expect(text).toContain(`${I18N_STATUS_STALE} ${mockGroupRunnersCount}`);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('shows the runners list', async () => {
|
it('shows the runners list', async () => {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import RunnerUpdateForm from '~/runner/components/runner_update_form.vue';
|
||||||
import runnerFormQuery from '~/runner/graphql/edit/runner_form.query.graphql';
|
import runnerFormQuery from '~/runner/graphql/edit/runner_form.query.graphql';
|
||||||
import RunnerEditApp from '~//runner/runner_edit/runner_edit_app.vue';
|
import RunnerEditApp from '~//runner/runner_edit/runner_edit_app.vue';
|
||||||
import { captureException } from '~/runner/sentry_utils';
|
import { captureException } from '~/runner/sentry_utils';
|
||||||
|
import { I18N_STATUS_NEVER_CONTACTED, I18N_INSTANCE_TYPE } from '~/runner/constants';
|
||||||
|
|
||||||
import { runnerFormData } from '../mock_data';
|
import { runnerFormData } from '../mock_data';
|
||||||
|
|
||||||
|
@ -69,8 +70,8 @@ describe('RunnerEditApp', () => {
|
||||||
it('displays the runner type and status', async () => {
|
it('displays the runner type and status', async () => {
|
||||||
await createComponentWithApollo({ mountFn: mount });
|
await createComponentWithApollo({ mountFn: mount });
|
||||||
|
|
||||||
expect(findRunnerHeader().text()).toContain(`never contacted`);
|
expect(findRunnerHeader().text()).toContain(I18N_STATUS_NEVER_CONTACTED);
|
||||||
expect(findRunnerHeader().text()).toContain(`shared`);
|
expect(findRunnerHeader().text()).toContain(I18N_INSTANCE_TYPE);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('displays a loading runner form', () => {
|
it('displays a loading runner form', () => {
|
||||||
|
|
|
@ -9,6 +9,7 @@ RSpec.describe Mutations::Commits::Create do
|
||||||
|
|
||||||
let_it_be(:user) { create(:user) }
|
let_it_be(:user) { create(:user) }
|
||||||
let_it_be(:project) { create(:project, :public, :repository) }
|
let_it_be(:project) { create(:project, :public, :repository) }
|
||||||
|
let_it_be(:group) { create(:group, :public) }
|
||||||
|
|
||||||
let(:context) do
|
let(:context) do
|
||||||
GraphQL::Query::Context.new(
|
GraphQL::Query::Context.new(
|
||||||
|
@ -39,11 +40,14 @@ RSpec.describe Mutations::Commits::Create do
|
||||||
|
|
||||||
let(:mutated_commit) { subject[:commit] }
|
let(:mutated_commit) { subject[:commit] }
|
||||||
|
|
||||||
it 'raises an error if the resource is not accessible to the user' do
|
context 'when user is not a project member' do
|
||||||
|
it 'raises an error' do
|
||||||
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
|
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when user does not have enough permissions' do
|
context 'when user is a direct project member' do
|
||||||
|
context 'and user is a guest' do
|
||||||
before do
|
before do
|
||||||
project.add_guest(user)
|
project.add_guest(user)
|
||||||
end
|
end
|
||||||
|
@ -53,17 +57,7 @@ RSpec.describe Mutations::Commits::Create do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when user is a maintainer of a different project' do
|
context 'and user is a developer' do
|
||||||
before do
|
|
||||||
create(:project_empty_repo).add_maintainer(user)
|
|
||||||
end
|
|
||||||
|
|
||||||
it 'raises an error' do
|
|
||||||
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
context 'when the user can create a commit' do
|
|
||||||
let(:deltas) { mutated_commit.raw_deltas }
|
let(:deltas) { mutated_commit.raw_deltas }
|
||||||
|
|
||||||
before_all do
|
before_all do
|
||||||
|
@ -152,7 +146,7 @@ RSpec.describe Mutations::Commits::Create do
|
||||||
|
|
||||||
it 'returns errors' do
|
it 'returns errors' do
|
||||||
expect(mutated_commit).to be_nil
|
expect(mutated_commit).to be_nil
|
||||||
expect(subject[:errors]).to eq(['You can only create or edit files when you are on a branch'])
|
expect(subject[:errors]).to match_array(['You can only create or edit files when you are on a branch'])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -194,7 +188,7 @@ RSpec.describe Mutations::Commits::Create do
|
||||||
|
|
||||||
it 'returns errors' do
|
it 'returns errors' do
|
||||||
expect(mutated_commit).to be_nil
|
expect(mutated_commit).to be_nil
|
||||||
expect(subject[:errors]).to eq(['Unknown action \'unknown\''])
|
expect(subject[:errors]).to match_array(['Unknown action \'unknown\''])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -205,12 +199,53 @@ RSpec.describe Mutations::Commits::Create do
|
||||||
|
|
||||||
it 'returns errors' do
|
it 'returns errors' do
|
||||||
expect(mutated_commit).to be_nil
|
expect(mutated_commit).to be_nil
|
||||||
expect(subject[:errors]).to eq(['You are not allowed to push into this branch'])
|
expect(subject[:errors]).to match_array(['You are not allowed to push into this branch'])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when user is an inherited member from the group' do
|
||||||
|
context 'when project is public with private repository' do
|
||||||
|
let(:project) { create(:project, :public, :repository, :repository_private, group: group) }
|
||||||
|
|
||||||
|
context 'and user is a guest' do
|
||||||
|
before do
|
||||||
|
group.add_guest(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'raises an error' do
|
||||||
|
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when project is private' do
|
||||||
|
let(:project) { create(:project, :private, :repository, group: group) }
|
||||||
|
|
||||||
|
context 'and user is a guest' do
|
||||||
|
before do
|
||||||
|
group.add_guest(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'raises an error' do
|
||||||
|
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is a maintainer of a different project' do
|
||||||
|
before do
|
||||||
|
create(:project_empty_repo).add_maintainer(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'raises an error' do
|
||||||
|
expect { subject }.to raise_error(Gitlab::Graphql::Errors::ResourceNotAvailable)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def expect_to_contain_deltas(expected_deltas)
|
def expect_to_contain_deltas(expected_deltas)
|
||||||
expect(deltas.count).to eq(expected_deltas.count)
|
expect(deltas.count).to eq(expected_deltas.count)
|
||||||
expect(deltas).to include(*expected_deltas)
|
expect(deltas).to include(*expected_deltas)
|
||||||
|
|
|
@ -10,11 +10,12 @@ RSpec.describe Gitlab::Metrics::Exporter::BaseExporter do
|
||||||
describe 'when exporter is enabled' do
|
describe 'when exporter is enabled' do
|
||||||
before do
|
before do
|
||||||
allow(::WEBrick::HTTPServer).to receive(:new).with(
|
allow(::WEBrick::HTTPServer).to receive(:new).with(
|
||||||
|
{
|
||||||
Port: anything,
|
Port: anything,
|
||||||
BindAddress: anything,
|
BindAddress: anything,
|
||||||
Logger: anything,
|
Logger: anything,
|
||||||
AccessLog: anything
|
AccessLog: anything
|
||||||
).and_call_original
|
}).and_call_original
|
||||||
|
|
||||||
allow(settings).to receive(:enabled).and_return(true)
|
allow(settings).to receive(:enabled).and_return(true)
|
||||||
allow(settings).to receive(:port).and_return(0)
|
allow(settings).to receive(:port).and_return(0)
|
||||||
|
@ -45,11 +46,12 @@ RSpec.describe Gitlab::Metrics::Exporter::BaseExporter do
|
||||||
|
|
||||||
it 'starts server with port and address from settings' do
|
it 'starts server with port and address from settings' do
|
||||||
expect(::WEBrick::HTTPServer).to receive(:new).with(
|
expect(::WEBrick::HTTPServer).to receive(:new).with(
|
||||||
|
{
|
||||||
Port: port,
|
Port: port,
|
||||||
BindAddress: address,
|
BindAddress: address,
|
||||||
Logger: anything,
|
Logger: anything,
|
||||||
AccessLog: anything
|
AccessLog: anything
|
||||||
).and_wrap_original do |m, *args|
|
}).and_wrap_original do |m, *args|
|
||||||
m.call(DoNotListen: true, Logger: args.first[:Logger])
|
m.call(DoNotListen: true, Logger: args.first[:Logger])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@ require 'spec_helper'
|
||||||
|
|
||||||
RSpec.describe CommitPolicy do
|
RSpec.describe CommitPolicy do
|
||||||
describe '#rules' do
|
describe '#rules' do
|
||||||
|
let(:group) { create(:group, :public) }
|
||||||
let(:user) { create(:user) }
|
let(:user) { create(:user) }
|
||||||
let(:commit) { project.repository.head_commit }
|
let(:commit) { project.repository.head_commit }
|
||||||
let(:policy) { described_class.new(user, commit) }
|
let(:policy) { described_class.new(user, commit) }
|
||||||
|
@ -19,26 +20,31 @@ RSpec.describe CommitPolicy do
|
||||||
end
|
end
|
||||||
|
|
||||||
shared_examples 'cannot read commit nor create a note' do
|
shared_examples 'cannot read commit nor create a note' do
|
||||||
it 'can not read commit' do
|
it 'cannot read commit' do
|
||||||
expect(policy).to be_disallowed(:read_commit)
|
expect(policy).to be_disallowed(:read_commit)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'can not create a note' do
|
it 'cannot create a note' do
|
||||||
expect(policy).to be_disallowed(:create_note)
|
expect(policy).to be_disallowed(:create_note)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when project is public' do
|
context 'when project is public' do
|
||||||
let(:project) { create(:project, :public, :repository) }
|
let(:project) { create(:project, :public, :repository, group: group) }
|
||||||
|
|
||||||
|
context 'when the user is not a project member' do
|
||||||
it_behaves_like 'can read commit and create a note'
|
it_behaves_like 'can read commit and create a note'
|
||||||
|
end
|
||||||
|
|
||||||
context 'when repository access level is private' do
|
context 'when repository access level is private' do
|
||||||
let(:project) { create(:project, :public, :repository, :repository_private) }
|
let(:project) { create(:project, :public, :repository, :repository_private, group: group) }
|
||||||
|
|
||||||
|
context 'when the user is not a project member' do
|
||||||
it_behaves_like 'cannot read commit nor create a note'
|
it_behaves_like 'cannot read commit nor create a note'
|
||||||
|
end
|
||||||
|
|
||||||
context 'when the user is a project member' do
|
context 'when the user is a direct project member' do
|
||||||
|
context 'and the user is a developer' do
|
||||||
before do
|
before do
|
||||||
project.add_developer(user)
|
project.add_developer(user)
|
||||||
end
|
end
|
||||||
|
@ -46,24 +52,52 @@ RSpec.describe CommitPolicy do
|
||||||
it_behaves_like 'can read commit and create a note'
|
it_behaves_like 'can read commit and create a note'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when the user is an inherited member from the group' do
|
||||||
|
context 'and the user is a guest' do
|
||||||
|
before do
|
||||||
|
group.add_guest(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'can read commit and create a note'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the user is a reporter' do
|
||||||
|
before do
|
||||||
|
group.add_reporter(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'can read commit and create a note'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the user is a developer' do
|
||||||
|
before do
|
||||||
|
group.add_developer(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'can read commit and create a note'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when project is private' do
|
context 'when project is private' do
|
||||||
let(:project) { create(:project, :private, :repository) }
|
let(:project) { create(:project, :private, :repository, group: group) }
|
||||||
|
|
||||||
|
context 'when the user is not a project member' do
|
||||||
it_behaves_like 'cannot read commit nor create a note'
|
it_behaves_like 'cannot read commit nor create a note'
|
||||||
|
end
|
||||||
|
|
||||||
context 'when the user is a project member' do
|
context 'when the user is a direct project member' do
|
||||||
|
context 'and the user is a developer' do
|
||||||
before do
|
before do
|
||||||
project.add_developer(user)
|
project.add_developer(user)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'can read commit and create a note' do
|
it_behaves_like 'can read commit and create a note'
|
||||||
expect(policy).to be_allowed(:read_commit)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when the user is a guest' do
|
context 'and the user is a guest' do
|
||||||
before do
|
before do
|
||||||
project.add_guest(user)
|
project.add_guest(user)
|
||||||
end
|
end
|
||||||
|
@ -75,5 +109,32 @@ RSpec.describe CommitPolicy do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when the user is an inherited member from the group' do
|
||||||
|
context 'and the user is a guest' do
|
||||||
|
before do
|
||||||
|
group.add_guest(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'cannot read commit nor create a note'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the user is a reporter' do
|
||||||
|
before do
|
||||||
|
group.add_reporter(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'can read commit and create a note'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'and the user is a developer' do
|
||||||
|
before do
|
||||||
|
group.add_developer(user)
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like 'can read commit and create a note'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -15,6 +15,8 @@ RSpec.describe API::Commits do
|
||||||
let(:branch_with_slash) { project.repository.find_branch('improve/awesome') }
|
let(:branch_with_slash) { project.repository.find_branch('improve/awesome') }
|
||||||
let(:project_id) { project.id }
|
let(:project_id) { project.id }
|
||||||
let(:current_user) { nil }
|
let(:current_user) { nil }
|
||||||
|
let(:group) { create(:group, :public) }
|
||||||
|
let(:inherited_guest) { create(:user).tap { |u| group.add_guest(u) } }
|
||||||
|
|
||||||
before do
|
before do
|
||||||
project.add_maintainer(user)
|
project.add_maintainer(user)
|
||||||
|
@ -56,7 +58,9 @@ RSpec.describe API::Commits do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'when authenticated', 'as a maintainer' do
|
context 'when authenticated' do
|
||||||
|
context 'when user is a direct project member' do
|
||||||
|
context 'and user is a maintainer' do
|
||||||
let(:current_user) { user }
|
let(:current_user) { user }
|
||||||
|
|
||||||
it_behaves_like 'project commits'
|
it_behaves_like 'project commits'
|
||||||
|
@ -366,6 +370,33 @@ RSpec.describe API::Commits do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when user is an inherited member from the group' do
|
||||||
|
context 'when project is public with private repository' do
|
||||||
|
let(:project) { create(:project, :public, :repository, :repository_private, group: group) }
|
||||||
|
|
||||||
|
context 'and user is a guest' do
|
||||||
|
let(:current_user) { inherited_guest }
|
||||||
|
|
||||||
|
it_behaves_like 'project commits'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when project is private' do
|
||||||
|
let(:project) { create(:project, :private, :repository, group: group) }
|
||||||
|
|
||||||
|
context 'and user is a guest' do
|
||||||
|
let(:current_user) { inherited_guest }
|
||||||
|
|
||||||
|
it_behaves_like '404 response' do
|
||||||
|
let(:request) { get api(route) }
|
||||||
|
let(:message) { '404 Project Not Found' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "POST /projects/:id/repository/commits" do
|
describe "POST /projects/:id/repository/commits" do
|
||||||
let!(:url) { "/projects/#{project_id}/repository/commits" }
|
let!(:url) { "/projects/#{project_id}/repository/commits" }
|
||||||
|
|
||||||
|
@ -466,11 +497,37 @@ RSpec.describe API::Commits do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'a new file in project repo' do
|
context 'a new file in project repo' do
|
||||||
|
context 'when user is a direct project member' do
|
||||||
before do
|
before do
|
||||||
post api(url, user), params: valid_c_params
|
post api(url, user), params: valid_c_params
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like "successfully creates the commit"
|
it_behaves_like 'successfully creates the commit'
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when user is an inherited member from the group' do
|
||||||
|
context 'when project is public with private repository' do
|
||||||
|
let(:project) { create(:project, :public, :repository, :repository_private, group: group) }
|
||||||
|
|
||||||
|
context 'and user is a guest' do
|
||||||
|
it_behaves_like '403 response' do
|
||||||
|
let(:request) { post api(url, inherited_guest), params: valid_c_params }
|
||||||
|
let(:message) { '403 Forbidden' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'when project is private' do
|
||||||
|
let(:project) { create(:project, :private, :repository, group: group) }
|
||||||
|
|
||||||
|
context 'and user is a guest' do
|
||||||
|
it_behaves_like '403 response' do
|
||||||
|
let(:request) { post api(url, inherited_guest), params: valid_c_params }
|
||||||
|
let(:message) { '403 Forbidden' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'a new file with utf8 chars in project repo' do
|
context 'a new file with utf8 chars in project repo' do
|
||||||
|
|
|
@ -304,7 +304,7 @@ RSpec.shared_examples 'thread comments for issue, epic and merge request' do |re
|
||||||
let(:reply_id) { find("#{comments_selector} .note:last-of-type", match: :first)['data-note-id'] }
|
let(:reply_id) { find("#{comments_selector} .note:last-of-type", match: :first)['data-note-id'] }
|
||||||
|
|
||||||
it 'can be replied to after resolving' do
|
it 'can be replied to after resolving' do
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
find('button[data-testid="resolve-discussion-button"]').click
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
refresh
|
refresh
|
||||||
|
@ -316,7 +316,7 @@ RSpec.shared_examples 'thread comments for issue, epic and merge request' do |re
|
||||||
it 'shows resolved thread when toggled' do
|
it 'shows resolved thread when toggled' do
|
||||||
submit_reply('a')
|
submit_reply('a')
|
||||||
|
|
||||||
find('button[data-qa-selector="resolve_discussion_button"]').click # rubocop:disable QA/SelectorUsage
|
find('button[data-testid="resolve-discussion-button"]').click
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
expect(page).to have_selector(".note-row-#{note_id}", visible: true)
|
expect(page).to have_selector(".note-row-#{note_id}", visible: true)
|
||||||
|
|
|
@ -14,7 +14,7 @@ RSpec.shared_examples 'packages list' do |check_project_name: false|
|
||||||
end
|
end
|
||||||
|
|
||||||
def package_table_row(index)
|
def package_table_row(index)
|
||||||
page.all("#{packages_table_selector} > [data-qa-selector=\"package_row\"]")[index].text # rubocop:disable QA/SelectorUsage
|
page.all("#{packages_table_selector} > [data-testid=\"package-row\"]")[index].text
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ RSpec.shared_examples 'shared package sorting' do
|
||||||
end
|
end
|
||||||
|
|
||||||
def packages_table_selector
|
def packages_table_selector
|
||||||
'[data-qa-selector="packages-table"]' # rubocop:disable QA/SelectorUsage
|
'[data-testid="packages-table"]'
|
||||||
end
|
end
|
||||||
|
|
||||||
def click_sort_option(option, ascending)
|
def click_sort_option(option, ascending)
|
||||||
|
|
|
@ -64,9 +64,9 @@ end
|
||||||
|
|
||||||
RSpec.shared_examples 'shows no runners registered' do
|
RSpec.shared_examples 'shows no runners registered' do
|
||||||
it 'shows counts with 0' do
|
it 'shows counts with 0' do
|
||||||
expect(page).to have_text "Online 0"
|
expect(page).to have_text "#{s_('Runners|Online')} 0"
|
||||||
expect(page).to have_text "Offline 0"
|
expect(page).to have_text "#{s_('Runners|Offline')} 0"
|
||||||
expect(page).to have_text "Stale 0"
|
expect(page).to have_text "#{s_('Runners|Stale')} 0"
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'shows "no runners" message' do
|
it 'shows "no runners" message' do
|
||||||
|
@ -101,7 +101,7 @@ RSpec.shared_examples 'pauses, resumes and deletes a runner' do
|
||||||
within_runner_row(runner.id) do
|
within_runner_row(runner.id) do
|
||||||
click_button "Pause"
|
click_button "Pause"
|
||||||
|
|
||||||
expect(page).to have_text 'paused'
|
expect(page).to have_text s_('Runners|Paused')
|
||||||
expect(page).to have_button 'Resume'
|
expect(page).to have_button 'Resume'
|
||||||
expect(page).not_to have_button 'Pause'
|
expect(page).not_to have_button 'Pause'
|
||||||
|
|
||||||
|
|
|
@ -91,7 +91,7 @@ RSpec.shared_examples 'variable list' do |is_admin|
|
||||||
end
|
end
|
||||||
|
|
||||||
page.within('#add-ci-variable') do
|
page.within('#add-ci-variable') do
|
||||||
find('[data-qa-selector="ci_variable_key_field"] input').set('new_key') # rubocop:disable QA/SelectorUsage
|
find('[data-testid="pipeline-form-ci-variable-key"] input').set('new_key')
|
||||||
|
|
||||||
click_button('Update variable')
|
click_button('Update variable')
|
||||||
end
|
end
|
||||||
|
@ -173,7 +173,7 @@ RSpec.shared_examples 'variable list' do |is_admin|
|
||||||
click_button('Add variable')
|
click_button('Add variable')
|
||||||
|
|
||||||
page.within('#add-ci-variable') do
|
page.within('#add-ci-variable') do
|
||||||
find('[data-qa-selector="ci_variable_key_field"] input').set('empty_mask_key') # rubocop:disable QA/SelectorUsage
|
find('[data-testid="pipeline-form-ci-variable-key"] input').set('empty_mask_key')
|
||||||
find('[data-testid="ci-variable-protected-checkbox"]').click
|
find('[data-testid="ci-variable-protected-checkbox"]').click
|
||||||
find('[data-testid="ci-variable-masked-checkbox"]').click
|
find('[data-testid="ci-variable-masked-checkbox"]').click
|
||||||
|
|
||||||
|
@ -290,8 +290,8 @@ RSpec.shared_examples 'variable list' do |is_admin|
|
||||||
wait_for_requests
|
wait_for_requests
|
||||||
|
|
||||||
page.within('#add-ci-variable') do
|
page.within('#add-ci-variable') do
|
||||||
find('[data-qa-selector="ci_variable_key_field"] input').set(key) # rubocop:disable QA/SelectorUsage
|
find('[data-testid="pipeline-form-ci-variable-key"] input').set(key)
|
||||||
find('[data-qa-selector="ci_variable_value_field"]').set(value) if value.present? # rubocop:disable QA/SelectorUsage
|
find('[data-testid="pipeline-form-ci-variable-value"]').set(value) if value.present?
|
||||||
find('[data-testid="ci-variable-protected-checkbox"]').click if protected
|
find('[data-testid="ci-variable-protected-checkbox"]').click if protected
|
||||||
find('[data-testid="ci-variable-masked-checkbox"]').click if masked
|
find('[data-testid="ci-variable-masked-checkbox"]').click if masked
|
||||||
|
|
||||||
|
|
|
@ -64,7 +64,7 @@ RSpec.shared_examples 'User previews wiki changes' do
|
||||||
end
|
end
|
||||||
|
|
||||||
it_behaves_like 'relative links' do
|
it_behaves_like 'relative links' do
|
||||||
let(:element) { page.find('[data-testid="wiki_page_content"]') }
|
let(:element) { page.find('[data-testid="wiki-page-content"]') }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
RSpec.shared_examples 'User views AsciiDoc page with includes' do
|
RSpec.shared_examples 'User views AsciiDoc page with includes' do
|
||||||
let_it_be(:wiki_content_selector) { '[data-qa-selector=wiki_page_content]' } # rubocop:disable QA/SelectorUsage
|
let_it_be(:wiki_content_selector) { '[data-testid=wiki-page-content]' }
|
||||||
let!(:included_wiki_page) { create_wiki_page('included_page', content: 'Content from the included page') }
|
let!(:included_wiki_page) { create_wiki_page('included_page', content: 'Content from the included page') }
|
||||||
let!(:wiki_page) { create_wiki_page('home', content: "Content from the main page.\ninclude::included_page.asciidoc[]") }
|
let!(:wiki_page) { create_wiki_page('home', content: "Content from the main page.\ninclude::included_page.asciidoc[]") }
|
||||||
|
|
||||||
|
|
|
@ -185,6 +185,28 @@ RSpec.shared_examples_for 'collection cache helper' do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when presentable has a group by clause' do
|
||||||
|
let(:presentable) { MergeRequest.group(:id) }
|
||||||
|
|
||||||
|
it "returns the presentables" do
|
||||||
|
expect(transaction)
|
||||||
|
.to receive(:increment)
|
||||||
|
.with(:cached_object_operations_total, 0, { caller_id: caller_id, render_type: :collection, cache_hit: true }).once
|
||||||
|
|
||||||
|
expect(transaction)
|
||||||
|
.to receive(:increment)
|
||||||
|
.with(:cached_object_operations_total, MergeRequest.count, { caller_id: caller_id, render_type: :collection, cache_hit: false }).once
|
||||||
|
|
||||||
|
parsed = Gitlab::Json.parse(subject.to_s)
|
||||||
|
|
||||||
|
expect(parsed).to be_an(Array)
|
||||||
|
|
||||||
|
presentable.each_with_index do |item, i|
|
||||||
|
expect(parsed[i]["id"]).to eq(item.id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
context 'when the presentables all miss' do
|
context 'when the presentables all miss' do
|
||||||
it 'increments the counters' do
|
it 'increments the counters' do
|
||||||
expect(transaction)
|
expect(transaction)
|
||||||
|
|
Loading…
Reference in New Issue