diff options
36 files changed, 203 insertions, 805 deletions
diff --git a/app/assets/javascripts/boards/components/board_form.vue b/app/assets/javascripts/boards/components/board_form.vue index 88bd1b0eaf0..e939f0c0ebe 100644 --- a/app/assets/javascripts/boards/components/board_form.vue +++ b/app/assets/javascripts/boards/components/board_form.vue @@ -1,7 +1,7 @@ <script> import { GlModal, GlAlert } from '@gitlab/ui'; import { mapGetters, mapActions, mapState } from 'vuex'; -import { TYPE_ITERATION, TYPE_MILESTONE } from '~/graphql_shared/constants'; +import { TYPE_USER, TYPE_ITERATION, TYPE_MILESTONE } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import { getParameterByName, visitUrl } from '~/lib/utils/url_utility'; import { __, s__ } from '~/locale'; @@ -188,7 +188,9 @@ export default { issueBoardScopeMutationVariables() { return { weight: this.board.weight, - assigneeId: this.board.assignee?.id || null, + assigneeId: this.board.assignee?.id + ? convertToGraphQLId(TYPE_USER, this.board.assignee.id) + : null, milestoneId: this.board.milestone?.id ? convertToGraphQLId(TYPE_MILESTONE, this.board.milestone.id) : null, diff --git a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue index 65547af3913..44d7807639d 100644 --- a/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue +++ b/app/assets/javascripts/packages_and_registries/package_registry/components/details/package_title.vue @@ -1,5 +1,5 @@ <script> -import { GlIcon, GlSprintf, GlBadge } from '@gitlab/ui'; +import { GlIcon, GlSprintf, GlBadge, GlResizeObserverDirective } from '@gitlab/ui'; import { GlBreakpointInstance } from '@gitlab/ui/dist/utils'; import { numberToHumanSize } from '~/lib/utils/number_utils'; import { __ } from '~/locale'; @@ -21,6 +21,9 @@ export default { GlBadge, TimeAgoTooltip, }, + directives: { + GlResizeObserver: GlResizeObserverDirective, + }, i18n: { packageInfo: __('v%{version} published %{timeAgo}'), }, @@ -60,18 +63,26 @@ export default { }, }, mounted() { - this.isDesktop = GlBreakpointInstance.isDesktop(); + this.checkBreakpoints(); }, methods: { dynamicSlotName(index) { return `metadata-tag${index}`; }, + checkBreakpoints() { + this.isDesktop = GlBreakpointInstance.isDesktop(); + }, }, }; </script> <template> - <title-area :title="packageEntity.name" :avatar="packageIcon" data-qa-selector="package_title"> + <title-area + v-gl-resize-observer="checkBreakpoints" + :title="packageEntity.name" + :avatar="packageIcon" + data-qa-selector="package_title" + > <template #sub-header> <gl-icon name="eye" class="gl-mr-3" /> <span data-testid="sub-header"> diff --git a/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue b/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue index 55179947756..9fdf941579d 100644 --- a/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue +++ b/app/assets/javascripts/sidebar/components/labels/sidebar_labels.vue @@ -144,16 +144,11 @@ export default { v-if="glFeatures.labelsWidget" class="block labels js-labels-block" :allow-label-remove="allowLabelEdit" - :allow-label-create="allowLabelCreate" - :allow-label-edit="allowLabelEdit" :allow-multiselect="true" - :allow-scoped-labels="allowScopedLabels" :footer-create-label-title="__('Create project label')" :footer-manage-label-title="__('Manage project labels')" :labels-create-title="__('Create project label')" - :labels-fetch-path="labelsFetchPath" :labels-filter-base-path="projectIssuesPath" - :labels-manage-path="labelsManagePath" :labels-select-in-progress="isLabelsSelectInProgress" :selected-labels="selectedLabels" :variant="$options.variant" diff --git a/app/assets/javascripts/vue_shared/components/registry/title_area.vue b/app/assets/javascripts/vue_shared/components/registry/title_area.vue index c63d91b78d3..4b21ec0330a 100644 --- a/app/assets/javascripts/vue_shared/components/registry/title_area.vue +++ b/app/assets/javascripts/vue_shared/components/registry/title_area.vue @@ -1,5 +1,6 @@ <script> import { GlAvatar, GlSprintf, GlLink, GlSkeletonLoader } from '@gitlab/ui'; +import { isEqual } from 'lodash'; export default { name: 'TitleArea', @@ -36,13 +37,21 @@ export default { metadataSlots: [], }; }, - async mounted() { - const METADATA_PREFIX = 'metadata-'; - this.metadataSlots = Object.keys(this.$slots).filter((k) => k.startsWith(METADATA_PREFIX)); + mounted() { + this.recalculateMetadataSlots(); + }, + updated() { + this.recalculateMetadataSlots(); + }, + methods: { + recalculateMetadataSlots() { + const METADATA_PREFIX = 'metadata-'; + const metadataSlots = Object.keys(this.$slots).filter((k) => k.startsWith(METADATA_PREFIX)); - // we need to wait for next tick to ensure that dynamic names slots are picked up - await this.$nextTick(); - this.metadataSlots = Object.keys(this.$slots).filter((k) => k.startsWith(METADATA_PREFIX)); + if (!isEqual(metadataSlots, this.metadataSlots)) { + this.metadataSlots = metadataSlots; + } + }, }, }; </script> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue index 3145f0aaf7a..0fcc67c0ffa 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue @@ -1,9 +1,9 @@ <script> import { GlButton, GlDropdown, GlDropdownItem, GlLink } from '@gitlab/ui'; -import { mapActions, mapGetters, mapState } from 'vuex'; import DropdownContentsCreateView from './dropdown_contents_create_view.vue'; import DropdownContentsLabelsView from './dropdown_contents_labels_view.vue'; +import { isDropdownVariantSidebar, isDropdownVariantEmbedded } from './utils'; export default { components: { @@ -32,6 +32,10 @@ export default { type: String, required: true, }, + dropdownButtonText: { + type: String, + required: true, + }, footerCreateLabelTitle: { type: String, required: true, @@ -40,10 +44,17 @@ export default { type: String, required: true, }, + variant: { + type: String, + required: true, + }, + }, + data() { + return { + showDropdownContentsCreateView: false, + }; }, computed: { - ...mapState(['showDropdownContentsCreateView']), - ...mapGetters(['dropdownButtonText', 'isDropdownVariantSidebar', 'isDropdownVariantEmbedded']), dropdownContentsView() { if (this.showDropdownContentsCreateView) { return 'dropdown-contents-create-view'; @@ -56,20 +67,25 @@ export default { showDropdownFooter() { return ( !this.showDropdownContentsCreateView && - (this.isDropdownVariantSidebar || this.isDropdownVariantEmbedded) + (this.isDropdownVariantSidebar(this.variant) || + this.isDropdownVariantEmbedded(this.variant)) ); }, }, methods: { - ...mapActions(['toggleDropdownContentsCreateView']), showDropdown() { this.$refs.dropdown.show(); }, + toggleDropdownContentsCreateView() { + this.showDropdownContentsCreateView = !this.showDropdownContentsCreateView; + }, toggleDropdownContent() { this.toggleDropdownContentsCreateView(); // Required to recalculate dropdown position as its size changes this.$refs.dropdown.$refs.dropdown.$_popper.scheduleUpdate(); }, + isDropdownVariantSidebar, + isDropdownVariantEmbedded, }, }; </script> @@ -83,7 +99,7 @@ export default { > <template #header> <div - v-if="isDropdownVariantSidebar || isDropdownVariantEmbedded" + v-if="isDropdownVariantSidebar(variant) || isDropdownVariantEmbedded(variant)" class="dropdown-title gl-display-flex gl-align-items-center gl-pt-0 gl-pb-3!" > <gl-button @@ -123,7 +139,7 @@ export default { > {{ footerCreateLabelTitle }} </gl-dropdown-item> - <gl-dropdown-item :href="labelsManagePath"> + <gl-dropdown-item :href="labelsManagePath" @click.native.capture.stop> {{ footerManageLabelTitle }} </gl-dropdown-item> </div> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue index 58a940bca3b..3575f3865ff 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue @@ -7,6 +7,7 @@ export default { components: { GlLabel, }, + inject: ['allowScopedLabels'], props: { disableLabels: { type: Boolean, @@ -21,10 +22,6 @@ export default { type: Boolean, required: true, }, - allowScopedLabels: { - type: Boolean, - required: true, - }, labelsFilterBasePath: { type: String, required: true, diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue index c222ad657f8..3c834770563 100644 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue @@ -1,6 +1,6 @@ <script> import Vue from 'vue'; -import Vuex, { mapActions, mapGetters } from 'vuex'; +import Vuex from 'vuex'; import { __ } from '~/locale'; import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue'; import { DropdownVariant } from './constants'; @@ -8,45 +8,33 @@ import DropdownContents from './dropdown_contents.vue'; import DropdownValue from './dropdown_value.vue'; import DropdownValueCollapsed from './dropdown_value_collapsed.vue'; import issueLabelsQuery from './graphql/issue_labels.query.graphql'; -import labelsSelectModule from './store'; +import { + isDropdownVariantSidebar, + isDropdownVariantStandalone, + isDropdownVariantEmbedded, +} from './utils'; Vue.use(Vuex); export default { - store: new Vuex.Store(labelsSelectModule()), components: { DropdownValue, DropdownContents, DropdownValueCollapsed, SidebarEditableItem, }, - inject: ['iid', 'projectPath'], + inject: ['iid', 'projectPath', 'allowLabelEdit'], props: { allowLabelRemove: { type: Boolean, required: false, default: false, }, - allowLabelEdit: { - type: Boolean, - required: false, - default: false, - }, - allowLabelCreate: { - type: Boolean, - required: false, - default: false, - }, allowMultiselect: { type: Boolean, required: false, default: false, }, - allowScopedLabels: { - type: Boolean, - required: false, - default: false, - }, variant: { type: String, required: false, @@ -62,16 +50,6 @@ export default { required: false, default: false, }, - labelsFetchPath: { - type: String, - required: false, - default: '', - }, - labelsManagePath: { - type: String, - required: false, - default: '', - }, labelsFilterBasePath: { type: String, required: false, @@ -133,46 +111,7 @@ export default { }, }, }, - computed: { - ...mapGetters([ - 'isDropdownVariantSidebar', - 'isDropdownVariantStandalone', - 'isDropdownVariantEmbedded', - ]), - }, - watch: { - selectedLabels(selectedLabels) { - this.setInitialState({ - selectedLabels, - }); - }, - isEditing(newVal) { - if (newVal) { - this.toggleDropdownContents(); - } - }, - }, - mounted() { - this.setInitialState({ - variant: this.variant, - allowLabelRemove: this.allowLabelRemove, - allowLabelEdit: this.allowLabelEdit, - allowLabelCreate: this.allowLabelCreate, - allowMultiselect: this.allowMultiselect, - allowScopedLabels: this.allowScopedLabels, - dropdownButtonText: this.dropdownButtonText, - selectedLabels: this.selectedLabels, - labelsFetchPath: this.labelsFetchPath, - labelsManagePath: this.labelsManagePath, - labelsFilterBasePath: this.labelsFilterBasePath, - labelsFilterParam: this.labelsFilterParam, - labelsListTitle: this.labelsListTitle, - footerCreateLabelTitle: this.footerCreateLabelTitle, - footerManageLabelTitle: this.footerManageLabelTitle, - }); - }, methods: { - ...mapActions(['setInitialState']), handleDropdownClose(labels) { if (labels.length) this.$emit('updateSelectedLabels', labels); this.$emit('onDropdownClose'); @@ -188,6 +127,9 @@ export default { this.$refs.dropdownContents.showDropdown(); }); }, + isDropdownVariantSidebar, + isDropdownVariantStandalone, + isDropdownVariantEmbedded, }, }; </script> @@ -196,11 +138,11 @@ export default { <div class="labels-select-wrapper position-relative" :class="{ - 'is-standalone': isDropdownVariantStandalone, - 'is-embedded': isDropdownVariantEmbedded, + 'is-standalone': isDropdownVariantStandalone(variant), + 'is-embedded': isDropdownVariantEmbedded(variant), }" > - <template v-if="isDropdownVariantSidebar"> + <template v-if="isDropdownVariantSidebar(variant)"> <dropdown-value-collapsed ref="dropdownButtonCollapsed" :labels="issueLabels" @@ -210,6 +152,7 @@ export default { ref="editable" :title="__('Labels')" :loading="labelsSelectInProgress" + :can-edit="allowLabelEdit" @open="showDropdown" > <template #collapsed> @@ -217,7 +160,6 @@ export default { :disable-labels="labelsSelectInProgress" :selected-labels="issueLabels" :allow-label-remove="allowLabelRemove" - :allow-scoped-labels="allowScopedLabels" :labels-filter-base-path="labelsFilterBasePath" :labels-filter-param="labelsFilterParam" @onLabelRemove="$emit('onLabelRemove', $event)" @@ -230,7 +172,6 @@ export default { :disable-labels="labelsSelectInProgress" :selected-labels="issueLabels" :allow-label-remove="allowLabelRemove" - :allow-scoped-labels="allowScopedLabels" :labels-filter-base-path="labelsFilterBasePath" :labels-filter-param="labelsFilterParam" class="gl-mb-2" @@ -241,12 +182,14 @@ export default { <dropdown-contents v-if="edit" ref="dropdownContents" + :dropdown-button-text="dropdownButtonText" :allow-multiselect="allowMultiselect" :labels-list-title="labelsListTitle" :footer-create-label-title="footerCreateLabelTitle" :footer-manage-label-title="footerManageLabelTitle" :labels-create-title="labelsCreateTitle" :selected-labels="selectedLabels" + :variant="variant" @closeDropdown="collapseDropdown" @setLabels="handleDropdownClose" /> diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js deleted file mode 100644 index b3d4a204a81..00000000000 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/actions.js +++ /dev/null @@ -1,12 +0,0 @@ -import * as types from './mutation_types'; - -export const setInitialState = ({ commit }, props) => commit(types.SET_INITIAL_STATE, props); - -export const toggleDropdownButton = ({ commit }) => commit(types.TOGGLE_DROPDOWN_BUTTON); -export const toggleDropdownContents = ({ commit }) => commit(types.TOGGLE_DROPDOWN_CONTENTS); - -export const toggleDropdownContentsCreateView = ({ commit }) => - commit(types.TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW); - -export const updateSelectedLabels = ({ commit }, labels) => - commit(types.UPDATE_SELECTED_LABELS, { labels }); diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/getters.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/getters.js deleted file mode 100644 index d14f96720b7..00000000000 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/getters.js +++ /dev/null @@ -1,52 +0,0 @@ -import { __, s__, sprintf } from '~/locale'; -import { DropdownVariant } from '../constants'; - -/** - * Returns string representing current labels - * selection on dropdown button. - * - * @param {object} state - */ -export const dropdownButtonText = (state, getters) => { - const selectedLabels = getters.isDropdownVariantSidebar - ? state.labels.filter((label) => label.set) - : state.selectedLabels; - - if (!selectedLabels.length) { - return state.dropdownButtonText || __('Label'); - } else if (selectedLabels.length > 1) { - return sprintf(s__('LabelSelect|%{firstLabelName} +%{remainingLabelCount} more'), { - firstLabelName: selectedLabels[0].title, - remainingLabelCount: selectedLabels.length - 1, - }); - } - return selectedLabels[0].title; -}; - -/** - * Returns array containing only label IDs from - * selectedLabels array. - * @param {object} state - */ -export const selectedLabelsList = (state) => state.selectedLabels.map((label) => label.id); - -/** - * Returns boolean representing whether dropdown variant - * is `sidebar` - * @param {object} state - */ -export const isDropdownVariantSidebar = (state) => state.variant === DropdownVariant.Sidebar; - -/** - * Returns boolean representing whether dropdown variant - * is `standalone` - * @param {object} state - */ -export const isDropdownVariantStandalone = (state) => state.variant === DropdownVariant.Standalone; - -/** - * Returns boolean representing whether dropdown variant - * is `embedded` - * @param {object} state - */ -export const isDropdownVariantEmbedded = (state) => state.variant === DropdownVariant.Embedded; diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/index.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/index.js deleted file mode 100644 index 5f61cb732c8..00000000000 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/index.js +++ /dev/null @@ -1,12 +0,0 @@ -import * as actions from './actions'; -import * as getters from './getters'; -import mutations from './mutations'; -import state from './state'; - -export default () => ({ - namespaced: true, - state: state(), - actions, - getters, - mutations, -}); diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js deleted file mode 100644 index bd71c3b85f1..00000000000 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutation_types.js +++ /dev/null @@ -1,8 +0,0 @@ -export const SET_INITIAL_STATE = 'SET_INITIAL_STATE'; - -export const TOGGLE_DROPDOWN_BUTTON = 'TOGGLE_DROPDOWN_VISIBILITY'; -export const TOGGLE_DROPDOWN_CONTENTS = 'TOGGLE_DROPDOWN_CONTENTS'; - -export const UPDATE_SELECTED_LABELS = 'UPDATE_SELECTED_LABELS'; - -export const TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW = 'TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW'; diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js deleted file mode 100644 index 45ec4d7ae04..00000000000 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/mutations.js +++ /dev/null @@ -1,50 +0,0 @@ -import { isScopedLabel, scopedLabelKey } from '~/lib/utils/common_utils'; -import { DropdownVariant } from '../constants'; -import * as types from './mutation_types'; - -export default { - [types.SET_INITIAL_STATE](state, props) { - Object.assign(state, { ...props }); - }, - - [types.TOGGLE_DROPDOWN_BUTTON](state) { - state.showDropdownButton = !state.showDropdownButton; - }, - - [types.TOGGLE_DROPDOWN_CONTENTS](state) { - if (state.variant === DropdownVariant.Sidebar) { - state.showDropdownButton = !state.showDropdownButton; - } - state.showDropdownContents = !state.showDropdownContents; - // Ensure that Create View is hidden by default - // when dropdown contents are revealed. - if (state.showDropdownContents) { - state.showDropdownContentsCreateView = false; - } - }, - - [types.TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW](state) { - state.showDropdownContentsCreateView = !state.showDropdownContentsCreateView; - }, - [types.UPDATE_SELECTED_LABELS](state, { labels }) { - // Find the label to update from all the labels - // and change `set` prop value to represent their current state. - const labelId = labels.pop()?.id; - const candidateLabel = state.labels.find((label) => labelId === label.id); - if (candidateLabel) { - candidateLabel.touched = true; - candidateLabel.set = !candidateLabel.set; - } - - if (isScopedLabel(candidateLabel)) { - const scopedBase = scopedLabelKey(candidateLabel); - const currentActiveScopedLabel = state.labels.find( - ({ title }) => title.indexOf(scopedBase) === 0 && title !== candidateLabel.title, - ); - - if (currentActiveScopedLabel) { - currentActiveScopedLabel.set = false; - } - } - }, -}; diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/state.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/state.js deleted file mode 100644 index 220bab05ed2..00000000000 --- a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/store/state.js +++ /dev/null @@ -1,28 +0,0 @@ -export default () => ({ - // Initial Data - labels: [], - selectedLabels: [], - labelsListTitle: '', - footerCreateLabelTitle: '', - footerManageLabelTitle: '', - dropdownButtonText: '', - - // Paths - namespace: '', - labelsFetchPath: '', - labelsFilterBasePath: '', - - // UI Flags - variant: '', - allowLabelRemove: false, - allowLabelCreate: false, - allowLabelEdit: false, - allowScopedLabels: false, - allowMultiselect: false, - showDropdownButton: false, - showDropdownContents: false, - showDropdownContentsCreateView: false, - labelsFetchInProgress: false, - labelCreateInProgress: false, - selectedLabelsUpdated: false, -}); diff --git a/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/utils.js b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/utils.js new file mode 100644 index 00000000000..b5cd946a189 --- /dev/null +++ b/app/assets/javascripts/vue_shared/components/sidebar/labels_select_widget/utils.js @@ -0,0 +1,22 @@ +import { DropdownVariant } from './constants'; + +/** + * Returns boolean representing whether dropdown variant + * is `sidebar` + * @param {string} variant + */ +export const isDropdownVariantSidebar = (variant) => variant === DropdownVariant.Sidebar; + +/** + * Returns boolean representing whether dropdown variant + * is `standalone` + * @param {string} variant + */ +export const isDropdownVariantStandalone = (variant) => variant === DropdownVariant.Standalone; + +/** + * Returns boolean representing whether dropdown variant + * is `embedded` + * @param {string} variant + */ +export const isDropdownVariantEmbedded = (variant) => variant === DropdownVariant.Embedded; diff --git a/app/graphql/types/user_interface.rb b/app/graphql/types/user_interface.rb index 95038c0f863..8c67275eb73 100644 --- a/app/graphql/types/user_interface.rb +++ b/app/graphql/types/user_interface.rb @@ -61,7 +61,8 @@ module Types description: 'Group memberships of the user.' field :groups, resolver: Resolvers::Users::GroupsResolver, - description: 'Groups where the user has access.' + description: 'Groups where the user has access. Will always return `null` if ' \ + '`paginatable_namespace_drop_down_for_project_creation` feature flag is disabled.' field :group_count, resolver: Resolvers::Users::GroupCountResolver, description: 'Group count for the user.' diff --git a/config/initializers/zz_metrics.rb b/config/initializers/zz_metrics.rb index bb768070b1f..b23d20aa4cd 100644 --- a/config/initializers/zz_metrics.rb +++ b/config/initializers/zz_metrics.rb @@ -162,25 +162,25 @@ if Gitlab::Metrics.enabled? && !Rails.env.test? && !(Rails.env.development? && d config.middleware.use(Gitlab::Metrics::ElasticsearchRackMiddleware) end - # This instruments all methods residing in app/models that (appear to) use any - # of the ActiveRecord methods. This has to take place _after_ initializing as - # for some unknown reason calling eager_load! earlier breaks Devise. - Gitlab::Application.config.after_initialize do - # We should move all the logic of this file to somewhere else - # and require it after `Rails.application.initialize!` in `environment.rb` file. - models_path = Rails.root.join('app', 'models').to_s - - Dir.glob("**/*.rb", base: models_path).sort.each do |file| - require_dependency file - end + # We are removing the Instrumentation module entirely in steps. + # More in https://gitlab.com/gitlab-org/gitlab/-/issues/217978. + unless ::Feature.enabled?(:method_instrumentation_disable_initialization) + # This instruments all methods residing in app/models that (appear to) use any + # of the ActiveRecord methods. This has to take place _after_ initializing as + # for some unknown reason calling eager_load! earlier breaks Devise. + Gitlab::Application.config.after_initialize do + # We should move all the logic of this file to somewhere else + # and require it after `Rails.application.initialize!` in `environment.rb` file. + models_path = Rails.root.join('app', 'models').to_s + + Dir.glob("**/*.rb", base: models_path).sort.each do |file| + require_dependency file + end - regex = Regexp.union( - ActiveRecord::Querying.public_instance_methods(false).map(&:to_s) - ) + regex = Regexp.union( + ActiveRecord::Querying.public_instance_methods(false).map(&:to_s) + ) - # We are removing the Instrumentation module entirely in steps. - # More in https://gitlab.com/gitlab-org/gitlab/-/issues/217978. - unless ::Feature.enabled?(:method_instrumentation_disable_initialization) Gitlab::Metrics::Instrumentation .instrument_class_hierarchy(ActiveRecord::Base) do |klass, method| # Instrumenting the ApplicationSetting class can lead to an infinite @@ -199,9 +199,7 @@ if Gitlab::Metrics.enabled? && !Rails.env.test? && !(Rails.env.development? && d # be instrumented. Gitlab::Metrics::Instrumentation.instrument_methods(Ability) end - end - unless ::Feature.enabled?(:method_instrumentation_disable_initialization) Gitlab::Metrics::Instrumentation.configure do |config| instrument_classes(config) end diff --git a/doc/administration/job_artifacts.md b/doc/administration/job_artifacts.md index 3b1d253b4b6..b4c16e007cc 100644 --- a/doc/administration/job_artifacts.md +++ b/doc/administration/job_artifacts.md @@ -435,6 +435,27 @@ Ci::JobArtifact.where(project: project).order(size: :desc).limit(50).map { |a| p You can change the number of job artifacts listed by modifying `.limit(50)` to the number you want. +#### List artifacts in a single project + +List the artifacts for a single project, sorted by artifact size. The output includes the: + +- ID of the job that created the artifact +- artifact size +- artifact file type +- artifact creation date +- on-disk location of the artifact + +```ruby +p = Project.find_by_id(:project ID) +arts = Ci::JobArtifact.where(project: p) + +list = arts.order('sort DESC').limit(50).each do |art| + puts "Job ID: #{art.job_id} - Size: #{art.size}b - Type: #{art.file_type} - Created: #{art.created_at} - File loc: #{art.file}" +end +``` + +To change the number of projects listed, change the number in `limit(50)`. + #### Delete job artifacts from jobs completed before a specific date WARNING: diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 7deadc6b2e6..af9a70725c1 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -11105,7 +11105,7 @@ four standard [pagination arguments](#connection-pagination-arguments): ##### `MergeRequestAssignee.groups` -Groups where the user has access. +Groups where the user has access. Will always return `null` if `paginatable_namespace_drop_down_for_project_creation` feature flag is disabled. Returns [`GroupConnection`](#groupconnection). @@ -11351,7 +11351,7 @@ four standard [pagination arguments](#connection-pagination-arguments): ##### `MergeRequestReviewer.groups` -Groups where the user has access. +Groups where the user has access. Will always return `null` if `paginatable_namespace_drop_down_for_project_creation` feature flag is disabled. Returns [`GroupConnection`](#groupconnection). @@ -14260,7 +14260,7 @@ four standard [pagination arguments](#connection-pagination-arguments): ##### `UserCore.groups` -Groups where the user has access. +Groups where the user has access. Will always return `null` if `paginatable_namespace_drop_down_for_project_creation` feature flag is disabled. Returns [`GroupConnection`](#groupconnection). @@ -17255,7 +17255,7 @@ four standard [pagination arguments](#connection-pagination-arguments): ###### `User.groups` -Groups where the user has access. +Groups where the user has access. Will always return `null` if `paginatable_namespace_drop_down_for_project_creation` feature flag is disabled. Returns [`GroupConnection`](#groupconnection). diff --git a/doc/integration/kerberos.md b/doc/integration/kerberos.md index d4c0f6402cb..23565e6f370 100644 --- a/doc/integration/kerberos.md +++ b/doc/integration/kerberos.md @@ -85,6 +85,9 @@ For source installations, make sure the `kerberos` gem group gitlab_rails['kerberos_keytab'] = "/etc/http.keytab" ``` + To avoid GitLab creating users automatically on their first sign in through Kerberos, + don't set `kerberos` for `gitlab_rails['omniauth_allow_single_sign_on']`. + 1. [Reconfigure GitLab](../administration/restart_gitlab.md#omnibus-gitlab-reconfigure) for the changes to take effect. GitLab now offers the `negotiate` authentication method for signing in and diff --git a/doc/user/profile/personal_access_tokens.md b/doc/user/profile/personal_access_tokens.md index 9bd5153d6d5..bdd49b00a15 100644 --- a/doc/user/profile/personal_access_tokens.md +++ b/doc/user/profile/personal_access_tokens.md @@ -22,16 +22,22 @@ In both cases, you authenticate with a personal access token in place of your pa Personal access tokens are: - Required when [two-factor authentication (2FA)](account/two_factor_authentication.md) is enabled. -- Similar to [project access tokens](../project/settings/project_access_tokens.md), but are attached to a user rather than a project. +- Used with a GitLab username to authenticate with GitLab features that require usernames. For example, + [GitLab managed Terraform state backend](../infrastructure/iac/terraform_state.md#using-a-gitlab-managed-terraform-state-backend-as-a-remote-data-source) + and [Docker container registry](../packages/container_registry/index.md#authenticate-with-the-container-registry), +- Similar to [project access tokens](../project/settings/project_access_tokens.md), but are attached + to a user rather than a project. + +NOTE: +Though required, GitLab usernames are ignored when authenticating with a personal access token. +There is an [issue for tracking](https://gitlab.com/gitlab-org/gitlab/-/issues/212953) to make GitLab +use the username. For examples of how you can use a personal access token to authenticate with the API, see the [API documentation](../../api/index.md#personalproject-access-tokens). Alternately, GitLab administrators can use the API to create [impersonation tokens](../../api/index.md#impersonation-tokens). Use impersonation tokens to automate authentication as a specific user. -NOTE: -Use your GitLab username and personal access tokens to authenticate with [GitLab managed Terraform state backend](../infrastructure/iac/terraform_state.md#using-a-gitlab-managed-terraform-state-backend-as-a-remote-data-source), [Docker container registry](../packages/container_registry/index.md#authenticate-with-the-container-registry), or when authenticating to a Git remote repository. Currently, GitLab usernames are ignored when authenticating with a personal access token, however, usernames may become a requirement in the future as per [issue #212953](https://gitlab.com/gitlab-org/gitlab/-/issues/212953). - ## Create a personal access token You can create as many personal access tokens as you like. diff --git a/lib/gitlab/github_import/importer/diff_note_importer.rb b/lib/gitlab/github_import/importer/diff_note_importer.rb index 9bda066efcc..4cfc920e2e3 100644 --- a/lib/gitlab/github_import/importer/diff_note_importer.rb +++ b/lib/gitlab/github_import/importer/diff_note_importer.rb @@ -24,13 +24,14 @@ module Gitlab note_body = MarkdownText.format(note.note, note.author, author_found) attributes = { + discussion_id: Discussion.discussion_id(note), noteable_type: 'MergeRequest', noteable_id: mr_id, project_id: project.id, author_id: author_id, note: note_body, system: false, - commit_id: note.commit_id, + commit_id: note.original_commit_id, line_code: note.line_code, type: 'LegacyDiffNote', created_at: note.created_at, diff --git a/lib/gitlab/github_import/representation/diff_note.rb b/lib/gitlab/github_import/representation/diff_note.rb index d336b1ba797..d0584cc6255 100644 --- a/lib/gitlab/github_import/representation/diff_note.rb +++ b/lib/gitlab/github_import/representation/diff_note.rb @@ -11,7 +11,7 @@ module Gitlab expose_attribute :noteable_type, :noteable_id, :commit_id, :file_path, :diff_hunk, :author, :note, :created_at, :updated_at, - :github_id + :github_id, :original_commit_id NOTEABLE_ID_REGEX = %r{/pull/(?<iid>\d+)}i.freeze @@ -34,6 +34,7 @@ module Gitlab noteable_id: matches[:iid].to_i, file_path: note.path, commit_id: note.commit_id, + original_commit_id: note.original_commit_id, diff_hunk: note.diff_hunk, author: user, note: note.body, diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap index 45d261625b4..451cf743e35 100644 --- a/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap +++ b/spec/frontend/packages_and_registries/package_registry/components/details/__snapshots__/package_title_spec.js.snap @@ -177,15 +177,6 @@ exports[`PackageTitle renders without tags 1`] = ` texttooltip="" /> </div> - <div - class="gl-display-flex gl-align-items-center gl-mr-5" - > - <package-tags-stub - hidelabel="true" - tagdisplaylimit="2" - tags="[object Object],[object Object],[object Object]" - /> - </div> </div> </div> diff --git a/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js b/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js index 327f6d81905..d59c3184e4e 100644 --- a/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js +++ b/spec/frontend/packages_and_registries/package_registry/components/details/package_title_spec.js @@ -1,5 +1,6 @@ import { GlIcon, GlSprintf } from '@gitlab/ui'; import { GlBreakpointInstance } from '@gitlab/ui/dist/utils'; +import { createMockDirective, getBinding } from 'helpers/vue_mock_directive'; import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; import PackageTags from '~/packages/shared/components/package_tags.vue'; import PackageTitle from '~/packages_and_registries/package_registry/components/details/package_title.vue'; @@ -30,6 +31,9 @@ describe('PackageTitle', () => { TitleArea, GlSprintf, }, + directives: { + GlResizeObserver: createMockDirective(), + }, }); return wrapper.vm.$nextTick(); } @@ -51,7 +55,7 @@ describe('PackageTitle', () => { describe('renders', () => { it('without tags', async () => { - await createComponent(); + await createComponent({ ...packageData(), packageFiles: { nodes: packageFiles() } }); expect(wrapper.element).toMatchSnapshot(); }); @@ -64,12 +68,26 @@ describe('PackageTitle', () => { it('with tags on mobile', async () => { jest.spyOn(GlBreakpointInstance, 'isDesktop').mockReturnValue(false); + await createComponent(); await wrapper.vm.$nextTick(); expect(findPackageBadges()).toHaveLength(packageTags().length); }); + + it('when the page is resized', async () => { + await createComponent(); + + expect(findPackageBadges()).toHaveLength(0); + + jest.spyOn(GlBreakpointInstance, 'isDesktop').mockReturnValue(false); + const { value } = getBinding(wrapper.element, 'gl-resize-observer'); + value(); + + await wrapper.vm.$nextTick(); + expect(findPackageBadges()).toHaveLength(packageTags().length); + }); }); describe('package title', () => { diff --git a/spec/frontend/vue_shared/components/registry/title_area_spec.js b/spec/frontend/vue_shared/components/registry/title_area_spec.js index fb0009ebb8d..75aa3bc7096 100644 --- a/spec/frontend/vue_shared/components/registry/title_area_spec.js +++ b/spec/frontend/vue_shared/components/registry/title_area_spec.js @@ -135,15 +135,16 @@ describe('title area', () => { }, }); }; + it('shows dynamic slots', async () => { mountComponent(); // we manually add a new slot to simulate dynamic slots being evaluated after the initial mount wrapper.vm.$slots[DYNAMIC_SLOT] = createDynamicSlot(); + // updating the slots like we do on line 141 does not cause the updated lifecycle-hook to be triggered + wrapper.vm.$forceUpdate(); await wrapper.vm.$nextTick(); - expect(findDynamicSlot().exists()).toBe(false); - await wrapper.vm.$nextTick(); expect(findDynamicSlot().exists()).toBe(true); }); @@ -160,10 +161,8 @@ describe('title area', () => { 'metadata-foo': wrapper.vm.$slots['metadata-foo'], }; - await wrapper.vm.$nextTick(); - expect(findDynamicSlot().exists()).toBe(false); - expect(findMetadataSlot('metadata-foo').exists()).toBe(true); - + // updating the slots like we do on line 159 does not cause the updated lifecycle-hook to be triggered + wrapper.vm.$forceUpdate(); await wrapper.vm.$nextTick(); expect(findSlotOrderElements().at(0).attributes('data-testid')).toBe(DYNAMIC_SLOT); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js index 59605761986..a1b40a891ec 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_spec.js @@ -1,46 +1,34 @@ import { GlDropdown } from '@gitlab/ui'; import { shallowMount } from '@vue/test-utils'; -import Vue from 'vue'; -import Vuex from 'vuex'; import { DropdownVariant } from '~/vue_shared/components/sidebar/labels_select_widget/constants'; import DropdownContents from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue'; import DropdownContentsCreateView from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_create_view.vue'; import DropdownContentsLabelsView from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents_labels_view.vue'; -import labelsSelectModule from '~/vue_shared/components/sidebar/labels_select_widget/store'; -import { mockConfig, mockLabels } from './mock_data'; - -Vue.use(Vuex); +import { mockLabels } from './mock_data'; describe('DropdownContent', () => { let wrapper; - const createComponent = ({ - initialState = mockConfig, - defaultProps = {}, - injected = {}, - } = {}) => { - const store = new Vuex.Store(labelsSelectModule()); - - store.dispatch('setInitialState', initialState); - + const createComponent = ({ props = {}, injected = {} } = {}) => { wrapper = shallowMount(DropdownContents, { propsData: { - ...defaultProps, labelsCreateTitle: 'test', selectedLabels: mockLabels, allowMultiselect: true, labelsListTitle: 'Assign labels', footerCreateLabelTitle: 'create', footerManageLabelTitle: 'manage', + dropdownButtonText: 'Labels', + variant: 'sidebar', + ...props, }, provide: { allowLabelCreate: true, labelsManagePath: 'foo/bar', ...injected, }, - store, stubs: { GlDropdown, }, @@ -61,7 +49,7 @@ describe('DropdownContent', () => { describe('Create view', () => { beforeEach(() => { - wrapper.vm.$store.dispatch('toggleDropdownContentsCreateView'); + wrapper.vm.toggleDropdownContentsCreateView(); }); it('renders create view when `showDropdownContentsCreateView` prop is `true`', () => { @@ -91,13 +79,13 @@ describe('DropdownContent', () => { }); it('does not render footer on standalone dropdown', () => { - createComponent({ initialState: { ...mockConfig, variant: DropdownVariant.Standalone } }); + createComponent({ props: { variant: DropdownVariant.Standalone } }); expect(findDropdownFooter().exists()).toBe(false); }); it('renders footer on embedded dropdown', () => { - createComponent({ initialState: { ...mockConfig, variant: DropdownVariant.Embedded } }); + createComponent({ props: { variant: DropdownVariant.Embedded } }); expect(findDropdownFooter().exists()).toBe(true); }); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_value_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_value_spec.js index b3ffee2d020..6dcd0e4e8ac 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_value_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/dropdown_value_spec.js @@ -20,11 +20,13 @@ describe('DropdownValue', () => { propsData: { selectedLabels: [mockRegularLabel, mockScopedLabel], allowLabelRemove: true, - allowScopedLabels: true, labelsFilterBasePath: '/gitlab-org/my-project/issues', labelsFilterParam: 'label_name', ...props, }, + provide: { + allowScopedLabels: true, + }, }); }; diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js index d91d87ee6f0..a18511fa21d 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js @@ -1,31 +1,18 @@ -import { shallowMount, createLocalVue } from '@vue/test-utils'; -import Vuex from 'vuex'; +import { shallowMount } from '@vue/test-utils'; import SidebarEditableItem from '~/sidebar/components/sidebar_editable_item.vue'; import DropdownContents from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_contents.vue'; import DropdownValue from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_value.vue'; import DropdownValueCollapsed from '~/vue_shared/components/sidebar/labels_select_widget/dropdown_value_collapsed.vue'; import LabelsSelectRoot from '~/vue_shared/components/sidebar/labels_select_widget/labels_select_root.vue'; -import labelsSelectModule from '~/vue_shared/components/sidebar/labels_select_widget/store'; - import { mockConfig } from './mock_data'; -jest.mock('~/lib/utils/common_utils', () => ({ - isInViewport: jest.fn().mockReturnValue(true), -})); - -const localVue = createLocalVue(); -localVue.use(Vuex); - describe('LabelsSelectRoot', () => { let wrapper; - let store; const createComponent = (config = mockConfig, slots = {}) => { wrapper = shallowMount(LabelsSelectRoot, { - localVue, slots, - store, propsData: config, stubs: { DropdownContents, @@ -35,14 +22,11 @@ describe('LabelsSelectRoot', () => { iid: '1', projectPath: 'test', canUpdate: true, + allowLabelEdit: true, }, }); }; - beforeEach(() => { - store = new Vuex.Store(labelsSelectModule()); - }); - afterEach(() => { wrapper.destroy(); }); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js index 982b2e15e46..fceaabec2d0 100644 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js +++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js @@ -34,18 +34,12 @@ export const mockLabels = [ ]; export const mockConfig = { - allowLabelEdit: true, - allowLabelCreate: true, - allowScopedLabels: true, allowMultiselect: true, labelsListTitle: 'Assign labels', labelsCreateTitle: 'Create label', variant: 'sidebar', - dropdownOnly: false, selectedLabels: [mockRegularLabel, mockScopedLabel], labelsSelectInProgress: false, - labelsFetchPath: '/gitlab-org/my-project/-/labels.json', - labelsManagePath: '/gitlab-org/my-project/-/labels', labelsFilterBasePath: '/gitlab-org/my-project/issues', labelsFilterParam: 'label_name', footerCreateLabelTitle: 'create', diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js deleted file mode 100644 index ee905410ffa..00000000000 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/actions_spec.js +++ /dev/null @@ -1,85 +0,0 @@ -import testAction from 'helpers/vuex_action_helper'; -import * as actions from '~/vue_shared/components/sidebar/labels_select_widget/store/actions'; -import * as types from '~/vue_shared/components/sidebar/labels_select_widget/store/mutation_types'; -import defaultState from '~/vue_shared/components/sidebar/labels_select_widget/store/state'; - -jest.mock('~/flash'); - -describe('LabelsSelect Actions', () => { - let state; - const mockInitialState = { - labels: [], - selectedLabels: [], - }; - - beforeEach(() => { - state = { ...defaultState() }; - }); - - describe('setInitialState', () => { - it('sets initial store state', (done) => { - testAction( - actions.setInitialState, - mockInitialState, - state, - [{ type: types.SET_INITIAL_STATE, payload: mockInitialState }], - [], - done, - ); - }); - }); - - describe('toggleDropdownButton', () => { - it('toggles dropdown button', (done) => { - testAction( - actions.toggleDropdownButton, - {}, - state, - [{ type: types.TOGGLE_DROPDOWN_BUTTON }], - [], - done, - ); - }); - }); - - describe('toggleDropdownContents', () => { - it('toggles dropdown contents', (done) => { - testAction( - actions.toggleDropdownContents, - {}, - state, - [{ type: types.TOGGLE_DROPDOWN_CONTENTS }], - [], - done, - ); - }); - }); - - describe('toggleDropdownContentsCreateView', () => { - it('toggles dropdown create view', (done) => { - testAction( - actions.toggleDropdownContentsCreateView, - {}, - state, - [{ type: types.TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW }], - [], - done, - ); - }); - }); - - describe('updateSelectedLabels', () => { - it('updates `state.labels` based on provided `labels` param', (done) => { - const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]; - - testAction( - actions.updateSelectedLabels, - labels, - state, - [{ type: types.UPDATE_SELECTED_LABELS, payload: { labels } }], - [], - done, - ); - }); - }); -}); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/getters_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/getters_spec.js deleted file mode 100644 index 40eb0323146..00000000000 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/getters_spec.js +++ /dev/null @@ -1,59 +0,0 @@ -import * as getters from '~/vue_shared/components/sidebar/labels_select_widget/store/getters'; - -describe('LabelsSelect Getters', () => { - describe('dropdownButtonText', () => { - it.each` - labelType | dropdownButtonText | expected - ${'default'} | ${''} | ${'Label'} - ${'custom'} | ${'Custom label'} | ${'Custom label'} - `( - 'returns $labelType text when state.labels has no selected labels', - ({ dropdownButtonText, expected }) => { - const labels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]; - const selectedLabels = []; - const state = { labels, selectedLabels, dropdownButtonText }; - - expect(getters.dropdownButtonText(state, {})).toBe(expected); - }, - ); - - it('returns label title when state.labels has only 1 label', () => { - const labels = [{ id: 1, title: 'Foobar', set: true }]; - - expect(getters.dropdownButtonText({ labels }, { isDropdownVariantSidebar: true })).toBe( - 'Foobar', - ); - }); - - it('returns first label title and remaining labels count when state.labels has more than 1 label', () => { - const labels = [ - { id: 1, title: 'Foo', set: true }, - { id: 2, title: 'Bar', set: true }, - ]; - - expect(getters.dropdownButtonText({ labels }, { isDropdownVariantSidebar: true })).toBe( - 'Foo +1 more', - ); - }); - }); - - describe('selectedLabelsList', () => { - it('returns array of IDs of all labels within `state.selectedLabels`', () => { - const selectedLabels = [{ id: 1 }, { id: 2 }, { id: 3 }, { id: 4 }]; - - expect(getters.selectedLabelsList({ selectedLabels })).toEqual([1, 2, 3, 4]); - }); - }); - - describe('isDropdownVariantSidebar', () => { - it('returns `true` when `state.variant` is "sidebar"', () => { - expect(getters.isDropdownVariantSidebar({ variant: 'sidebar' })).toBe(true); - }); - }); - - describe('isDropdownVariantStandalone', () => { - it('returns `true` when `state.variant` is "standalone"', () => { - expect(getters.isDropdownVariantStandalone({ variant: 'standalone' })).toBe(true); - }); - }); -}); diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js deleted file mode 100644 index 1f0e0eee420..00000000000 --- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/store/mutations_spec.js +++ /dev/null @@ -1,115 +0,0 @@ -import * as types from '~/vue_shared/components/sidebar/labels_select_widget/store/mutation_types'; -import mutations from '~/vue_shared/components/sidebar/labels_select_widget/store/mutations'; - -describe('LabelsSelect Mutations', () => { - describe(`${types.SET_INITIAL_STATE}`, () => { - it('initializes provided props to store state', () => { - const state = {}; - mutations[types.SET_INITIAL_STATE](state, { - labels: 'foo', - }); - - expect(state.labels).toEqual('foo'); - }); - }); - - describe(`${types.TOGGLE_DROPDOWN_BUTTON}`, () => { - it('toggles value of `state.showDropdownButton`', () => { - const state = { - showDropdownButton: false, - }; - mutations[types.TOGGLE_DROPDOWN_BUTTON](state); - - expect(state.showDropdownButton).toBe(true); - }); - }); - - describe(`${types.TOGGLE_DROPDOWN_CONTENTS}`, () => { - it('toggles value of `state.showDropdownButton` when `state.dropdownOnly` is false', () => { - const state = { - dropdownOnly: false, - showDropdownButton: false, - variant: 'sidebar', - }; - mutations[types.TOGGLE_DROPDOWN_CONTENTS](state); - - expect(state.showDropdownButton).toBe(true); - }); - - it('toggles value of `state.showDropdownContents`', () => { - const state = { - showDropdownContents: false, - }; - mutations[types.TOGGLE_DROPDOWN_CONTENTS](state); - - expect(state.showDropdownContents).toBe(true); - }); - - it('sets value of `state.showDropdownContentsCreateView` to `false` when `showDropdownContents` is true', () => { - const state = { - showDropdownContents: false, - showDropdownContentsCreateView: true, - }; - mutations[types.TOGGLE_DROPDOWN_CONTENTS](state); - - expect(state.showDropdownContentsCreateView).toBe(false); - }); - }); - - describe(`${types.TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW}`, () => { - it('toggles value of `state.showDropdownContentsCreateView`', () => { - const state = { - showDropdownContentsCreateView: false, - }; - mutations[types.TOGGLE_DROPDOWN_CONTENTS_CREATE_VIEW](state); - - expect(state.showDropdownContentsCreateView).toBe(true); - }); - }); - - describe(`${types.UPDATE_SELECTED_LABELS}`, () => { - let labels; - - beforeEach(() => { - labels = [ - { id: 1, title: 'scoped::test', set: true }, - { id: 2, set: false, title: 'scoped::one' }, - { id: 3, title: '' }, - { id: 4, title: '' }, - ]; - }); - - it('updates `state.labels` to include `touched` and `set` props based on provided `labels` param', () => { - const updatedLabelIds = [2]; - const state = { - labels, - }; - mutations[types.UPDATE_SELECTED_LABELS](state, { labels: [{ id: 2 }] }); - - state.labels.forEach((label) => { - if (updatedLabelIds.includes(label.id)) { - expect(label.touched).toBe(true); - expect(label.set).toBe(true); - } - }); - }); - - describe('when label is scoped', () => { - it('unsets the currently selected scoped label and sets the current label', () => { - const state = { - labels, - }; - mutations[types.UPDATE_SELECTED_LABELS](state, { - labels: [{ id: 2, title: 'scoped::one' }], - }); - - expect(state.labels).toEqual([ - { id: 1, title: 'scoped::test', set: false }, - { id: 2, set: true, title: 'scoped::one', touched: true }, - { id: 3, title: '' }, - { id: 4, title: '' }, - ]); - }); - }); - }); -}); diff --git a/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb b/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb index 0af840d2c10..3dc15c7c059 100644 --- a/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb +++ b/spec/lib/gitlab/github_import/importer/diff_note_importer_spec.rb @@ -20,6 +20,7 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter do noteable_type: 'MergeRequest', noteable_id: 1, commit_id: '123abc', + original_commit_id: 'original123abc', file_path: 'README.md', diff_hunk: hunk, author: Gitlab::GithubImport::Representation::User @@ -64,13 +65,14 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter do LegacyDiffNote.table_name, [ { + discussion_id: anything, noteable_type: 'MergeRequest', noteable_id: merge_request.id, project_id: project.id, author_id: user.id, note: 'Hello', system: false, - commit_id: '123abc', + commit_id: 'original123abc', line_code: note.line_code, type: 'LegacyDiffNote', created_at: created_at, @@ -95,13 +97,14 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNoteImporter do LegacyDiffNote.table_name, [ { + discussion_id: anything, noteable_type: 'MergeRequest', noteable_id: merge_request.id, project_id: project.id, author_id: project.creator_id, note: "*Created by: #{user.username}*\n\nHello", system: false, - commit_id: '123abc', + commit_id: 'original123abc', line_code: note.line_code, type: 'LegacyDiffNote', created_at: created_at, diff --git a/spec/lib/gitlab/github_import/importer/diff_notes_importer_spec.rb b/spec/lib/gitlab/github_import/importer/diff_notes_importer_spec.rb index 7750e508713..46b9959ff64 100644 --- a/spec/lib/gitlab/github_import/importer/diff_notes_importer_spec.rb +++ b/spec/lib/gitlab/github_import/importer/diff_notes_importer_spec.rb @@ -12,6 +12,7 @@ RSpec.describe Gitlab::GithubImport::Importer::DiffNotesImporter do html_url: 'https://github.com/foo/bar/pull/42', path: 'README.md', commit_id: '123abc', + original_commit_id: 'original123abc', diff_hunk: "@@ -1 +1 @@\n-Hello\n+Hello world", user: double(:user, id: 4, login: 'alice'), body: 'Hello world', diff --git a/spec/lib/gitlab/github_import/representation/diff_note_spec.rb b/spec/lib/gitlab/github_import/representation/diff_note_spec.rb index 7e540674258..7c24cd0a5db 100644 --- a/spec/lib/gitlab/github_import/representation/diff_note_spec.rb +++ b/spec/lib/gitlab/github_import/representation/diff_note_spec.rb @@ -67,6 +67,7 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote do html_url: 'https://github.com/foo/bar/pull/42', path: 'README.md', commit_id: '123abc', + original_commit_id: 'original123abc', diff_hunk: hunk, user: double(:user, id: 4, login: 'alice'), body: 'Hello world', @@ -99,6 +100,7 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote do 'noteable_id' => 42, 'file_path' => 'README.md', 'commit_id' => '123abc', + 'original_commit_id' => 'original123abc', 'diff_hunk' => hunk, 'author' => { 'id' => 4, 'login' => 'alice' }, 'note' => 'Hello world', @@ -117,6 +119,7 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote do 'noteable_id' => 42, 'file_path' => 'README.md', 'commit_id' => '123abc', + 'original_commit_id' => 'original123abc', 'diff_hunk' => hunk, 'note' => 'Hello world', 'created_at' => created_at.to_s, @@ -145,6 +148,7 @@ RSpec.describe Gitlab::GithubImport::Representation::DiffNote do 'noteable_id' => 42, 'file_path' => 'README.md', 'commit_id' => '123abc', + 'original_commit_id' => 'original123abc', 'diff_hunk' => hunk, 'author' => { 'id' => 4, 'login' => 'alice' }, 'note' => 'Hello world', diff --git a/spec/support/database/cross-join-allowlist.yml b/spec/support/database/cross-join-allowlist.yml index 2bb41281746..67045c7deba 100644 --- a/spec/support/database/cross-join-allowlist.yml +++ b/spec/support/database/cross-join-allowlist.yml @@ -1,32 +1,12 @@ -- "./ee/spec/controllers/ee/projects/jobs_controller_spec.rb" - "./ee/spec/controllers/operations_controller_spec.rb" - "./ee/spec/controllers/projects/issues_controller_spec.rb" - "./ee/spec/controllers/projects/security/vulnerabilities_controller_spec.rb" - "./ee/spec/features/ci/ci_minutes_spec.rb" -- "./ee/spec/features/ci_shared_runner_warnings_spec.rb" -- "./ee/spec/features/groups/analytics/cycle_analytics/filters_and_data_spec.rb" -- "./ee/spec/features/merge_request/sidebar_spec.rb" -- "./ee/spec/features/merge_request/user_approves_with_password_spec.rb" -- "./ee/spec/features/merge_request/user_creates_merge_request_spec.rb" -- "./ee/spec/features/merge_request/user_creates_merge_request_with_blocking_mrs_spec.rb" -- "./ee/spec/features/merge_request/user_edits_merge_request_blocking_mrs_spec.rb" - "./ee/spec/features/merge_request/user_merges_immediately_spec.rb" -- "./ee/spec/features/merge_request/user_merges_with_push_rules_spec.rb" -- "./ee/spec/features/merge_request/user_sees_approval_widget_spec.rb" -- "./ee/spec/features/merge_request/user_sees_closing_issues_message_spec.rb" - "./ee/spec/features/merge_request/user_sees_merge_widget_spec.rb" -- "./ee/spec/features/merge_request/user_sees_status_checks_widget_spec.rb" -- "./ee/spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb" -- "./ee/spec/features/merge_request/user_sets_approval_rules_spec.rb" -- "./ee/spec/features/merge_request/user_sets_approvers_spec.rb" -- "./ee/spec/features/merge_request/user_uses_slash_commands_spec.rb" -- "./ee/spec/features/merge_request/user_views_blocked_merge_request_spec.rb" -- "./ee/spec/features/merge_requests/user_resets_approvers_spec.rb" - "./ee/spec/features/merge_trains/two_merge_requests_on_train_spec.rb" - "./ee/spec/features/merge_trains/user_adds_merge_request_to_merge_train_spec.rb" - "./ee/spec/features/merge_trains/user_adds_to_merge_train_when_pipeline_succeeds_spec.rb" -- "./ee/spec/features/projects/jobs_spec.rb" -- "./ee/spec/features/projects/merge_requests/user_approves_merge_request_spec.rb" - "./ee/spec/features/projects/pipelines/pipeline_spec.rb" - "./ee/spec/features/projects/settings/auto_rollback_spec.rb" - "./ee/spec/features/projects/settings/pipeline_subscriptions_spec.rb" @@ -34,9 +14,6 @@ - "./ee/spec/finders/ee/namespaces/projects_finder_spec.rb" - "./ee/spec/finders/group_projects_finder_spec.rb" - "./ee/spec/finders/security/findings_finder_spec.rb" -- "./ee/spec/frontend/fixtures/analytics/metrics.rb" -- "./ee/spec/frontend/fixtures/analytics/value_streams.rb" -- "./ee/spec/frontend/fixtures/merge_requests.rb" - "./ee/spec/graphql/ee/resolvers/namespace_projects_resolver_spec.rb" - "./ee/spec/lib/analytics/devops_adoption/snapshot_calculator_spec.rb" - "./ee/spec/lib/ee/gitlab/background_migration/migrate_approver_to_approval_rules_spec.rb" @@ -46,13 +23,7 @@ - "./ee/spec/lib/ee/gitlab/background_migration/populate_uuids_for_security_findings_spec.rb" - "./ee/spec/lib/ee/gitlab/background_migration/populate_vulnerability_feedback_pipeline_id_spec.rb" - "./ee/spec/lib/ee/gitlab/usage_data_spec.rb" -- "./ee/spec/lib/gitlab/ci/minutes/runners_availability_spec.rb" -- "./ee/spec/lib/gitlab/ci/templates/Jobs/browser_performance_testing_gitlab_ci_yaml_spec.rb" -- "./ee/spec/lib/gitlab/ci/templates/Jobs/load_performance_testing_gitlab_ci_yaml_spec.rb" -- "./ee/spec/lib/gitlab/ci/templates/Verify/browser_performance_testing_gitlab_ci_yaml_spec.rb" -- "./ee/spec/lib/gitlab/ci/templates/Verify/load_performance_testing_gitlab_ci_yaml_spec.rb" - "./ee/spec/migrations/schedule_populate_resolved_on_default_branch_column_spec.rb" -- "./ee/spec/models/analytics/cycle_analytics/group_level_spec.rb" - "./ee/spec/models/ci/build_spec.rb" - "./ee/spec/models/ci/minutes/project_monthly_usage_spec.rb" - "./ee/spec/models/ci/pipeline_spec.rb" @@ -62,7 +33,6 @@ - "./ee/spec/models/security/finding_spec.rb" - "./ee/spec/models/security/scan_spec.rb" - "./ee/spec/presenters/ci/pipeline_presenter_spec.rb" -- "./ee/spec/requests/api/ci/jobs_spec.rb" - "./ee/spec/requests/api/ci/minutes_spec.rb" - "./ee/spec/requests/api/graphql/ci/minutes/usage_spec.rb" - "./ee/spec/requests/api/graphql/mutations/environments/canary_ingress/update_spec.rb" @@ -71,174 +41,71 @@ - "./ee/spec/requests/api/graphql/vulnerabilities/location_spec.rb" - "./ee/spec/requests/api/groups_spec.rb" - "./ee/spec/requests/api/namespaces_spec.rb" -- "./ee/spec/requests/api/search_spec.rb" - "./ee/spec/requests/api/vulnerability_findings_spec.rb" - "./ee/spec/serializers/dashboard_environment_entity_spec.rb" - "./ee/spec/serializers/dashboard_environments_serializer_spec.rb" -- "./ee/spec/serializers/merge_request_poll_widget_entity_spec.rb" - "./ee/spec/services/auto_merge/add_to_merge_train_when_pipeline_succeeds_service_spec.rb" -- "./ee/spec/services/ci/create_pipeline_service/needs_spec.rb" - "./ee/spec/services/ci/create_pipeline_service/runnable_builds_spec.rb" - "./ee/spec/services/ci/minutes/additional_packs/change_namespace_service_spec.rb" - "./ee/spec/services/ci/minutes/additional_packs/create_service_spec.rb" - "./ee/spec/services/ci/minutes/refresh_cached_data_service_spec.rb" -- "./ee/spec/services/ci/pipeline_creation/drop_not_runnable_builds_service_spec.rb" - "./ee/spec/services/ci/process_pipeline_service_spec.rb" -- "./ee/spec/services/ci/retry_pipeline_service_spec.rb" - "./ee/spec/services/ci/trigger_downstream_subscription_service_spec.rb" - "./ee/spec/services/clear_namespace_shared_runners_minutes_service_spec.rb" - "./ee/spec/services/deployments/auto_rollback_service_spec.rb" - "./ee/spec/services/ee/ci/job_artifacts/destroy_all_expired_service_spec.rb" - "./ee/spec/services/ee/ci/job_artifacts/destroy_batch_service_spec.rb" - "./ee/spec/services/ee/issues/build_from_vulnerability_service_spec.rb" -- "./ee/spec/services/ee/merge_requests/after_create_service_spec.rb" - "./ee/spec/services/ee/merge_requests/create_pipeline_service_spec.rb" - "./ee/spec/services/ee/merge_requests/refresh_service_spec.rb" -- "./ee/spec/services/merge_trains/refresh_merge_request_service_spec.rb" - "./ee/spec/services/security/report_summary_service_spec.rb" - "./ee/spec/services/security/vulnerability_counting_service_spec.rb" -- "./ee/spec/support/features/redacted_search_results_examples.rb" -- "./ee/spec/support/shared_examples/fixtures/analytics_value_streams_shared_examples.rb" -- "./ee/spec/support/shared_examples/services/build_execute_shared_examples.rb" -- "./ee/spec/support/shared_examples/services/search_service_shared_examples.rb" -- "./ee/spec/workers/ci/initial_pipeline_process_worker_spec.rb" - "./ee/spec/workers/scan_security_report_secrets_worker_spec.rb" - "./ee/spec/workers/security/store_scans_worker_spec.rb" - "./spec/controllers/admin/runners_controller_spec.rb" - "./spec/controllers/groups/runners_controller_spec.rb" - "./spec/controllers/groups/settings/ci_cd_controller_spec.rb" -- "./spec/controllers/projects/issues_controller_spec.rb" -- "./spec/controllers/projects/jobs_controller_spec.rb" - "./spec/controllers/projects/logs_controller_spec.rb" -- "./spec/controllers/projects/merge_requests/content_controller_spec.rb" - "./spec/controllers/projects/merge_requests_controller_spec.rb" -- "./spec/controllers/projects/pipelines_controller_spec.rb" - "./spec/controllers/projects/runners_controller_spec.rb" - "./spec/controllers/projects/serverless/functions_controller_spec.rb" - "./spec/controllers/projects/settings/ci_cd_controller_spec.rb" -- "./spec/controllers/projects/web_ide_terminals_controller_spec.rb" -- "./spec/features/admin/admin_builds_spec.rb" - "./spec/features/admin/admin_runners_spec.rb" -- "./spec/features/commits_spec.rb" -- "./spec/features/cycle_analytics_spec.rb" - "./spec/features/groups/settings/ci_cd_spec.rb" - "./spec/features/ide/user_opens_merge_request_spec.rb" -- "./spec/features/issuables/markdown_references/internal_references_spec.rb" -- "./spec/features/issuables/markdown_references/jira_spec.rb" -- "./spec/features/issues/create_issue_for_discussions_in_merge_request_spec.rb" -- "./spec/features/issues/create_issue_for_single_discussion_in_merge_request_spec.rb" -- "./spec/features/issues/notes_on_issues_spec.rb" -- "./spec/features/issues/user_creates_branch_and_merge_request_spec.rb" -- "./spec/features/issues/user_creates_confidential_merge_request_spec.rb" -- "./spec/features/markdown/gitlab_flavored_markdown_spec.rb" -- "./spec/features/merge_request/batch_comments_spec.rb" -- "./spec/features/merge_request/close_reopen_report_toggle_spec.rb" -- "./spec/features/merge_request/maintainer_edits_fork_spec.rb" -- "./spec/features/merge_request/merge_request_discussion_lock_spec.rb" -- "./spec/features/merge_request/user_accepts_merge_request_spec.rb" -- "./spec/features/merge_request/user_allows_commits_from_memebers_who_can_merge_spec.rb" -- "./spec/features/merge_request/user_approves_spec.rb" -- "./spec/features/merge_request/user_assigns_themselves_spec.rb" -- "./spec/features/merge_request/user_awards_emoji_spec.rb" -- "./spec/features/merge_request/user_clicks_merge_request_tabs_spec.rb" -- "./spec/features/merge_request/user_comments_on_diff_spec.rb" -- "./spec/features/merge_request/user_comments_on_merge_request_spec.rb" -- "./spec/features/merge_request/user_creates_image_diff_notes_spec.rb" -- "./spec/features/merge_request/user_creates_merge_request_spec.rb" -- "./spec/features/merge_request/user_customizes_merge_commit_message_spec.rb" -- "./spec/features/merge_request/user_edits_assignees_sidebar_spec.rb" -- "./spec/features/merge_request/user_edits_merge_request_spec.rb" -- "./spec/features/merge_request/user_edits_reviewers_sidebar_spec.rb" -- "./spec/features/merge_request/user_expands_diff_spec.rb" -- "./spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb" -- "./spec/features/merge_request/user_invites_from_a_comment_spec.rb" -- "./spec/features/merge_request/user_jumps_to_discussion_spec.rb" -- "./spec/features/merge_request/user_locks_discussion_spec.rb" -- "./spec/features/merge_request/user_manages_subscription_spec.rb" -- "./spec/features/merge_request/user_marks_merge_request_as_draft_spec.rb" - "./spec/features/merge_request/user_merges_immediately_spec.rb" -- "./spec/features/merge_request/user_merges_merge_request_spec.rb" - "./spec/features/merge_request/user_merges_only_if_pipeline_succeeds_spec.rb" - "./spec/features/merge_request/user_merges_when_pipeline_succeeds_spec.rb" -- "./spec/features/merge_request/user_posts_diff_notes_spec.rb" -- "./spec/features/merge_request/user_posts_notes_spec.rb" -- "./spec/features/merge_request/user_rebases_merge_request_spec.rb" -- "./spec/features/merge_request/user_resolves_conflicts_spec.rb" -- "./spec/features/merge_request/user_resolves_diff_notes_and_discussions_resolve_spec.rb" -- "./spec/features/merge_request/user_resolves_outdated_diff_discussions_spec.rb" - "./spec/features/merge_request/user_resolves_wip_mr_spec.rb" -- "./spec/features/merge_request/user_reverts_merge_request_spec.rb" -- "./spec/features/merge_request/user_reviews_image_spec.rb" -- "./spec/features/merge_request/user_scrolls_to_note_on_load_spec.rb" -- "./spec/features/merge_request/user_sees_avatar_on_diff_notes_spec.rb" -- "./spec/features/merge_request/user_sees_check_out_branch_modal_spec.rb" -- "./spec/features/merge_request/user_sees_cherry_pick_modal_spec.rb" -- "./spec/features/merge_request/user_sees_closing_issues_message_spec.rb" -- "./spec/features/merge_request/user_sees_deleted_target_branch_spec.rb" - "./spec/features/merge_request/user_sees_deployment_widget_spec.rb" -- "./spec/features/merge_request/user_sees_diff_spec.rb" -- "./spec/features/merge_request/user_sees_discussions_spec.rb" -- "./spec/features/merge_request/user_sees_merge_button_depending_on_unresolved_discussions_spec.rb" - "./spec/features/merge_request/user_sees_merge_request_pipelines_spec.rb" - "./spec/features/merge_request/user_sees_merge_widget_spec.rb" - "./spec/features/merge_request/user_sees_mini_pipeline_graph_spec.rb" -- "./spec/features/merge_request/user_sees_notes_from_forked_project_spec.rb" - "./spec/features/merge_request/user_sees_pipelines_from_forked_project_spec.rb" - "./spec/features/merge_request/user_sees_pipelines_spec.rb" -- "./spec/features/merge_request/user_sees_suggest_pipeline_spec.rb" -- "./spec/features/merge_request/user_sees_system_notes_spec.rb" -- "./spec/features/merge_request/user_sees_versions_spec.rb" -- "./spec/features/merge_request/user_selects_branches_for_new_mr_spec.rb" -- "./spec/features/merge_request/user_squashes_merge_request_spec.rb" -- "./spec/features/merge_request/user_suggests_changes_on_diff_spec.rb" -- "./spec/features/merge_request/user_toggles_whitespace_changes_spec.rb" -- "./spec/features/merge_request/user_views_auto_expanding_diff_spec.rb" -- "./spec/features/merge_request/user_views_diffs_commit_spec.rb" -- "./spec/features/merge_request/user_views_diffs_file_by_file_spec.rb" -- "./spec/features/merge_request/user_views_diffs_spec.rb" -- "./spec/features/merge_request/user_views_merge_request_from_deleted_fork_spec.rb" -- "./spec/features/merge_request/user_views_open_merge_request_spec.rb" -- "./spec/features/participants_autocomplete_spec.rb" - "./spec/features/project_group_variables_spec.rb" - "./spec/features/project_variables_spec.rb" - "./spec/features/projects/badges/list_spec.rb" -- "./spec/features/projects/badges/pipeline_badge_spec.rb" -- "./spec/features/projects/blobs/edit_spec.rb" -- "./spec/features/projects/environments/environment_spec.rb" -- "./spec/features/projects/environments/environments_spec.rb" - "./spec/features/projects/environments_pod_logs_spec.rb" - "./spec/features/projects/infrastructure_registry_spec.rb" -- "./spec/features/projects/issuable_templates_spec.rb" -- "./spec/features/projects/jobs/permissions_spec.rb" -- "./spec/features/projects/jobs/user_browses_job_spec.rb" -- "./spec/features/projects/jobs/user_browses_jobs_spec.rb" - "./spec/features/projects/jobs_spec.rb" - "./spec/features/projects/package_files_spec.rb" - "./spec/features/projects/pipelines/pipeline_spec.rb" - "./spec/features/projects/pipelines/pipelines_spec.rb" - "./spec/features/projects/serverless/functions_spec.rb" - "./spec/features/projects/settings/pipelines_settings_spec.rb" -- "./spec/features/projects/user_sees_user_popover_spec.rb" -- "./spec/features/projects/view_on_env_spec.rb" - "./spec/features/runners_spec.rb" - "./spec/features/security/project/internal_access_spec.rb" - "./spec/features/security/project/private_access_spec.rb" - "./spec/features/security/project/public_access_spec.rb" -- "./spec/features/task_lists_spec.rb" - "./spec/features/triggers_spec.rb" -- "./spec/features/user_sees_revert_modal_spec.rb" - "./spec/finders/ci/pipelines_finder_spec.rb" - "./spec/finders/ci/pipelines_for_merge_request_finder_spec.rb" - "./spec/finders/ci/runners_finder_spec.rb" - "./spec/finders/clusters/knative_services_finder_spec.rb" - "./spec/finders/projects/serverless/functions_finder_spec.rb" -- "./spec/frontend/fixtures/analytics.rb" -- "./spec/frontend/fixtures/jobs.rb" -- "./spec/frontend/fixtures/merge_requests.rb" -- "./spec/frontend/fixtures/pipelines.rb" - "./spec/frontend/fixtures/runner.rb" - "./spec/graphql/mutations/ci/runner/delete_spec.rb" -- "./spec/graphql/mutations/ci/runner/update_spec.rb" - "./spec/graphql/resolvers/ci/group_runners_resolver_spec.rb" - "./spec/graphql/resolvers/ci/job_token_scope_resolver_spec.rb" - "./spec/graphql/resolvers/merge_request_pipelines_resolver_spec.rb" @@ -246,21 +113,13 @@ - "./spec/helpers/packages_helper_spec.rb" - "./spec/lib/api/entities/package_spec.rb" - "./spec/lib/gitlab/background_migration/migrate_legacy_artifacts_spec.rb" -- "./spec/lib/gitlab/ci/badge/pipeline/status_spec.rb" -- "./spec/lib/gitlab/ci/templates/Jobs/build_gitlab_ci_yaml_spec.rb" -- "./spec/lib/gitlab/ci/templates/Jobs/code_quality_gitlab_ci_yaml_spec.rb" -- "./spec/lib/gitlab/ci/templates/Jobs/deploy_gitlab_ci_yaml_spec.rb" -- "./spec/lib/gitlab/ci/templates/Jobs/test_gitlab_ci_yaml_spec.rb" -- "./spec/lib/gitlab/ci/templates/Verify/load_performance_testing_gitlab_ci_yaml_spec.rb" - "./spec/lib/gitlab/prometheus/query_variables_spec.rb" - "./spec/mailers/emails/pipelines_spec.rb" - "./spec/migrations/cleanup_legacy_artifact_migration_spec.rb" - "./spec/migrations/migrate_protected_attribute_to_pending_builds_spec.rb" - "./spec/migrations/re_schedule_latest_pipeline_id_population_with_all_security_related_artifact_types_spec.rb" - "./spec/migrations/schedule_migrate_security_scans_spec.rb" -- "./spec/models/ci/build_dependencies_spec.rb" - "./spec/models/ci/build_spec.rb" -- "./spec/models/ci/build_trace_chunk_spec.rb" - "./spec/models/ci/job_artifact_spec.rb" - "./spec/models/ci/job_token/scope_spec.rb" - "./spec/models/ci/pipeline_spec.rb" @@ -275,20 +134,13 @@ - "./spec/presenters/ci/build_runner_presenter_spec.rb" - "./spec/presenters/ci/pipeline_presenter_spec.rb" - "./spec/presenters/packages/detail/package_presenter_spec.rb" -- "./spec/requests/api/ci/jobs_spec.rb" - "./spec/requests/api/ci/pipelines_spec.rb" -- "./spec/requests/api/ci/runner/jobs_put_spec.rb" - "./spec/requests/api/ci/runner/jobs_request_post_spec.rb" - "./spec/requests/api/ci/runner/runners_post_spec.rb" - "./spec/requests/api/ci/runners_spec.rb" - "./spec/requests/api/commit_statuses_spec.rb" -- "./spec/requests/api/graphql/ci/groups_spec.rb" -- "./spec/requests/api/graphql/ci/job_spec.rb" -- "./spec/requests/api/graphql/ci/runner_spec.rb" - "./spec/requests/api/graphql/group_query_spec.rb" - "./spec/requests/api/graphql/merge_request/merge_request_spec.rb" -- "./spec/requests/api/graphql/mutations/ci/job_play_spec.rb" -- "./spec/requests/api/graphql/mutations/ci/job_retry_spec.rb" - "./spec/requests/api/graphql/mutations/ci/job_token_scope/add_project_spec.rb" - "./spec/requests/api/graphql/mutations/ci/job_token_scope/remove_project_spec.rb" - "./spec/requests/api/graphql/mutations/environments/canary_ingress/update_spec.rb" @@ -305,84 +157,41 @@ - "./spec/requests/api/graphql/project/pipeline_spec.rb" - "./spec/requests/api/merge_requests_spec.rb" - "./spec/requests/api/package_files_spec.rb" -- "./spec/requests/projects/cycle_analytics_events_spec.rb" -- "./spec/serializers/ci/pipeline_entity_spec.rb" -- "./spec/serializers/merge_request_serializer_spec.rb" -- "./spec/serializers/pipeline_details_entity_spec.rb" -- "./spec/serializers/pipeline_serializer_spec.rb" -- "./spec/serializers/runner_entity_spec.rb" - "./spec/services/auto_merge/merge_when_pipeline_succeeds_service_spec.rb" -- "./spec/services/auto_merge_service_spec.rb" - "./spec/services/ci/create_pipeline_service/cross_project_pipeline_spec.rb" - "./spec/services/ci/create_pipeline_service/needs_spec.rb" -- "./spec/services/ci/create_pipeline_service/parent_child_pipeline_spec.rb" - "./spec/services/ci/create_pipeline_service_spec.rb" - "./spec/services/ci/destroy_pipeline_service_spec.rb" -- "./spec/services/ci/drop_pipeline_service_spec.rb" - "./spec/services/ci/expire_pipeline_cache_service_spec.rb" - "./spec/services/ci/job_artifacts/destroy_all_expired_service_spec.rb" - "./spec/services/ci/job_artifacts/destroy_associations_service_spec.rb" - "./spec/services/ci/job_artifacts/destroy_batch_service_spec.rb" - "./spec/services/ci/pipeline_processing/shared_processing_service.rb" - "./spec/services/ci/pipeline_processing/shared_processing_service_tests_with_yaml.rb" -- "./spec/services/ci/play_build_service_spec.rb" - "./spec/services/ci/register_job_service_spec.rb" -- "./spec/services/ci/retry_pipeline_service_spec.rb" - "./spec/services/clusters/applications/prometheus_config_service_spec.rb" - "./spec/services/deployments/older_deployments_drop_service_spec.rb" - "./spec/services/environments/auto_stop_service_spec.rb" - "./spec/services/environments/stop_service_spec.rb" - "./spec/services/merge_requests/add_todo_when_build_fails_service_spec.rb" -- "./spec/services/merge_requests/after_create_service_spec.rb" -- "./spec/services/merge_requests/create_from_issue_service_spec.rb" -- "./spec/services/merge_requests/create_pipeline_service_spec.rb" - "./spec/services/merge_requests/create_service_spec.rb" -- "./spec/services/merge_requests/merge_orchestration_service_spec.rb" - "./spec/services/merge_requests/post_merge_service_spec.rb" - "./spec/services/merge_requests/refresh_service_spec.rb" -- "./spec/services/merge_requests/reopen_service_spec.rb" -- "./spec/services/projects/update_pages_service_spec.rb" -- "./spec/services/quick_actions/interpret_service_spec.rb" - "./spec/support/prometheus/additional_metrics_shared_examples.rb" - "./spec/support/shared_examples/ci/pipeline_email_shared_examples.rb" -- "./spec/support/shared_examples/controllers/unique_hll_events_examples.rb" -- "./spec/support/shared_examples/features/comments_on_merge_request_files_shared_examples.rb" -- "./spec/support/shared_examples/features/creatable_merge_request_shared_examples.rb" -- "./spec/support/shared_examples/features/discussion_comments_shared_example.rb" -- "./spec/support/shared_examples/features/editable_merge_request_shared_examples.rb" -- "./spec/support/shared_examples/features/issuable_invite_members_shared_examples.rb" -- "./spec/support/shared_examples/features/issuable_sidebar_shared_examples.rb" -- "./spec/support/shared_examples/features/multiple_assignees_mr_shared_examples.rb" -- "./spec/support/shared_examples/features/multiple_reviewers_mr_shared_examples.rb" - "./spec/support/shared_examples/features/packages_shared_examples.rb" -- "./spec/support/shared_examples/features/page_description_shared_examples.rb" -- "./spec/support/shared_examples/features/reportable_note_shared_examples.rb" -- "./spec/support/shared_examples/features/resolving_discussions_in_issues_shared_examples.rb" - "./spec/support/shared_examples/features/search_settings_shared_examples.rb" -- "./spec/support/shared_examples/features/showing_user_status_shared_examples.rb" - "./spec/support/shared_examples/features/variable_list_shared_examples.rb" -- "./spec/support/shared_examples/lib/gitlab/search_results_sorted_shared_examples.rb" - "./spec/support/shared_examples/models/concerns/limitable_shared_examples.rb" -- "./spec/support/shared_examples/quick_actions/issuable/close_quick_action_shared_examples.rb" -- "./spec/support/shared_examples/quick_actions/issuable/time_tracking_quick_action_shared_examples.rb" -- "./spec/support/shared_examples/quick_actions/issue/create_merge_request_quick_action_shared_examples.rb" - "./spec/support/shared_examples/quick_actions/merge_request/merge_quick_action_shared_examples.rb" -- "./spec/support/shared_examples/quick_actions/merge_request/rebase_quick_action_shared_examples.rb" - "./spec/support/shared_examples/requests/api/graphql/packages/group_and_project_packages_list_shared_examples.rb" - "./spec/support/shared_examples/requests/api/graphql/packages/package_details_shared_examples.rb" - "./spec/support/shared_examples/requests/api/logging_application_context_shared_examples.rb" - "./spec/support/shared_examples/requests/api/status_shared_examples.rb" - "./spec/support/shared_examples/requests/graphql_shared_examples.rb" -- "./spec/support/shared_examples/services/merge_request_shared_examples.rb" - "./spec/support/shared_examples/services/onboarding_progress_shared_examples.rb" - "./spec/support/shared_examples/services/packages_shared_examples.rb" - "./spec/support/shared_examples/workers/idempotency_shared_examples.rb" - "./spec/tasks/gitlab/generate_sample_prometheus_data_spec.rb" -- "./spec/views/projects/jobs/_build.html.haml_spec.rb" -- "./spec/workers/ci/drop_pipeline_worker_spec.rb" -- "./spec/workers/ci/initial_pipeline_process_worker_spec.rb" -- "./spec/workers/new_merge_request_worker_spec.rb" - "./spec/workers/pipeline_process_worker_spec.rb" - "./spec/workers/pipeline_schedule_worker_spec.rb" -- "./spec/workers/stuck_merge_jobs_worker_spec.rb" -- "./spec/workers/update_head_pipeline_for_merge_request_worker_spec.rb" |