Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
df65129ab4
commit
f8888a274f
|
|
@ -1,6 +1,6 @@
|
|||
include:
|
||||
- project: gitlab-org/quality/pipeline-common
|
||||
ref: 7.7.0
|
||||
ref: 7.8.0
|
||||
file:
|
||||
- /ci/danger-review.yml
|
||||
|
||||
|
|
|
|||
|
|
@ -277,11 +277,7 @@ export default {
|
|||
>
|
||||
{{ saveText }}
|
||||
</gl-button>
|
||||
<gl-button
|
||||
:type="cancelButtonType"
|
||||
data-qa-selector="cancel_badge_button"
|
||||
@click="handleCancel"
|
||||
>
|
||||
<gl-button :type="cancelButtonType" @click="handleCancel">
|
||||
{{ __('Cancel') }}
|
||||
</gl-button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,6 @@ export default {
|
|||
<div
|
||||
class="board-add-new-list board gl-display-inline-block gl-h-full gl-vertical-align-top gl-white-space-normal gl-flex-shrink-0 gl-rounded-base gl-px-3"
|
||||
data-testid="board-add-new-column"
|
||||
data-qa-selector="board_add_new_list"
|
||||
>
|
||||
<div
|
||||
class="board-inner gl-display-flex gl-flex-direction-column gl-relative gl-h-full gl-rounded-base gl-bg-gray-50"
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ export default {
|
|||
<template #control> </template>
|
||||
<template #candidate>
|
||||
<div v-if="canShowCreateButton" class="gl-ml-1 gl-mr-3 gl-display-flex gl-align-items-center">
|
||||
<gl-button data-qa-selector="new_board_button" @click.prevent="showDialog">
|
||||
<gl-button @click.prevent="showDialog">
|
||||
{{ createButtonText }}
|
||||
</gl-button>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -386,7 +386,6 @@ export default {
|
|||
icon="remove"
|
||||
size="small"
|
||||
:aria-label="$options.i18n.deleteButton"
|
||||
data-qa-selector="delete_ci_variable_button"
|
||||
/>
|
||||
<gl-modal
|
||||
ref="modal"
|
||||
|
|
|
|||
|
|
@ -132,7 +132,6 @@ export default {
|
|||
<template>
|
||||
<div
|
||||
class="ci-job-component gl-display-flex gl-align-items-center gl-justify-content-space-between"
|
||||
data-qa-selector="job_item_container"
|
||||
>
|
||||
<gl-link
|
||||
v-if="hasDetails"
|
||||
|
|
|
|||
|
|
@ -371,11 +371,7 @@ export default {
|
|||
</gl-form-group>
|
||||
<!--Variable List-->
|
||||
<gl-form-group class="gl-mb-0" :label="$options.i18n.variables">
|
||||
<div
|
||||
v-for="(variable, index) in variables"
|
||||
:key="`var-${index}`"
|
||||
data-qa-selector="ci_variable_row_container"
|
||||
>
|
||||
<div v-for="(variable, index) in variables" :key="`var-${index}`">
|
||||
<div
|
||||
v-if="!variable.destroy"
|
||||
class="gl-display-flex gl-align-items-stretch gl-flex-direction-column gl-md-flex-direction-row gl-mb-3 gl-pb-2"
|
||||
|
|
|
|||
|
|
@ -180,17 +180,11 @@ export default {
|
|||
data-confirm-btn-variant="danger"
|
||||
rel="nofollow"
|
||||
data-testid="trigger_revoke_button"
|
||||
data-qa-selector="trigger_revoke_button"
|
||||
:href="item.projectTriggerPath"
|
||||
/>
|
||||
</template>
|
||||
</gl-table>
|
||||
<div
|
||||
v-else
|
||||
class="gl-new-card-empty gl-px-5 gl-py-4"
|
||||
data-testid="no_triggers_content"
|
||||
data-qa-selector="no_triggers_content"
|
||||
>
|
||||
<div v-else class="gl-new-card-empty gl-px-5 gl-py-4" data-testid="no_triggers_content">
|
||||
{{ s__('Pipelines|No triggers have been created yet. Add one using the form above.') }}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -142,7 +142,6 @@ export default {
|
|||
ref="freezeStartCron"
|
||||
v-model="freezeStartCron"
|
||||
class="gl-font-monospace!"
|
||||
data-qa-selector="deploy_freeze_start_field"
|
||||
:placeholder="$options.i18n.cronPlaceholder"
|
||||
:state="freezeStartCronState"
|
||||
autofocus
|
||||
|
|
@ -160,7 +159,6 @@ export default {
|
|||
id="deploy-freeze-end"
|
||||
v-model="freezeEndCron"
|
||||
class="gl-font-monospace!"
|
||||
data-qa-selector="deploy_freeze_end_field"
|
||||
:placeholder="$options.i18n.cronPlaceholder"
|
||||
:state="freezeEndCronState"
|
||||
trim
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ export default {
|
|||
title: s__('DesignManagement|Are you sure you want to archive the selected designs?'),
|
||||
actionPrimary: {
|
||||
text: s__('DesignManagement|Archive designs'),
|
||||
attributes: { variant: 'confirm', 'data-qa-selector': 'confirm_archiving_button' },
|
||||
attributes: { variant: 'confirm', 'data-testid': 'confirm-archiving-button' },
|
||||
},
|
||||
actionCancel: {
|
||||
text: __('Cancel'),
|
||||
|
|
|
|||
|
|
@ -293,7 +293,6 @@ export default {
|
|||
<ul
|
||||
class="design-discussion bordered-box gl-relative gl-p-0 gl-list-style-none"
|
||||
:class="{ 'gl-bg-blue-50': isDiscussionActive }"
|
||||
data-qa-selector="design_discussion_content"
|
||||
data-testid="design-discussion-content"
|
||||
>
|
||||
<design-note
|
||||
|
|
|
|||
|
|
@ -129,8 +129,6 @@ export default {
|
|||
this.isEditing = true;
|
||||
},
|
||||
extraAttrs: {
|
||||
'data-testid': 'delete-note-button',
|
||||
'data-qa-selector': 'delete_design_note_button',
|
||||
class: 'gl-sm-display-none!',
|
||||
},
|
||||
},
|
||||
|
|
@ -140,8 +138,6 @@ export default {
|
|||
this.$emit('delete-note', this.note);
|
||||
},
|
||||
extraAttrs: {
|
||||
'data-testid': 'delete-note-button',
|
||||
'data-qa-selector': 'delete_design_note_button',
|
||||
class: 'gl-text-red-500!',
|
||||
},
|
||||
},
|
||||
|
|
@ -311,7 +307,6 @@ export default {
|
|||
v-gl-tooltip.hover
|
||||
icon="ellipsis_v"
|
||||
category="tertiary"
|
||||
data-qa-selector="design_discussion_actions_ellipsis_dropdown"
|
||||
text-sr-only
|
||||
:title="$options.i18n.moreActionsLabel"
|
||||
:aria-label="$options.i18n.moreActionsLabel"
|
||||
|
|
@ -322,12 +317,7 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
<template v-if="!isEditing">
|
||||
<div
|
||||
v-safe-html="note.bodyHtml"
|
||||
class="note-text md"
|
||||
data-qa-selector="note_content"
|
||||
data-testid="note-text"
|
||||
></div>
|
||||
<div v-safe-html="note.bodyHtml" class="note-text md" data-testid="note-text"></div>
|
||||
<slot name="resolved-status"></slot>
|
||||
</template>
|
||||
<design-note-awards-list
|
||||
|
|
|
|||
|
|
@ -221,7 +221,7 @@ export default {
|
|||
class="note-textarea js-gfm-input js-autosize markdown-area"
|
||||
dir="auto"
|
||||
data-supports-quick-actions="false"
|
||||
data-qa-selector="note_textarea"
|
||||
data-testid="note-textarea"
|
||||
:aria-label="__('Description')"
|
||||
:placeholder="__('Write a comment…')"
|
||||
@input="handleInput"
|
||||
|
|
@ -243,7 +243,7 @@ export default {
|
|||
variant="confirm"
|
||||
type="submit"
|
||||
data-track-action="click_button"
|
||||
data-qa-selector="save_comment_button"
|
||||
data-testid="save-comment-button"
|
||||
@click="submitForm"
|
||||
>
|
||||
{{ buttonText }}
|
||||
|
|
|
|||
|
|
@ -272,7 +272,7 @@ export default {
|
|||
role="button"
|
||||
:aria-label="$options.i18n.newCommentButtonLabel"
|
||||
class="gl-absolute gl-w-full gl-h-full gl-p-0 gl-top-0 gl-left-0 gl-outline-0! btn-transparent gl-hover-cursor-crosshair"
|
||||
data-qa-selector="design_image_button"
|
||||
data-testid="design-image-button"
|
||||
@mouseup="onAddCommentMouseup"
|
||||
></button>
|
||||
|
||||
|
|
|
|||
|
|
@ -144,12 +144,17 @@ export default {
|
|||
:name="icon.name"
|
||||
:size="16"
|
||||
:class="icon.classes"
|
||||
data-qa-selector="design_status_icon"
|
||||
data-testid="design-status-icon"
|
||||
:data-qa-status="icon.name"
|
||||
/>
|
||||
</span>
|
||||
</div>
|
||||
<gl-intersection-observer class="gl-flex-grow-1" @appear="onAppear">
|
||||
<gl-intersection-observer
|
||||
class="gl-flex-grow-1"
|
||||
data-testid="design-image"
|
||||
:data-qa-filename="filename"
|
||||
@appear="onAppear"
|
||||
>
|
||||
<gl-loading-icon v-if="showLoadingSpinner" size="lg" />
|
||||
<gl-icon
|
||||
v-else-if="showImageErrorIcon"
|
||||
|
|
@ -162,8 +167,6 @@ export default {
|
|||
:src="imageLink"
|
||||
:alt="filename"
|
||||
class="gl-display-block gl-mx-auto gl-max-w-full gl-max-h-full gl-w-auto design-img"
|
||||
data-qa-selector="design_image"
|
||||
:data-qa-filename="filename"
|
||||
:data-testid="`design-img-${id}`"
|
||||
@load="onImageLoad"
|
||||
@error="onImageError"
|
||||
|
|
@ -171,11 +174,13 @@ export default {
|
|||
</gl-intersection-observer>
|
||||
</div>
|
||||
<div class="card-footer gl-display-flex gl-w-full gl-bg-white gl-py-3 gl-px-4">
|
||||
<div class="gl-display-flex gl-flex-direction-column str-truncated-100">
|
||||
<div
|
||||
class="gl-display-flex gl-flex-direction-column str-truncated-100"
|
||||
data-testid="design-file-name"
|
||||
>
|
||||
<span
|
||||
v-gl-tooltip
|
||||
class="gl-font-weight-semibold str-truncated-100"
|
||||
data-qa-selector="design_file_name"
|
||||
:data-testid="`design-img-filename-${id}`"
|
||||
:title="filename"
|
||||
>{{ filename }}</span
|
||||
|
|
|
|||
|
|
@ -402,7 +402,7 @@ export default {
|
|||
button-variant="default"
|
||||
button-class="gl-mr-3"
|
||||
button-size="small"
|
||||
data-qa-selector="archive_button"
|
||||
data-testid="archive-button"
|
||||
:loading="loading"
|
||||
:has-selected-designs="hasSelectedDesigns"
|
||||
@delete-selected-designs="mutate()"
|
||||
|
|
@ -490,7 +490,7 @@ export default {
|
|||
:checked="isDesignSelected(design.filename)"
|
||||
type="checkbox"
|
||||
class="design-checkbox gl-absolute gl-top-4 gl-left-6 gl-ml-2"
|
||||
data-qa-selector="design_checkbox"
|
||||
data-testid="design-checkbox"
|
||||
:data-qa-design="design.filename"
|
||||
@change="changeSelectedDesigns(design.filename)"
|
||||
/>
|
||||
|
|
@ -506,7 +506,7 @@ export default {
|
|||
:class="{ 'design-list-item': !isDesignListEmpty }"
|
||||
:display-as-card="hasDesigns"
|
||||
v-bind="$options.dropzoneProps"
|
||||
data-qa-selector="design_dropzone_content"
|
||||
data-testid="design-dropzone-content"
|
||||
@change="onUploadDesign"
|
||||
@error="onDesignDropzoneError"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -147,12 +147,7 @@ export default {
|
|||
</div>
|
||||
</div>
|
||||
<template v-for="(model, i) in sortedEnvironments">
|
||||
<environment-item
|
||||
:key="`environment-item-${i}`"
|
||||
:model="model"
|
||||
:table-data="tableData"
|
||||
data-qa-selector="environment_item"
|
||||
/>
|
||||
<environment-item :key="`environment-item-${i}`" :model="model" :table-data="tableData" />
|
||||
|
||||
<div
|
||||
v-if="shouldRenderDeployBoard(model)"
|
||||
|
|
@ -185,7 +180,6 @@ export default {
|
|||
:key="`environment-row-${i}-${index}`"
|
||||
:model="child"
|
||||
:table-data="tableData"
|
||||
data-qa-selector="environment_item"
|
||||
/>
|
||||
|
||||
<div
|
||||
|
|
|
|||
|
|
@ -196,7 +196,7 @@ export default {
|
|||
text: __('Create issue'),
|
||||
action: this.createIssue,
|
||||
extraAttrs: {
|
||||
'data-qa-selector': 'create_issue_button',
|
||||
'data-testid': 'create-issue-button',
|
||||
},
|
||||
};
|
||||
},
|
||||
|
|
@ -309,7 +309,7 @@ export default {
|
|||
<div
|
||||
v-if="!loadingStacktrace && stacktrace"
|
||||
class="gl-my-auto gl-text-truncate"
|
||||
data-qa-selector="reported_text"
|
||||
data-testid="reported-text"
|
||||
>
|
||||
<gl-sprintf :message="__('Reported %{timeAgo} by %{reportedBy}')">
|
||||
<template #reportedBy>
|
||||
|
|
@ -367,7 +367,7 @@ export default {
|
|||
category="primary"
|
||||
variant="confirm"
|
||||
:loading="issueCreationInProgress"
|
||||
data-qa-selector="create_issue_button"
|
||||
data-testid="create-issue-button"
|
||||
@click="createIssue"
|
||||
>
|
||||
{{ __('Create issue') }}
|
||||
|
|
|
|||
|
|
@ -206,7 +206,6 @@ export default {
|
|||
v-gl-modal="'configure-feature-flags'"
|
||||
variant="confirm"
|
||||
category="secondary"
|
||||
data-qa-selector="configure_feature_flags_button"
|
||||
data-testid="ff-configure-button"
|
||||
class="gl-mb-0 gl-mr-3"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -57,7 +57,6 @@ export default {
|
|||
icon="ellipsis_v"
|
||||
no-caret
|
||||
:data-testid="`group-${group.id}-dropdown-button`"
|
||||
data-qa-selector="group_dropdown_button"
|
||||
:data-qa-group-id="group.id"
|
||||
>
|
||||
<gl-dropdown-item
|
||||
|
|
|
|||
|
|
@ -260,11 +260,7 @@ export default {
|
|||
>
|
||||
<gl-dropdown-divider />
|
||||
</template>
|
||||
<div
|
||||
v-if="hasUserTransferLocations"
|
||||
data-qa-selector="namespaces_list_users"
|
||||
data-testid="user-transfer-locations"
|
||||
>
|
||||
<div v-if="hasUserTransferLocations" data-testid="user-transfer-locations">
|
||||
<gl-dropdown-section-header>{{ $options.i18n.USERS }}</gl-dropdown-section-header>
|
||||
<gl-dropdown-item
|
||||
v-for="item in userTransferLocations"
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@ export default {
|
|||
@input="setFilter({ organization_login: $event })"
|
||||
/>
|
||||
<gl-search-box-by-click
|
||||
data-qa-selector="githubish_import_filter_field"
|
||||
name="filter"
|
||||
:disabled="isNameFilterDisabled"
|
||||
:value="nameFilter"
|
||||
|
|
|
|||
|
|
@ -155,7 +155,6 @@ export default {
|
|||
<slot name="actions"></slot>
|
||||
<form v-if="filterable" class="gl-ml-auto" novalidate @submit.prevent>
|
||||
<gl-search-box-by-click
|
||||
data-qa-selector="githubish_import_filter_field"
|
||||
name="filter"
|
||||
:placeholder="__('Filter by name')"
|
||||
autofocus
|
||||
|
|
|
|||
|
|
@ -115,7 +115,6 @@ export default {
|
|||
:search-placeholder="$options.i18n.searchPlaceholder"
|
||||
:no-results-text="$options.i18n.emptySearchResult"
|
||||
data-testid="project-select-dropdown"
|
||||
data-qa-selector="project_select_dropdown"
|
||||
class="gl-collapsible-listbox-w-full"
|
||||
@search="searchTerm = $event"
|
||||
@select="selectProject"
|
||||
|
|
|
|||
|
|
@ -79,7 +79,6 @@ export default {
|
|||
:autocomplete-data-sources="autocompleteDataSources"
|
||||
supports-quick-actions
|
||||
autofocus
|
||||
data-qa-selector="description_field"
|
||||
@input="$emit('input', $event)"
|
||||
@keydown.meta.enter="saveIssuable"
|
||||
@keydown.ctrl.enter="saveIssuable"
|
||||
|
|
|
|||
|
|
@ -44,12 +44,7 @@ export default {
|
|||
<template>
|
||||
<list-item v-bind="$attrs">
|
||||
<template #left-primary>
|
||||
<router-link
|
||||
class="gl-text-body gl-font-weight-bold"
|
||||
data-testid="details-link"
|
||||
data-qa-selector="registry_image_content"
|
||||
:to="linkTo"
|
||||
>
|
||||
<router-link class="gl-text-body gl-font-weight-bold" data-testid="details-link" :to="linkTo">
|
||||
{{ item.name }}
|
||||
</router-link>
|
||||
<clipboard-button
|
||||
|
|
|
|||
|
|
@ -167,7 +167,7 @@ export default {
|
|||
|
||||
<gl-tabs>
|
||||
<gl-tab :title="__('Detail')">
|
||||
<div data-qa-selector="package_information_content">
|
||||
<div>
|
||||
<package-history :package-entity="packageEntity" :project-name="projectName" />
|
||||
<terraform-installation />
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<title-area :title="packageEntity.name" data-qa-selector="package_title">
|
||||
<title-area :title="packageEntity.name">
|
||||
<template #sub-header>
|
||||
<gl-icon name="eye" class="gl-mr-3" />
|
||||
<gl-sprintf :message="$options.i18n.packageInfo">
|
||||
|
|
|
|||
|
|
@ -77,7 +77,6 @@ export default {
|
|||
v-gl-resize-observer="checkBreakpoints"
|
||||
:title="packageEntity.name"
|
||||
:avatar="packageIcon"
|
||||
data-qa-selector="package_title"
|
||||
>
|
||||
<template #sub-header>
|
||||
<div data-testid="sub-header" class="gl-display-flex gl-flex-wrap gl-gap-3">
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ export default {
|
|||
</script>
|
||||
|
||||
<template>
|
||||
<div data-qa-selector="package_path" class="gl-display-flex gl-align-items-center">
|
||||
<div class="gl-display-flex gl-align-items-center">
|
||||
<gl-icon data-testid="base-icon" name="project" class="gl-mx-3 gl-min-w-0" />
|
||||
|
||||
<gl-link
|
||||
|
|
|
|||
|
|
@ -225,12 +225,7 @@ export default {
|
|||
:description="s__('BulkImport|Your imported groups and projects will appear here.')"
|
||||
/>
|
||||
<template v-else>
|
||||
<gl-table-lite
|
||||
:fields="$options.fields"
|
||||
:items="historyItems"
|
||||
data-qa-selector="import_history_table"
|
||||
class="gl-w-full"
|
||||
>
|
||||
<gl-table-lite :fields="$options.fields" :items="historyItems" class="gl-w-full">
|
||||
<template #cell(destination_name)="{ item }">
|
||||
<gl-icon
|
||||
v-gl-tooltip
|
||||
|
|
|
|||
|
|
@ -144,12 +144,7 @@ export default {
|
|||
:description="s__('BulkImport|Your imported projects will appear here.')"
|
||||
/>
|
||||
<template v-else>
|
||||
<gl-table
|
||||
:fields="$options.fields"
|
||||
:items="historyItems"
|
||||
data-qa-selector="import_history_table"
|
||||
class="gl-w-full"
|
||||
>
|
||||
<gl-table :fields="$options.fields" :items="historyItems" class="gl-w-full">
|
||||
<template #cell(source)="{ item }">
|
||||
<template v-if="item.import_url">
|
||||
<gl-link
|
||||
|
|
|
|||
|
|
@ -311,7 +311,6 @@ export default {
|
|||
variant="confirm"
|
||||
class="gl-mt-5"
|
||||
data-testid="save_service_desk_settings_button"
|
||||
data-qa-selector="save_service_desk_settings_button"
|
||||
:disabled="isTemplateSaving || !isIssueTrackerEnabled"
|
||||
@click="onSaveTemplate"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -84,7 +84,6 @@ export default {
|
|||
id="service-desk-template-select"
|
||||
:text="selectedTemplate || $options.i18n.defaultDropdownText"
|
||||
:header-text="$options.i18n.defaultDropdownText"
|
||||
data-qa-selector="service_desk_template_dropdown"
|
||||
:block="true"
|
||||
class="service-desk-template-select"
|
||||
toggle-class="gl-m-0"
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ export default {
|
|||
class="js-sidebar-dropdown-toggle edit-link btn gl-text-gray-900! gl-ml-auto hide-collapsed btn-default btn-sm gl-button btn-default-tertiary float-right"
|
||||
href="#"
|
||||
data-test-id="edit-link"
|
||||
data-qa-selector="edit_link"
|
||||
data-track-action="click_edit_button"
|
||||
data-track-label="right_sidebar"
|
||||
data-track-property="assignee"
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ export default {
|
|||
type="button"
|
||||
class="gl-button btn-link gl-reset-color!"
|
||||
data-testid="assign-yourself"
|
||||
data-qa-selector="assign_yourself_button"
|
||||
@click="assignSelf"
|
||||
>
|
||||
{{ __('assign yourself') }}
|
||||
|
|
|
|||
|
|
@ -58,7 +58,6 @@ export default {
|
|||
<template v-for="label in sortedSelectedLabels" v-else>
|
||||
<gl-label
|
||||
:key="label.id"
|
||||
data-qa-selector="selected_label_content"
|
||||
:data-qa-label-name="label.title"
|
||||
:title="label.title"
|
||||
:description="label.description"
|
||||
|
|
|
|||
|
|
@ -40,7 +40,6 @@ export default {
|
|||
:width="imgSize"
|
||||
:class="`s${imgSize}`"
|
||||
class="avatar avatar-inline m-0"
|
||||
data-qa-selector="avatar_image"
|
||||
/>
|
||||
<gl-icon v-if="hasMergeIcon" name="warning-solid" aria-hidden="true" class="merge-icon" />
|
||||
</span>
|
||||
|
|
|
|||
|
|
@ -71,7 +71,6 @@ export default {
|
|||
variant="link"
|
||||
class="gl-ml-2"
|
||||
data-testid="assign-yourself"
|
||||
data-qa-selector="assign_yourself_button"
|
||||
@click="assignSelf"
|
||||
>
|
||||
<span class="gl-text-gray-500 gl-hover-text-blue-800">{{ __('assign yourself') }}</span>
|
||||
|
|
|
|||
|
|
@ -70,7 +70,6 @@ export default {
|
|||
:toggle-text="$options.i18n.createNew"
|
||||
:toggle-id="$options.toggleId"
|
||||
:dropdown-offset="dropdownOffset"
|
||||
data-qa-selector="new_menu_toggle"
|
||||
data-testid="new-menu-toggle"
|
||||
@shown="dropdownOpen = true"
|
||||
@hidden="dropdownOpen = false"
|
||||
|
|
|
|||
|
|
@ -151,7 +151,6 @@ export default {
|
|||
ref="deleteTagButton"
|
||||
:disabled="deleteButtonDisabled"
|
||||
variant="danger"
|
||||
data-qa-selector="delete_tag_confirmation_button"
|
||||
data-testid="delete-tag-confirmation-button"
|
||||
@click="submitForm"
|
||||
>{{ buttonText }}</gl-button
|
||||
|
|
|
|||
|
|
@ -662,7 +662,6 @@ export default {
|
|||
<template v-if="showAutoMergeHelperText">
|
||||
<div
|
||||
class="gl-ml-4 gl-text-gray-500 gl-font-sm"
|
||||
data-qa-selector="auto_merge_helper_text"
|
||||
data-testid="auto-merge-helper-text"
|
||||
>
|
||||
{{ autoMergeHelperText }}
|
||||
|
|
|
|||
|
|
@ -284,13 +284,7 @@ export default {
|
|||
>
|
||||
<div v-if="userName" class="gl-display-inline-flex gl-mt-2" data-testid="assigned-users">
|
||||
<span class="gl-relative gl-mr-4">
|
||||
<img
|
||||
:alt="userName"
|
||||
:src="userImg"
|
||||
:width="32"
|
||||
class="avatar avatar-inline gl-m-0 s32"
|
||||
data-qa-selector="avatar_image"
|
||||
/>
|
||||
<img :alt="userName" :src="userImg" :width="32" class="avatar avatar-inline gl-m-0 s32" />
|
||||
</span>
|
||||
<span class="gl-display-flex gl-flex-direction-column gl-overflow-hidden">
|
||||
<strong class="dropdown-menu-user-full-name">
|
||||
|
|
|
|||
|
|
@ -98,7 +98,6 @@ export default {
|
|||
:class="$options.userColorScheme"
|
||||
data-type="simple"
|
||||
:data-path="blob.path"
|
||||
data-qa-selector="blob_viewer_file_content"
|
||||
>
|
||||
<chunk
|
||||
v-for="(chunk, index) in chunks"
|
||||
|
|
|
|||
|
|
@ -54,7 +54,6 @@ export default {
|
|||
label-position="left"
|
||||
aria-describedby="board-labels-toggle-text"
|
||||
data-testid="show-labels-toggle"
|
||||
data-qa-selector="show_labels_toggle"
|
||||
class="gl-flex-direction-row"
|
||||
@change="setShowLabels"
|
||||
/>
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ export default {
|
|||
value="all_branches"
|
||||
data-testid="rule_all_branches"
|
||||
>
|
||||
<div data-qa-selector="strategy_radio_all">{{ __('All branches') }}</div>
|
||||
<div>{{ __('All branches') }}</div>
|
||||
</gl-form-radio>
|
||||
|
||||
<!-- wildcard -->
|
||||
|
|
@ -52,7 +52,7 @@ export default {
|
|||
value="wildcard"
|
||||
data-testid="rule_wildcard"
|
||||
>
|
||||
<div data-qa-selector="strategy_radio_wildcard">
|
||||
<div>
|
||||
{{ s__('Webhooks|Wildcard pattern') }}
|
||||
</div>
|
||||
</gl-form-radio>
|
||||
|
|
@ -61,7 +61,6 @@ export default {
|
|||
v-if="branchFilterStrategyData === 'wildcard'"
|
||||
v-model="pushEventsBranchFilterData"
|
||||
name="hook[push_events_branch_filter]"
|
||||
data-qa-selector="webhook_branch_filter_field"
|
||||
data-testid="webhook_branch_filter_field"
|
||||
/>
|
||||
</div>
|
||||
|
|
@ -85,7 +84,7 @@ export default {
|
|||
value="regex"
|
||||
data-testid="rule_regex"
|
||||
>
|
||||
<div data-qa-selector="strategy_radio_regex">
|
||||
<div>
|
||||
{{ s__('Webhooks|Regular expression') }}
|
||||
</div>
|
||||
</gl-form-radio>
|
||||
|
|
@ -94,7 +93,6 @@ export default {
|
|||
v-if="branchFilterStrategyData === 'regex'"
|
||||
v-model="pushEventsBranchFilterData"
|
||||
name="hook[push_events_branch_filter]"
|
||||
data-qa-selector="webhook_branch_filter_field"
|
||||
data-testid="webhook_branch_filter_field"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
= render 'usage'
|
||||
|
||||
- if Feature.enabled?(:configure_sentry_in_application_settings)
|
||||
%section.settings.as-sentry.no-animate#js-sentry-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'sentry_settings_content' } }
|
||||
%section.settings.as-sentry.no-animate#js-sentry-settings{ class: ('expanded' if expanded_by_default?) }
|
||||
.settings-header
|
||||
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
|
||||
= _('Sentry')
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
.settings-content
|
||||
= render 'ip_limits'
|
||||
|
||||
%section.settings.as-packages-limits.no-animate#js-packages-limits-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'packages_limits_content' } }
|
||||
%section.settings.as-packages-limits.no-animate#js-packages-limits-settings{ class: ('expanded' if expanded_by_default?) }
|
||||
.settings-header
|
||||
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
|
||||
= _('Package registry rate limits')
|
||||
|
|
@ -72,7 +72,7 @@
|
|||
.settings-content
|
||||
= render partial: 'network_rate_limits', locals: { anchor: 'js-deprecated-limits-settings', setting_fragment: 'deprecated_api' }
|
||||
|
||||
%section.settings.as-git-lfs-limits.no-animate#js-git-lfs-limits-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'git_lfs_limits_content' } }
|
||||
%section.settings.as-git-lfs-limits.no-animate#js-git-lfs-limits-settings{ class: ('expanded' if expanded_by_default?) }
|
||||
.settings-header
|
||||
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
|
||||
= _('Git LFS Rate Limits')
|
||||
|
|
|
|||
|
|
@ -26,7 +26,7 @@
|
|||
.settings-content
|
||||
= render partial: 'repository_mirrors_form'
|
||||
|
||||
%section.settings.as-repository-storage.no-animate#js-repository-storage-settings{ class: ('expanded' if expanded_by_default?), data: { qa_selector: 'repository_storage_settings_content' } }
|
||||
%section.settings.as-repository-storage.no-animate#js-repository-storage-settings{ class: ('expanded' if expanded_by_default?) }
|
||||
.settings-header
|
||||
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only
|
||||
= _('Repository storage')
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
.form-group
|
||||
= f.label :name do
|
||||
= _("Topic slug (name)")
|
||||
= f.text_field :name, placeholder: _('my-topic'), class: 'form-control input-lg', data: { qa_selector: 'topic_name_field' },
|
||||
= f.text_field :name, placeholder: _('my-topic'), class: 'form-control input-lg',
|
||||
required: true,
|
||||
title: _('Please fill in a name for your topic.'),
|
||||
autofocus: true
|
||||
|
|
@ -12,7 +12,7 @@
|
|||
.form-group
|
||||
= f.label :title do
|
||||
= _("Topic title")
|
||||
= f.text_field :title, placeholder: _('My topic'), class: 'form-control input-lg', data: { qa_selector: 'topic_title_field' },
|
||||
= f.text_field :title, placeholder: _('My topic'), class: 'form-control input-lg',
|
||||
required: true,
|
||||
title: _('Please fill in a title for your topic.')
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
- topic = local_assigns.fetch(:topic)
|
||||
- title = topic.title || topic.name
|
||||
|
||||
%li.topic-row.gl-py-3.gl-align-items-center{ class: 'gl-display-flex!', data: { qa_selector: 'topic_row_content' } }
|
||||
%li.topic-row.gl-py-3.gl-align-items-center{ class: 'gl-display-flex!' }
|
||||
= render Pajamas::AvatarComponent.new(topic, size: 32, alt: '')
|
||||
|
||||
.gl-min-w-0.gl-flex-grow-1.gl-ml-3
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
= form_tag admin_topics_path, method: :get do |f|
|
||||
- search = params.fetch(:search, nil)
|
||||
.search-field-holder
|
||||
= search_field_tag :search, search, class: "form-control gl-form-input search-text-input js-search-input", autofocus: true, spellcheck: false, placeholder: _('Search by name'), data: { qa_selector: 'topic_search_field' }
|
||||
= search_field_tag :search, search, class: "form-control gl-form-input search-text-input js-search-input", autofocus: true, spellcheck: false, placeholder: _('Search by name')
|
||||
= sprite_icon('search', css_class: 'search-icon')
|
||||
.gl-flex-grow-1
|
||||
.js-merge-topics{ data: { path: merge_admin_topics_path } }
|
||||
|
|
|
|||
|
|
@ -17,15 +17,15 @@
|
|||
= _("New project")
|
||||
- c.with_body do
|
||||
%ul.content-list{ class: 'gl-px-3!' }
|
||||
- @projects.each_with_index do |project, idx|
|
||||
%li.project-row.gl-align-items-center{ class: 'gl-display-flex!', data: { qa_selector: 'project_row_container', qa_index: idx } }
|
||||
- @projects.each do |project|
|
||||
%li.project-row.gl-align-items-center{ class: 'gl-display-flex!' }
|
||||
.avatar-container.rect-avatar.s40.gl-flex-shrink-0
|
||||
= project_icon(project, alt: '', class: 'avatar project-avatar s40', width: 40, height: 40)
|
||||
.gl-min-w-0.gl-flex-grow-1
|
||||
.title
|
||||
= link_to project_path(project), class: 'js-prefetch-document' do
|
||||
%span.project-full-name{ data: { qa_selector: 'project_fullname_content' } }
|
||||
%span.namespace-name{ data: { qa_selector: 'project_namespace_content' } }
|
||||
%span.project-full-name
|
||||
%span.namespace-name
|
||||
- if project.namespace
|
||||
= project.namespace.human_name
|
||||
\/
|
||||
|
|
@ -43,13 +43,12 @@
|
|||
.controls.gl-flex-shrink-0.gl-ml-5
|
||||
= render Pajamas::ButtonComponent.new(href: project_project_members_path(project),
|
||||
variant: :link,
|
||||
button_options: { class: 'gl-mr-2', data: { qa_selector: 'project_members_button' } }) do
|
||||
button_options: { class: 'gl-mr-2' }) do
|
||||
= _('View members')
|
||||
= render Pajamas::ButtonComponent.new(href: edit_project_path(project),
|
||||
size: :small,
|
||||
button_options: { data: { qa_selector: 'project_edit_button' } }) do
|
||||
size: :small) do
|
||||
= _('Edit')
|
||||
= render 'delete_project_button', project: project, data: { qa_selector: 'project_delete_button' }
|
||||
= render 'delete_project_button', project: project
|
||||
- if @projects.blank?
|
||||
.nothing-here-block= _("This group has no projects yet")
|
||||
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@
|
|||
- if group.export_file_exists?
|
||||
= render Pajamas::ButtonComponent.new(href: download_export_group_path(group), button_options: { rel: 'nofollow', data: { method: :get, qa_selector: 'download_export_link' } }) do
|
||||
= _('Download export')
|
||||
= render Pajamas::ButtonComponent.new(href: export_group_path(group), button_options: { data: { method: :post, qa_selector: 'regenerate_export_group_link' } }) do
|
||||
= render Pajamas::ButtonComponent.new(href: export_group_path(group), button_options: { data: { method: :post } }) do
|
||||
= _('Regenerate export')
|
||||
- else
|
||||
= render Pajamas::ButtonComponent.new(href: export_group_path(group), button_options: { data: { method: :post, qa_selector: 'export_group_link' } }) do
|
||||
= render Pajamas::ButtonComponent.new(href: export_group_path(group), button_options: { data: { method: :post } }) do
|
||||
= _('Export group')
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
- if group.root?
|
||||
.form-group
|
||||
= f.label _('Enabled Git access protocols'), class: 'label-bold'
|
||||
= f.select :enabled_git_access_protocol, options_for_select(enabled_git_access_protocol_options_for_group(group), group.enabled_git_access_protocol), {}, class: 'form-control', data: { qa_selector: 'enabled_git_access_protocol_dropdown' }, disabled: !::Gitlab::CurrentSettings.enabled_git_access_protocol.blank?
|
||||
= f.select :enabled_git_access_protocol, options_for_select(enabled_git_access_protocol_options_for_group(group), group.enabled_git_access_protocol), {}, class: 'form-control', disabled: !::Gitlab::CurrentSettings.enabled_git_access_protocol.blank?
|
||||
- if !::Gitlab::CurrentSettings.enabled_git_access_protocol.blank?
|
||||
.form-text.text-muted
|
||||
= _("This setting has been configured at the instance level and cannot be overridden per group")
|
||||
|
|
|
|||
|
|
@ -7,4 +7,4 @@
|
|||
- link_start_group = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: group_access_tokens_link }
|
||||
= f.gitlab_ui_checkbox_component :resource_access_token_creation_allowed,
|
||||
s_('GroupSettings|Users can create %{link_start_project}project access tokens%{link_end} and %{link_start_group}group access tokens%{link_end} in this group').html_safe % { link_start_project: link_start_project, link_start_group: link_start_group, link_end: '</a>'.html_safe },
|
||||
checkbox_options: { checked: group.namespace_settings.resource_access_token_creation_allowed?, data: { qa_selector: 'resource_access_token_creation_allowed_checkbox' } }
|
||||
checkbox_options: { checked: group.namespace_settings.resource_access_token_creation_allowed? }
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
!!! 5
|
||||
%html.html-devise-layout{ lang: I18n.locale }
|
||||
= render "layouts/head"
|
||||
%body.signup-page.navless{ class: "#{system_message_class} #{user_application_theme} #{client_class_list}", data: { page: body_data_page, qa_selector: 'signup_page' } }
|
||||
%body.signup-page.navless{ class: "#{system_message_class} #{user_application_theme} #{client_class_list}", data: { page: body_data_page } }
|
||||
= header_message
|
||||
= render "layouts/init_client_detection_flags"
|
||||
= render "layouts/header/logo_with_title"
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
- expanded = expanded_by_default?
|
||||
%section.settings.js-service-desk-setting-wrapper.no-animate#js-service-desk{ class: ('expanded' if expanded), data: { qa_selector: 'service_desk_settings_content' } }
|
||||
%section.settings.js-service-desk-setting-wrapper.no-animate#js-service-desk{ class: ('expanded' if expanded) }
|
||||
.settings-header
|
||||
%h4.settings-title.js-settings-toggle.js-settings-toggle-trigger-only= _('Service Desk')
|
||||
= render Pajamas::ButtonComponent.new(button_options: { class: 'js-settings-toggle' }) do
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
%li{ id: dom_id(issue), class: issue_css_classes(issue), url: issue_path(issue), data: { labels: issue.label_ids, id: issue.id, qa_selector: 'issue_container', qa_issue_title: issue.title } }
|
||||
%li{ id: dom_id(issue), class: issue_css_classes(issue), url: issue_path(issue), data: { labels: issue.label_ids, id: issue.id } }
|
||||
.issuable-info-container
|
||||
.issuable-main-info
|
||||
.issue-title.title
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
- issue = local_assigns.fetch(:issue)
|
||||
|
||||
- if issue.time_estimate > 0
|
||||
%span.issuable-estimate.d-none.d-sm-inline-block.has-tooltip{ data: { container: 'body', qa_selector: 'issuable_estimate' }, title: _('Estimate') }
|
||||
%span.issuable-estimate.d-none.d-sm-inline-block.has-tooltip{ data: { container: 'body' }, title: _('Estimate') }
|
||||
|
||||
= sprite_icon('timer', css_class: 'issue-estimate-icon')
|
||||
= Gitlab::TimeTrackingFormatter.output(issue.time_estimate)
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@
|
|||
.form-group
|
||||
= label_tag :access_level, s_("AccessTokens|Select a role"), class: "label-bold"
|
||||
.select-wrapper.gl-form-input-md
|
||||
= select_tag :"#{prefix}[access_level]", options_for_select(access_levels, default_access_level), class: "form-control select-control", data: { qa_selector: 'access_token_access_level' }
|
||||
= select_tag :"#{prefix}[access_level]", options_for_select(access_levels, default_access_level), class: "form-control select-control"
|
||||
= sprite_icon('chevron-down', css_class: "gl-icon gl-absolute gl-top-3 gl-right-3 gl-text-gray-200")
|
||||
|
||||
.form-group
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@
|
|||
= link_to_member(@project, assignee, name: false, title: s_("MrList|Assigned to %{name}") % { name: assignee.name})
|
||||
|
||||
- if more_assignees_count > 0
|
||||
%span{ class: 'avatar-counter has-tooltip', data: { container: 'body', placement: 'bottom', 'line-type' => 'old', qa_selector: 'avatar_counter_content' }, title: _("+%{more_assignees_count} more assignees") % { more_assignees_count: more_assignees_count} }
|
||||
%span{ class: 'avatar-counter has-tooltip', data: { container: 'body', placement: 'bottom', 'line-type' => 'old' }, title: _("+%{more_assignees_count} more assignees") % { more_assignees_count: more_assignees_count} }
|
||||
= _("+%{more_assignees_count}") % { more_assignees_count: more_assignees_count}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
= gl_tab_link_to page_filter_path(state: 'closed'), item_active: params[:state] == 'closed', id: 'state-closed', title: _('Filter by merge requests that are currently closed and unmerged.'), data: { state: 'closed' } do
|
||||
#{issuables_state_counter_text(type, :closed, display_count)}
|
||||
- else
|
||||
= gl_tab_link_to page_filter_path(state: 'closed'), item_active: params[:state] == 'closed', id: 'state-closed', title: _('Filter by issues that are currently closed.'), data: { state: 'closed', qa_selector: 'closed_issues_link' } do
|
||||
= gl_tab_link_to page_filter_path(state: 'closed'), item_active: params[:state] == 'closed', id: 'state-closed', title: _('Filter by issues that are currently closed.'), data: { state: 'closed' } do
|
||||
#{issuables_state_counter_text(type, :closed, display_count)}
|
||||
|
||||
= render 'shared/issuable/nav_links/all', page_context_word: page_context_word, counter: issuables_state_counter_text(type, :all, display_count)
|
||||
|
|
|
|||
|
|
@ -157,7 +157,7 @@
|
|||
= gl_badge_tag @user.followers.count, size: :sm
|
||||
- if profile_tab?(:following)
|
||||
%li.js-following-tab
|
||||
= link_to user_following_path, data: { target: 'div#following', action: 'following', toggle: 'tab', endpoint: user_following_path(format: :json), qa_selector: 'following_tab' } do
|
||||
= link_to user_following_path, data: { target: 'div#following', action: 'following', toggle: 'tab', endpoint: user_following_path(format: :json) } do
|
||||
= s_('UserProfile|Following')
|
||||
= gl_badge_tag @user.followees.count, size: :sm
|
||||
- if !profile_tabs.empty? && Feature.enabled?(:profile_tabs_vue, current_user)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class CleanupCiPipelineChatDataPipelineIdBigint < Gitlab::Database::Migration[2.1]
|
||||
disable_ddl_transaction!
|
||||
|
||||
TABLE = :ci_pipeline_chat_data
|
||||
COLUMNS = [:pipeline_id]
|
||||
|
||||
def up
|
||||
with_lock_retries(raise_on_exhaustion: true) do
|
||||
cleanup_conversion_of_integer_to_bigint(TABLE, COLUMNS) # rubocop:disable Migration/WithLockRetriesDisallowedMethod
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
restore_conversion_of_integer_to_bigint(TABLE, COLUMNS)
|
||||
|
||||
add_concurrent_index(
|
||||
TABLE, :pipeline_id_convert_to_bigint,
|
||||
name: :index_ci_pipeline_chat_data_on_pipeline_id_convert_to_bigint,
|
||||
unique: true
|
||||
)
|
||||
add_concurrent_foreign_key(
|
||||
TABLE, :ci_pipelines,
|
||||
column: :pipeline_id_convert_to_bigint,
|
||||
on_delete: :cascade, validate: true, reverse_lock_order: true
|
||||
)
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1 @@
|
|||
4c90d6df75ddb93f8fd8fb89131256fc97bac990f024576fa57a3a8c6b60fee9
|
||||
|
|
@ -307,15 +307,6 @@ BEGIN
|
|||
END;
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_239c8032a8d6() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
BEGIN
|
||||
NEW."pipeline_id_convert_to_bigint" := NEW."pipeline_id";
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION trigger_68d7b6653c7d() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
|
|
@ -13817,7 +13808,6 @@ ALTER SEQUENCE ci_pipeline_artifacts_id_seq OWNED BY ci_pipeline_artifacts.id;
|
|||
|
||||
CREATE TABLE ci_pipeline_chat_data (
|
||||
id bigint NOT NULL,
|
||||
pipeline_id_convert_to_bigint integer DEFAULT 0 NOT NULL,
|
||||
chat_name_id integer NOT NULL,
|
||||
response_url text NOT NULL,
|
||||
pipeline_id bigint NOT NULL
|
||||
|
|
@ -31771,8 +31761,6 @@ CREATE INDEX index_ci_pipeline_chat_data_on_chat_name_id ON ci_pipeline_chat_dat
|
|||
|
||||
CREATE UNIQUE INDEX index_ci_pipeline_chat_data_on_pipeline_id ON ci_pipeline_chat_data USING btree (pipeline_id);
|
||||
|
||||
CREATE UNIQUE INDEX index_ci_pipeline_chat_data_on_pipeline_id_convert_to_bigint ON ci_pipeline_chat_data USING btree (pipeline_id_convert_to_bigint);
|
||||
|
||||
CREATE INDEX index_ci_pipeline_messages_on_pipeline_id ON ci_pipeline_messages USING btree (pipeline_id);
|
||||
|
||||
CREATE INDEX index_ci_pipeline_messages_on_pipeline_id_convert_to_bigint ON ci_pipeline_messages USING btree (pipeline_id_convert_to_bigint);
|
||||
|
|
@ -36667,8 +36655,6 @@ CREATE TRIGGER trigger_07bc3c48f407 BEFORE INSERT OR UPDATE ON ci_stages FOR EAC
|
|||
|
||||
CREATE TRIGGER trigger_1bd97da9c1a4 BEFORE INSERT OR UPDATE ON ci_pipelines FOR EACH ROW EXECUTE FUNCTION trigger_1bd97da9c1a4();
|
||||
|
||||
CREATE TRIGGER trigger_239c8032a8d6 BEFORE INSERT OR UPDATE ON ci_pipeline_chat_data FOR EACH ROW EXECUTE FUNCTION trigger_239c8032a8d6();
|
||||
|
||||
CREATE TRIGGER trigger_68d7b6653c7d BEFORE INSERT OR UPDATE ON ci_sources_pipelines FOR EACH ROW EXECUTE FUNCTION trigger_68d7b6653c7d();
|
||||
|
||||
CREATE TRIGGER trigger_7f3d66a7d7f5 BEFORE INSERT OR UPDATE ON ci_pipeline_variables FOR EACH ROW EXECUTE FUNCTION trigger_7f3d66a7d7f5();
|
||||
|
|
@ -37095,9 +37081,6 @@ ALTER TABLE ONLY approval_merge_request_rules
|
|||
ALTER TABLE ONLY deploy_keys_projects
|
||||
ADD CONSTRAINT fk_58a901ca7e FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY ci_pipeline_chat_data
|
||||
ADD CONSTRAINT fk_5b21bde562 FOREIGN KEY (pipeline_id_convert_to_bigint) REFERENCES ci_pipelines(id) ON DELETE CASCADE;
|
||||
|
||||
ALTER TABLE ONLY dependency_list_exports
|
||||
ADD CONSTRAINT fk_5b3d11e1ef FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE SET NULL;
|
||||
|
||||
|
|
|
|||
|
|
@ -17102,8 +17102,10 @@ Total weight of open and closed descendant issues.
|
|||
|
||||
| Name | Type | Description |
|
||||
| ---- | ---- | ----------- |
|
||||
| <a id="epicdescendantweightsclosedissues"></a>`closedIssues` | [`Int`](#int) | Total weight of completed (closed) issues in this epic, including epic descendants. |
|
||||
| <a id="epicdescendantweightsopenedissues"></a>`openedIssues` | [`Int`](#int) | Total weight of opened issues in this epic, including epic descendants. |
|
||||
| <a id="epicdescendantweightsclosedissues"></a>`closedIssues` **{warning-solid}** | [`Int`](#int) | **Deprecated** in 16.6. Use `closedIssuesTotal`. |
|
||||
| <a id="epicdescendantweightsclosedissuestotal"></a>`closedIssuesTotal` | [`BigInt`](#bigint) | Total weight of completed (closed) issues in this epic, including epic descendants, encoded as a string. |
|
||||
| <a id="epicdescendantweightsopenedissues"></a>`openedIssues` **{warning-solid}** | [`Int`](#int) | **Deprecated** in 16.6. Use `OpenedIssuesTotal`. |
|
||||
| <a id="epicdescendantweightsopenedissuestotal"></a>`openedIssuesTotal` | [`BigInt`](#bigint) | Total weight of opened issues in this epic, including epic descendants, encoded as a string. |
|
||||
|
||||
### `EpicHealthStatus`
|
||||
|
||||
|
|
|
|||
|
|
@ -62,22 +62,13 @@ Code Suggestions do not prevent you from writing code in your IDE.
|
|||
|
||||
## Supported languages
|
||||
|
||||
The best results from Code Suggestions are expected for languages that [Anthropic Claude](https://www.anthropic.com/product) and the [Google Vertex AI Codey APIs](https://cloud.google.com/vertex-ai/docs/generative-ai/code/code-models-overview#supported_coding_languages) directly support:
|
||||
Code Suggestions support is a function of the:
|
||||
|
||||
- C++
|
||||
- C#
|
||||
- Go
|
||||
- Google SQL
|
||||
- Java
|
||||
- JavaScript
|
||||
- Kotlin
|
||||
- PHP
|
||||
- Python
|
||||
- Ruby
|
||||
- Rust
|
||||
- Scala
|
||||
- Swift
|
||||
- TypeScript
|
||||
- Underlying large language model.
|
||||
- IDE used.
|
||||
- Extension or plug-in support in the IDE.
|
||||
|
||||
For languages not listed in the following table, Code Suggestions might not function as expected.
|
||||
|
||||
### Supported languages in IDEs
|
||||
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@
|
|||
"gettext-parser": "^6.0.0",
|
||||
"graphql": "^15.7.2",
|
||||
"graphql-tag": "^2.11.0",
|
||||
"gridstack": "^9.3.0",
|
||||
"gridstack": "^9.4.0",
|
||||
"highlight.js": "^11.8.0",
|
||||
"immer": "^9.0.15",
|
||||
"ipaddr.js": "^1.9.1",
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ module Gitlab
|
|||
# @option plan [Hash] Support::Helpers::PREMIUM_SELF_MANAGED
|
||||
# @option plan [Hash] Support::Helpers::ULTIMATE
|
||||
# @option plan [Hash] Support::Helpers::ULTIMATE_SELF_MANAGED
|
||||
# @option plan [Hash] Support::Helpers::CI_MINUTES
|
||||
# @option plan [Hash] Support::Helpers::COMPUTE_MINUTES
|
||||
# @option plan [Hash] Support::Helpers::STORAGE
|
||||
# @param users_in_license [Integer] Number of users in license
|
||||
# @param license_type [Hash] Type of the license
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ module Gitlab
|
|||
|
||||
# Pipelines section
|
||||
link :pipelines_tab
|
||||
link :buy_ci_minutes
|
||||
div :plan_ci_minutes
|
||||
div :additional_ci_minutes
|
||||
link :buy_compute_minutes
|
||||
div :plan_compute_minutes
|
||||
div :additional_compute_minutes
|
||||
div :ci_purchase_successful_alert, text: /You have successfully purchased CI minutes/
|
||||
|
||||
# Storage section
|
||||
|
|
@ -39,17 +39,17 @@ module Gitlab
|
|||
button :confirm_member_approval, text: /^OK$/
|
||||
|
||||
def plan_ci_limits
|
||||
plan_ci_minutes[/(\d+){2}/]
|
||||
plan_compute_minutes[/(\d+){2}/]
|
||||
end
|
||||
|
||||
def additional_ci_limits
|
||||
additional_ci_minutes[/(\d+){2}/]
|
||||
additional_compute_minutes[/(\d+){2}/]
|
||||
end
|
||||
|
||||
def additional_ci_minutes_added?
|
||||
def additional_compute_minutes_added?
|
||||
# When opening the Usage quotas page, Seats quota tab is opened briefly even when url is to a different tab
|
||||
::QA::Support::WaitForRequests.wait_for_requests
|
||||
additional_ci_minutes?
|
||||
additional_compute_minutes?
|
||||
end
|
||||
|
||||
# Returns total purchased storage value once it's ready on page
|
||||
|
|
@ -61,29 +61,29 @@ module Gitlab
|
|||
storage_purchased[/(\d+){2}.\d+/].to_f
|
||||
end
|
||||
|
||||
# Waits for additional CI minutes to be available on the page
|
||||
def wait_for_additional_ci_minutes_available
|
||||
# Waits for additional compute minutes to be available on the page
|
||||
def wait_for_additional_compute_minutes_available
|
||||
::QA::Support::Waiter.wait_until(
|
||||
max_duration: ::QA::Support::Helpers::Zuora::ZUORA_TIMEOUT,
|
||||
sleep_interval: 2,
|
||||
reload_page: Chemlab.configuration.browser.session,
|
||||
message: 'Expected additional CI minutes but they did not appear.'
|
||||
message: 'Expected additional compute minutes but they did not appear.'
|
||||
) do
|
||||
additional_ci_minutes_added?
|
||||
additional_compute_minutes_added?
|
||||
end
|
||||
end
|
||||
|
||||
# Waits for additional CI minutes amount to match the expected number of minutes
|
||||
# Waits for additional compute minutes amount to match the expected number of minutes
|
||||
#
|
||||
# @param [String] minutes
|
||||
def wait_for_additional_ci_minute_limits(minutes)
|
||||
wait_for_additional_ci_minutes_available
|
||||
def wait_for_additional_compute_minute_limits(minutes)
|
||||
wait_for_additional_compute_minutes_available
|
||||
|
||||
::QA::Support::Waiter.wait_until(
|
||||
max_duration: ::QA::Support::Helpers::Zuora::ZUORA_TIMEOUT,
|
||||
sleep_interval: 2,
|
||||
reload_page: Chemlab.configuration.browser.session,
|
||||
message: "Expected additional CI minutes to equal #{minutes}"
|
||||
message: "Expected additional compute minutes to equal #{minutes}"
|
||||
) do
|
||||
additional_ci_limits == minutes
|
||||
end
|
||||
|
|
|
|||
|
|
@ -125,75 +125,75 @@ module Gitlab
|
|||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +link :buy_ci_minutes+
|
||||
# Clicks +buy_ci_minutes+
|
||||
def buy_ci_minutes
|
||||
# @note Defined as +link :buy_compute_minutes+
|
||||
# Clicks +buy_compute_minutes+
|
||||
def buy_compute_minutes
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
|
||||
# expect(usage_quotas.buy_ci_minutes_element).to exist
|
||||
# expect(usage_quotas.buy_compute_minutes_element).to exist
|
||||
# end
|
||||
# @return [Watir::Link] The raw +Link+ element
|
||||
def buy_ci_minutes_element
|
||||
def buy_compute_minutes_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
|
||||
# expect(usage_quotas).to be_buy_ci_minutes
|
||||
# expect(usage_quotas).to be_buy_compute_minutes
|
||||
# end
|
||||
# @return [Boolean] true if the +buy_ci_minutes+ element is present on the page
|
||||
def buy_ci_minutes?
|
||||
# @return [Boolean] true if the +buy_compute_minutes+ element is present on the page
|
||||
def buy_compute_minutes?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +div :plan_ci_minutes+
|
||||
# @return [String] The text content or value of +plan_ci_minutes+
|
||||
def plan_ci_minutes
|
||||
# @note Defined as +div :plan_compute_minutes+
|
||||
# @return [String] The text content or value of +plan_compute_minutes+
|
||||
def plan_compute_minutes
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
|
||||
# expect(usage_quotas.plan_ci_minutes_element).to exist
|
||||
# expect(usage_quotas.plan_compute_minutes_element).to exist
|
||||
# end
|
||||
# @return [Watir::Div] The raw +Div+ element
|
||||
def plan_ci_minutes_element
|
||||
def plan_compute_minutes_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
|
||||
# expect(usage_quotas).to be_plan_ci_minutes
|
||||
# expect(usage_quotas).to be_plan_compute_minutes
|
||||
# end
|
||||
# @return [Boolean] true if the +plan_ci_minutes+ element is present on the page
|
||||
def plan_ci_minutes?
|
||||
# @return [Boolean] true if the +plan_compute_minutes+ element is present on the page
|
||||
def plan_compute_minutes?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @note Defined as +div :additional_ci_minutes+
|
||||
# @return [String] The text content or value of +additional_ci_minutes+
|
||||
def additional_ci_minutes
|
||||
# @note Defined as +div :additional_compute_minutes+
|
||||
# @return [String] The text content or value of +additional_compute_minutes+
|
||||
def additional_compute_minutes
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
|
||||
# expect(usage_quotas.additional_ci_minutes_element).to exist
|
||||
# expect(usage_quotas.additional_compute_minutes_element).to exist
|
||||
# end
|
||||
# @return [Watir::Div] The raw +Div+ element
|
||||
def additional_ci_minutes_element
|
||||
def additional_compute_minutes_element
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
# @example
|
||||
# Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quotas|
|
||||
# expect(usage_quotas).to be_additional_ci_minutes
|
||||
# expect(usage_quotas).to be_additional_compute_minutes
|
||||
# end
|
||||
# @return [Boolean] true if the +additional_ci_minutes+ element is present on the page
|
||||
def additional_ci_minutes?
|
||||
# @return [Boolean] true if the +additional_compute_minutes+ element is present on the page
|
||||
def additional_compute_minutes?
|
||||
# This is a stub, used for indexing. The method is dynamically generated.
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -23,21 +23,21 @@ module QA
|
|||
end
|
||||
end
|
||||
|
||||
def purchase_ci_minutes(quantity: 1)
|
||||
def purchase_compute_minutes(quantity: 1)
|
||||
Page::Group::Menu.perform(&:go_to_usage_quotas)
|
||||
Gitlab::Page::Group::Settings::UsageQuotas.perform do |usage_quota|
|
||||
usage_quota.pipelines_tab
|
||||
usage_quota.buy_ci_minutes
|
||||
usage_quota.buy_compute_minutes
|
||||
end
|
||||
|
||||
Gitlab::Page::Subscriptions::New.perform do |ci_minutes|
|
||||
ci_minutes.quantity = quantity
|
||||
ci_minutes.continue_to_billing
|
||||
Gitlab::Page::Subscriptions::New.perform do |compute_minutes|
|
||||
compute_minutes.quantity = quantity
|
||||
compute_minutes.continue_to_billing
|
||||
|
||||
fill_in_customer_info
|
||||
fill_in_payment_info
|
||||
|
||||
ci_minutes.purchase
|
||||
compute_minutes.purchase
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -11,49 +11,49 @@ module QA
|
|||
|
||||
base.class_eval do
|
||||
view 'app/assets/javascripts/design_management/components/design_notes/design_discussion.vue' do
|
||||
element :design_discussion_content
|
||||
element 'design-discussion-content'
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/design_management/components/design_notes/design_note.vue' do
|
||||
element :note_content
|
||||
element 'note-text'
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/design_management/components/design_notes/design_reply_form.vue' do
|
||||
element :note_textarea
|
||||
element :save_comment_button
|
||||
element 'note-textarea'
|
||||
element 'save-comment-button'
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/design_management/components/design_overlay.vue' do
|
||||
element :design_image_button
|
||||
element 'design-image-button'
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/design_management/components/list/item.vue' do
|
||||
element :design_file_name
|
||||
element :design_image
|
||||
element :design_status_icon
|
||||
element 'design-file-name'
|
||||
element 'design-image'
|
||||
element 'design-status-icon'
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/design_management/pages/index.vue' do
|
||||
element :archive_button
|
||||
element :design_checkbox
|
||||
element :design_dropzone_content
|
||||
element 'archive-button'
|
||||
element 'design-checkbox'
|
||||
element 'design-dropzone-content'
|
||||
end
|
||||
|
||||
view 'app/assets/javascripts/design_management/components/delete_button.vue' do
|
||||
element :confirm_archiving_button
|
||||
element 'confirm-archiving-button'
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def add_annotation(note)
|
||||
click_element(:design_image_button)
|
||||
fill_element(:note_textarea, note)
|
||||
click_element(:save_comment_button)
|
||||
click_element('design-image-button')
|
||||
fill_element('note-textarea', note)
|
||||
click_element('save-comment-button')
|
||||
|
||||
# It takes a moment for the annotation to be saved.
|
||||
# We'll check for the annotation in a test, but here we'll at least
|
||||
# wait for the "Save comment" button to disappear
|
||||
saved = has_no_element?(:save_comment_button)
|
||||
saved = has_no_element?('save-comment-button')
|
||||
return if saved
|
||||
|
||||
raise RSpec::Expectations::ExpectationNotMetError, %q(There was a problem while adding the annotation)
|
||||
|
|
@ -64,16 +64,16 @@ module QA
|
|||
# It accepts a `class:` option, but that only works for class attributes
|
||||
# It doesn't work as a CSS selector.
|
||||
# So instead we use the name attribute as a locator
|
||||
within_element(:design_dropzone_content) do
|
||||
within_element('design-dropzone-content') do
|
||||
page.attach_file("upload_file", design_file_path, make_visible: { display: 'block' })
|
||||
end
|
||||
|
||||
filename = ::File.basename(design_file_path)
|
||||
|
||||
wait_until(reload: false, sleep_interval: 1, message: "Design upload") do
|
||||
image = find_element(:design_image, filename: filename)
|
||||
image = find_element('design-image', filename: filename).find('img')
|
||||
|
||||
has_element?(:design_file_name, text: filename) && image["complete"] && image["naturalWidth"].to_i > 0
|
||||
has_element?('design-file-name', text: filename) && image["complete"] && image["naturalWidth"].to_i > 0
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -83,38 +83,38 @@ module QA
|
|||
end
|
||||
|
||||
def click_design(filename)
|
||||
click_element(:design_file_name, text: filename)
|
||||
click_element('design-file-name', text: filename)
|
||||
end
|
||||
|
||||
def select_design(filename)
|
||||
click_element(:design_checkbox, design: filename)
|
||||
click_element('design-checkbox', design: filename)
|
||||
end
|
||||
|
||||
def archive_selected_designs
|
||||
click_element(:archive_button)
|
||||
click_element(:confirm_archiving_button)
|
||||
click_element('archive-button')
|
||||
click_element('confirm-archiving-button')
|
||||
end
|
||||
|
||||
def has_annotation?(note)
|
||||
within_element_by_index(:design_discussion_content, 0) do
|
||||
has_element?(:note_content, text: note)
|
||||
within_element_by_index('design-discussion-content', 0) do
|
||||
has_element?('note-text', text: note)
|
||||
end
|
||||
end
|
||||
|
||||
def has_design?(filename)
|
||||
has_element?(:design_file_name, text: filename)
|
||||
has_element?('design-file-name', text: filename)
|
||||
end
|
||||
|
||||
def has_no_design?(filename)
|
||||
has_no_element?(:design_file_name, text: filename)
|
||||
has_no_element?('design-file-name', text: filename)
|
||||
end
|
||||
|
||||
def has_created_icon?
|
||||
has_element?(:design_status_icon, status: 'file-addition-solid')
|
||||
has_element?('design-status-icon', status: 'file-addition-solid')
|
||||
end
|
||||
|
||||
def has_modified_icon?
|
||||
has_element?(:design_status_icon, status: 'file-modified-solid')
|
||||
has_element?('design-status-icon', status: 'file-modified-solid')
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ module QA
|
|||
module Support
|
||||
module Helpers
|
||||
module Plan
|
||||
FREE = { name: 'free', price: 0, yearly_price: 0, ci_minutes: 400 }.freeze
|
||||
FREE = { name: 'free', price: 0, yearly_price: 0, compute_minutes: 400 }.freeze
|
||||
|
||||
PREMIUM = {
|
||||
plan_id: '2c92a00d76f0d5060176f2fb0a5029ff',
|
||||
|
|
@ -12,7 +12,7 @@ module QA
|
|||
name: 'premium',
|
||||
price: 19,
|
||||
yearly_price: 228,
|
||||
ci_minutes: 10000
|
||||
compute_minutes: 10000
|
||||
}.freeze
|
||||
|
||||
PREMIUM_SELF_MANAGED = {
|
||||
|
|
@ -29,7 +29,7 @@ module QA
|
|||
name: 'ultimate',
|
||||
price: 99,
|
||||
yearly_price: 1188,
|
||||
ci_minutes: 50000
|
||||
compute_minutes: 50000
|
||||
}.freeze
|
||||
|
||||
ULTIMATE_SELF_MANAGED = {
|
||||
|
|
@ -40,12 +40,12 @@ module QA
|
|||
yearly_price: 1188
|
||||
}.freeze
|
||||
|
||||
CI_MINUTES = {
|
||||
COMPUTE_MINUTES = {
|
||||
plan_id: '2c92a0086a07f4a8016a2c0a1f7b4b4c',
|
||||
rate_charge_id: '2c92a0fd6a07f4c6016a2c0af07c3f21',
|
||||
name: 'ci_minutes',
|
||||
name: 'compute_minutes',
|
||||
price: 10,
|
||||
ci_minutes: 1000
|
||||
compute_minutes: 1000
|
||||
}.freeze
|
||||
|
||||
STORAGE = {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
exports[`Design reply form component renders button text as "Comment" when creating a comment 1`] = `
|
||||
<button
|
||||
class="btn btn-confirm btn-md disabled gl-button gl-mr-3 gl-w-auto!"
|
||||
data-qa-selector="save_comment_button"
|
||||
data-testid="save-comment-button"
|
||||
data-track-action="click_button"
|
||||
disabled=""
|
||||
type="submit"
|
||||
|
|
@ -19,7 +19,7 @@ exports[`Design reply form component renders button text as "Comment" when creat
|
|||
exports[`Design reply form component renders button text as "Save comment" when creating a comment 1`] = `
|
||||
<button
|
||||
class="btn btn-confirm btn-md disabled gl-button gl-mr-3 gl-w-auto!"
|
||||
data-qa-selector="save_comment_button"
|
||||
data-testid="save-comment-button"
|
||||
data-track-action="click_button"
|
||||
disabled=""
|
||||
type="submit"
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ describe('Design overlay component', () => {
|
|||
};
|
||||
|
||||
wrapper
|
||||
.find('[data-qa-selector="design_image_button"]')
|
||||
.find('[data-testid="design-image-button"]')
|
||||
.trigger('mouseup', { offsetX: newCoordinates.x, offsetY: newCoordinates.y });
|
||||
|
||||
expect(wrapper.emitted('openCommentForm')).toEqual([
|
||||
|
|
|
|||
|
|
@ -46,7 +46,7 @@ describe('Design management design presentation component', () => {
|
|||
wrapper.element.scrollTo = jest.fn();
|
||||
}
|
||||
|
||||
const findOverlayCommentButton = () => wrapper.find('[data-qa-selector="design_image_button"]');
|
||||
const findOverlayCommentButton = () => wrapper.find('[data-testid="design-image-button"]');
|
||||
|
||||
/**
|
||||
* Spy on $refs and mock given values
|
||||
|
|
|
|||
|
|
@ -17,12 +17,12 @@ exports[`Design management list item component with notes renders item with mult
|
|||
>
|
||||
<gl-intersection-observer-stub
|
||||
class="gl-flex-grow-1"
|
||||
data-qa-filename="test"
|
||||
data-testid="design-image"
|
||||
>
|
||||
<img
|
||||
alt="test"
|
||||
class="design-img gl-display-block gl-max-h-full gl-max-w-full gl-mx-auto gl-w-auto"
|
||||
data-qa-filename="test"
|
||||
data-qa-selector="design_image"
|
||||
data-testid="design-img-1"
|
||||
src="null"
|
||||
/>
|
||||
|
|
@ -33,10 +33,10 @@ exports[`Design management list item component with notes renders item with mult
|
|||
>
|
||||
<div
|
||||
class="gl-display-flex gl-flex-direction-column str-truncated-100"
|
||||
data-testid="design-file-name"
|
||||
>
|
||||
<span
|
||||
class="gl-font-weight-semibold str-truncated-100"
|
||||
data-qa-selector="design_file_name"
|
||||
data-testid="design-img-filename-1"
|
||||
title="test"
|
||||
>
|
||||
|
|
@ -82,12 +82,12 @@ exports[`Design management list item component with notes renders item with sing
|
|||
>
|
||||
<gl-intersection-observer-stub
|
||||
class="gl-flex-grow-1"
|
||||
data-qa-filename="test"
|
||||
data-testid="design-image"
|
||||
>
|
||||
<img
|
||||
alt="test"
|
||||
class="design-img gl-display-block gl-max-h-full gl-max-w-full gl-mx-auto gl-w-auto"
|
||||
data-qa-filename="test"
|
||||
data-qa-selector="design_image"
|
||||
data-testid="design-img-1"
|
||||
src="null"
|
||||
/>
|
||||
|
|
@ -98,10 +98,10 @@ exports[`Design management list item component with notes renders item with sing
|
|||
>
|
||||
<div
|
||||
class="gl-display-flex gl-flex-direction-column str-truncated-100"
|
||||
data-testid="design-file-name"
|
||||
>
|
||||
<span
|
||||
class="gl-font-weight-semibold str-truncated-100"
|
||||
data-qa-selector="design_file_name"
|
||||
data-testid="design-img-filename-1"
|
||||
title="test"
|
||||
>
|
||||
|
|
|
|||
|
|
@ -190,7 +190,7 @@ describe('ErrorDetails', () => {
|
|||
});
|
||||
|
||||
describe('unsafe chars for culprit field', () => {
|
||||
const findReportedText = () => wrapper.find('[data-qa-selector="reported_text"]');
|
||||
const findReportedText = () => wrapper.find('[data-testid="reported-text"]');
|
||||
const culprit = '<script>console.log("surprise!")</script>';
|
||||
beforeEach(() => {
|
||||
store.state.details.loadingStacktrace = false;
|
||||
|
|
@ -350,7 +350,7 @@ describe('ErrorDetails', () => {
|
|||
it('should submit the form', () => {
|
||||
window.HTMLFormElement.prototype.submit = () => {};
|
||||
const submitSpy = jest.spyOn(wrapper.vm.$refs.sentryIssueForm, 'submit');
|
||||
wrapper.find('[data-qa-selector="create_issue_button"]').vm.$emit('click');
|
||||
wrapper.find('[data-testid="create-issue-button"]').vm.$emit('click');
|
||||
expect(submitSpy).toHaveBeenCalled();
|
||||
submitSpy.mockRestore();
|
||||
});
|
||||
|
|
@ -462,7 +462,7 @@ describe('ErrorDetails', () => {
|
|||
describe('GitLab issue link', () => {
|
||||
const gitlabIssuePath = 'https://gitlab.example.com/issues/1';
|
||||
const findGitLabLink = () => wrapper.find(`[href="${gitlabIssuePath}"]`);
|
||||
const findCreateIssueButton = () => wrapper.find('[data-qa-selector="create_issue_button"]');
|
||||
const findCreateIssueButton = () => wrapper.find('[data-testid="create-issue-button"]');
|
||||
const findViewIssueButton = () => wrapper.find('[data-qa-selector="view_issue_button"]');
|
||||
|
||||
describe('is present', () => {
|
||||
|
|
@ -562,7 +562,7 @@ describe('ErrorDetails', () => {
|
|||
});
|
||||
|
||||
it('should track create issue button click', async () => {
|
||||
await wrapper.find('[data-qa-selector="create_issue_button"]').vm.$emit('click');
|
||||
await wrapper.find('[data-testid="create-issue-button"]').vm.$emit('click');
|
||||
expect(Tracking.event).toHaveBeenCalledWith(category, 'click_create_issue_from_error', {
|
||||
extra: {
|
||||
variant: integrated ? 'integrated' : 'external',
|
||||
|
|
|
|||
|
|
@ -15,9 +15,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_all_branches"
|
||||
value="all_branches"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_all"
|
||||
>
|
||||
<div>
|
||||
All branches
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -26,9 +24,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_wildcard"
|
||||
value="wildcard"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_wildcard"
|
||||
>
|
||||
<div>
|
||||
Wildcard pattern
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -40,9 +36,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_regex"
|
||||
value="regex"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_regex"
|
||||
>
|
||||
<div>
|
||||
Regular expression
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -67,9 +61,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_all_branches"
|
||||
value="all_branches"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_all"
|
||||
>
|
||||
<div>
|
||||
All branches
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -78,9 +70,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_wildcard"
|
||||
value="wildcard"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_wildcard"
|
||||
>
|
||||
<div>
|
||||
Wildcard pattern
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -92,9 +82,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_regex"
|
||||
value="regex"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_regex"
|
||||
>
|
||||
<div>
|
||||
Regular expression
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -102,7 +90,6 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
class="gl-ml-6"
|
||||
>
|
||||
<gl-form-input-stub
|
||||
data-qa-selector="webhook_branch_filter_field"
|
||||
data-testid="webhook_branch_filter_field"
|
||||
name="hook[push_events_branch_filter]"
|
||||
value="foo"
|
||||
|
|
@ -133,9 +120,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_all_branches"
|
||||
value="all_branches"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_all"
|
||||
>
|
||||
<div>
|
||||
All branches
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -144,9 +129,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_wildcard"
|
||||
value="wildcard"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_wildcard"
|
||||
>
|
||||
<div>
|
||||
Wildcard pattern
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -154,7 +137,6 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
class="gl-ml-6"
|
||||
>
|
||||
<gl-form-input-stub
|
||||
data-qa-selector="webhook_branch_filter_field"
|
||||
data-testid="webhook_branch_filter_field"
|
||||
name="hook[push_events_branch_filter]"
|
||||
value="foo"
|
||||
|
|
@ -172,9 +154,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_regex"
|
||||
value="regex"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_regex"
|
||||
>
|
||||
<div>
|
||||
Regular expression
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -199,9 +179,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_all_branches"
|
||||
value="all_branches"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_all"
|
||||
>
|
||||
<div>
|
||||
All branches
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -210,9 +188,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_wildcard"
|
||||
value="wildcard"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_wildcard"
|
||||
>
|
||||
<div>
|
||||
Wildcard pattern
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -224,9 +200,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_regex"
|
||||
value="regex"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_regex"
|
||||
>
|
||||
<div>
|
||||
Regular expression
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -251,9 +225,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_all_branches"
|
||||
value="all_branches"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_all"
|
||||
>
|
||||
<div>
|
||||
All branches
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -262,9 +234,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_wildcard"
|
||||
value="wildcard"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_wildcard"
|
||||
>
|
||||
<div>
|
||||
Wildcard pattern
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -276,9 +246,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_regex"
|
||||
value="regex"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_regex"
|
||||
>
|
||||
<div>
|
||||
Regular expression
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -286,7 +254,6 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
class="gl-ml-6"
|
||||
>
|
||||
<gl-form-input-stub
|
||||
data-qa-selector="webhook_branch_filter_field"
|
||||
data-testid="webhook_branch_filter_field"
|
||||
name="hook[push_events_branch_filter]"
|
||||
value=""
|
||||
|
|
@ -317,9 +284,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_all_branches"
|
||||
value="all_branches"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_all"
|
||||
>
|
||||
<div>
|
||||
All branches
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -328,9 +293,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_wildcard"
|
||||
value="wildcard"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_wildcard"
|
||||
>
|
||||
<div>
|
||||
Wildcard pattern
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
@ -338,7 +301,6 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
class="gl-ml-6"
|
||||
>
|
||||
<gl-form-input-stub
|
||||
data-qa-selector="webhook_branch_filter_field"
|
||||
data-testid="webhook_branch_filter_field"
|
||||
name="hook[push_events_branch_filter]"
|
||||
value=""
|
||||
|
|
@ -356,9 +318,7 @@ exports[`Webhook push events form editor component Different push events rules w
|
|||
data-testid="rule_regex"
|
||||
value="regex"
|
||||
>
|
||||
<div
|
||||
data-qa-selector="strategy_radio_regex"
|
||||
>
|
||||
<div>
|
||||
Regular expression
|
||||
</div>
|
||||
</gl-form-radio-stub>
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ require 'spec_helper'
|
|||
|
||||
RSpec.describe 'Creating the packages protection rule', :aggregate_failures, feature_category: :package_registry do
|
||||
include GraphqlHelpers
|
||||
using RSpec::Parameterized::TableSyntax
|
||||
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:user) { create(:user, maintainer_projects: [project]) }
|
||||
|
|
@ -15,151 +14,160 @@ RSpec.describe 'Creating the packages protection rule', :aggregate_failures, fea
|
|||
{
|
||||
project_path: project.full_path,
|
||||
package_name_pattern: package_protection_rule_attributes.package_name_pattern,
|
||||
package_type: "NPM",
|
||||
push_protected_up_to_access_level: "MAINTAINER"
|
||||
package_type: 'NPM',
|
||||
push_protected_up_to_access_level: 'MAINTAINER'
|
||||
}
|
||||
end
|
||||
|
||||
let(:mutation) do
|
||||
graphql_mutation(:create_packages_protection_rule, kwargs,
|
||||
<<~QUERY
|
||||
clientMutationId
|
||||
packageProtectionRule {
|
||||
packageNamePattern
|
||||
packageType
|
||||
pushProtectedUpToAccessLevel
|
||||
}
|
||||
errors
|
||||
QUERY
|
||||
)
|
||||
end
|
||||
|
||||
let(:mutation_response) { graphql_mutation_response(:create_packages_protection_rule) }
|
||||
let(:mutation_response_package_protection_rule) do
|
||||
graphql_data_at(:createPackagesProtectionRule, :packageProtectionRule)
|
||||
end
|
||||
|
||||
describe 'post graphql mutation' do
|
||||
subject { post_graphql_mutation(mutation, current_user: user) }
|
||||
let(:mutation_response_errors) { graphql_data_at(:createPackagesProtectionRule, :errors) }
|
||||
|
||||
context 'without existing packages protection rule' do
|
||||
it 'returns without error' do
|
||||
subject
|
||||
subject { post_graphql_mutation(mutation, current_user: user) }
|
||||
|
||||
expect_graphql_errors_to_be_empty
|
||||
end
|
||||
shared_examples 'a successful response' do
|
||||
it 'returns without error' do
|
||||
subject
|
||||
|
||||
it 'returns the created packages protection rule' do
|
||||
expect { subject }.to change { ::Packages::Protection::Rule.count }.by(1)
|
||||
|
||||
expect_graphql_errors_to_be_empty
|
||||
expect(Packages::Protection::Rule.where(project: project).count).to eq 1
|
||||
|
||||
expect(Packages::Protection::Rule.where(project: project,
|
||||
package_name_pattern: kwargs[:package_name_pattern])).to exist
|
||||
end
|
||||
|
||||
context 'when invalid fields are given' do
|
||||
let(:kwargs) do
|
||||
{
|
||||
project_path: project.full_path,
|
||||
package_name_pattern: '',
|
||||
package_type: 'UNKNOWN_PACKAGE_TYPE',
|
||||
push_protected_up_to_access_level: 'UNKNOWN_ACCESS_LEVEL'
|
||||
}
|
||||
end
|
||||
|
||||
it 'returns error about required argument' do
|
||||
subject
|
||||
|
||||
expect_graphql_errors_to_include(/was provided invalid value for packageType/)
|
||||
expect_graphql_errors_to_include(/pushProtectedUpToAccessLevel/)
|
||||
end
|
||||
end
|
||||
expect_graphql_errors_to_be_empty
|
||||
expect(mutation_response_errors).to be_empty
|
||||
end
|
||||
|
||||
context 'when user does not have permission' do
|
||||
let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } }
|
||||
let_it_be(:reporter) { create(:user).tap { |u| project.add_reporter(u) } }
|
||||
let_it_be(:guest) { create(:user).tap { |u| project.add_guest(u) } }
|
||||
let_it_be(:anonymous) { create(:user) }
|
||||
it 'returns the created packages protection rule' do
|
||||
subject
|
||||
|
||||
where(:user) do
|
||||
[ref(:developer), ref(:reporter), ref(:guest), ref(:anonymous)]
|
||||
end
|
||||
|
||||
with_them do
|
||||
it 'returns an error' do
|
||||
expect { subject }.not_to change { ::Packages::Protection::Rule.count }
|
||||
|
||||
expect_graphql_errors_to_include(/you don't have permission to perform this action/)
|
||||
end
|
||||
end
|
||||
expect(mutation_response_package_protection_rule).to include(
|
||||
'packageNamePattern' => kwargs[:package_name_pattern],
|
||||
'packageType' => kwargs[:package_type],
|
||||
'pushProtectedUpToAccessLevel' => kwargs[:push_protected_up_to_access_level]
|
||||
)
|
||||
end
|
||||
|
||||
context 'with existing packages protection rule' do
|
||||
let_it_be(:existing_package_protection_rule) do
|
||||
create(:package_protection_rule, project: project, push_protected_up_to_access_level: Gitlab::Access::DEVELOPER)
|
||||
end
|
||||
it 'creates one package protection rule' do
|
||||
expect { subject }.to change { ::Packages::Protection::Rule.count }.by(1)
|
||||
|
||||
context 'when package name pattern is slightly different' do
|
||||
let(:kwargs) do
|
||||
{
|
||||
project_path: project.full_path,
|
||||
# The field `package_name_pattern` is unique; this is why we change the value in a minimum way
|
||||
package_name_pattern: "#{existing_package_protection_rule.package_name_pattern}-unique",
|
||||
package_type: "NPM",
|
||||
push_protected_up_to_access_level: "DEVELOPER"
|
||||
}
|
||||
end
|
||||
expect(Packages::Protection::Rule.last).to have_attributes(
|
||||
project: project,
|
||||
package_name_pattern: kwargs[:package_name_pattern],
|
||||
package_type: kwargs[:package_type].downcase,
|
||||
push_protected_up_to_access_level: kwargs[:push_protected_up_to_access_level].downcase
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
it 'returns the created packages protection rule' do
|
||||
expect { subject }.to change { ::Packages::Protection::Rule.count }.by(1)
|
||||
shared_examples 'an erroneous response' do
|
||||
it 'does not create one package protection rule' do
|
||||
expect { subject }.not_to change { ::Packages::Protection::Rule.count }
|
||||
end
|
||||
end
|
||||
|
||||
expect(Packages::Protection::Rule.where(project: project).count).to eq 2
|
||||
expect(Packages::Protection::Rule.where(project: project,
|
||||
package_name_pattern: kwargs[:package_name_pattern])).to exist
|
||||
end
|
||||
it_behaves_like 'a successful response'
|
||||
|
||||
it 'returns without error' do
|
||||
subject
|
||||
|
||||
expect_graphql_errors_to_be_empty
|
||||
end
|
||||
end
|
||||
|
||||
context 'when field `package_name_pattern` is taken' do
|
||||
let(:kwargs) do
|
||||
{
|
||||
project_path: project.full_path,
|
||||
package_name_pattern: existing_package_protection_rule.package_name_pattern,
|
||||
package_type: 'NPM',
|
||||
push_protected_up_to_access_level: 'MAINTAINER'
|
||||
}
|
||||
end
|
||||
|
||||
it 'returns without error' do
|
||||
subject
|
||||
|
||||
expect(mutation_response).to include 'errors' => ['Package name pattern has already been taken']
|
||||
end
|
||||
|
||||
it 'does not create new package protection rules' do
|
||||
expect { subject }.to change { Packages::Protection::Rule.count }.by(0)
|
||||
|
||||
expect(Packages::Protection::Rule.where(project: project,
|
||||
package_name_pattern: kwargs[:package_name_pattern],
|
||||
push_protected_up_to_access_level: Gitlab::Access::MAINTAINER)).not_to exist
|
||||
end
|
||||
end
|
||||
context 'with invalid kwargs leading to error from graphql' do
|
||||
let(:kwargs) do
|
||||
super().merge!(
|
||||
package_name_pattern: '',
|
||||
package_type: 'UNKNOWN_PACKAGE_TYPE',
|
||||
push_protected_up_to_access_level: 'UNKNOWN_ACCESS_LEVEL'
|
||||
)
|
||||
end
|
||||
|
||||
context "when feature flag ':packages_protected_packages' disabled" do
|
||||
before do
|
||||
stub_feature_flags(packages_protected_packages: false)
|
||||
it_behaves_like 'an erroneous response'
|
||||
|
||||
it 'returns error about required argument' do
|
||||
subject
|
||||
|
||||
expect_graphql_errors_to_include(/was provided invalid value for packageType/)
|
||||
expect_graphql_errors_to_include(/pushProtectedUpToAccessLevel/)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with invalid kwargs leading to error from business model' do
|
||||
let(:kwargs) { super().merge!(package_name_pattern: '') }
|
||||
|
||||
it_behaves_like 'an erroneous response'
|
||||
|
||||
it 'returns an error' do
|
||||
subject.tap { expect(mutation_response_errors).to include(/Package name pattern can't be blank/) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'with existing packages protection rule' do
|
||||
let_it_be(:existing_package_protection_rule) do
|
||||
create(:package_protection_rule, project: project, push_protected_up_to_access_level: :maintainer)
|
||||
end
|
||||
|
||||
let(:kwargs) { super().merge!(package_name_pattern: existing_package_protection_rule.package_name_pattern) }
|
||||
|
||||
it_behaves_like 'an erroneous response'
|
||||
|
||||
it 'returns an error' do
|
||||
subject.tap { expect(mutation_response_errors).to include(/Package name pattern has already been taken/) }
|
||||
end
|
||||
|
||||
context 'when field `package_name_pattern` is different than existing one' do
|
||||
let(:kwargs) do
|
||||
# The field `package_name_pattern` is unique; this is why we change the value in a minimum way
|
||||
super().merge!(package_name_pattern: "#{existing_package_protection_rule.package_name_pattern}-unique")
|
||||
end
|
||||
|
||||
it 'does not create any package protection rules' do
|
||||
expect { subject }.to change { Packages::Protection::Rule.count }.by(0)
|
||||
it_behaves_like 'a successful response'
|
||||
end
|
||||
|
||||
expect(Packages::Protection::Rule.where(project: project)).not_to exist
|
||||
end
|
||||
context 'when field `push_protected_up_to_access_level` is different than existing one' do
|
||||
let(:kwargs) { super().merge!(push_protected_up_to_access_level: 'DEVELOPER') }
|
||||
|
||||
it 'returns error of disabled feature flag' do
|
||||
subject.tap { expect_graphql_errors_to_include(/'packages_protected_packages' feature flag is disabled/) }
|
||||
it_behaves_like 'an erroneous response'
|
||||
|
||||
it 'returns an error' do
|
||||
subject.tap { expect(mutation_response_errors).to include(/Package name pattern has already been taken/) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when user does not have permission' do
|
||||
let_it_be(:anonymous) { create(:user) }
|
||||
let_it_be(:developer) { create(:user).tap { |u| project.add_developer(u) } }
|
||||
let_it_be(:guest) { create(:user).tap { |u| project.add_guest(u) } }
|
||||
let_it_be(:reporter) { create(:user).tap { |u| project.add_reporter(u) } }
|
||||
|
||||
where(:user) do
|
||||
[ref(:developer), ref(:reporter), ref(:guest), ref(:anonymous)]
|
||||
end
|
||||
|
||||
with_them do
|
||||
it_behaves_like 'an erroneous response'
|
||||
|
||||
it 'returns an error' do
|
||||
subject.tap { expect_graphql_errors_to_include(/you don't have permission to perform this action/) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context "when feature flag ':packages_protected_packages' disabled" do
|
||||
before do
|
||||
stub_feature_flags(packages_protected_packages: false)
|
||||
end
|
||||
|
||||
it_behaves_like 'an erroneous response'
|
||||
|
||||
it 'returns error of disabled feature flag' do
|
||||
subject.tap { expect_graphql_errors_to_include(/'packages_protected_packages' feature flag is disabled/) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7213,10 +7213,10 @@ graphql@^15.7.2:
|
|||
resolved "https://registry.yarnpkg.com/graphql/-/graphql-15.7.2.tgz#85ab0eeb83722977151b3feb4d631b5f2ab287ef"
|
||||
integrity sha512-AnnKk7hFQFmU/2I9YSQf3xw44ctnSFCfp3zE0N6W174gqe9fWG/2rKaKxROK7CcI3XtERpjEKFqts8o319Kf7A==
|
||||
|
||||
gridstack@^9.3.0:
|
||||
version "9.3.0"
|
||||
resolved "https://registry.yarnpkg.com/gridstack/-/gridstack-9.3.0.tgz#0f86cb8aabc3249e340900a5d9505e37e6d7c85e"
|
||||
integrity sha512-IamRPgMK0AyFsGefosPfz3i6ehNfbx7mVsZDumEbsGeN2BDZt15Ae6AOowl9D5I6d6c0mhQyYoifAfykefXf1g==
|
||||
gridstack@^9.4.0:
|
||||
version "9.4.0"
|
||||
resolved "https://registry.yarnpkg.com/gridstack/-/gridstack-9.4.0.tgz#806b5f8dc2d52ac6aade5d5fc799979a167f6977"
|
||||
integrity sha512-4dcXGT5IzWfLxJIj4oGZPohgYfHrbdNHenRwwApzialkG2bVd9J9NmcdZsRFX6Q4cANqR0M56yF2Km2FAQkVCw==
|
||||
|
||||
gzip-size@^6.0.0:
|
||||
version "6.0.0"
|
||||
|
|
|
|||
Loading…
Reference in New Issue