Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-09-17 12:12:06 +00:00
parent 877f19a2a1
commit bb5c4817e5
48 changed files with 741 additions and 356 deletions

View file

@ -2,6 +2,13 @@
documentation](doc/development/changelog.md) for instructions on adding your own
entry.
## 14.2.4 (2021-09-17)
### Fixed (2 changes)
- [Fix Elastic::MigrationWorker current_migration (2nd attempt)](gitlab-org/gitlab@65bf8636d35edc6f580c7f09e1ffafc46ca5fbdb) ([merge request](gitlab-org/gitlab!70494)) **GitLab Enterprise Edition**
- [Removes cleanup job from Terraform.latest](gitlab-org/gitlab@6085d73d1a88aa98310f775fe2ff74584948e1a9) ([merge request](gitlab-org/gitlab!70494))
## 14.2.3 (2021-09-01)
### Fixed (4 changes)

View file

@ -96,12 +96,23 @@ export default {
}
},
},
i18n: {
project: __('Project'),
privateForkSelected: __(
"To protect this issue's confidentiality, a private fork of this project was selected.",
),
noForks: __('No forks are available to you.'),
forkTheProject: __(
`To protect this issue's confidentiality, %{linkStart}fork this project%{linkEnd} and set the fork's visibility to private.`,
),
readMore: __('Read more'),
},
};
</script>
<template>
<div class="confidential-merge-request-fork-group form-group">
<label>{{ __('Project') }}</label>
<label>{{ $options.i18n.project }}</label>
<div>
<dropdown
v-if="projects.length"
@ -111,25 +122,13 @@ export default {
/>
<p class="text-muted mt-1 mb-0">
<template v-if="projects.length">
{{
__(
"To protect this issue's confidentiality, a private fork of this project was selected.",
)
}}
{{ $options.i18n.privateForkSelected }}
</template>
<template v-else>
{{ __('No forks are available to you.') }}<br />
<gl-sprintf
:message="
__(
`To protect this issue's confidentiality, %{forkLink} and set the fork's visibility to private.`,
)
"
>
<template #forkLink>
<a :href="newForkPath" target="_blank" class="help-link">{{
__('fork this project')
}}</a>
{{ $options.i18n.noForks }}<br />
<gl-sprintf :message="$options.i18n.forkTheProject">
<template #link="{ content }">
<a :href="newForkPath" target="_blank" class="help-link">{{ content }}</a>
</template>
</gl-sprintf>
</template>
@ -138,7 +137,7 @@ export default {
class="w-auto p-0 d-inline-block text-primary bg-transparent"
target="_blank"
>
<span class="sr-only">{{ __('Read more') }}</span>
<span class="sr-only">{{ $options.i18n.readMore }}</span>
<gl-icon name="question-o" />
</gl-link>
</p>

View file

@ -5,7 +5,7 @@ import { throttle, isEmpty } from 'lodash';
import { mapGetters, mapState, mapActions } from 'vuex';
import CodeQualityWalkthrough from '~/code_quality_walkthrough/components/step.vue';
import { isScrolledToBottom } from '~/lib/utils/scroll_utils';
import { sprintf } from '~/locale';
import { __, sprintf } from '~/locale';
import CiHeader from '~/vue_shared/components/header_ci_component.vue';
import delayedJobMixin from '../mixins/delayed_job_mixin';
import EmptyState from './empty_state.vue';
@ -126,6 +126,9 @@ export default {
shouldRenderCodeQualityWalkthrough() {
return this.job.status.group === 'failed-with-warnings';
},
itemName() {
return sprintf(__('Job %{jobName}'), { jobName: this.job.name });
},
},
watch: {
// Once the job log is loaded,
@ -205,12 +208,11 @@ export default {
<div class="build-header top-area">
<ci-header
:status="job.status"
:item-id="job.id"
:time="headerTime"
:user="job.user"
:has-sidebar-button="true"
:should-render-triggered-label="shouldRenderTriggeredLabel"
:item-name="__('Job')"
:item-name="itemName"
@clickedSidebarButton="toggleSidebar"
/>
</div>

View file

@ -1,35 +1,24 @@
<script>
import { GlLink, GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale';
import Composer from '~/packages_and_registries/package_registry/components/details/metadata/composer.vue';
import Conan from '~/packages_and_registries/package_registry/components/details/metadata/conan.vue';
import Maven from '~/packages_and_registries/package_registry/components/details/metadata/maven.vue';
import Nuget from '~/packages_and_registries/package_registry/components/details/metadata/nuget.vue';
import Pypi from '~/packages_and_registries/package_registry/components/details/metadata/pypi.vue';
import {
PACKAGE_TYPE_NUGET,
PACKAGE_TYPE_COMPOSER,
PACKAGE_TYPE_CONAN,
PACKAGE_TYPE_MAVEN,
PACKAGE_TYPE_COMPOSER,
PACKAGE_TYPE_NUGET,
PACKAGE_TYPE_PYPI,
} from '~/packages_and_registries/package_registry/constants';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
export default {
i18n: {
sourceText: s__('PackageRegistry|Source project located at %{link}'),
licenseText: s__('PackageRegistry|License information located at %{link}'),
recipeText: s__('PackageRegistry|Recipe: %{recipe}'),
appGroup: s__('PackageRegistry|App group: %{group}'),
appName: s__('PackageRegistry|App name: %{name}'),
targetShaCopyButton: s__('PackageRegistry|Copy target SHA'),
targetSha: s__('PackageRegistry|Target SHA: %{sha}'),
composerJson: s__(
'PackageRegistry|Composer.json with license: %{license} and version: %{version}',
),
requiredPython: s__('PackageRegistry|Required Python: %{pythonVersion}'),
},
components: {
DetailsRow,
GlLink,
GlSprintf,
ClipboardButton,
Composer,
Conan,
Maven,
Nuget,
Pypi,
},
props: {
packageEntity: {
@ -38,31 +27,17 @@ export default {
},
},
computed: {
metadataComponent() {
return {
[PACKAGE_TYPE_COMPOSER]: Composer,
[PACKAGE_TYPE_CONAN]: Conan,
[PACKAGE_TYPE_MAVEN]: Maven,
[PACKAGE_TYPE_NUGET]: Nuget,
[PACKAGE_TYPE_PYPI]: Pypi,
}[this.packageEntity.packageType];
},
showMetadata() {
return (
[
PACKAGE_TYPE_NUGET,
PACKAGE_TYPE_CONAN,
PACKAGE_TYPE_MAVEN,
PACKAGE_TYPE_COMPOSER,
PACKAGE_TYPE_PYPI,
].includes(this.packageEntity.packageType) && this.packageEntity.metadata
);
},
showNugetMetadata() {
return this.packageEntity.packageType === PACKAGE_TYPE_NUGET;
},
showConanMetadata() {
return this.packageEntity.packageType === PACKAGE_TYPE_CONAN;
},
showMavenMetadata() {
return this.packageEntity.packageType === PACKAGE_TYPE_MAVEN;
},
showComposerMetadata() {
return this.packageEntity.packageType === PACKAGE_TYPE_COMPOSER;
},
showPypiMetadata() {
return this.packageEntity.packageType === PACKAGE_TYPE_PYPI;
return this.metadataComponent && this.packageEntity.metadata;
},
},
};
@ -71,95 +46,12 @@ export default {
<template>
<div v-if="showMetadata">
<h3 class="gl-font-lg" data-testid="title">{{ __('Additional Metadata') }}</h3>
<div class="gl-bg-gray-50 gl-inset-border-1-gray-100 gl-rounded-base" data-testid="main">
<template v-if="showNugetMetadata">
<details-row icon="project" padding="gl-p-4" dashed data-testid="nuget-source">
<gl-sprintf :message="$options.i18n.sourceText">
<template #link>
<gl-link :href="packageEntity.metadata.projectUrl" target="_blank">{{
packageEntity.metadata.projectUrl
}}</gl-link>
</template>
</gl-sprintf>
</details-row>
<details-row icon="license" padding="gl-p-4" data-testid="nuget-license">
<gl-sprintf :message="$options.i18n.licenseText">
<template #link>
<gl-link :href="packageEntity.metadata.licenseUrl" target="_blank">{{
packageEntity.metadata.licenseUrl
}}</gl-link>
</template>
</gl-sprintf>
</details-row>
</template>
<details-row
v-else-if="showConanMetadata"
icon="information-o"
padding="gl-p-4"
data-testid="conan-recipe"
>
<gl-sprintf :message="$options.i18n.recipeText">
<template #recipe>{{ packageEntity.metadata.recipe }}</template>
</gl-sprintf>
</details-row>
<template v-else-if="showMavenMetadata">
<details-row icon="information-o" padding="gl-p-4" dashed data-testid="maven-app">
<gl-sprintf :message="$options.i18n.appName">
<template #name>
<strong>{{ packageEntity.metadata.appName }}</strong>
</template>
</gl-sprintf>
</details-row>
<details-row icon="information-o" padding="gl-p-4" data-testid="maven-group">
<gl-sprintf :message="$options.i18n.appGroup">
<template #group>
<strong>{{ packageEntity.metadata.appGroup }}</strong>
</template>
</gl-sprintf>
</details-row>
</template>
<template v-else-if="showComposerMetadata">
<details-row icon="information-o" padding="gl-p-4" dashed data-testid="composer-target-sha">
<gl-sprintf :message="$options.i18n.targetSha">
<template #sha>
<strong>{{ packageEntity.metadata.targetSha }}</strong>
<clipboard-button
:title="$options.i18n.targetShaCopyButton"
:text="packageEntity.metadata.targetSha"
category="tertiary"
css-class="gl-p-0!"
/>
</template>
</gl-sprintf>
</details-row>
<details-row icon="information-o" padding="gl-p-4" data-testid="composer-json">
<gl-sprintf :message="$options.i18n.composerJson">
<template #license>
<strong>{{ packageEntity.metadata.composerJson.license }}</strong>
</template>
<template #version>
<strong>{{ packageEntity.metadata.composerJson.version }}</strong>
</template>
</gl-sprintf>
</details-row>
</template>
<details-row
v-else-if="showPypiMetadata"
icon="information-o"
padding="gl-p-4"
data-testid="pypi-required-python"
>
<gl-sprintf :message="$options.i18n.requiredPython">
<template #pythonVersion>
<strong>{{ packageEntity.metadata.requiredPython }}</strong>
</template>
</gl-sprintf>
</details-row>
<component
:is="metadataComponent"
:package-entity="packageEntity"
data-testid="component-is"
/>
</div>
</div>
</template>

View file

@ -0,0 +1,55 @@
<script>
import { GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
export default {
i18n: {
targetShaCopyButton: s__('PackageRegistry|Copy target SHA'),
targetSha: s__('PackageRegistry|Target SHA: %{sha}'),
composerJson: s__(
'PackageRegistry|Composer.json with license: %{license} and version: %{version}',
),
},
components: {
DetailsRow,
GlSprintf,
ClipboardButton,
},
props: {
packageEntity: {
type: Object,
required: true,
},
},
};
</script>
<template>
<div>
<details-row icon="information-o" padding="gl-p-4" dashed data-testid="composer-target-sha">
<gl-sprintf :message="$options.i18n.targetSha">
<template #sha>
<strong>{{ packageEntity.metadata.targetSha }}</strong>
<clipboard-button
:title="$options.i18n.targetShaCopyButton"
:text="packageEntity.metadata.targetSha"
category="tertiary"
css-class="gl-p-0!"
/>
</template>
</gl-sprintf>
</details-row>
<details-row icon="information-o" padding="gl-p-4" data-testid="composer-json">
<gl-sprintf :message="$options.i18n.composerJson">
<template #license>
<strong>{{ packageEntity.metadata.composerJson.license }}</strong>
</template>
<template #version>
<strong>{{ packageEntity.metadata.composerJson.version }}</strong>
</template>
</gl-sprintf>
</details-row>
</div>
</template>

View file

@ -0,0 +1,32 @@
<script>
import { GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
export default {
i18n: {
recipeText: s__('PackageRegistry|Recipe: %{recipe}'),
},
components: {
DetailsRow,
GlSprintf,
},
props: {
packageEntity: {
type: Object,
required: true,
},
},
};
</script>
<template>
<div>
<details-row icon="information-o" padding="gl-p-4" data-testid="conan-recipe">
<gl-sprintf :message="$options.i18n.recipeText">
<template #recipe>{{ packageEntity.metadata.recipe }}</template>
</gl-sprintf>
</details-row>
</div>
</template>

View file

@ -0,0 +1,42 @@
<script>
import { GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
export default {
i18n: {
appGroup: s__('PackageRegistry|App group: %{group}'),
appName: s__('PackageRegistry|App name: %{name}'),
},
components: {
DetailsRow,
GlSprintf,
},
props: {
packageEntity: {
type: Object,
required: true,
},
},
};
</script>
<template>
<div>
<details-row icon="information-o" padding="gl-p-4" dashed data-testid="maven-app">
<gl-sprintf :message="$options.i18n.appName">
<template #name>
<strong>{{ packageEntity.metadata.appName }}</strong>
</template>
</gl-sprintf>
</details-row>
<details-row icon="information-o" padding="gl-p-4" data-testid="maven-group">
<gl-sprintf :message="$options.i18n.appGroup">
<template #group>
<strong>{{ packageEntity.metadata.appGroup }}</strong>
</template>
</gl-sprintf>
</details-row>
</div>
</template>

View file

@ -0,0 +1,46 @@
<script>
import { GlLink, GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
export default {
i18n: {
sourceText: s__('PackageRegistry|Source project located at %{link}'),
licenseText: s__('PackageRegistry|License information located at %{link}'),
},
components: {
DetailsRow,
GlLink,
GlSprintf,
},
props: {
packageEntity: {
type: Object,
required: true,
},
},
};
</script>
<template>
<div>
<details-row icon="project" padding="gl-p-4" dashed data-testid="nuget-source">
<gl-sprintf :message="$options.i18n.sourceText">
<template #link>
<gl-link :href="packageEntity.metadata.projectUrl" target="_blank">{{
packageEntity.metadata.projectUrl
}}</gl-link>
</template>
</gl-sprintf>
</details-row>
<details-row icon="license" padding="gl-p-4" data-testid="nuget-license">
<gl-sprintf :message="$options.i18n.licenseText">
<template #link>
<gl-link :href="packageEntity.metadata.licenseUrl" target="_blank">{{
packageEntity.metadata.licenseUrl
}}</gl-link>
</template>
</gl-sprintf>
</details-row>
</div>
</template>

View file

@ -0,0 +1,34 @@
<script>
import { GlSprintf } from '@gitlab/ui';
import { s__ } from '~/locale';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
export default {
i18n: {
requiredPython: s__('PackageRegistry|Required Python: %{pythonVersion}'),
},
components: {
DetailsRow,
GlSprintf,
},
props: {
packageEntity: {
type: Object,
required: true,
},
},
};
</script>
<template>
<div>
<details-row icon="information-o" padding="gl-p-4" data-testid="pypi-required-python">
<gl-sprintf :message="$options.i18n.requiredPython">
<template #pythonVersion>
<strong>{{ packageEntity.metadata.requiredPython }}</strong>
</template>
</gl-sprintf>
</details-row>
</div>
</template>

View file

@ -218,7 +218,7 @@ export default {
:status="pipeline.detailedStatus"
:time="pipeline.createdAt"
:user="pipeline.user"
:item-id="Number(pipelineId)"
:item-id="pipelineId"
item-name="Pipeline"
>
<gl-button

View file

@ -37,8 +37,9 @@ export default {
required: true,
},
itemId: {
type: Number,
required: true,
type: String,
required: false,
default: '',
},
time: {
type: String,
@ -86,6 +87,13 @@ export default {
message() {
return this.user?.status?.message;
},
item() {
if (this.itemId) {
return `${this.itemName} #${this.itemId}`;
}
return this.itemName;
},
},
methods: {
@ -106,7 +114,7 @@ export default {
<section class="header-main-content gl-mr-3">
<ci-icon-badge :status="status" />
<strong data-testid="ci-header-item-text"> {{ itemName }} #{{ itemId }} </strong>
<strong data-testid="ci-header-item-text">{{ item }}</strong>
<template v-if="shouldRenderTriggeredLabel">{{ __('triggered') }}</template>
<template v-else>{{ __('created') }}</template>

View file

@ -276,6 +276,10 @@ $well-inner-border: $gray-200;
color: $gray-900;
}
.gl-label-text-dark.gl-label-text-dark {
color: $gray-10;
}
// This applies to "gl-labels" from "gitlab-ui"
.gl-label.gl-label-scoped.gl-label-text-dark,
.gl-label.gl-label-scoped.gl-label-text-light {

View file

@ -135,21 +135,21 @@ module RelativePositioning
before, after = [before, after].sort_by(&:relative_position) if before && after
RelativePositioning.mover.move(self, before, after)
rescue ActiveRecord::QueryCanceled, NoSpaceLeft => e
rescue NoSpaceLeft => e
could_not_move(e)
raise e
end
def move_after(before = self)
RelativePositioning.mover.move(self, before, nil)
rescue ActiveRecord::QueryCanceled, NoSpaceLeft => e
rescue NoSpaceLeft => e
could_not_move(e)
raise e
end
def move_before(after = self)
RelativePositioning.mover.move(self, nil, after)
rescue ActiveRecord::QueryCanceled, NoSpaceLeft => e
rescue NoSpaceLeft => e
could_not_move(e)
raise e
end
@ -159,9 +159,6 @@ module RelativePositioning
rescue NoSpaceLeft => e
could_not_move(e)
self.relative_position = MAX_POSITION
rescue ActiveRecord::QueryCanceled => e
could_not_move(e)
raise e
end
def move_to_start
@ -169,9 +166,6 @@ module RelativePositioning
rescue NoSpaceLeft => e
could_not_move(e)
self.relative_position = MIN_POSITION
rescue ActiveRecord::QueryCanceled => e
could_not_move(e)
raise e
end
# This method is used during rebalancing - override it to customise the update

View file

@ -99,6 +99,7 @@
= f.text_field :pronouns, class: 'input-md gl-form-input', help: s_("Profiles|Enter your pronouns to let people know how to refer to you")
= f.text_field :pronunciation, class: 'input-md gl-form-input', help: s_("Profiles|Enter how your name is pronounced to help people address you correctly")
= render_if_exists 'profiles/extra_settings', form: f
= render_if_exists 'profiles/email_settings', form: f
= f.text_field :skype, class: 'input-md gl-form-input', placeholder: s_("Profiles|username")
= f.text_field :linkedin, class: 'input-md gl-form-input', help: s_("Profiles|Your LinkedIn profile name from linkedin.com/in/profilename")

View file

@ -6,6 +6,9 @@ comments: false
description: 'Making a GitLab codebase composable - allowing to run parts of the application'
---
NOTE:
Due to our focus on improving the overall availability of GitLab.com and reducing tech debt, we do not have capacity to act on this blueprint. We will re-evaluate in Q1-FY23.
# Composable GitLab codebase - using Rails Engines
The one of the major risks of a single codebase is an infinite growth of the whole

View file

@ -532,7 +532,7 @@ Example:
```ruby
field :foo, GraphQL::Types::String,
null: true,
description: 'Some test field. Will always return `null`' \
description: 'Some test field. Returns `null`' \
'if `my_feature_flag` feature flag is disabled.'
def foo

View file

@ -234,6 +234,14 @@ To resolve this issue:
[Contact GitLab Support](https://about.gitlab.com/support/) if none of these reasons apply.
### `410 : Gone` error when connecting to Jira
When you connect to Jira and synchronize repositories, you may receive a `410 : Gone` error.
This issue occurs when you use the Jira DVCS connector and your integration is configured to use **GitHub Enterprise**.
For more information and possible fixes, see [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/340160).
### Fix synchronization issues
If Jira displays incorrect information, such as deleted branches, you may have to

View file

@ -22,7 +22,7 @@ To access Sidekiq job size limits:
1. On the left sidebar, select **Settings > Preferences**.
1. Expand **Sidekiq job size limits**.
1. Adjust the compression threshold or size limit. The compression can
be disabled by selecting "Track" mode.
be disabled by selecting the **Track** mode.
## Available settings

View file

@ -15,7 +15,7 @@ module GemExtensions
def scope
if disable_joins
DisableJoins::Associations::AssociationScope.create.scope(self)
::GemExtensions::ActiveRecord::DisableJoins::Associations::AssociationScope.create.scope(self)
else
super
end
@ -25,7 +25,7 @@ module GemExtensions
if klass
@association_scope ||= begin # rubocop:disable Gitlab/ModuleWithInstanceVariables
if disable_joins
DisableJoins::Associations::AssociationScope.scope(self)
::GemExtensions::ActiveRecord::DisableJoins::Associations::AssociationScope.scope(self)
else
super
end

View file

@ -64,7 +64,7 @@ module GemExtensions
end
if scope.order_values.empty? && ordered
split_scope = DisableJoins::Relation.create(scope.klass, key, join_ids)
split_scope = ::GemExtensions::ActiveRecord::DisableJoins::Relation.create(scope.klass, key, join_ids)
split_scope.where_clause += scope.where_clause
split_scope
else

View file

@ -41,9 +41,9 @@
echo "Adopting Helm v2 manifests from $release"
# some resource kinds must be listed explicitly https://github.com/kubernetes/kubernetes/issues/42885
for name in $(kubectl -n "$KUBE_NAMESPACE" get all,ingress,daemonset -o name -l chart="$chart"); do
kubectl annotate --overwrite "$name" meta.helm.sh/release-name="$release"
kubectl annotate --overwrite "$name" meta.helm.sh/release-namespace="$KUBE_NAMESPACE"
kubectl label --overwrite "$name" app.kubernetes.io/managed-by=Helm
kubectl annotate -n "$KUBE_NAMESPACE" --overwrite "$name" meta.helm.sh/release-name="$release"
kubectl annotate -n "$KUBE_NAMESPACE" --overwrite "$name" meta.helm.sh/release-namespace="$KUBE_NAMESPACE"
kubectl label -n "$KUBE_NAMESPACE" --overwrite "$name" app.kubernetes.io/managed-by=Helm
done
done
# migrate each release

View file

@ -19351,6 +19351,9 @@ msgstr ""
msgid "Job"
msgstr ""
msgid "Job %{jobName}"
msgstr ""
msgid "Job Failed #%{build_id}"
msgstr ""
@ -35307,7 +35310,7 @@ msgstr ""
msgid "To preserve performance only %{strong_open}%{display_size} of %{real_size}%{strong_close} files are displayed."
msgstr ""
msgid "To protect this issue's confidentiality, %{forkLink} and set the fork's visibility to private."
msgid "To protect this issue's confidentiality, %{linkStart}fork this project%{linkEnd} and set the fork's visibility to private."
msgstr ""
msgid "To protect this issue's confidentiality, a private fork of this project was selected."
@ -39911,9 +39914,6 @@ msgstr ""
msgid "fork"
msgstr ""
msgid "fork this project"
msgstr ""
msgid "from"
msgstr ""

View file

@ -57,7 +57,7 @@
"@gitlab/favicon-overlay": "2.0.0",
"@gitlab/svgs": "1.212.0",
"@gitlab/tributejs": "1.0.0",
"@gitlab/ui": "32.10.2",
"@gitlab/ui": "32.11.0",
"@gitlab/visual-review-tools": "1.6.1",
"@rails/actioncable": "6.1.3-2",
"@rails/ujs": "6.1.3-2",

View file

@ -90,7 +90,7 @@ RSpec.describe 'Project Jobs Permissions' do
it_behaves_like 'recent job page details responds with status', 200 do
it 'renders job details', :js do
expect(page).to have_content "Job ##{job.id}"
expect(page).to have_content "Job #{job.name}"
expect(page).to have_css '.log-line'
end
end

View file

@ -21,7 +21,7 @@ RSpec.describe 'User browses a job', :js do
it 'erases the job log', :js do
wait_for_requests
expect(page).to have_content("Job ##{build.id}")
expect(page).to have_content("Job #{build.name}")
expect(page).to have_css('.job-log')
# scroll to the top of the page first

View file

@ -55,7 +55,10 @@ exports[`Alert integration settings form default state should match the default
data-qa-selector="incident_templates_dropdown"
headertext=""
hideheaderborder="true"
highlighteditemstitle="Selected"
highlighteditemstitleclass="gl-px-5"
id="alert-integration-settings-issue-template"
showhighlighteditemstitle="true"
size="medium"
text="selecte_tmpl"
variant="default"

View file

@ -46,11 +46,27 @@ exports[`Remove cluster confirmation modal renders splitbutton with modal includ
>
<!---->
<!---->
<div
class="gl-display-flex gl-flex-direction-row gl-justify-content-space-between gl-align-items-center gl-px-5"
>
<div
class="gl-display-flex"
>
<!---->
</div>
<div
class="gl-display-flex"
>
<!---->
</div>
</div>
<div
class="gl-new-dropdown-contents"
>
<!---->
<li
class="gl-new-dropdown-item"
role="presentation"

View file

@ -17,11 +17,15 @@ exports[`Confidential merge request project form group component renders empty s
No forks are available to you.
<br />
<gl-sprintf-stub
message="To protect this issue's confidentiality, %{forkLink} and set the fork's visibility to private."
/>
To protect this issue's confidentiality,
<a
class="help-link"
href="https://test.com"
target="_blank"
>
fork this project
</a>
and set the fork's visibility to private.
<gl-link-stub
class="w-auto p-0 d-inline-block text-primary bg-transparent"
href="/help"
@ -52,18 +56,16 @@ exports[`Confidential merge request project form group component renders fork dr
</label>
<div>
<!---->
<dropdown-stub
projects="[object Object],[object Object]"
selectedproject="[object Object]"
/>
<p
class="text-muted mt-1 mb-0"
>
No forks are available to you.
<br />
<gl-sprintf-stub
message="To protect this issue's confidentiality, %{forkLink} and set the fork's visibility to private."
/>
To protect this issue's confidentiality, a private fork of this project was selected.
<gl-link-stub
class="w-auto p-0 d-inline-block text-primary bg-transparent"

View file

@ -1,3 +1,4 @@
import { GlSprintf } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import MockAdapter from 'axios-mock-adapter';
import ProjectFormGroup from '~/confidential_merge_request/components/project_form_group.vue';
@ -21,55 +22,52 @@ const mockData = [
},
},
];
let vm;
let wrapper;
let mock;
function factory(projects = mockData) {
mock = new MockAdapter(axios);
mock.onGet(/api\/(.*)\/projects\/gitlab-org%2Fgitlab-ce\/forks/).reply(200, projects);
vm = shallowMount(ProjectFormGroup, {
wrapper = shallowMount(ProjectFormGroup, {
propsData: {
namespacePath: 'gitlab-org',
projectPath: 'gitlab-org/gitlab-ce',
newForkPath: 'https://test.com',
helpPagePath: '/help',
},
stubs: { GlSprintf },
});
return axios.waitForAll();
}
describe('Confidential merge request project form group component', () => {
afterEach(() => {
mock.restore();
vm.destroy();
wrapper.destroy();
});
it('renders fork dropdown', () => {
factory();
it('renders fork dropdown', async () => {
await factory();
return vm.vm.$nextTick(() => {
expect(vm.element).toMatchSnapshot();
expect(wrapper.element).toMatchSnapshot();
});
it('sets selected project as first fork', async () => {
await factory();
expect(wrapper.vm.selectedProject).toEqual({
id: 1,
name: 'root / gitlab-ce',
pathWithNamespace: 'root/gitlab-ce',
namespaceFullpath: 'root',
});
});
it('sets selected project as first fork', () => {
factory();
it('renders empty state when response is empty', async () => {
await factory([]);
return vm.vm.$nextTick(() => {
expect(vm.vm.selectedProject).toEqual({
id: 1,
name: 'root / gitlab-ce',
pathWithNamespace: 'root/gitlab-ce',
namespaceFullpath: 'root',
});
});
});
it('renders empty state when response is empty', () => {
factory([]);
return vm.vm.$nextTick(() => {
expect(vm.element).toMatchSnapshot();
});
expect(wrapper.element).toMatchSnapshot();
});
});

View file

@ -11,8 +11,16 @@ exports[`content_editor/components/toolbar_link_button renders dropdown componen
<ul role=\\"menu\\" tabindex=\\"-1\\" class=\\"dropdown-menu\\">
<div class=\\"gl-new-dropdown-inner\\">
<!---->
<!---->
<div class=\\"gl-display-flex gl-flex-direction-row gl-justify-content-space-between gl-align-items-center gl-px-5\\">
<div class=\\"gl-display-flex\\">
<!---->
</div>
<div class=\\"gl-display-flex\\">
<!---->
</div>
</div>
<div class=\\"gl-new-dropdown-contents\\">
<!---->
<li role=\\"presentation\\" class=\\"gl-px-3!\\">
<form tabindex=\\"-1\\" class=\\"b-dropdown-form gl-p-0\\">
<div placeholder=\\"Link URL\\">

View file

@ -6,8 +6,11 @@ exports[`Design management design version dropdown component renders design vers
clearalltext="Clear all"
headertext=""
hideheaderborder="true"
highlighteditemstitle="Selected"
highlighteditemstitleclass="gl-px-5"
issueiid=""
projectpath=""
showhighlighteditemstitle="true"
size="small"
text="Showing latest version"
variant="default"
@ -84,8 +87,11 @@ exports[`Design management design version dropdown component renders design vers
clearalltext="Clear all"
headertext=""
hideheaderborder="true"
highlighteditemstitle="Selected"
highlighteditemstitleclass="gl-px-5"
issueiid=""
projectpath=""
showhighlighteditemstitle="true"
size="small"
text="Showing latest version"
variant="default"

View file

@ -127,11 +127,27 @@ exports[`JiraImportForm table body shows correct information in each cell 1`] =
>
<!---->
<!---->
<div
class="gl-display-flex gl-flex-direction-row gl-justify-content-space-between gl-align-items-center gl-px-5"
>
<div
class="gl-display-flex"
>
<!---->
</div>
<div
class="gl-display-flex"
>
<!---->
</div>
</div>
<div
class="gl-new-dropdown-contents"
>
<!---->
<div
class="gl-search-box-by-type"
>
@ -256,11 +272,27 @@ exports[`JiraImportForm table body shows correct information in each cell 1`] =
>
<!---->
<!---->
<div
class="gl-display-flex gl-flex-direction-row gl-justify-content-space-between gl-align-items-center gl-px-5"
>
<div
class="gl-display-flex"
>
<!---->
</div>
<div
class="gl-display-flex"
>
<!---->
</div>
</div>
<div
class="gl-new-dropdown-contents"
>
<!---->
<div
class="gl-search-box-by-type"
>

View file

@ -140,7 +140,7 @@ describe('Job App', () => {
it('should render provided job information', () => {
expect(wrapper.find('.header-main-content').text().replace(/\s+/g, ' ').trim()).toContain(
'passed Job #4757 triggered 1 year ago by Root',
'passed Job test triggered 1 year ago by Root',
);
});
@ -154,7 +154,7 @@ describe('Job App', () => {
setupAndMount().then(() => {
expect(
wrapper.find('.header-main-content').text().replace(/\s+/g, ' ').trim(),
).toContain('passed Job #4757 created 3 weeks ago by Root');
).toContain('passed Job test created 3 weeks ago by Root');
}));
});
});

View file

@ -40,8 +40,11 @@ exports[`Dashboard template matches the default snapshot 1`] = `
data-qa-selector="environments_dropdown"
headertext=""
hideheaderborder="true"
highlighteditemstitle="Selected"
highlighteditemstitleclass="gl-px-5"
id="monitor-environments-dropdown"
menu-class="monitor-environment-dropdown-menu"
showhighlighteditemstitle="true"
size="medium"
text="production"
toggleclass="dropdown-menu-toggle"

View file

@ -1,4 +1,3 @@
import { GlLink, GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import {
conanMetadata,
@ -17,8 +16,6 @@ import {
PACKAGE_TYPE_COMPOSER,
PACKAGE_TYPE_PYPI,
} from '~/packages_and_registries/package_registry/constants';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
const mavenPackage = { packageType: PACKAGE_TYPE_MAVEN, metadata: mavenMetadata() };
const conanPackage = { packageType: PACKAGE_TYPE_CONAN, metadata: conanMetadata() };
@ -39,8 +36,7 @@ describe('Package Additional Metadata', () => {
wrapper = shallowMountExtended(component, {
propsData: { ...defaultProps, ...props },
stubs: {
DetailsRow,
GlSprintf,
component: { template: '<div data-testid="component-is"></div>' },
},
});
};
@ -52,16 +48,7 @@ describe('Package Additional Metadata', () => {
const findTitle = () => wrapper.findByTestId('title');
const findMainArea = () => wrapper.findByTestId('main');
const findNugetSource = () => wrapper.findByTestId('nuget-source');
const findNugetLicense = () => wrapper.findByTestId('nuget-license');
const findConanRecipe = () => wrapper.findByTestId('conan-recipe');
const findMavenApp = () => wrapper.findByTestId('maven-app');
const findMavenGroup = () => wrapper.findByTestId('maven-group');
const findElementLink = (container) => container.findComponent(GlLink);
const findComposerTargetSha = () => wrapper.findByTestId('composer-target-sha');
const findComposerTargetShaCopyButton = () => wrapper.findComponent(ClipboardButton);
const findComposerJson = () => wrapper.findByTestId('composer-json');
const findPypiRequiredPython = () => wrapper.findByTestId('pypi-required-python');
const findComponentIs = () => wrapper.findByTestId('component-is');
it('has the correct title', () => {
mountComponent();
@ -87,98 +74,11 @@ describe('Package Additional Metadata', () => {
expect(findTitle().exists()).toBe(visible);
expect(findMainArea().exists()).toBe(visible);
expect(findComponentIs().exists()).toBe(visible);
if (visible) {
expect(findComponentIs().props('packageEntity')).toEqual(packageEntity);
}
},
);
describe('nuget metadata', () => {
beforeEach(() => {
mountComponent({ packageEntity: nugetPackage });
});
it.each`
name | finderFunction | text | link | icon
${'source'} | ${findNugetSource} | ${'Source project located at projectUrl'} | ${'projectUrl'} | ${'project'}
${'license'} | ${findNugetLicense} | ${'License information located at licenseUrl'} | ${'licenseUrl'} | ${'license'}
`('$name element', ({ finderFunction, text, link, icon }) => {
const element = finderFunction();
expect(element.exists()).toBe(true);
expect(element.text()).toBe(text);
expect(element.props('icon')).toBe(icon);
expect(findElementLink(element).attributes('href')).toBe(nugetPackage.metadata[link]);
});
});
describe('conan metadata', () => {
beforeEach(() => {
mountComponent({ packageEntity: conanPackage });
});
it.each`
name | finderFunction | text | icon
${'recipe'} | ${findConanRecipe} | ${'Recipe: package-8/1.0.0@gitlab-org+gitlab-test/stable'} | ${'information-o'}
`('$name element', ({ finderFunction, text, icon }) => {
const element = finderFunction();
expect(element.exists()).toBe(true);
expect(element.text()).toBe(text);
expect(element.props('icon')).toBe(icon);
});
});
describe('maven metadata', () => {
beforeEach(() => {
mountComponent();
});
it.each`
name | finderFunction | text | icon
${'app'} | ${findMavenApp} | ${'App name: appName'} | ${'information-o'}
${'group'} | ${findMavenGroup} | ${'App group: appGroup'} | ${'information-o'}
`('$name element', ({ finderFunction, text, icon }) => {
const element = finderFunction();
expect(element.exists()).toBe(true);
expect(element.text()).toBe(text);
expect(element.props('icon')).toBe(icon);
});
});
describe('composer metadata', () => {
beforeEach(() => {
mountComponent({ packageEntity: composerPackage });
});
it.each`
name | finderFunction | text | icon
${'target-sha'} | ${findComposerTargetSha} | ${'Target SHA: b83d6e391c22777fca1ed3012fce84f633d7fed0'} | ${'information-o'}
${'composer-json'} | ${findComposerJson} | ${'Composer.json with license: MIT and version: 1.0.0'} | ${'information-o'}
`('$name element', ({ finderFunction, text, icon }) => {
const element = finderFunction();
expect(element.exists()).toBe(true);
expect(element.text()).toBe(text);
expect(element.props('icon')).toBe(icon);
});
it('target-sha has a copy button', () => {
expect(findComposerTargetShaCopyButton().exists()).toBe(true);
expect(findComposerTargetShaCopyButton().props()).toMatchObject({
text: 'b83d6e391c22777fca1ed3012fce84f633d7fed0',
title: 'Copy target SHA',
});
});
});
describe('pypi metadata', () => {
beforeEach(() => {
mountComponent({ packageEntity: pypiPackage });
});
it.each`
name | finderFunction | text | icon
${'pypi-required-python'} | ${findPypiRequiredPython} | ${'Required Python: 1.0.0'} | ${'information-o'}
`('$name element', ({ finderFunction, text, icon }) => {
const element = finderFunction();
expect(element.exists()).toBe(true);
expect(element.text()).toBe(text);
expect(element.props('icon')).toBe(icon);
});
});
});

View file

@ -0,0 +1,58 @@
import { GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import {
packageData,
composerMetadata,
} from 'jest/packages_and_registries/package_registry/mock_data';
import component from '~/packages_and_registries/package_registry/components/details/metadata/composer.vue';
import { PACKAGE_TYPE_COMPOSER } from '~/packages_and_registries/package_registry/constants';
import ClipboardButton from '~/vue_shared/components/clipboard_button.vue';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
const composerPackage = { packageType: PACKAGE_TYPE_COMPOSER, metadata: composerMetadata() };
describe('Composer Metadata', () => {
let wrapper;
const mountComponent = () => {
wrapper = shallowMountExtended(component, {
propsData: { packageEntity: packageData(composerPackage) },
stubs: {
DetailsRow,
GlSprintf,
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findComposerTargetSha = () => wrapper.findByTestId('composer-target-sha');
const findComposerTargetShaCopyButton = () => wrapper.findComponent(ClipboardButton);
const findComposerJson = () => wrapper.findByTestId('composer-json');
beforeEach(() => {
mountComponent();
});
it.each`
name | finderFunction | text | icon
${'target-sha'} | ${findComposerTargetSha} | ${'Target SHA: b83d6e391c22777fca1ed3012fce84f633d7fed0'} | ${'information-o'}
${'composer-json'} | ${findComposerJson} | ${'Composer.json with license: MIT and version: 1.0.0'} | ${'information-o'}
`('$name element', ({ finderFunction, text, icon }) => {
const element = finderFunction();
expect(element.exists()).toBe(true);
expect(element.text()).toBe(text);
expect(element.props('icon')).toBe(icon);
});
it('target-sha has a copy button', () => {
expect(findComposerTargetShaCopyButton().exists()).toBe(true);
expect(findComposerTargetShaCopyButton().props()).toMatchObject({
text: 'b83d6e391c22777fca1ed3012fce84f633d7fed0',
title: 'Copy target SHA',
});
});
});

View file

@ -0,0 +1,48 @@
import { GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import {
conanMetadata,
packageData,
} from 'jest/packages_and_registries/package_registry/mock_data';
import component from '~/packages_and_registries/package_registry/components/details/metadata/conan.vue';
import { PACKAGE_TYPE_CONAN } from '~/packages_and_registries/package_registry/constants';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
const conanPackage = { packageType: PACKAGE_TYPE_CONAN, metadata: conanMetadata() };
describe('Conan Metadata', () => {
let wrapper;
const mountComponent = () => {
wrapper = shallowMountExtended(component, {
propsData: {
packageEntity: packageData(conanPackage),
},
stubs: {
DetailsRow,
GlSprintf,
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findConanRecipe = () => wrapper.findByTestId('conan-recipe');
beforeEach(() => {
mountComponent();
});
it.each`
name | finderFunction | text | icon
${'recipe'} | ${findConanRecipe} | ${'Recipe: package-8/1.0.0@gitlab-org+gitlab-test/stable'} | ${'information-o'}
`('$name element', ({ finderFunction, text, icon }) => {
const element = finderFunction();
expect(element.exists()).toBe(true);
expect(element.text()).toBe(text);
expect(element.props('icon')).toBe(icon);
});
});

View file

@ -0,0 +1,52 @@
import { GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import {
mavenMetadata,
packageData,
} from 'jest/packages_and_registries/package_registry/mock_data';
import component from '~/packages_and_registries/package_registry/components/details/metadata/maven.vue';
import { PACKAGE_TYPE_MAVEN } from '~/packages_and_registries/package_registry/constants';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
const mavenPackage = { packageType: PACKAGE_TYPE_MAVEN, metadata: mavenMetadata() };
describe('Maven Metadata', () => {
let wrapper;
const mountComponent = () => {
wrapper = shallowMountExtended(component, {
propsData: {
packageEntity: {
...packageData(mavenPackage),
},
},
stubs: {
DetailsRow,
GlSprintf,
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findMavenApp = () => wrapper.findByTestId('maven-app');
const findMavenGroup = () => wrapper.findByTestId('maven-group');
beforeEach(() => {
mountComponent();
});
it.each`
name | finderFunction | text | icon
${'app'} | ${findMavenApp} | ${'App name: appName'} | ${'information-o'}
${'group'} | ${findMavenGroup} | ${'App group: appGroup'} | ${'information-o'}
`('$name element', ({ finderFunction, text, icon }) => {
const element = finderFunction();
expect(element.exists()).toBe(true);
expect(element.text()).toBe(text);
expect(element.props('icon')).toBe(icon);
});
});

View file

@ -0,0 +1,55 @@
import { GlLink, GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import {
nugetMetadata,
packageData,
} from 'jest/packages_and_registries/package_registry/mock_data';
import component from '~/packages_and_registries/package_registry/components/details/metadata/nuget.vue';
import { PACKAGE_TYPE_NUGET } from '~/packages_and_registries/package_registry/constants';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
const nugetPackage = { packageType: PACKAGE_TYPE_NUGET, metadata: nugetMetadata() };
describe('Nuget Metadata', () => {
let wrapper;
const mountComponent = () => {
wrapper = shallowMountExtended(component, {
propsData: {
packageEntity: {
...packageData(nugetPackage),
},
},
stubs: {
DetailsRow,
GlSprintf,
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findNugetSource = () => wrapper.findByTestId('nuget-source');
const findNugetLicense = () => wrapper.findByTestId('nuget-license');
const findElementLink = (container) => container.findComponent(GlLink);
beforeEach(() => {
mountComponent({ packageEntity: nugetPackage });
});
it.each`
name | finderFunction | text | link | icon
${'source'} | ${findNugetSource} | ${'Source project located at projectUrl'} | ${'projectUrl'} | ${'project'}
${'license'} | ${findNugetLicense} | ${'License information located at licenseUrl'} | ${'licenseUrl'} | ${'license'}
`('$name element', ({ finderFunction, text, link, icon }) => {
const element = finderFunction();
expect(element.exists()).toBe(true);
expect(element.text()).toBe(text);
expect(element.props('icon')).toBe(icon);
expect(findElementLink(element).attributes('href')).toBe(nugetPackage.metadata[link]);
});
});

View file

@ -0,0 +1,48 @@
import { GlSprintf } from '@gitlab/ui';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import { packageData, pypiMetadata } from 'jest/packages_and_registries/package_registry/mock_data';
import component from '~/packages_and_registries/package_registry/components/details/metadata/pypi.vue';
import { PACKAGE_TYPE_PYPI } from '~/packages_and_registries/package_registry/constants';
import DetailsRow from '~/vue_shared/components/registry/details_row.vue';
const pypiPackage = { packageType: PACKAGE_TYPE_PYPI, metadata: pypiMetadata() };
describe('Package Additional Metadata', () => {
let wrapper;
const mountComponent = () => {
wrapper = shallowMountExtended(component, {
propsData: {
packageEntity: {
...packageData(pypiPackage),
},
},
stubs: {
DetailsRow,
GlSprintf,
},
});
};
afterEach(() => {
wrapper.destroy();
wrapper = null;
});
const findPypiRequiredPython = () => wrapper.findByTestId('pypi-required-python');
beforeEach(() => {
mountComponent();
});
it.each`
name | finderFunction | text | icon
${'pypi-required-python'} | ${findPypiRequiredPython} | ${'Required Python: 1.0.0'} | ${'information-o'}
`('$name element', ({ finderFunction, text, icon }) => {
const element = finderFunction();
expect(element.exists()).toBe(true);
expect(element.text()).toBe(text);
expect(element.props('icon')).toBe(icon);
});
});

View file

@ -14,6 +14,9 @@ exports[`Code Coverage when fetching data is successful matches the snapshot 1`]
clearalltext="Clear all"
headertext=""
hideheaderborder="true"
highlighteditemstitle="Selected"
highlighteditemstitleclass="gl-px-5"
showhighlighteditemstitle="true"
size="medium"
text="rspec"
variant="default"

View file

@ -24,7 +24,7 @@ describe('Pipeline details header', () => {
const findLoadingIcon = () => wrapper.find(GlLoadingIcon);
const defaultProvideOptions = {
pipelineId: 14,
pipelineId: '14',
pipelineIid: 1,
paths: {
pipelinesPath: '/namespace/my-project/-/pipelines',

View file

@ -6,7 +6,10 @@ exports[`Clone Dropdown Button rendering matches the snapshot 1`] = `
clearalltext="Clear all"
headertext=""
hideheaderborder="true"
highlighteditemstitle="Selected"
highlighteditemstitleclass="gl-px-5"
right="true"
showhighlighteditemstitle="true"
size="medium"
text="Clone"
variant="info"

View file

@ -6,7 +6,10 @@ exports[`SplitButton renders actionItems 1`] = `
clearalltext="Clear all"
headertext=""
hideheaderborder="true"
highlighteditemstitle="Selected"
highlighteditemstitleclass="gl-px-5"
menu-class=""
showhighlighteditemstitle="true"
size="medium"
split="true"
text="professor"

View file

@ -16,8 +16,6 @@ describe('Header CI Component', () => {
text: 'failed',
details_path: 'path',
},
itemName: 'job',
itemId: 123,
time: '2017-05-08T14:57:39.781Z',
user: {
web_url: 'path',
@ -55,17 +53,13 @@ describe('Header CI Component', () => {
describe('render', () => {
beforeEach(() => {
createComponent();
createComponent({ itemName: 'Pipeline' });
});
it('should render status badge', () => {
expect(findIconBadge().exists()).toBe(true);
});
it('should render item name and id', () => {
expect(findHeaderItemText().text()).toBe('job #123');
});
it('should render timeago date', () => {
expect(findTimeAgo().exists()).toBe(true);
});
@ -83,9 +77,29 @@ describe('Header CI Component', () => {
});
});
describe('with item id', () => {
beforeEach(() => {
createComponent({ itemName: 'Pipeline', itemId: '123' });
});
it('should render item name and id', () => {
expect(findHeaderItemText().text()).toBe('Pipeline #123');
});
});
describe('without item id', () => {
beforeEach(() => {
createComponent({ itemName: 'Job build_job' });
});
it('should render item name', () => {
expect(findHeaderItemText().text()).toBe('Job build_job');
});
});
describe('slot', () => {
it('should render header action buttons', () => {
createComponent({}, { slots: { default: 'Test Actions' } });
createComponent({ itemName: 'Job build_job' }, { slots: { default: 'Test Actions' } });
expect(findActionButtons().exists()).toBe(true);
expect(findActionButtons().text()).toBe('Test Actions');
@ -94,7 +108,7 @@ describe('Header CI Component', () => {
describe('shouldRenderTriggeredLabel', () => {
it('should render created keyword when the shouldRenderTriggeredLabel is false', () => {
createComponent({ shouldRenderTriggeredLabel: false });
createComponent({ shouldRenderTriggeredLabel: false, itemName: 'Job build_job' });
expect(wrapper.text()).toContain('created');
expect(wrapper.text()).not.toContain('triggered');

View file

@ -1435,19 +1435,19 @@ RSpec.describe Issue do
describe 'scheduling rebalancing' do
before do
allow_next_instance_of(RelativePositioning::Mover) do |mover|
allow(mover).to receive(:move) { raise ActiveRecord::QueryCanceled }
allow(mover).to receive(:move) { raise RelativePositioning::NoSpaceLeft }
end
end
shared_examples 'schedules issues rebalancing' do
let(:issue) { build_stubbed(:issue, relative_position: 100, project: project) }
it 'schedules rebalancing if we time-out when moving' do
it 'schedules rebalancing if there is no space left' do
lhs = build_stubbed(:issue, relative_position: 99, project: project)
to_move = build(:issue, project: project)
expect(IssueRebalancingWorker).to receive(:perform_async).with(nil, project_id, namespace_id)
expect { to_move.move_between(lhs, issue) }.to raise_error(ActiveRecord::QueryCanceled)
expect { to_move.move_between(lhs, issue) }.to raise_error(RelativePositioning::NoSpaceLeft)
end
end

View file

@ -69,13 +69,19 @@ RSpec.shared_examples 'namespace traversal scopes' do
context 'when hierarchy_order is ascending' do
subject { described_class.where(id: [nested_group_1, nested_group_2]).self_and_ancestors(hierarchy_order: :asc) }
it { is_expected.to eq [nested_group_1, nested_group_2, group_1, group_2] }
# Recursive order per level is not defined.
it { is_expected.to contain_exactly(nested_group_1, nested_group_2, group_1, group_2) }
it { expect(subject[0, 2]).to contain_exactly(nested_group_1, nested_group_2) }
it { expect(subject[2, 2]).to contain_exactly(group_1, group_2) }
end
context 'when hierarchy_order is descending' do
subject { described_class.where(id: [nested_group_1, nested_group_2]).self_and_ancestors(hierarchy_order: :desc) }
it { is_expected.to eq [group_1, group_2, nested_group_1, nested_group_2] }
# Recursive order per level is not defined.
it { is_expected.to contain_exactly(nested_group_1, nested_group_2, group_1, group_2) }
it { expect(subject[0, 2]).to contain_exactly(group_1, group_2) }
it { expect(subject[2, 2]).to contain_exactly(nested_group_1, nested_group_2) }
end
end

View file

@ -974,15 +974,15 @@
resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8"
integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw==
"@gitlab/ui@32.10.2":
version "32.10.2"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-32.10.2.tgz#d663faaddd5aecf52e7e97b598dfb71a14da60c5"
integrity sha512-WJEVktJjwUoTrR9z8xa3gx73dWwLTq+wsXYH0mfRWzkXHnvjdDp3h8cYj3s1NZ0eAPQ6yVrkvYrTTgLVHZgSbA==
"@gitlab/ui@32.11.0":
version "32.11.0"
resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-32.11.0.tgz#8c4a1724c1733a243f96e4a4813ae7f348502ba6"
integrity sha512-EqP5Ub/IWEi5ErX0txx5vsd6hF7d7dOT5GqaRX6rVaLsUhWLYQZ8ld2yEl5Hx7FLki1t3uag17KII5FcvRTDLg==
dependencies:
"@babel/standalone" "^7.0.0"
bootstrap-vue "2.18.1"
copy-to-clipboard "^3.0.8"
dompurify "^2.3.1"
dompurify "^2.3.2"
echarts "^4.9.0"
highlight.js "^10.6.0"
js-beautify "^1.8.8"
@ -4675,7 +4675,7 @@ dompurify@2.3.0:
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.0.tgz#07bb39515e491588e5756b1d3e8375b5964814e2"
integrity sha512-VV5C6Kr53YVHGOBKO/F86OYX6/iLTw2yVSI721gKetxpHCK/V5TaLEf9ODjRgl1KLSWRMY6cUhAbv/c+IUnwQw==
dompurify@^2.3.1, dompurify@^2.3.2:
dompurify@^2.3.2:
version "2.3.2"
resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-2.3.2.tgz#c773efa410abb5c087c7caf44934fefa448f6e60"
integrity sha512-jXJnvWloI+scD+N5uBikpUMsYXZb0LCAXxLFAOLS5duCzKfXLqBCpuINvFOiI4eJgTLggrngljT18HNoakHUsA==