diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-11-02 18:12:43 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-11-02 18:12:43 +0300 |
commit | ef211f6aff22891e232a700b61d2d3bf567ed6bf (patch) | |
tree | 555016653a6598927c852a4eb20fa2a842a7b4b4 | |
parent | d8c4c08d4999959ca9b5a87a32153013791e96e0 (diff) |
Add latest changes from gitlab-org/gitlab@master
93 files changed, 962 insertions, 713 deletions
diff --git a/.rubocop_todo/layout/argument_alignment.yml b/.rubocop_todo/layout/argument_alignment.yml index 7b372bfd01a..5173e67b843 100644 --- a/.rubocop_todo/layout/argument_alignment.yml +++ b/.rubocop_todo/layout/argument_alignment.yml @@ -1405,23 +1405,6 @@ Layout/ArgumentAlignment: - 'spec/lib/gitlab/auth/otp/strategies/forti_token_cloud_spec.rb' - 'spec/lib/gitlab/auth/saml/auth_hash_spec.rb' - 'spec/lib/gitlab/auth/saml/user_spec.rb' - - 'spec/lib/gitlab/background_migration/batched_migration_job_spec.rb' - - 'spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb' - - 'spec/lib/gitlab/background_migration/delete_orphaned_operational_vulnerabilities_spec.rb' - - 'spec/lib/gitlab/background_migration/delete_orphans_approval_merge_request_rules_spec.rb' - - 'spec/lib/gitlab/background_migration/delete_orphans_approval_project_rules_spec.rb' - - 'spec/lib/gitlab/background_migration/destroy_invalid_group_members_spec.rb' - - 'spec/lib/gitlab/background_migration/destroy_invalid_members_spec.rb' - - 'spec/lib/gitlab/background_migration/destroy_invalid_project_members_spec.rb' - - 'spec/lib/gitlab/background_migration/disable_legacy_open_source_licence_for_recent_public_projects_spec.rb' - - 'spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_inactive_public_projects_spec.rb' - - 'spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb' - - 'spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_one_member_no_repo_projects_spec.rb' - - 'spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb' - - 'spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb' - - 'spec/lib/gitlab/background_migration/expire_o_auth_tokens_spec.rb' - - 'spec/lib/gitlab/background_migration/fix_incoherent_packages_size_on_project_statistics_spec.rb' - - 'spec/lib/gitlab/background_migration/legacy_upload_mover_spec.rb' - 'spec/lib/gitlab/bitbucket_import/importer_spec.rb' - 'spec/lib/gitlab/bitbucket_import/project_creator_spec.rb' - 'spec/lib/gitlab/bitbucket_import/wiki_formatter_spec.rb' diff --git a/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue b/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue index 771ecb1a0d4..a4dec8199a3 100644 --- a/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue +++ b/app/assets/javascripts/ci/runner/components/registration/registration_instructions.vue @@ -100,11 +100,11 @@ export default { tokenMessage() { if (this.token) { return s__( - 'Runners|The %{boldStart}runner token%{boldEnd} %{token} displays %{boldStart}only for a short time%{boldEnd}, and is stored in the %{codeStart}config.toml%{codeEnd} after you register the runner. It will not be visible once the runner is registered.', + 'Runners|The %{boldStart}runner authentication token%{boldEnd} %{token} displays here %{boldStart}for a short time only%{boldEnd}. After you register the runner, this token is stored in the %{codeStart}config.toml%{codeEnd} and cannot be accessed again from the UI.', ); } return s__( - 'Runners|The %{boldStart}runner token%{boldEnd} is no longer visible, it is stored in the %{codeStart}config.toml%{codeEnd} if you have registered the runner.', + 'Runners|The %{boldStart}runner authentication token%{boldEnd} is no longer visible, it is stored in the %{codeStart}config.toml%{codeEnd} if you have registered the runner.', ); }, commandPrompt() { diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 5bfdd174694..29189e3ac2f 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -29,7 +29,6 @@ import initBreadcrumbs from './breadcrumb'; import initPersistentUserCallouts from './persistent_user_callouts'; import { initUserTracking, initDefaultTrackers } from './tracking'; import { initSidebarTracking } from './pages/shared/nav/sidebar_tracking'; -import initServicePingConsent from './service_ping_consent'; import GlFieldErrors from './gl_field_errors'; import initUserPopovers from './user_popovers'; import initBroadcastNotifications from './broadcast_notification'; @@ -93,7 +92,6 @@ function deferredInitialisation() { initBreadcrumbs(); initPrefetchLinks('.js-prefetch-document'); initLogoAnimation(); - initServicePingConsent(); initUserPopovers(); initBroadcastNotifications(); initPersistentUserCallouts(); diff --git a/app/assets/javascripts/observability/client.js b/app/assets/javascripts/observability/client.js index 884aa841b68..fa75ead2f92 100644 --- a/app/assets/javascripts/observability/client.js +++ b/app/assets/javascripts/observability/client.js @@ -70,6 +70,7 @@ const SUPPORTED_FILTERS = { serviceName: ['=', '!='], period: ['='], traceId: ['=', '!='], + attribute: ['='], // free-text 'search' temporarily ignored https://gitlab.com/gitlab-org/opstrace/opstrace/-/issues/2309 }; @@ -82,6 +83,7 @@ const FILTER_TO_QUERY_PARAM = { serviceName: 'service_name', period: 'period', traceId: 'trace_id', + attribute: 'attribute', }; const FILTER_OPERATORS_PREFIX = { @@ -114,6 +116,25 @@ function getFilterParamName(filterName, operator) { } /** + * Process `filterValue` and append the proper query params to the `searchParams` arg + * + * It mutates `searchParams` + * + * @param {String} filterValue The filter value, in the format `attribute_name=attribute_value` + * @param {String} filterOperator The filter operator + * @param {URLSearchParams} searchParams The URLSearchParams object where to append the proper query params + */ +function handleAttributeFilter(filterValue, filterOperator, searchParams) { + const [attrName, attrValue] = filterValue.split('='); + if (attrName && attrValue) { + if (filterOperator === '=') { + searchParams.append('attr_name', attrName); + searchParams.append('attr_value', attrValue); + } + } +} + +/** * Builds URLSearchParams from a filter object of type { [filterName]: undefined | null | Array<{operator: String, value: any} } * e.g: * @@ -133,20 +154,22 @@ function filterObjToQueryParams(filterObj) { Object.keys(SUPPORTED_FILTERS).forEach((filterName) => { const filterValues = filterObj[filterName] || []; - const supportedFilters = filterValues.filter((f) => + const validFilters = filterValues.filter((f) => SUPPORTED_FILTERS[filterName].includes(f.operator), ); - supportedFilters.forEach(({ operator, value: rawValue }) => { - const paramName = getFilterParamName(filterName, operator); - - let value = rawValue; - if (filterName === 'durationMs') { - // converting durationMs to duration_nano - value *= 1000000; - } - - if (paramName && value) { - filterParams.append(paramName, value); + validFilters.forEach(({ operator, value: rawValue }) => { + if (filterName === 'attribute') { + handleAttributeFilter(rawValue, operator, filterParams); + } else { + const paramName = getFilterParamName(filterName, operator); + let value = rawValue; + if (filterName === 'durationMs') { + // converting durationMs to duration_nano + value *= 1000000; + } + if (paramName && value) { + filterParams.append(paramName, value); + } } }); }); @@ -248,12 +271,33 @@ async function fetchMetrics() { /* eslint-enable @gitlab/require-i18n-strings */ } -export function buildClient({ provisioningUrl, tracingUrl, servicesUrl, operationsUrl } = {}) { - if (!provisioningUrl || !tracingUrl || !servicesUrl || !operationsUrl) { - throw new Error( - 'missing required params. provisioningUrl, tracingUrl, servicesUrl, operationsUrl are required', - ); +export function buildClient(options) { + if (!options) { + throw new Error('No options object provided'); // eslint-disable-line @gitlab/require-i18n-strings } + + const { provisioningUrl, tracingUrl, servicesUrl, operationsUrl, metricsUrl } = options; + + if (typeof provisioningUrl !== 'string') { + throw new Error('provisioningUrl param must be a string'); + } + + if (typeof tracingUrl !== 'string') { + throw new Error('tracingUrl param must be a string'); + } + + if (typeof servicesUrl !== 'string') { + throw new Error('servicesUrl param must be a string'); + } + + if (typeof operationsUrl !== 'string') { + throw new Error('operationsUrl param must be a string'); + } + + if (typeof metricsUrl !== 'string') { + throw new Error('metricsUrl param must be a string'); + } + return { enableObservability: () => enableObservability(provisioningUrl), isObservabilityEnabled: () => isObservabilityEnabled(provisioningUrl), @@ -261,6 +305,6 @@ export function buildClient({ provisioningUrl, tracingUrl, servicesUrl, operatio fetchTrace: (traceId) => fetchTrace(tracingUrl, traceId), fetchServices: () => fetchServices(servicesUrl), fetchOperations: (serviceName) => fetchOperations(operationsUrl, serviceName), - fetchMetrics: () => fetchMetrics(), + fetchMetrics: () => fetchMetrics(metricsUrl), }; } diff --git a/app/assets/javascripts/observability/components/observability_container.vue b/app/assets/javascripts/observability/components/observability_container.vue index 33d05b01556..b89c2624f81 100644 --- a/app/assets/javascripts/observability/components/observability_container.vue +++ b/app/assets/javascripts/observability/components/observability_container.vue @@ -10,24 +10,8 @@ export default { ObservabilityLoader, }, props: { - oauthUrl: { - type: String, - required: true, - }, - provisioningUrl: { - type: String, - required: true, - }, - tracingUrl: { - type: String, - required: true, - }, - servicesUrl: { - type: String, - required: true, - }, - operationsUrl: { - type: String, + apiConfig: { + type: Object, required: true, }, }, @@ -55,7 +39,7 @@ export default { }, methods: { messageHandler(e) { - const isExpectedOrigin = e.origin === new URL(this.oauthUrl).origin; + const isExpectedOrigin = e.origin === new URL(this.apiConfig.oauthUrl).origin; if (!isExpectedOrigin) return; const { data } = e; @@ -65,12 +49,7 @@ export default { const { status, message, statusCode } = data; if (status === 'success') { - this.observabilityClient = buildClient({ - provisioningUrl: this.provisioningUrl, - tracingUrl: this.tracingUrl, - servicesUrl: this.servicesUrl, - operationsUrl: this.operationsUrl, - }); + this.observabilityClient = buildClient(this.apiConfig); this.$emit('observability-client-ready', this.observabilityClient); this.loaderContentState = CONTENT_STATE.LOADED; } else if (status === 'error') { @@ -92,7 +71,7 @@ export default { v-if="!authCompleted" sandbox="allow-same-origin allow-forms allow-scripts" hidden - :src="oauthUrl" + :src="apiConfig.oauthUrl" data-testid="observability-oauth-iframe" ></iframe> diff --git a/app/assets/javascripts/observability/components/provisioned_observability_container.vue b/app/assets/javascripts/observability/components/provisioned_observability_container.vue index 1fe10a634f4..9fb4bdd7b95 100644 --- a/app/assets/javascripts/observability/components/provisioned_observability_container.vue +++ b/app/assets/javascripts/observability/components/provisioned_observability_container.vue @@ -12,24 +12,8 @@ export default { GlLoadingIcon, }, props: { - oauthUrl: { - type: String, - required: true, - }, - tracingUrl: { - type: String, - required: true, - }, - servicesUrl: { - type: String, - required: true, - }, - provisioningUrl: { - type: String, - required: true, - }, - operationsUrl: { - type: String, + apiConfig: { + type: Object, required: true, }, }, @@ -91,11 +75,7 @@ export default { <template> <observability-container - :oauth-url="oauthUrl" - :tracing-url="tracingUrl" - :provisioning-url="provisioningUrl" - :services-url="servicesUrl" - :operations-url="operationsUrl" + :api-config="apiConfig" @observability-client-ready="onObservabilityClientReady" > <div v-if="loading" class="gl-py-5"> diff --git a/app/assets/javascripts/profile/edit/components/profile_edit_app.vue b/app/assets/javascripts/profile/edit/components/profile_edit_app.vue index 6b39f137880..815b8742500 100644 --- a/app/assets/javascripts/profile/edit/components/profile_edit_app.vue +++ b/app/assets/javascripts/profile/edit/components/profile_edit_app.vue @@ -109,8 +109,11 @@ export default { async syncHeaderAvatars() { const dataURL = await readFileAsDataURL(this.avatarBlob); - // TODO: implement sync for super sidebar - ['.header-user-avatar', '.js-sidebar-user-avatar'].forEach((selector) => { + const elements = gon?.use_new_navigation + ? ['[data-testid="user-dropdown"] .gl-avatar'] + : ['.header-user-avatar', '.js-sidebar-user-avatar']; + + elements.forEach((selector) => { const node = document.querySelector(selector); if (!node) return; diff --git a/app/assets/javascripts/profile/profile.js b/app/assets/javascripts/profile/profile.js index 947bf7acd5c..2ccb360c7c1 100644 --- a/app/assets/javascripts/profile/profile.js +++ b/app/assets/javascripts/profile/profile.js @@ -89,8 +89,12 @@ export default class Profile { } updateHeaderAvatar() { - $('.header-user-avatar').attr('src', this.avatarGlCrop.dataURL); - $('.js-sidebar-user-avatar').attr('src', this.avatarGlCrop.dataURL); + if (gon?.use_new_navigation) { + $('[data-testid="user-dropdown"] .gl-avatar').attr('src', this.avatarGlCrop.dataURL); + } else { + $('.header-user-avatar').attr('src', this.avatarGlCrop.dataURL); + $('.js-sidebar-user-avatar').attr('src', this.avatarGlCrop.dataURL); + } } setRepoRadio() { diff --git a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue index 2b2722ab329..6674937be67 100644 --- a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue +++ b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_root.vue @@ -55,6 +55,9 @@ export default { projectKey: { default: '', }, + addExternalParticipantsFromCc: { + default: false, + }, templates: { default: [], }, @@ -109,13 +112,20 @@ export default { }); }, - onSaveTemplate({ selectedTemplate, fileTemplateProjectId, outgoingName, projectKey }) { + onSaveTemplate({ + selectedTemplate, + fileTemplateProjectId, + outgoingName, + projectKey, + addExternalParticipantsFromCc, + }) { this.isTemplateSaving = true; const body = { issue_template_key: selectedTemplate, outgoing_name: outgoingName, project_key: projectKey, + add_external_participants_from_cc: addExternalParticipantsFromCc, service_desk_enabled: this.isEnabled, file_template_project_id: fileTemplateProjectId, }; @@ -187,6 +197,7 @@ export default { :initial-selected-file-template-project-id="selectedFileTemplateProjectId" :initial-outgoing-name="outgoingName" :initial-project-key="projectKey" + :initial-add-external-participants-from-cc="addExternalParticipantsFromCc" :templates="templates" :is-template-saving="isTemplateSaving" @save="onSaveTemplate" diff --git a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue index 2c447c3066e..5febb6ff0aa 100644 --- a/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue +++ b/app/assets/javascripts/projects/settings_service_desk/components/service_desk_setting.vue @@ -4,6 +4,7 @@ import { GlToggle, GlLoadingIcon, GlSprintf, + GlFormCheckbox, GlFormInputGroup, GlFormGroup, GlFormInput, @@ -11,7 +12,8 @@ import { GlAlert, } from '@gitlab/ui'; import { helpPagePath } from '~/helpers/help_page_helper'; -import { __ } from '~/locale'; +import { __, s__ } from '~/locale'; +import glFeatureFlagsMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import ClipboardButton from '~/vue_shared/components/clipboard_button.vue'; import ServiceDeskTemplateDropdown from './service_desk_template_dropdown.vue'; @@ -21,12 +23,22 @@ export default { issueTrackerEnableMessage: __( 'To use Service Desk in this project, you must %{linkStart}activate the issue tracker%{linkEnd}.', ), + addExternalParticipantsFromCc: { + label: s__('ServiceDesk|Add external participants from the %{codeStart}Cc%{codeEnd} header'), + help: s__( + 'ServiceDesk|Add email addresses in the %{codeStart}Cc%{codeEnd} header of Service Desk emails to the issue.', + ), + helpNotificationExtra: s__( + 'ServiceDesk|Like the author, external participants receive Service Desk emails and can participate in the discussion.', + ), + }, }, components: { ClipboardButton, GlButton, GlToggle, GlLoadingIcon, + GlFormCheckbox, GlSprintf, GlFormInput, GlFormGroup, @@ -35,6 +47,7 @@ export default { GlAlert, ServiceDeskTemplateDropdown, }, + mixins: [glFeatureFlagsMixin()], props: { isEnabled: { type: Boolean, @@ -78,6 +91,11 @@ export default { required: false, default: '', }, + initialAddExternalParticipantsFromCc: { + type: Boolean, + required: false, + default: false, + }, templates: { type: Array, required: false, @@ -95,11 +113,15 @@ export default { selectedFileTemplateProjectId: this.initialSelectedFileTemplateProjectId, outgoingName: this.initialOutgoingName || __('GitLab Support Bot'), projectKey: this.initialProjectKey, + addExternalParticipantsFromCc: this.initialAddExternalParticipantsFromCc, searchTerm: '', projectKeyError: null, }; }, computed: { + showAddExternalParticipantsFromCC() { + return this.glFeatures.issueEmailParticipants; + }, hasProjectKeySupport() { return Boolean(this.serviceDeskEmailEnabled); }, @@ -134,6 +156,7 @@ export default { selectedTemplate: this.selectedTemplate, outgoingName: this.outgoingName, projectKey: this.projectKey, + addExternalParticipantsFromCc: this.addExternalParticipantsFromCc, fileTemplateProjectId: this.selectedFileTemplateProjectId, }); }, @@ -299,6 +322,27 @@ export default { </template> </gl-form-group> + <gl-form-checkbox + v-if="showAddExternalParticipantsFromCC" + v-model="addExternalParticipantsFromCc" + :disabled="!isIssueTrackerEnabled" + > + <gl-sprintf :message="$options.i18n.addExternalParticipantsFromCc.label"> + <template #code="{ content }"> + <code>{{ content }}</code> + </template> + </gl-sprintf> + + <template #help> + <gl-sprintf :message="$options.i18n.addExternalParticipantsFromCc.help"> + <template #code="{ content }"> + <code>{{ content }}</code> + </template> + </gl-sprintf> + {{ $options.i18n.addExternalParticipantsFromCc.helpNotificationExtra }} + </template> + </gl-form-checkbox> + <gl-button variant="confirm" class="gl-mt-5" diff --git a/app/assets/javascripts/projects/settings_service_desk/index.js b/app/assets/javascripts/projects/settings_service_desk/index.js index c4d4f42576f..ce223b349bf 100644 --- a/app/assets/javascripts/projects/settings_service_desk/index.js +++ b/app/assets/javascripts/projects/settings_service_desk/index.js @@ -21,6 +21,7 @@ export default () => { incomingEmail, outgoingName, projectKey, + addExternalParticipantsFromCc, selectedTemplate, selectedFileTemplateProjectId, templates, @@ -39,6 +40,7 @@ export default () => { isIssueTrackerEnabled: parseBoolean(issueTrackerEnabled), outgoingName, projectKey, + addExternalParticipantsFromCc: parseBoolean(addExternalParticipantsFromCc), selectedTemplate, selectedFileTemplateProjectId: parseInt(selectedFileTemplateProjectId, 10) || null, templates: JSON.parse(templates), diff --git a/app/assets/javascripts/service_ping_consent.js b/app/assets/javascripts/service_ping_consent.js deleted file mode 100644 index 7d6e7e81f3b..00000000000 --- a/app/assets/javascripts/service_ping_consent.js +++ /dev/null @@ -1,35 +0,0 @@ -import $ from 'jquery'; -import { createAlert } from '~/alert'; -import axios from './lib/utils/axios_utils'; -import { parseBoolean } from './lib/utils/common_utils'; -import { __ } from './locale'; - -export default () => { - $('body').on('click', '.js-service-ping-consent-action', (e) => { - e.preventDefault(); - e.stopImmediatePropagation(); // overwrite rails listener - - const { url, checkEnabled, servicePingEnabled } = e.target.dataset; - const data = { - application_setting: { - version_check_enabled: parseBoolean(checkEnabled), - service_ping_enabled: parseBoolean(servicePingEnabled), - }, - }; - - const hideConsentMessage = () => - document.querySelector('.service-ping-consent-message .js-close')?.click(); - - axios - .put(url, data) - .then(() => { - hideConsentMessage(); - }) - .catch(() => { - hideConsentMessage(); - createAlert({ - message: __('Something went wrong. Try again later.'), - }); - }); - }); -}; diff --git a/app/assets/javascripts/work_items/components/shared/work_item_token_input.vue b/app/assets/javascripts/work_items/components/shared/work_item_token_input.vue index 3595ab631df..ce3d4749f17 100644 --- a/app/assets/javascripts/work_items/components/shared/work_item_token_input.vue +++ b/app/assets/javascripts/work_items/components/shared/work_item_token_input.vue @@ -4,6 +4,7 @@ import { debounce } from 'lodash'; import { getIdFromGraphQLId } from '~/graphql_shared/utils'; import { DEFAULT_DEBOUNCE_AND_THROTTLE_MS } from '~/lib/utils/constants'; +import groupWorkItemsQuery from '../../graphql/group_work_items.query.graphql'; import projectWorkItemsQuery from '../../graphql/project_work_items.query.graphql'; import { WORK_ITEMS_TYPE_MAP, @@ -15,6 +16,7 @@ export default { components: { GlTokenSelector, }, + inject: ['isGroup'], props: { value: { type: Array, @@ -47,7 +49,9 @@ export default { }, apollo: { availableWorkItems: { - query: projectWorkItemsQuery, + query() { + return this.isGroup ? groupWorkItemsQuery : projectWorkItemsQuery; + }, variables() { return { fullPath: this.fullPath, diff --git a/app/assets/javascripts/work_items/components/work_item_parent.vue b/app/assets/javascripts/work_items/components/work_item_parent.vue index 74f0ec42905..d0e83ba8c21 100644 --- a/app/assets/javascripts/work_items/components/work_item_parent.vue +++ b/app/assets/javascripts/work_items/components/work_item_parent.vue @@ -9,6 +9,7 @@ import glFeatureFlagMixin from '~/vue_shared/mixins/gl_feature_flags_mixin'; import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutation.graphql'; import { removeHierarchyChild } from '../graphql/cache_utils'; +import groupWorkItemsQuery from '../graphql/group_work_items.query.graphql'; import projectWorkItemsQuery from '../graphql/project_work_items.query.graphql'; import { I18N_WORK_ITEM_ERROR_UPDATING, @@ -97,7 +98,9 @@ export default { }, apollo: { availableWorkItems: { - query: projectWorkItemsQuery, + query() { + return this.isGroup ? groupWorkItemsQuery : projectWorkItemsQuery; + }, variables() { return { fullPath: this.fullPath, diff --git a/app/assets/javascripts/work_items/components/work_item_relationships/work_item_add_relationship_form.vue b/app/assets/javascripts/work_items/components/work_item_relationships/work_item_add_relationship_form.vue index d242db95896..c98bd6ce1e9 100644 --- a/app/assets/javascripts/work_items/components/work_item_relationships/work_item_add_relationship_form.vue +++ b/app/assets/javascripts/work_items/components/work_item_relationships/work_item_add_relationship_form.vue @@ -4,6 +4,7 @@ import { GlFormGroup, GlForm, GlFormRadioGroup, GlButton, GlAlert } from '@gitla import { __, s__ } from '~/locale'; import WorkItemTokenInput from '../shared/work_item_token_input.vue'; import addLinkedItemsMutation from '../../graphql/add_linked_items.mutation.graphql'; +import groupWorkItemByIidQuery from '../../graphql/group_work_item_by_iid.query.graphql'; import workItemByIidQuery from '../../graphql/work_item_by_iid.query.graphql'; import { LINK_ITEM_FORM_HEADER_LABEL, @@ -23,6 +24,7 @@ export default { GlAlert, WorkItemTokenInput, }, + inject: ['isGroup'], props: { workItemId: { type: String, @@ -121,7 +123,7 @@ export default { }, ) => { const queryArgs = { - query: workItemByIidQuery, + query: this.isGroup ? groupWorkItemByIidQuery : workItemByIidQuery, variables: { fullPath: this.workItemFullPath, iid: this.workItemIid }, }; const sourceData = cache.readQuery(queryArgs); diff --git a/app/assets/javascripts/work_items/components/work_item_relationships/work_item_relationships.vue b/app/assets/javascripts/work_items/components/work_item_relationships/work_item_relationships.vue index 842bdd36a58..3dc7004fbb0 100644 --- a/app/assets/javascripts/work_items/components/work_item_relationships/work_item_relationships.vue +++ b/app/assets/javascripts/work_items/components/work_item_relationships/work_item_relationships.vue @@ -147,7 +147,7 @@ export default { return; } const queryArgs = { - query: workItemByIidQuery, + query: this.isGroup ? groupWorkItemByIidQuery : workItemByIidQuery, variables: { fullPath: this.workItemFullPath, iid: this.workItemIid }, }; const sourceData = cache.readQuery(queryArgs); diff --git a/app/assets/javascripts/work_items/graphql/group_work_items.query.graphql b/app/assets/javascripts/work_items/graphql/group_work_items.query.graphql new file mode 100644 index 00000000000..320bb4a2494 --- /dev/null +++ b/app/assets/javascripts/work_items/graphql/group_work_items.query.graphql @@ -0,0 +1,19 @@ +query groupWorkItems( + $searchTerm: String + $fullPath: ID! + $types: [IssueType!] + $in: [IssuableSearchableField!] +) { + workspace: group(fullPath: $fullPath) { + id + workItems(search: $searchTerm, types: $types, in: $in) { + nodes { + id + iid + title + state + confidential + } + } + } +} diff --git a/app/helpers/ci/catalog/resources_helper.rb b/app/helpers/ci/catalog/resources_helper.rb index bc77e0cd33a..8324da870d3 100644 --- a/app/helpers/ci/catalog/resources_helper.rb +++ b/app/helpers/ci/catalog/resources_helper.rb @@ -3,8 +3,8 @@ module Ci module Catalog module ResourcesHelper - def can_add_catalog_resource?(_project) - false + def can_add_catalog_resource?(project) + can?(current_user, :add_catalog_resource, project) end def can_view_namespace_catalog?(_project) diff --git a/app/helpers/users/callouts_helper.rb b/app/helpers/users/callouts_helper.rb index b94f477de5a..8c26dd8ba9e 100644 --- a/app/helpers/users/callouts_helper.rb +++ b/app/helpers/users/callouts_helper.rb @@ -70,10 +70,6 @@ module Users !user_dismissed?(MERGE_REQUEST_SETTINGS_MOVED_CALLOUT) && project.merge_requests_enabled? end - def show_pages_menu_callout? - !user_dismissed?(PAGES_MOVED_CALLOUT) - end - def show_branch_rules_info? !user_dismissed?(BRANCH_RULES_INFO_CALLOUT) end diff --git a/app/views/events/event/_created_project.html.haml b/app/views/events/event/_created_project.html.haml index f0bb07d062c..390c9ec6c89 100644 --- a/app/views/events/event/_created_project.html.haml +++ b/app/views/events/event/_created_project.html.haml @@ -4,7 +4,7 @@ .event-title.d-flex.flex-wrap = inline_event_icon(event) - %span.event-type.d-inline-block.gl-mr-2{ class: event.action_name } + %span.event-type.d-inline-block.gl-mr-2{ class: event.action_name + user_profile_activity_classes } = event_action_name(event) - if event.project diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml index 0ad969116e0..ff7983a9ba4 100644 --- a/app/views/events/event/_push.html.haml +++ b/app/views/events/event/_push.html.haml @@ -6,7 +6,7 @@ .event-title.d-flex.flex-wrap = inline_event_icon(event) - %span.event-type.d-inline-block.gl-mr-2.pushed= event.push_activity_description + %span.event-type.d-inline-block.gl-mr-2.pushed{ class: user_profile_activity_classes }= event.push_activity_description - unless event.batch_push? %span.gl-mr-2.text-truncate - commits_link = project_commits_path(project, event.ref_name) diff --git a/app/views/projects/_service_desk_settings.html.haml b/app/views/projects/_service_desk_settings.html.haml index 907d9683823..aee61624f69 100644 --- a/app/views/projects/_service_desk_settings.html.haml +++ b/app/views/projects/_service_desk_settings.html.haml @@ -18,6 +18,7 @@ selected_file_template_project_id: "#{@project.service_desk_setting&.file_template_project_id}", outgoing_name: "#{@project.service_desk_setting&.outgoing_name}", project_key: "#{@project.service_desk_setting&.project_key}", + add_external_participants_from_cc: "#{@project.service_desk_setting&.add_external_participants_from_cc}", templates: available_service_desk_templates_for(@project), public_project: "#{@project.public?}", custom_email_endpoint: project_service_desk_custom_email_path(@project) } } diff --git a/app/views/shared/_service_ping_consent.html.haml b/app/views/shared/_service_ping_consent.html.haml index cfc0afb4646..a5e63896367 100644 --- a/app/views/shared/_service_ping_consent.html.haml +++ b/app/views/shared/_service_ping_consent.html.haml @@ -8,7 +8,7 @@ - c.with_actions do - send_service_data_path = admin_application_settings_path(application_setting: { version_check_enabled: 1, usage_ping_enabled: 1 }) - not_now_path = admin_application_settings_path(application_setting: { version_check_enabled: 0, usage_ping_enabled: 0 }) - = render Pajamas::ButtonComponent.new(href: send_service_data_path, method: :put, variant: :confirm, button_options: { 'data-url' => admin_application_settings_path, 'data-check-enabled': true, 'data-service-ping-enabled': true, class: 'js-service-ping-consent-action alert-link' }) do + = render Pajamas::ButtonComponent.new(href: send_service_data_path, method: :put, variant: :confirm, button_options: { class: 'alert-link' }) do = _('Send service data') - = render Pajamas::ButtonComponent.new(href: not_now_path, method: :put, button_options: { 'data-url' => admin_application_settings_path, 'data-check-enabled': false, 'data-service-ping-enabled': false, class: 'js-service-ping-consent-action alert-link gl-ml-3' }) do + = render Pajamas::ButtonComponent.new(href: not_now_path, method: :put, button_options: { class: 'alert-link gl-ml-3' }) do = _("Don't send service data") diff --git a/config/feature_flags/development/build_service_proxy.yml b/config/feature_flags/development/build_service_proxy.yml index 8032a39e959..cefb88b7b24 100644 --- a/config/feature_flags/development/build_service_proxy.yml +++ b/config/feature_flags/development/build_service_proxy.yml @@ -1,8 +1,8 @@ --- name: build_service_proxy introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/9723 -rollout_issue_url: +rollout_issue_url: milestone: '11.11' type: development -group: group::editor +group: group::ide default_enabled: false diff --git a/config/feature_flags/development/ci_require_credit_card_on_free_plan.yml b/config/feature_flags/development/ci_require_credit_card_on_free_plan.yml index 7e5795de6a0..8816e0ebec4 100644 --- a/config/feature_flags/development/ci_require_credit_card_on_free_plan.yml +++ b/config/feature_flags/development/ci_require_credit_card_on_free_plan.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61152 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/330104 milestone: '13.12' type: development -group: group::fulfillment +group: group::anti-abuse default_enabled: false diff --git a/config/feature_flags/development/ci_require_credit_card_on_trial_plan.yml b/config/feature_flags/development/ci_require_credit_card_on_trial_plan.yml index 578101a1ba4..402a2b42310 100644 --- a/config/feature_flags/development/ci_require_credit_card_on_trial_plan.yml +++ b/config/feature_flags/development/ci_require_credit_card_on_trial_plan.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/61152 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/330105 milestone: '13.12' type: development -group: group::fulfillment +group: group::anti-abuse default_enabled: false diff --git a/config/feature_flags/development/code_suggestions_for_instance_admin_enabled.yml b/config/feature_flags/development/code_suggestions_for_instance_admin_enabled.yml index 1a7b2356f55..5df6440bd5b 100644 --- a/config/feature_flags/development/code_suggestions_for_instance_admin_enabled.yml +++ b/config/feature_flags/development/code_suggestions_for_instance_admin_enabled.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/122645 rollout_issue_url: milestone: '16.1' type: development -group: group::application performance +group: group::cloud connector default_enabled: false diff --git a/config/feature_flags/development/personal_snippet_reference_filters.yml b/config/feature_flags/development/personal_snippet_reference_filters.yml index eb97a2caf0d..099378f7da0 100644 --- a/config/feature_flags/development/personal_snippet_reference_filters.yml +++ b/config/feature_flags/development/personal_snippet_reference_filters.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38571 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/235155 milestone: '13.3' type: development -group: group::editor +group: group::source code default_enabled: false diff --git a/config/feature_flags/development/preserve_unchanged_markdown.yml b/config/feature_flags/development/preserve_unchanged_markdown.yml index 55e5d913389..8d0dc879bdb 100644 --- a/config/feature_flags/development/preserve_unchanged_markdown.yml +++ b/config/feature_flags/development/preserve_unchanged_markdown.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/86060 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/360713 milestone: '15.0' type: development -group: group::editor +group: group::knowledge default_enabled: false diff --git a/config/feature_flags/development/reject_unsigned_commits_by_gitlab.yml b/config/feature_flags/development/reject_unsigned_commits_by_gitlab.yml index 93c0026d59d..d44e1e22902 100644 --- a/config/feature_flags/development/reject_unsigned_commits_by_gitlab.yml +++ b/config/feature_flags/development/reject_unsigned_commits_by_gitlab.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/58453 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/326775 milestone: '13.11' type: development -group: group::editor +group: group::ide default_enabled: true diff --git a/config/feature_flags/development/source_editor_toolbar.yml b/config/feature_flags/development/source_editor_toolbar.yml index 6fe2dd2d306..6d8a749b945 100644 --- a/config/feature_flags/development/source_editor_toolbar.yml +++ b/config/feature_flags/development/source_editor_toolbar.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/82304 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/354748 milestone: '14.9' type: development -group: group::editor +group: group::source code default_enabled: false diff --git a/config/feature_flags/development/sourcegraph.yml b/config/feature_flags/development/sourcegraph.yml index f9aa76f6c7c..0b9e45ef4b4 100644 --- a/config/feature_flags/development/sourcegraph.yml +++ b/config/feature_flags/development/sourcegraph.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/16556 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/292199 milestone: '12.5' type: development -group: group::editor +group: group::source code default_enabled: true diff --git a/config/feature_flags/development/summarize_notes_with_anthropic.yml b/config/feature_flags/development/summarize_notes_with_anthropic.yml new file mode 100644 index 00000000000..d9e91748d5a --- /dev/null +++ b/config/feature_flags/development/summarize_notes_with_anthropic.yml @@ -0,0 +1,8 @@ +--- +name: summarize_notes_with_anthropic +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/134731 +rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/work_items/430196 +milestone: '16.6' +type: development +group: group::duo chat +default_enabled: false diff --git a/config/feature_flags/development/vscode_web_ide.yml b/config/feature_flags/development/vscode_web_ide.yml index dc9d9d5f5f1..93f4141ed97 100644 --- a/config/feature_flags/development/vscode_web_ide.yml +++ b/config/feature_flags/development/vscode_web_ide.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/95169 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/371084 milestone: '15.4' type: development -group: group::editor +group: group::ide default_enabled: true diff --git a/config/feature_flags/development/wiki_front_matter.yml b/config/feature_flags/development/wiki_front_matter.yml index 20316142c41..6e4cf0db88b 100644 --- a/config/feature_flags/development/wiki_front_matter.yml +++ b/config/feature_flags/development/wiki_front_matter.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/27706 rollout_issue_url: milestone: '12.10' type: development -group: group::editor +group: group::knowledge default_enabled: false diff --git a/config/feature_flags/ops/code_suggestions_tokens_api.yml b/config/feature_flags/ops/code_suggestions_tokens_api.yml index 9fc2a5358cc..2de8afc0428 100644 --- a/config/feature_flags/ops/code_suggestions_tokens_api.yml +++ b/config/feature_flags/ops/code_suggestions_tokens_api.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120892 rollout_issue_url: milestone: '16.1' type: ops -group: group::ai assisted +group: group::ai model validation default_enabled: true diff --git a/config/feature_flags/ops/enforce_memory_watchdog.yml b/config/feature_flags/ops/enforce_memory_watchdog.yml index ae0ab81f9f6..e87e897d223 100644 --- a/config/feature_flags/ops/enforce_memory_watchdog.yml +++ b/config/feature_flags/ops/enforce_memory_watchdog.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91910 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/367534 milestone: '15.2' type: ops -group: group::application performance +group: group::cloud connector default_enabled: true diff --git a/config/feature_flags/ops/report_heap_dumps.yml b/config/feature_flags/ops/report_heap_dumps.yml index 12b126a8f80..9583ebd9970 100644 --- a/config/feature_flags/ops/report_heap_dumps.yml +++ b/config/feature_flags/ops/report_heap_dumps.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106406 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/385175 milestone: '15.7' type: ops -group: group::application performance +group: group::cloud connector default_enabled: false diff --git a/config/feature_flags/ops/report_jemalloc_stats.yml b/config/feature_flags/ops/report_jemalloc_stats.yml index 61fbfa26206..f2a34dae232 100644 --- a/config/feature_flags/ops/report_jemalloc_stats.yml +++ b/config/feature_flags/ops/report_jemalloc_stats.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/91283 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/367845 milestone: '15.2' type: ops -group: group::application performance +group: group::cloud connector default_enabled: false diff --git a/config/feature_flags/ops/suggested_reviewers_internal_api.yml b/config/feature_flags/ops/suggested_reviewers_internal_api.yml index 44e197307a5..62cdf94a5b9 100644 --- a/config/feature_flags/ops/suggested_reviewers_internal_api.yml +++ b/config/feature_flags/ops/suggested_reviewers_internal_api.yml @@ -4,5 +4,5 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/106648 rollout_issue_url: milestone: '15.7' type: ops -group: group::ai assisted +group: group::ai model validation default_enabled: true diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb index 96a81c7be15..960caf1dc35 100644 --- a/config/initializers/1_settings.rb +++ b/config/initializers/1_settings.rb @@ -799,15 +799,9 @@ Gitlab.ee do Settings.cron_jobs['llm_embedding_gitlab_documentation_create_empty_embeddings_records_worker'] ||= {} Settings.cron_jobs['llm_embedding_gitlab_documentation_create_empty_embeddings_records_worker']['cron'] ||= '0 5 * * 1,2,3,4,5' Settings.cron_jobs['llm_embedding_gitlab_documentation_create_empty_embeddings_records_worker']['job_class'] ||= 'Llm::Embedding::GitlabDocumentation::CreateEmptyEmbeddingsRecordsWorker' - Settings.cron_jobs['tanuki_bot_recreate_records_worker'] ||= {} - Settings.cron_jobs['tanuki_bot_recreate_records_worker']['cron'] ||= '0 5 * * 1,2,3,4,5' - Settings.cron_jobs['tanuki_bot_recreate_records_worker']['job_class'] ||= 'Llm::TanukiBot::RecreateRecordsWorker' Settings.cron_jobs['llm_embedding_gitlab_documentation_cleanup_previous_versions_records_worker'] ||= {} Settings.cron_jobs['llm_embedding_gitlab_documentation_cleanup_previous_versions_records_worker']['cron'] ||= '0 0 * * *' Settings.cron_jobs['llm_embedding_gitlab_documentation_cleanup_previous_versions_records_worker']['job_class'] ||= 'Llm::Embedding::GitlabDocumentation::CleanupPreviousVersionsRecordsWorker' - Settings.cron_jobs['tanuki_bot_remove_previous_records_worker'] ||= {} - Settings.cron_jobs['tanuki_bot_remove_previous_records_worker']['cron'] ||= '0 0 * * *' - Settings.cron_jobs['tanuki_bot_remove_previous_records_worker']['job_class'] ||= 'Llm::TanukiBot::RemovePreviousRecordsWorker' Settings.cron_jobs['users_create_statistics_worker'] ||= {} Settings.cron_jobs['users_create_statistics_worker']['cron'] ||= '2 15 * * *' Settings.cron_jobs['users_create_statistics_worker']['job_class'] = 'Users::CreateStatisticsWorker' diff --git a/db/migrate/20231030205756_index_user_details_on_enterprise_group_id_and_user_id.rb b/db/migrate/20231030205756_index_user_details_on_enterprise_group_id_and_user_id.rb new file mode 100644 index 00000000000..a993944e152 --- /dev/null +++ b/db/migrate/20231030205756_index_user_details_on_enterprise_group_id_and_user_id.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +class IndexUserDetailsOnEnterpriseGroupIdAndUserId < Gitlab::Database::Migration[2.2] + milestone '16.6' + + disable_ddl_transaction! + + INDEX_NAME = 'index_user_details_on_enterprise_group_id_and_user_id' + INDEX_NAME_TO_REMOVE = 'index_user_details_on_enterprise_group_id' + + def up + add_concurrent_index(:user_details, [:enterprise_group_id, :user_id], name: INDEX_NAME) + + remove_concurrent_index_by_name :user_details, INDEX_NAME_TO_REMOVE + end + + def down + remove_concurrent_index_by_name :user_details, INDEX_NAME + + add_concurrent_index :user_details, :enterprise_group_id, name: INDEX_NAME_TO_REMOVE + end +end diff --git a/db/schema_migrations/20231030205756 b/db/schema_migrations/20231030205756 new file mode 100644 index 00000000000..3923ee6dbd0 --- /dev/null +++ b/db/schema_migrations/20231030205756 @@ -0,0 +1 @@ +fd45299e8376db582461fa4b714b3718c4f589bc087d73465ac51d04437e07c3
\ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index 76bc41b3bda..3381764ee2e 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -34594,7 +34594,7 @@ CREATE INDEX index_user_custom_attributes_on_key_and_value ON user_custom_attrib CREATE UNIQUE INDEX index_user_custom_attributes_on_user_id_and_key ON user_custom_attributes USING btree (user_id, key); -CREATE INDEX index_user_details_on_enterprise_group_id ON user_details USING btree (enterprise_group_id); +CREATE INDEX index_user_details_on_enterprise_group_id_and_user_id ON user_details USING btree (enterprise_group_id, user_id); CREATE INDEX index_user_details_on_password_last_changed_at ON user_details USING btree (password_last_changed_at); diff --git a/doc/api/settings.md b/doc/api/settings.md index 03877c6c489..3c64e295b27 100644 --- a/doc/api/settings.md +++ b/doc/api/settings.md @@ -19,6 +19,7 @@ For information on how to control the application settings cache for an instance > - `always_perform_delayed_deletion` feature flag [enabled](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/113332) in GitLab 15.11. > - `delayed_project_deletion` and `delayed_group_deletion` attributes removed in GitLab 16.0. +> - `in_product_marketing_emails_enabled` attribute [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/418137) in GitLab 16.6. List the current [application settings](#list-of-settings-that-can-be-accessed-via-api-calls) of the GitLab instance. @@ -452,7 +453,6 @@ listed in the descriptions of the relevant settings. | `housekeeping_optimize_repository_period`| integer | no | Number of Git pushes after which an incremental `git repack` is run. | | `html_emails_enabled` | boolean | no | Enable HTML emails. | | `import_sources` | array of strings | no | Sources to allow project import from, possible values: `github`, `bitbucket`, `bitbucket_server`, `fogbugz`, `git`, `gitlab_project`, `gitea`, and `manifest`. | -| `in_product_marketing_emails_enabled` | boolean | no | Enable [in-product marketing emails](../user/profile/notifications.md#global-notification-settings). Enabled by default. | | `invisible_captcha_enabled` | boolean | no | Enable Invisible CAPTCHA spam detection during sign-up. Disabled by default. | | `issues_create_limit` | integer | no | Max number of issue creation requests per minute per user. Disabled by default.| | `keep_latest_artifact` | boolean | no | Prevent the deletion of the artifacts from the most recent successful jobs, regardless of the expiry time. Enabled by default. | diff --git a/doc/development/feature_flags/index.md b/doc/development/feature_flags/index.md index 552a4ccc84b..c1a5963e97f 100644 --- a/doc/development/feature_flags/index.md +++ b/doc/development/feature_flags/index.md @@ -203,7 +203,7 @@ Only feature flags that have a YAML definition file can be used when running the ```shell $ bin/feature-flag my_feature_flag >> Specify the group introducing the feature flag, like `group::project management`: -?> group::application performance +?> group::cloud connector >> URL of the MR introducing the feature flag (enter to skip): ?> https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38602 @@ -218,7 +218,7 @@ create config/feature_flags/development/my_feature_flag.yml name: my_feature_flag introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/38602 rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/232533 -group: group::application performance +group: group::cloud connector type: development default_enabled: false ``` @@ -625,7 +625,7 @@ A common pattern of testing both paths looks like: ```ruby it 'ci_live_trace works' do # tests assuming ci_live_trace is enabled in tests by default - Feature.enabled?(:ci_live_trace) # => true + Feature.enabled?(:ci_live_trace) # => true end context 'when ci_live_trace is disabled' do diff --git a/doc/user/group/index.md b/doc/user/group/index.md index 484fd8c533b..ab8cba48dc4 100644 --- a/doc/user/group/index.md +++ b/doc/user/group/index.md @@ -219,7 +219,7 @@ Filter a group to find members. By default, all members in the group and subgrou In lists of group members, entries can display the following badges: - **SAML**, to indicate the member has a [SAML account](saml_sso/index.md) connected to them. -- **Enterprise**, to indicate that the member is an [enterprise user](../enterprise_user/index.md). +- **Enterprise**, to indicate that the member of the top-level group is an [enterprise user](../enterprise_user/index.md). 1. On the left sidebar, select **Search or go to** and find your group. 1. Select **Manage > Members**. @@ -227,7 +227,7 @@ In lists of group members, entries can display the following badges: - To view members in the group only, select **Membership = Direct**. - To view members of the group and its subgroups, select **Membership = Inherited**. - To view members with two-factor authentication enabled or disabled, select **2FA = Enabled** or **Disabled**. - - [In GitLab 14.0 and later](https://gitlab.com/gitlab-org/gitlab/-/issues/349887), to view GitLab users created by [SAML SSO](saml_sso/index.md) or [SCIM provisioning](saml_sso/scim_setup.md) select **Enterprise = true**. + - To view members of the top-level group who are [enterprise users](../enterprise_user/index.md), select **Enterprise = true**. ### Search a group diff --git a/doc/user/profile/notifications.md b/doc/user/profile/notifications.md index 706065d4693..8d34055d42c 100644 --- a/doc/user/profile/notifications.md +++ b/doc/user/profile/notifications.md @@ -9,6 +9,7 @@ info: To determine the technical writer assigned to the Stage/Group associated w > - Enhanced email styling [introduced](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/78604) in GitLab 14.9 [with a feature flag](../../administration/feature_flags.md) named `enhanced_notify_css`. Disabled by default. > - Enhanced email styling [enabled on GitLab.com](https://gitlab.com/gitlab-org/gitlab/-/issues/355907) in GitLab 14.9. > - Enhanced email styling [enabled on self-managed](https://gitlab.com/gitlab-org/gitlab/-/issues/355907) in GitLab 15.0. +> - Product marketing emails [removed](https://gitlab.com/gitlab-org/gitlab/-/issues/418137) in GitLab 16.6. Stay informed about what's happening in GitLab with email notifications. You can receive updates about activity in issues, merge requests, epics, and designs. @@ -84,8 +85,6 @@ different values for a project or a group. - **Notification email**: the email address your notifications are sent to. Defaults to your primary email address. -- **Receive product marketing emails**: select this checkbox to receive - [periodic emails](#opt-out-of-product-marketing-emails) about GitLab features. - **Global notification level**: the default [notification level](#notification-levels) which applies to all your notifications. - **Receive notifications about your own activity**: select this checkbox to receive @@ -145,32 +144,6 @@ Or: <i class="fa fa-youtube-play youtube" aria-hidden="true"></i> To learn how to be notified when a new release is available, watch [Notification for releases](https://www.youtube.com/watch?v=qyeNkGgqmH4). -### Opt out of product marketing emails - -You can receive emails that teach you about various GitLab features. -These emails are enabled by default. - -To opt out: - -1. On the left sidebar, select your avatar. -1. Select **Preferences**. -1. On the left sidebar, select **Notifications**. -1. Clear the **Receive product marketing emails** checkbox. - Edited settings are automatically saved and enabled. - -Disabling these emails does not disable all emails. -Learn how to [opt out of all emails from GitLab](#opt-out-of-all-gitlab-emails). - -#### Self-managed product marketing emails **(FREE SELF)** - -The self-managed installation generates and automatically sends these emails based on user actions. -Turning this on does not cause your GitLab instance or your company to send any personal information to -GitLab Inc. - -An instance administrator can configure this setting for all users. If you choose to opt out, your -setting overrides the instance-wide setting, even when an administrator later enables these emails -for all users. - ## Notification events Users are notified of the following events: @@ -348,7 +321,6 @@ If you no longer wish to receive any email notifications: 1. On the left sidebar, select your avatar. 1. Select **Preferences**. 1. On the left sidebar, select **Notifications**. -1. Clear the **Receive product marketing emails** checkbox. 1. Set your **Global notification level** to **Disabled**. 1. Clear the **Receive notifications about your own activity** checkbox. 1. If you belong to any groups or projects, set their notification setting to **Global** or diff --git a/doc/user/project/service_desk/configure.md b/doc/user/project/service_desk/configure.md index 172a105cc28..8d0fbd81ebd 100644 --- a/doc/user/project/service_desk/configure.md +++ b/doc/user/project/service_desk/configure.md @@ -191,6 +191,8 @@ The custom email address you want to use must meet all of the following requirem by any text to the local part. Given the email address `support@example.com`, check whether sub-addressing is supported by sending an email to `support+1@example.com`. This email should appear in your mailbox. - You have SMTP credentials (ideally, you should use an app password). + The username and password are stored in the database using the Advanced Encryption Standard (AES) + with a 256-bit key. - You must have at least the Maintainer role for the project. - Service Desk must be configured for the project. diff --git a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml index 9620a214792..6898923bc53 100644 --- a/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Jobs/Build.gitlab-ci.yml @@ -1,5 +1,5 @@ variables: - AUTO_BUILD_IMAGE_VERSION: 'v1.46.0' + AUTO_BUILD_IMAGE_VERSION: 'v1.49.0' build: stage: build diff --git a/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml b/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml index 9620a214792..6898923bc53 100644 --- a/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml +++ b/lib/gitlab/ci/templates/Jobs/Build.latest.gitlab-ci.yml @@ -1,5 +1,5 @@ variables: - AUTO_BUILD_IMAGE_VERSION: 'v1.46.0' + AUTO_BUILD_IMAGE_VERSION: 'v1.49.0' build: stage: build diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 50f5efeb5cc..9f16738dcaa 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -41508,10 +41508,10 @@ msgstr "" msgid "Runners|Tags control which type of jobs a runner can handle. By tagging a runner, you make sure shared runners only handle the jobs they are equipped to run." msgstr "" -msgid "Runners|The %{boldStart}runner token%{boldEnd} %{token} displays %{boldStart}only for a short time%{boldEnd}, and is stored in the %{codeStart}config.toml%{codeEnd} after you register the runner. It will not be visible once the runner is registered." +msgid "Runners|The %{boldStart}runner authentication token%{boldEnd} %{token} displays here %{boldStart}for a short time only%{boldEnd}. After you register the runner, this token is stored in the %{codeStart}config.toml%{codeEnd} and cannot be accessed again from the UI." msgstr "" -msgid "Runners|The %{boldStart}runner token%{boldEnd} is no longer visible, it is stored in the %{codeStart}config.toml%{codeEnd} if you have registered the runner." +msgid "Runners|The %{boldStart}runner authentication token%{boldEnd} is no longer visible, it is stored in the %{codeStart}config.toml%{codeEnd} if you have registered the runner." msgstr "" msgid "Runners|The project, group or instance where the runner was registered. Instance runners are always owned by Administrator." @@ -44082,6 +44082,12 @@ msgstr "" msgid "ServiceDesk|A verification email has been sent to a sub-address of your custom email address. This can take up to 30 minutes. The screen refreshes automatically." msgstr "" +msgid "ServiceDesk|Add email addresses in the %{codeStart}Cc%{codeEnd} header of Service Desk emails to the issue." +msgstr "" + +msgid "ServiceDesk|Add external participants from the %{codeStart}Cc%{codeEnd} header" +msgstr "" + msgid "ServiceDesk|Cannot create custom email" msgstr "" @@ -44157,6 +44163,9 @@ msgstr "" msgid "ServiceDesk|Keep custom email" msgstr "" +msgid "ServiceDesk|Like the author, external participants receive Service Desk emails and can participate in the discussion." +msgstr "" + msgid "ServiceDesk|Minimum 8 characters long." msgstr "" @@ -45559,9 +45568,6 @@ msgstr "" msgid "Something went wrong. Please try again." msgstr "" -msgid "Something went wrong. Try again later." -msgstr "" - msgid "Something went wrong. Unable to create identity verification exemption." msgstr "" @@ -50286,6 +50292,9 @@ msgstr "" msgid "Tracing|%{ms} ms" msgstr "" +msgid "Tracing|Attribute" +msgstr "" + msgid "Tracing|Check again" msgstr "" @@ -50379,9 +50388,15 @@ msgstr "" msgid "Tracing|longer than" msgstr "" +msgid "Tracing|name" +msgstr "" + msgid "Tracing|shorter than" msgstr "" +msgid "Tracing|value" +msgstr "" + msgid "Track groups of issues that share a theme, across projects and milestones" msgstr "" diff --git a/package.json b/package.json index cf61540faca..4954e17ae8f 100644 --- a/package.json +++ b/package.json @@ -286,7 +286,6 @@ "timezone-mock": "^1.0.8", "vite": "^4.4.9", "vite-plugin-ruby": "^3.2.2", - "vite-svg-loader": "^3.6.0", "vue-loader-vue3": "npm:vue-loader@17", "vue-test-utils-compat": "0.0.14", "vuex-mock-store": "^0.1.0", diff --git a/scripts/lint/ruby-metrics-abc.rb b/scripts/lint/ruby-metrics-abc.rb new file mode 100755 index 00000000000..bea7be14a1e --- /dev/null +++ b/scripts/lint/ruby-metrics-abc.rb @@ -0,0 +1,62 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +require "rubocop" + +# Shows ABC size of methods and blocks for passed files. +# +# See https://docs.rubocop.org/rubocop/cops_metrics.html#metricsabcsize +# +# Usage: scripts/ruby-metrics-abc.rb <ruby file> ... +# Example: scripts/ruby-metrics-abc.rb app/models/project.rb app/models/user.rb + +module Tooling + class MetricsABC + extend RuboCop::AST::NodePattern::Macros + include RuboCop::AST::Traversal + + def run(source) + version = RUBY_VERSION[/^(\d+\.\d+)/, 1].to_f + ast = RuboCop::AST::ProcessedSource.new(source, version).ast + + walk(ast) + end + + def on_def(node) + print_abc("def #{node.method_name}", node) + end + + def on_defs(node) + print_abc("def self.#{node.method_name}", node) + end + + def on_block(node) + return unless node.parent&.send_type? + + method_name = node.parent.method_name + arguments = node.parent.arguments.select { |n| n.sym_type? || n.str_type? }.map(&:source) + + print_abc("#{method_name}(#{arguments.join(', ')})", node) + end + + private + + def print_abc(prefix, node) + # https://www.rubydoc.info/gems/rubocop/RuboCop/Cop/Metrics/Utils/AbcSizeCalculator#calculate-instance_method + abc_score, abc_vector = RuboCop::Cop::Metrics::Utils::AbcSizeCalculator + .calculate(node, discount_repeated_attributes: true) # rubocop:disable CodeReuse/ActiveRecord -- This is not AR + puts format(" %d: %s: %.2f %s", node.first_line, prefix, abc_score, abc_vector) + end + end + + if ARGV.empty? + puts "Usage: scripts/ruby-metrics-abc.rb <ruby file> ..." + puts " Example: scripts/ruby-metrics-abc.rb app/models/project.rb app/models/user.rb" + end + + ARGV.each do |file| + puts "Checking #{file}:" + + MetricsABC.new.run(File.read(file)) + end +end diff --git a/spec/features/groups/settings/packages_and_registries_spec.rb b/spec/features/groups/settings/packages_and_registries_spec.rb index fa310722860..cbd26441e2b 100644 --- a/spec/features/groups/settings/packages_and_registries_spec.rb +++ b/spec/features/groups/settings/packages_and_registries_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'Group Package and registry settings', feature_category: :package_registry do include WaitForRequests - let(:user) { create(:user, :no_super_sidebar) } + let(:user) { create(:user) } let(:group) { create(:group) } let(:sub_group) { create(:group, parent: group) } @@ -20,12 +20,13 @@ RSpec.describe 'Group Package and registry settings', feature_category: :package stub_packages_setting(enabled: false) end - it 'the menu item is not visible' do + it 'the menu item is not visible', :js do visit group_path(group) - settings_menu = find_settings_menu - - expect(settings_menu).not_to have_content 'Packages and registries' + within_testid('super-sidebar') do + click_button 'Settings' + expect(page).not_to have_content 'Packages and registries' + end end it 'renders 404 when navigating to page' do @@ -36,11 +37,13 @@ RSpec.describe 'Group Package and registry settings', feature_category: :package end context 'when packages feature is enabled on the group' do - it 'the menu item is visible' do + it 'the menu item is visible', :js do visit group_path(group) - settings_menu = find_settings_menu - expect(settings_menu).to have_content 'Packages and registries' + within_testid('super-sidebar') do + click_button 'Settings' + expect(page).to have_content 'Packages and registries' + end end it 'has a page title set' do @@ -49,11 +52,12 @@ RSpec.describe 'Group Package and registry settings', feature_category: :package expect(page).to have_title _('Packages and registries settings') end - it 'sidebar menu is open' do + it 'sidebar menu is open', :js do visit_settings_page - sidebar = find('.nav-sidebar') - expect(sidebar).to have_link _('Packages and registries') + within_testid('super-sidebar') do + expect(page).to have_link _('Packages and registries') + end end it 'passes axe automated accessibility testing', :js do @@ -62,7 +66,7 @@ RSpec.describe 'Group Package and registry settings', feature_category: :package wait_for_requests expect(page).to be_axe_clean.within('[data-testid="packages-and-registries-group-settings"]') - .skipping :'link-in-text-block' + .skipping :'link-in-text-block', :'heading-order' end it 'has a Duplicate packages section', :js do @@ -124,10 +128,6 @@ RSpec.describe 'Group Package and registry settings', feature_category: :package end end - def find_settings_menu - find('.shortcuts-settings ul') - end - def visit_settings_page visit group_settings_packages_and_registries_path(group) end diff --git a/spec/features/projects/settings/monitor_settings_spec.rb b/spec/features/projects/settings/monitor_settings_spec.rb index c2914c020e3..fca10d9c0b0 100644 --- a/spec/features/projects/settings/monitor_settings_spec.rb +++ b/spec/features/projects/settings/monitor_settings_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe 'Projects > Settings > For a forked project', :js, feature_category: :groups_and_projects do include ListboxHelpers - let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, :repository, create_templates: :issue, namespace: user.namespace) } before do @@ -15,13 +15,10 @@ RSpec.describe 'Projects > Settings > For a forked project', :js, feature_catego describe 'Sidebar > Monitor' do it 'renders the menu in the sidebar' do visit project_path(project) - wait_for_requests - expect(page).to have_selector( - '.sidebar-sub-level-items a[aria-label="Error Tracking"]', - text: 'Error Tracking', - visible: :hidden - ) + within_testid('super-sidebar') do + expect(page).to have_link('Error Tracking', visible: :hidden) + end end end diff --git a/spec/features/projects/settings/registry_settings_cleanup_tags_spec.rb b/spec/features/projects/settings/registry_settings_cleanup_tags_spec.rb index ee54065fdf8..1b53a6222e6 100644 --- a/spec/features/projects/settings/registry_settings_cleanup_tags_spec.rb +++ b/spec/features/projects/settings/registry_settings_cleanup_tags_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'Project > Settings > Packages and registries > Container registry tag expiration policy', feature_category: :groups_and_projects do - let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:user) { create(:user) } let_it_be(:project, reload: true) { create(:project, namespace: user.namespace) } let(:container_registry_enabled) { true } @@ -24,9 +24,10 @@ RSpec.describe 'Project > Settings > Packages and registries > Container registr it 'shows active tab on sidebar' do subject - expect(find('.sidebar-top-level-items > li.active')).to have_content('Settings') - expect(find('.sidebar-sub-level-items > li.active:not(.fly-out-top-item)')) - .to have_content('Packages and registries') + within_testid('super-sidebar') do + expect(page).to have_selector('button[aria-expanded="true"]', text: 'Settings') + expect(page).to have_selector('[aria-current="page"]', text: 'Packages and registries') + end end it 'shows available section' do @@ -44,7 +45,7 @@ RSpec.describe 'Project > Settings > Packages and registries > Container registr wait_for_requests expect(page).to be_axe_clean.within('[data-testid="container-expiration-policy-project-settings"]') - .skipping :'link-in-text-block' + .skipping :'link-in-text-block', :'heading-order' end it 'saves cleanup policy submit the form' do diff --git a/spec/features/projects/settings/registry_settings_spec.rb b/spec/features/projects/settings/registry_settings_spec.rb index 7f0367f47f7..d6e08628721 100644 --- a/spec/features/projects/settings/registry_settings_spec.rb +++ b/spec/features/projects/settings/registry_settings_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'Project > Settings > Packages and registries > Container registry tag expiration policy', feature_category: :groups_and_projects do - let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:user) { create(:user) } let_it_be(:project, reload: true) { create(:project, namespace: user.namespace) } let(:container_registry_enabled) { true } @@ -27,15 +27,16 @@ RSpec.describe 'Project > Settings > Packages and registries > Container registr wait_for_requests expect(page).to be_axe_clean.within('[data-testid="packages-and-registries-project-settings"]') - .skipping :'link-in-text-block' + .skipping :'link-in-text-block', :'heading-order' end it 'shows active tab on sidebar' do subject - expect(find('.sidebar-top-level-items > li.active')).to have_content('Settings') - expect(find('.sidebar-sub-level-items > li.active:not(.fly-out-top-item)')) - .to have_content('Packages and registries') + within_testid('super-sidebar') do + expect(page).to have_selector('button[aria-expanded="true"]', text: 'Settings') + expect(page).to have_selector('[aria-current="page"]', text: 'Packages and registries') + end end it 'shows available section' do diff --git a/spec/features/projects/show/user_sees_collaboration_links_spec.rb b/spec/features/projects/show/user_sees_collaboration_links_spec.rb index 626d4de7baf..f231b4a591a 100644 --- a/spec/features/projects/show/user_sees_collaboration_links_spec.rb +++ b/spec/features/projects/show/user_sees_collaboration_links_spec.rb @@ -6,14 +6,14 @@ RSpec.describe 'Projects > Show > Collaboration links', :js, feature_category: : using RSpec::Parameterized::TableSyntax let_it_be(:project) { create(:project, :repository, :public) } - let_it_be(:user) { create(:user, :no_super_sidebar) } + let_it_be(:user) { create(:user) } before do sign_in(user) end def find_new_menu_toggle - find('#js-onboarding-new-project-link') + find('[data-testid="base-dropdown-toggle"]', text: 'Create new...') end context 'with developer user' do @@ -25,7 +25,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js, feature_category: : visit project_path(project) # The navigation bar - page.within('.header-new') do + within_testid('super-sidebar') do find_new_menu_toggle.click aggregate_failures 'dropdown links in the navigation bar' do @@ -60,7 +60,7 @@ RSpec.describe 'Projects > Show > Collaboration links', :js, feature_category: : visit project_path(project) - page.within('.header-new') do + within_testid('super-sidebar') do find_new_menu_toggle.click aggregate_failures 'dropdown links' do diff --git a/spec/features/projects/user_sees_sidebar_spec.rb b/spec/features/projects/user_sees_sidebar_spec.rb index 22d00e9a351..61225b45760 100644 --- a/spec/features/projects/user_sees_sidebar_spec.rb +++ b/spec/features/projects/user_sees_sidebar_spec.rb @@ -2,8 +2,8 @@ require 'spec_helper' -RSpec.describe 'Projects > User sees sidebar', feature_category: :groups_and_projects do - let(:user) { create(:user, :no_super_sidebar) } +RSpec.describe 'Projects > User sees sidebar', :js, feature_category: :groups_and_projects do + let(:user) { create(:user) } let(:project) { create(:project, :private, public_builds: false, namespace: user.namespace) } # NOTE: See documented behaviour https://design.gitlab.com/regions/navigation#contextual-navigation @@ -14,44 +14,25 @@ RSpec.describe 'Projects > User sees sidebar', feature_category: :groups_and_pro sign_in(user) end - shared_examples 'has a expanded nav sidebar' do - it 'has a expanded desktop nav-sidebar on load' do - expect(page).to have_content('Collapse sidebar') - expect(page).not_to have_selector('.sidebar-collapsed-desktop') - expect(page).not_to have_selector('.sidebar-expanded-mobile') + shared_examples 'has an expanded nav sidebar' do + it 'has an expanded nav sidebar on load' do + expect(page).to have_selector('[data-testid="super-sidebar-collapse-button"]', visible: :visible) end - it 'can collapse the nav-sidebar' do - page.find('.nav-sidebar .js-toggle-sidebar').click - expect(page).to have_selector('.sidebar-collapsed-desktop') - expect(page).not_to have_content('Collapse sidebar') - expect(page).not_to have_selector('.sidebar-expanded-mobile') + it 'can collapse the nav sidebar' do + find_by_testid('super-sidebar-collapse-button').click + expect(page).to have_selector('[data-testid="super-sidebar-collapse-button"]', visible: :hidden) end end shared_examples 'has a collapsed nav sidebar' do - it 'has a collapsed desktop nav-sidebar on load' do - expect(page).not_to have_content('Collapse sidebar') - expect(page).not_to have_selector('.sidebar-expanded-mobile') + it 'has a collapsed nav sidebar on load' do + expect(page).to have_selector('[data-testid="super-sidebar-collapse-button"]', visible: :hidden) end - it 'can expand the nav-sidebar' do - page.find('.nav-sidebar .js-toggle-sidebar').click - expect(page).to have_selector('.sidebar-expanded-mobile') - expect(page).to have_content('Collapse sidebar') - end - end - - shared_examples 'has a mobile nav-sidebar' do - it 'has a hidden nav-sidebar on load' do - expect(page).not_to have_content('.mobile-nav-open') - expect(page).not_to have_selector('.sidebar-expanded-mobile') - end - - it 'can expand the nav-sidebar' do - page.find('.toggle-mobile-nav').click - expect(page).to have_selector('.mobile-nav-open') - expect(page).to have_selector('.sidebar-expanded-mobile') + it 'can expand the nav sidebar' do + page.find('.js-super-sidebar-toggle-expand').click + expect(page).to have_selector('[data-testid="super-sidebar-collapse-button"]', visible: :visible) end end @@ -59,29 +40,24 @@ RSpec.describe 'Projects > User sees sidebar', feature_category: :groups_and_pro before do resize_screen_xs visit project_path(project) - expect(page).to have_selector('.nav-sidebar') - expect(page).to have_selector('.toggle-mobile-nav') end - it_behaves_like 'has a mobile nav-sidebar' + it_behaves_like 'has a collapsed nav sidebar' end context 'with a small size viewport' do before do resize_screen_sm visit project_path(project) - expect(page).to have_selector('.nav-sidebar') - expect(page).to have_selector('.toggle-mobile-nav') end - it_behaves_like 'has a mobile nav-sidebar' + it_behaves_like 'has a collapsed nav sidebar' end context 'with medium size viewport' do before do resize_window(768, 800) visit project_path(project) - expect(page).to have_selector('.nav-sidebar') end it_behaves_like 'has a collapsed nav sidebar' @@ -91,7 +67,6 @@ RSpec.describe 'Projects > User sees sidebar', feature_category: :groups_and_pro before do resize_window(1199, 800) visit project_path(project) - expect(page).to have_selector('.nav-sidebar') end it_behaves_like 'has a collapsed nav sidebar' @@ -101,10 +76,9 @@ RSpec.describe 'Projects > User sees sidebar', feature_category: :groups_and_pro before do resize_window(1200, 800) visit project_path(project) - expect(page).to have_selector('.nav-sidebar') end - it_behaves_like 'has a expanded nav sidebar' + it_behaves_like 'has an expanded nav sidebar' end end @@ -121,8 +95,8 @@ RSpec.describe 'Projects > User sees sidebar', feature_category: :groups_and_pro it 'does not display a "Snippets" link' do visit project_path(project) - within('.nav-sidebar') do - expect(page).not_to have_content 'Snippets' + within_testid('super-sidebar') do + expect(page).not_to have_button 'Code' end end end @@ -182,7 +156,7 @@ RSpec.describe 'Projects > User sees sidebar', feature_category: :groups_and_pro end context 'as guest' do - let(:guest) { create(:user, :no_super_sidebar) } + let(:guest) { create(:user) } let!(:issue) { create(:issue, :opened, project: project, author: guest) } before do @@ -194,15 +168,19 @@ RSpec.describe 'Projects > User sees sidebar', feature_category: :groups_and_pro it 'shows allowed tabs only' do visit project_path(project) - within('.nav-sidebar') do - expect(page).to have_content 'Project' - expect(page).to have_content 'Issues' - expect(page).to have_content 'Wiki' - expect(page).to have_content 'Monitor' + within_testid('super-sidebar') do + expect(page).to have_button 'Pinned' + expect(page).to have_button 'Manage' + expect(page).to have_button 'Plan' + expect(page).to have_button 'Code' + expect(page).to have_button 'Monitor' + expect(page).to have_button 'Analyze' + + expect(page).not_to have_button 'Build' - expect(page).not_to have_content 'Repository' - expect(page).not_to have_content 'CI/CD' - expect(page).not_to have_content 'Merge Requests' + click_button 'Code' + expect(page).not_to have_link 'Repository' + expect(page).not_to have_link 'Merge requests' end end @@ -212,8 +190,8 @@ RSpec.describe 'Projects > User sees sidebar', feature_category: :groups_and_pro visit project_path(project) - within('.nav-sidebar') do - expect(page).to have_content 'CI/CD' + within_testid('super-sidebar') do + expect(page).to have_button 'Build' end end diff --git a/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb b/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb index 5de544e866e..83eb7cb989e 100644 --- a/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb +++ b/spec/features/uploads/user_uploads_avatar_to_profile_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' RSpec.describe 'User uploads avatar to profile', feature_category: :user_profile do - let!(:user) { create(:user, :no_super_sidebar) } + let!(:user) { create(:user) } let(:avatar_file_path) { Rails.root.join('spec', 'fixtures', 'dk.png') } shared_examples 'upload avatar' do @@ -19,8 +19,7 @@ RSpec.describe 'User uploads avatar to profile', feature_category: :user_profile wait_for_all_requests data_uri = find('.avatar-image .gl-avatar')['src'] - expect(page.find('.header-user-avatar')['src']).to eq data_uri - expect(page.find('[data-testid="sidebar-user-avatar"]')['src']).to eq data_uri + within_testid('user-dropdown') { expect(find('.gl-avatar')['src']).to eq data_uri } visit profile_path diff --git a/spec/features/usage_stats_consent_spec.rb b/spec/features/usage_stats_consent_spec.rb index 92f7a944007..ebf1cd9e143 100644 --- a/spec/features/usage_stats_consent_spec.rb +++ b/spec/features/usage_stats_consent_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' RSpec.describe 'Usage stats consent', feature_category: :service_ping do context 'when signed in' do - let(:user) { create(:admin, :no_super_sidebar, created_at: 8.days.ago) } + let(:user) { create(:admin, created_at: 8.days.ago) } let(:message) { 'To help improve GitLab, we would like to periodically collect usage information.' } before do @@ -22,24 +22,29 @@ RSpec.describe 'Usage stats consent', feature_category: :service_ping do gitlab_enable_admin_mode_sign_in(user) end - it 'hides the banner permanently when sets usage stats' do - visit root_dashboard_path + shared_examples 'dismissible banner' do |button_text| + it 'hides the banner permanently when sets usage stats', :js do + visit root_dashboard_path - expect(page).to have_content(message) + expect(page).to have_content(message) - click_link 'Send service data' + click_link button_text - expect(page).not_to have_content(message) - expect(page).to have_content('Application settings saved successfully') + expect(page).not_to have_content(message) + expect(page).to have_content('Application settings saved successfully') - gitlab_sign_out - gitlab_sign_in(user) - visit root_dashboard_path + gitlab_sign_out + gitlab_sign_in(user) + visit root_dashboard_path - expect(page).not_to have_content(message) + expect(page).not_to have_content(message) + end end - it 'shows banner on next session if user did not set usage stats' do + it_behaves_like 'dismissible banner', _('Send service data') + it_behaves_like 'dismissible banner', _("Don't send service data") + + it 'shows banner on next session if user did not set usage stats', :js do visit root_dashboard_path expect(page).to have_content(message) diff --git a/spec/frontend/__helpers__/mock_observability_client.js b/spec/frontend/__helpers__/mock_observability_client.js index 5384ac85f4c..82425aa2842 100644 --- a/spec/frontend/__helpers__/mock_observability_client.js +++ b/spec/frontend/__helpers__/mock_observability_client.js @@ -6,6 +6,7 @@ export function createMockClient() { tracingUrl: 'tracing-url', servicesUrl: 'services-url', operationsUrl: 'operations-url', + metricsUrl: 'metrics-url', }); Object.getOwnPropertyNames(mockClient) diff --git a/spec/frontend/members/mock_data.js b/spec/frontend/members/mock_data.js index 4fb0b76fa49..e0dc765b9e4 100644 --- a/spec/frontend/members/mock_data.js +++ b/spec/frontend/members/mock_data.js @@ -41,7 +41,7 @@ export const member = { usingLicense: false, groupSso: false, groupManagedAccount: false, - provisionedByThisGroup: false, + enterpriseUserOfThisGroup: false, validRoles: { Guest: 10, Reporter: 20, diff --git a/spec/frontend/observability/client_spec.js b/spec/frontend/observability/client_spec.js index c8c51b261b6..c7bb83fb4f2 100644 --- a/spec/frontend/observability/client_spec.js +++ b/spec/frontend/observability/client_spec.js @@ -16,18 +16,22 @@ describe('buildClient', () => { const provisioningUrl = 'https://example.com/provisioning'; const servicesUrl = 'https://example.com/services'; const operationsUrl = 'https://example.com/services/$SERVICE_NAME$/operations'; + const metricsUrl = 'https://example.com/metrics'; const FETCHING_TRACES_ERROR = 'traces are missing/invalid in the response'; + const apiConfig = { + tracingUrl, + provisioningUrl, + servicesUrl, + operationsUrl, + metricsUrl, + }; + beforeEach(() => { axiosMock = new MockAdapter(axios); jest.spyOn(axios, 'get'); - client = buildClient({ - tracingUrl, - provisioningUrl, - servicesUrl, - operationsUrl, - }); + client = buildClient(apiConfig); }); afterEach(() => { @@ -40,23 +44,18 @@ describe('buildClient', () => { }; describe('buildClient', () => { - it('rejects if params are missing', () => { - const e = new Error( - 'missing required params. provisioningUrl, tracingUrl, servicesUrl, operationsUrl are required', - ); - expect(() => - buildClient({ tracingUrl: 'test', servicesUrl: 'test', operationsUrl: 'test' }), - ).toThrow(e); - expect(() => - buildClient({ provisioningUrl: 'test', servicesUrl: 'test', operationsUrl: 'test' }), - ).toThrow(e); - expect(() => - buildClient({ provisioningUrl: 'test', tracingUrl: 'test', operationsUrl: 'test' }), - ).toThrow(e); + it('throws is option is missing', () => { + expect(() => buildClient()).toThrow(new Error('No options object provided')); + }); + it.each(Object.keys(apiConfig))('throws if %s is missing', (param) => { + const e = new Error(`${param} param must be a string`); + expect(() => - buildClient({ provisioningUrl: 'test', tracingUrl: 'test', servicesUrl: 'test' }), + buildClient({ + ...apiConfig, + [param]: undefined, + }), ).toThrow(e); - expect(() => buildClient({})).toThrow(e); }); }); @@ -260,6 +259,7 @@ describe('buildClient', () => { { operator: '=', value: 'trace-id' }, { operator: '!=', value: 'not-trace-id' }, ], + attribute: [{ operator: '=', value: 'name1=value1' }], }, }); expect(getQueryParam()).toBe( @@ -267,7 +267,8 @@ describe('buildClient', () => { '&operation=op¬[operation]=not-op' + '&service_name=service¬[service_name]=not-service' + '&period=5m' + - '&trace_id=trace-id¬[trace_id]=not-trace-id', + '&trace_id=trace-id¬[trace_id]=not-trace-id' + + '&attr_name=name1&attr_value=value1', ); }); @@ -387,9 +388,7 @@ describe('buildClient', () => { it('rejects if operationUrl does not contain $SERVICE_NAME$', async () => { client = buildClient({ - tracingUrl, - provisioningUrl, - servicesUrl, + ...apiConfig, operationsUrl: 'something', }); const e = 'fetchOperations() - operationsUrl must contain $SERVICE_NAME$'; diff --git a/spec/frontend/observability/observability_container_spec.js b/spec/frontend/observability/observability_container_spec.js index 1f5194a1bd8..41906b2f45d 100644 --- a/spec/frontend/observability/observability_container_spec.js +++ b/spec/frontend/observability/observability_container_spec.js @@ -19,6 +19,7 @@ describe('ObservabilityContainer', () => { const PROVISIONING_URL = 'https://example.com/provisioning'; const SERVICES_URL = 'https://example.com/services'; const OPERATIONS_URL = 'https://example.com/operations'; + const METRICS_URL = 'https://example.com/metrics'; const mockClient = { mock: 'client' }; @@ -29,11 +30,14 @@ describe('ObservabilityContainer', () => { wrapper = shallowMountExtended(ObservabilityContainer, { propsData: { - oauthUrl: OAUTH_URL, - tracingUrl: TRACING_URL, - provisioningUrl: PROVISIONING_URL, - servicesUrl: SERVICES_URL, - operationsUrl: OPERATIONS_URL, + apiConfig: { + oauthUrl: OAUTH_URL, + tracingUrl: TRACING_URL, + provisioningUrl: PROVISIONING_URL, + servicesUrl: SERVICES_URL, + operationsUrl: OPERATIONS_URL, + metricssUrl: METRICS_URL, + }, }, slots: { default: { @@ -100,12 +104,7 @@ describe('ObservabilityContainer', () => { }); it('build the observability client', () => { - expect(buildClient).toHaveBeenCalledWith({ - provisioningUrl: PROVISIONING_URL, - tracingUrl: TRACING_URL, - servicesUrl: SERVICES_URL, - operationsUrl: OPERATIONS_URL, - }); + expect(buildClient).toHaveBeenCalledWith(wrapper.props('apiConfig')); }); it('emits observability-client-ready', () => { diff --git a/spec/frontend/observability/provisioned_observability_container_spec.js b/spec/frontend/observability/provisioned_observability_container_spec.js index 7d84c1e80e7..b2aef36dbc9 100644 --- a/spec/frontend/observability/provisioned_observability_container_spec.js +++ b/spec/frontend/observability/provisioned_observability_container_spec.js @@ -31,11 +31,14 @@ describe('ProvisionedObservabilityContainer', () => { const findSlotComponent = () => wrapper.findComponent({ name: 'MockComponent' }); const props = { - oauthUrl: 'https://example.com/oauth', - tracingUrl: 'https://example.com/tracing', - servicesUrl: 'https://example.com/services', - provisioningUrl: 'https://example.com/provisioning', - operationsUrl: 'https://example.com/operations', + apiConfig: { + oauthUrl: 'https://example.com/oauth', + tracingUrl: 'https://example.com/tracing', + servicesUrl: 'https://example.com/services', + provisioningUrl: 'https://example.com/provisioning', + operationsUrl: 'https://example.com/operations', + metricsUrl: 'https://example.com/metrics', + }, }; beforeEach(() => { @@ -59,7 +62,7 @@ describe('ProvisionedObservabilityContainer', () => { it('renders the observability-container', () => { const observabilityContainer = wrapper.findComponent(ObservabilityContainer); expect(observabilityContainer.exists()).toBe(true); - expect(observabilityContainer.props()).toMatchObject(props); + expect(observabilityContainer.props('apiConfig')).toStrictEqual(props.apiConfig); }); describe('when the client is ready', () => { diff --git a/spec/frontend/projects/settings_service_desk/components/service_desk_root_spec.js b/spec/frontend/projects/settings_service_desk/components/service_desk_root_spec.js index 8655845d1b7..0eec981b67d 100644 --- a/spec/frontend/projects/settings_service_desk/components/service_desk_root_spec.js +++ b/spec/frontend/projects/settings_service_desk/components/service_desk_root_spec.js @@ -22,6 +22,7 @@ describe('ServiceDeskRoot', () => { isIssueTrackerEnabled: true, outgoingName: 'GitLab Support Bot', projectKey: 'key', + addExternalParticipantsFromCc: true, selectedTemplate: 'Bug', selectedFileTemplateProjectId: 42, templates: ['Bug', 'Documentation'], @@ -62,6 +63,7 @@ describe('ServiceDeskRoot', () => { incomingEmail: provideData.initialIncomingEmail, initialOutgoingName: provideData.outgoingName, initialProjectKey: provideData.projectKey, + initialAddExternalParticipantsFromCc: provideData.addExternalParticipantsFromCc, initialSelectedTemplate: provideData.selectedTemplate, initialSelectedFileTemplateProjectId: provideData.selectedFileTemplateProjectId, isEnabled: provideData.initialIsEnabled, @@ -147,6 +149,7 @@ describe('ServiceDeskRoot', () => { selectedTemplate: 'Bug', outgoingName: 'GitLab Support Bot', projectKey: 'key', + addExternalParticipantsFromCc: true, }; wrapper.findComponent(ServiceDeskSetting).vm.$emit('save', payload); @@ -160,6 +163,7 @@ describe('ServiceDeskRoot', () => { outgoing_name: 'GitLab Support Bot', project_key: 'key', service_desk_enabled: true, + add_external_participants_from_cc: true, }); }); @@ -178,6 +182,7 @@ describe('ServiceDeskRoot', () => { selectedTemplate: 'Bug', outgoingName: 'GitLab Support Bot', projectKey: 'key', + addExternalParticipantsFromCc: true, }; wrapper.findComponent(ServiceDeskSetting).vm.$emit('save', payload); diff --git a/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js b/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js index 260fd200f03..6449f9bb68e 100644 --- a/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js +++ b/spec/frontend/projects/settings_service_desk/components/service_desk_setting_spec.js @@ -1,4 +1,4 @@ -import { GlButton, GlDropdown, GlLoadingIcon, GlToggle, GlAlert } from '@gitlab/ui'; +import { GlButton, GlDropdown, GlFormCheckbox, GlLoadingIcon, GlToggle, GlAlert } from '@gitlab/ui'; import { mount } from '@vue/test-utils'; import { nextTick } from 'vue'; import { extendedWrapper } from 'helpers/vue_test_utils_helper'; @@ -19,8 +19,9 @@ describe('ServiceDeskSetting', () => { const findSuffixFormGroup = () => wrapper.findByTestId('suffix-form-group'); const findIssueTrackerInfo = () => wrapper.findComponent(GlAlert); const findIssueHelpLink = () => wrapper.findByTestId('issue-help-page'); + const findAddExternalParticipantsFromCcCheckbox = () => wrapper.findComponent(GlFormCheckbox); - const createComponent = ({ props = {} } = {}) => + const createComponent = ({ props = {}, provide = {} } = {}) => extendedWrapper( mount(ServiceDeskSetting, { propsData: { @@ -28,6 +29,12 @@ describe('ServiceDeskSetting', () => { isIssueTrackerEnabled: true, ...props, }, + provide: { + glFeatures: { + issueEmailParticipants: true, + }, + ...provide, + }, }), ); @@ -205,6 +212,25 @@ describe('ServiceDeskSetting', () => { }); }); + describe('add external participants from cc checkbox', () => { + it('is rendered', () => { + wrapper = createComponent(); + expect(findAddExternalParticipantsFromCcCheckbox().exists()).toBe(true); + }); + + it('forwards the initial value to the checkbox', () => { + wrapper = createComponent({ props: { initialAddExternalParticipantsFromCc: true } }); + expect(findAddExternalParticipantsFromCcCheckbox().find('input').element.checked).toBe(true); + }); + + describe('when feature flag issue_email_participants is disabled', () => { + it('is not rendered', () => { + wrapper = createComponent({ provide: { glFeatures: { issueEmailParticipants: false } } }); + expect(findAddExternalParticipantsFromCcCheckbox().exists()).toBe(false); + }); + }); + }); + describe('save button', () => { it('renders a save button to save a template', () => { wrapper = createComponent(); @@ -223,6 +249,7 @@ describe('ServiceDeskSetting', () => { initialSelectedFileTemplateProjectId: 42, initialOutgoingName: 'GitLab Support Bot', initialProjectKey: 'key', + initialAddExternalParticipantsFromCc: false, }, }); @@ -235,6 +262,7 @@ describe('ServiceDeskSetting', () => { fileTemplateProjectId: 42, outgoingName: 'GitLab Support Bot', projectKey: 'key', + addExternalParticipantsFromCc: false, }; expect(wrapper.emitted('save')[0]).toEqual([payload]); @@ -260,6 +288,10 @@ describe('ServiceDeskSetting', () => { expect(findButton().exists()).toBe(false); }); + it('does not render add external participants from cc checkbox', () => { + expect(findAddExternalParticipantsFromCcCheckbox().exists()).toBe(false); + }); + it('emits an event to turn on Service Desk when the toggle is clicked', async () => { findToggle().vm.$emit('change', false); diff --git a/spec/frontend/work_items/components/shared/work_item_token_input_spec.js b/spec/frontend/work_items/components/shared/work_item_token_input_spec.js index 075b69415cf..c70dbbd909d 100644 --- a/spec/frontend/work_items/components/shared/work_item_token_input_spec.js +++ b/spec/frontend/work_items/components/shared/work_item_token_input_spec.js @@ -6,6 +6,7 @@ import createMockApollo from 'helpers/mock_apollo_helper'; import waitForPromises from 'helpers/wait_for_promises'; import WorkItemTokenInput from '~/work_items/components/shared/work_item_token_input.vue'; import { WORK_ITEM_TYPE_ENUM_TASK } from '~/work_items/constants'; +import groupWorkItemsQuery from '~/work_items/graphql/group_work_items.query.graphql'; import projectWorkItemsQuery from '~/work_items/graphql/project_work_items.query.graphql'; import { availableWorkItemsResponse, searchedWorkItemsResponse } from '../../mock_data'; @@ -15,6 +16,7 @@ describe('WorkItemTokenInput', () => { let wrapper; const availableWorkItemsResolver = jest.fn().mockResolvedValue(availableWorkItemsResponse); + const groupSearchedWorkItemResolver = jest.fn().mockResolvedValue(searchedWorkItemsResponse); const searchedWorkItemResolver = jest.fn().mockResolvedValue(searchedWorkItemsResponse); const createComponent = async ({ @@ -23,9 +25,16 @@ describe('WorkItemTokenInput', () => { childrenType = WORK_ITEM_TYPE_ENUM_TASK, areWorkItemsToAddValid = true, workItemsResolver = searchedWorkItemResolver, + isGroup = false, } = {}) => { wrapper = shallowMountExtended(WorkItemTokenInput, { - apolloProvider: createMockApollo([[projectWorkItemsQuery, workItemsResolver]]), + apolloProvider: createMockApollo([ + [projectWorkItemsQuery, workItemsResolver], + [groupWorkItemsQuery, groupSearchedWorkItemResolver], + ]), + provide: { + isGroup, + }, propsData: { value: workItemsToAdd, childrenType, @@ -78,4 +87,34 @@ describe('WorkItemTokenInput', () => { expect(findTokenSelector().props('containerClass')).toBe('gl-inset-border-1-red-500!'); }); + + describe('when project context', () => { + beforeEach(() => { + createComponent(); + findTokenSelector().vm.$emit('focus'); + }); + + it('calls the project work items query', () => { + expect(searchedWorkItemResolver).toHaveBeenCalled(); + }); + + it('skips calling the group work items query', () => { + expect(groupSearchedWorkItemResolver).not.toHaveBeenCalled(); + }); + }); + + describe('when group context', () => { + beforeEach(() => { + createComponent({ isGroup: true }); + findTokenSelector().vm.$emit('focus'); + }); + + it('skips calling the project work items query', () => { + expect(searchedWorkItemResolver).not.toHaveBeenCalled(); + }); + + it('calls the group work items query', () => { + expect(groupSearchedWorkItemResolver).toHaveBeenCalled(); + }); + }); }); diff --git a/spec/frontend/work_items/components/work_item_parent_spec.js b/spec/frontend/work_items/components/work_item_parent_spec.js index c60620d210a..0c02f0c63ec 100644 --- a/spec/frontend/work_items/components/work_item_parent_spec.js +++ b/spec/frontend/work_items/components/work_item_parent_spec.js @@ -9,6 +9,7 @@ import * as Sentry from '~/sentry/sentry_browser_wrapper'; import WorkItemParent from '~/work_items/components/work_item_parent.vue'; import { removeHierarchyChild } from '~/work_items/graphql/cache_utils'; import updateWorkItemMutation from '~/work_items/graphql/update_work_item.mutation.graphql'; +import groupWorkItemsQuery from '~/work_items/graphql/group_work_items.query.graphql'; import projectWorkItemsQuery from '~/work_items/graphql/project_work_items.query.graphql'; import { WORK_ITEM_TYPE_ENUM_OBJECTIVE } from '~/work_items/constants'; @@ -34,6 +35,7 @@ describe('WorkItemParent component', () => { const workItemType = 'Objective'; const mockFullPath = 'full-path'; + const groupWorkItemsSuccessHandler = jest.fn().mockResolvedValue(availableObjectivesResponse); const availableWorkItemsSuccessHandler = jest.fn().mockResolvedValue(availableObjectivesResponse); const availableWorkItemsFailureHandler = jest.fn().mockRejectedValue(new Error()); @@ -51,6 +53,7 @@ describe('WorkItemParent component', () => { wrapper = shallowMountExtended(WorkItemParent, { apolloProvider: createMockApollo([ [projectWorkItemsQuery, searchQueryHandler], + [groupWorkItemsQuery, groupWorkItemsSuccessHandler], [updateWorkItemMutation, mutationHandler], ]), provide: { @@ -252,4 +255,34 @@ describe('WorkItemParent component', () => { expect(Sentry.captureException).toHaveBeenCalledWith(error); }); }); + + describe('when project context', () => { + beforeEach(() => { + createComponent(); + findCollapsibleListbox().vm.$emit('shown'); + }); + + it('calls the project work items query', () => { + expect(availableWorkItemsSuccessHandler).toHaveBeenCalled(); + }); + + it('skips calling the group work items query', () => { + expect(groupWorkItemsSuccessHandler).not.toHaveBeenCalled(); + }); + }); + + describe('when group context', () => { + beforeEach(() => { + createComponent({ isGroup: true }); + findCollapsibleListbox().vm.$emit('shown'); + }); + + it('skips calling the project work items query', () => { + expect(availableWorkItemsSuccessHandler).not.toHaveBeenCalled(); + }); + + it('calls the group work items query', () => { + expect(groupWorkItemsSuccessHandler).toHaveBeenCalled(); + }); + }); }); diff --git a/spec/frontend/work_items/components/work_item_relationships/work_item_add_relationship_form_spec.js b/spec/frontend/work_items/components/work_item_relationships/work_item_add_relationship_form_spec.js index d7b3ced2ff9..520cf5f7ea4 100644 --- a/spec/frontend/work_items/components/work_item_relationships/work_item_add_relationship_form_spec.js +++ b/spec/frontend/work_items/components/work_item_relationships/work_item_add_relationship_form_spec.js @@ -34,6 +34,9 @@ describe('WorkItemAddRelationshipForm', () => { wrapper = shallowMountExtended(WorkItemAddRelationshipForm, { apolloProvider: mockApolloProvider, + provide: { + isGroup: false, + }, propsData: { workItemId, workItemIid, diff --git a/spec/helpers/ci/catalog/resources_helper_spec.rb b/spec/helpers/ci/catalog/resources_helper_spec.rb index 3b29e6f292b..5c5d02ce6d8 100644 --- a/spec/helpers/ci/catalog/resources_helper_spec.rb +++ b/spec/helpers/ci/catalog/resources_helper_spec.rb @@ -5,17 +5,34 @@ require 'spec_helper' RSpec.describe Ci::Catalog::ResourcesHelper, feature_category: :pipeline_composition do include Devise::Test::ControllerHelpers - let_it_be(:project) { build(:project) } + let_it_be(:project) { create_default(:project) } + let_it_be(:user) { create_default(:user) } + + before do + allow(helper).to receive(:current_user).and_return(user) + end describe '#can_add_catalog_resource?' do subject { helper.can_add_catalog_resource?(project) } - before do - stub_licensed_features(ci_namespace_catalog: false) + context 'when user is not an owner' do + before_all do + project.add_maintainer(user) + end + + it 'returns false' do + expect(subject).to be false + end end - it 'user cannot add a catalog resource in CE regardless of permissions' do - expect(subject).to be false + context 'when user is an owner' do + before_all do + project.add_owner(user) + end + + it 'returns true' do + expect(subject).to be true + end end end diff --git a/spec/helpers/users/callouts_helper_spec.rb b/spec/helpers/users/callouts_helper_spec.rb index 2a0ba1279b0..5ec06507088 100644 --- a/spec/helpers/users/callouts_helper_spec.rb +++ b/spec/helpers/users/callouts_helper_spec.rb @@ -165,26 +165,6 @@ RSpec.describe Users::CalloutsHelper, feature_category: :navigation do end end - describe '.show_pages_menu_callout?' do - subject { helper.show_pages_menu_callout? } - - before do - allow(helper).to receive(:user_dismissed?).with(described_class::PAGES_MOVED_CALLOUT) { dismissed } - end - - context 'when user has not dismissed' do - let(:dismissed) { false } - - it { is_expected.to be true } - end - - context 'when user dismissed' do - let(:dismissed) { true } - - it { is_expected.to be false } - end - end - describe '#web_hook_disabled_dismissed?', feature_category: :webhooks do context 'without a project' do it 'is false' do diff --git a/spec/lib/gitlab/background_migration/batched_migration_job_spec.rb b/spec/lib/gitlab/background_migration/batched_migration_job_spec.rb index 7c09c69e5d1..93a4d0ca602 100644 --- a/spec/lib/gitlab/background_migration/batched_migration_job_spec.rb +++ b/spec/lib/gitlab/background_migration/batched_migration_job_spec.rb @@ -31,13 +31,16 @@ RSpec.describe Gitlab::BackgroundMigration::BatchedMigrationJob do end subject(:job_instance) do - job_class.new(start_id: 1, end_id: 10, - batch_table: '_test_table', - batch_column: 'id', - sub_batch_size: 2, - pause_ms: 1000, - job_arguments: %w[a b], - connection: connection) + job_class.new( + start_id: 1, + end_id: 10, + batch_table: '_test_table', + batch_column: 'id', + sub_batch_size: 2, + pause_ms: 1000, + job_arguments: %w[a b], + connection: connection + ) end it 'defines methods' do @@ -61,13 +64,16 @@ RSpec.describe Gitlab::BackgroundMigration::BatchedMigrationJob do subject(:perform_job) { job_instance.perform } let(:job_instance) do - job_class.new(start_id: 1, end_id: 10, - batch_table: '_test_table', - batch_column: 'id', - sub_batch_size: 2, - pause_ms: 1000, - job_arguments: %w[a b], - connection: connection) + job_class.new( + start_id: 1, + end_id: 10, + batch_table: '_test_table', + batch_column: 'id', + sub_batch_size: 2, + pause_ms: 1000, + job_arguments: %w[a b], + connection: connection + ) end let(:job_class) do @@ -124,13 +130,16 @@ RSpec.describe Gitlab::BackgroundMigration::BatchedMigrationJob do describe '.scope_to' do subject(:job_instance) do - job_class.new(start_id: 1, end_id: 10, - batch_table: '_test_table', - batch_column: 'id', - sub_batch_size: 2, - pause_ms: 1000, - job_arguments: %w[a b], - connection: connection) + job_class.new( + start_id: 1, + end_id: 10, + batch_table: '_test_table', + batch_column: 'id', + sub_batch_size: 2, + pause_ms: 1000, + job_arguments: %w[a b], + connection: connection + ) end context 'when additional scoping is defined' do @@ -203,12 +212,15 @@ RSpec.describe Gitlab::BackgroundMigration::BatchedMigrationJob do let(:job_class) { Class.new(described_class) } let(:job_instance) do - job_class.new(start_id: 1, end_id: 10, - batch_table: '_test_table', - batch_column: 'id', - sub_batch_size: 2, - pause_ms: 1000, - connection: connection) + job_class.new( + start_id: 1, + end_id: 10, + batch_table: '_test_table', + batch_column: 'id', + sub_batch_size: 2, + pause_ms: 1000, + connection: connection + ) end subject(:perform_job) { job_instance.perform } @@ -313,9 +325,16 @@ RSpec.describe Gitlab::BackgroundMigration::BatchedMigrationJob do end let(:job_instance) do - job_class.new(start_id: 1, end_id: 10, batch_table: '_test_table', batch_column: 'id', - sub_batch_size: 2, pause_ms: 1000, connection: connection, - sub_batch_exception: StandardError) + job_class.new( + start_id: 1, + end_id: 10, + batch_table: '_test_table', + batch_column: 'id', + sub_batch_size: 2, + pause_ms: 1000, + connection: connection, + sub_batch_exception: StandardError + ) end it 'raises the expected error type' do @@ -336,13 +355,15 @@ RSpec.describe Gitlab::BackgroundMigration::BatchedMigrationJob do context 'when the subclass uses distinct each batch' do let(:job_instance) do - job_class.new(start_id: 1, - end_id: 100, - batch_table: '_test_table', - batch_column: 'from_column', - sub_batch_size: 2, - pause_ms: 10, - connection: connection) + job_class.new( + start_id: 1, + end_id: 100, + batch_table: '_test_table', + batch_column: 'from_column', + sub_batch_size: 2, + pause_ms: 10, + connection: connection + ) end let(:job_class) do diff --git a/spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb b/spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb index 06325f7a70b..a827116a900 100644 --- a/spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb +++ b/spec/lib/gitlab/background_migration/copy_column_using_background_migration_job_spec.rb @@ -18,14 +18,16 @@ RSpec.describe Gitlab::BackgroundMigration::CopyColumnUsingBackgroundMigrationJo let(:job_arguments) { %w[name name_convert_to_text] } let(:copy_job) do - described_class.new(start_id: 12, - end_id: 20, - batch_table: table_name, - batch_column: 'id', - sub_batch_size: sub_batch_size, - pause_ms: pause_ms, - job_arguments: job_arguments, - connection: connection) + described_class.new( + start_id: 12, + end_id: 20, + batch_table: table_name, + batch_column: 'id', + sub_batch_size: sub_batch_size, + pause_ms: pause_ms, + job_arguments: job_arguments, + connection: connection + ) end before do diff --git a/spec/lib/gitlab/background_migration/delete_orphaned_operational_vulnerabilities_spec.rb b/spec/lib/gitlab/background_migration/delete_orphaned_operational_vulnerabilities_spec.rb index c03962c8d21..4a1985eeccd 100644 --- a/spec/lib/gitlab/background_migration/delete_orphaned_operational_vulnerabilities_spec.rb +++ b/spec/lib/gitlab/background_migration/delete_orphaned_operational_vulnerabilities_spec.rb @@ -87,13 +87,15 @@ RSpec.describe Gitlab::BackgroundMigration::DeleteOrphanedOperationalVulnerabili end subject(:background_migration) do - described_class.new(start_id: vulnerabilities.minimum(:id), - end_id: vulnerabilities.maximum(:id), - batch_table: :vulnerabilities, - batch_column: :id, - sub_batch_size: 2, - pause_ms: 0, - connection: ActiveRecord::Base.connection) + described_class.new( + start_id: vulnerabilities.minimum(:id), + end_id: vulnerabilities.maximum(:id), + batch_table: :vulnerabilities, + batch_column: :id, + sub_batch_size: 2, + pause_ms: 0, + connection: ActiveRecord::Base.connection + ) end it 'drops Cluster Image Scanning and Custom Vulnerabilities without any Findings' do diff --git a/spec/lib/gitlab/background_migration/delete_orphans_approval_merge_request_rules_spec.rb b/spec/lib/gitlab/background_migration/delete_orphans_approval_merge_request_rules_spec.rb index c5b46d3f57c..1ac4d184912 100644 --- a/spec/lib/gitlab/background_migration/delete_orphans_approval_merge_request_rules_spec.rb +++ b/spec/lib/gitlab/background_migration/delete_orphans_approval_merge_request_rules_spec.rb @@ -22,9 +22,12 @@ RSpec.describe Gitlab::BackgroundMigration::DeleteOrphansApprovalMergeRequestRul let(:namespace_2) { namespaces.create!(name: 'name_2', path: 'path_2') } let(:security_project) do - projects - .create!(name: "security_project", path: "security_project", namespace_id: namespace_2.id, - project_namespace_id: namespace_2.id) + projects.create!( + name: "security_project", + path: "security_project", + namespace_id: namespace_2.id, + project_namespace_id: namespace_2.id + ) end let!(:security_orchestration_policy_configuration) do diff --git a/spec/lib/gitlab/background_migration/delete_orphans_approval_project_rules_spec.rb b/spec/lib/gitlab/background_migration/delete_orphans_approval_project_rules_spec.rb index 16253255764..23026f76001 100644 --- a/spec/lib/gitlab/background_migration/delete_orphans_approval_project_rules_spec.rb +++ b/spec/lib/gitlab/background_migration/delete_orphans_approval_project_rules_spec.rb @@ -22,9 +22,12 @@ RSpec.describe Gitlab::BackgroundMigration::DeleteOrphansApprovalProjectRules do let(:namespace_2) { namespaces.create!(name: 'name_2', path: 'path_2') } let(:security_project) do - projects - .create!(name: "security_project", path: "security_project", namespace_id: namespace_2.id, - project_namespace_id: namespace_2.id) + projects.create!( + name: "security_project", + path: "security_project", + namespace_id: namespace_2.id, + project_namespace_id: namespace_2.id + ) end let!(:security_orchestration_policy_configuration) do diff --git a/spec/lib/gitlab/background_migration/destroy_invalid_group_members_spec.rb b/spec/lib/gitlab/background_migration/destroy_invalid_group_members_spec.rb index 76a9ea82c76..4e136808a36 100644 --- a/spec/lib/gitlab/background_migration/destroy_invalid_group_members_spec.rb +++ b/spec/lib/gitlab/background_migration/destroy_invalid_group_members_spec.rb @@ -76,13 +76,29 @@ RSpec.describe Gitlab::BackgroundMigration::DestroyInvalidGroupMembers, :migrati end def create_invalid_group_member(id:, user_id:) - members_table.create!(id: id, user_id: user_id, source_id: non_existing_record_id, access_level: Gitlab::Access::MAINTAINER, - type: "GroupMember", source_type: "Namespace", notification_level: 3, member_namespace_id: nil) + members_table.create!( + id: id, + user_id: user_id, + source_id: non_existing_record_id, + access_level: Gitlab::Access::MAINTAINER, + type: "GroupMember", + source_type: "Namespace", + notification_level: 3, + member_namespace_id: nil + ) end def create_valid_group_member(id:, user_id:, group_id:) - members_table.create!(id: id, user_id: user_id, source_id: group_id, access_level: Gitlab::Access::MAINTAINER, - type: "GroupMember", source_type: "Namespace", member_namespace_id: group_id, notification_level: 3) + members_table.create!( + id: id, + user_id: user_id, + source_id: group_id, + access_level: Gitlab::Access::MAINTAINER, + type: "GroupMember", + source_type: "Namespace", + member_namespace_id: group_id, + notification_level: 3 + ) end # rubocop: enable Layout/LineLength # rubocop: enable RSpec/ScatteredLet diff --git a/spec/lib/gitlab/background_migration/destroy_invalid_members_spec.rb b/spec/lib/gitlab/background_migration/destroy_invalid_members_spec.rb index 5059ad620aa..e5965d4a1d8 100644 --- a/spec/lib/gitlab/background_migration/destroy_invalid_members_spec.rb +++ b/spec/lib/gitlab/background_migration/destroy_invalid_members_spec.rb @@ -33,23 +33,39 @@ RSpec.describe Gitlab::BackgroundMigration::DestroyInvalidMembers, :migration, s let!(:group1) { namespaces_table.create!(name: 'marvellous group 1', path: 'group-path-1', type: 'Group') } let!(:group2) { namespaces_table.create!(name: 'outstanding group 2', path: 'group-path-2', type: 'Group') } let!(:project_namespace1) do - namespaces_table.create!(name: 'fabulous project', path: 'project-path-1', - type: 'ProjectNamespace', parent_id: group1.id) + namespaces_table.create!( + name: 'fabulous project', + path: 'project-path-1', + type: 'ProjectNamespace', + parent_id: group1.id + ) end let!(:project1) do - projects_table.create!(name: 'fabulous project', path: 'project-path-1', - project_namespace_id: project_namespace1.id, namespace_id: group1.id) + projects_table.create!( + name: 'fabulous project', + path: 'project-path-1', + project_namespace_id: project_namespace1.id, + namespace_id: group1.id + ) end let!(:project_namespace2) do - namespaces_table.create!(name: 'splendiferous project', path: 'project-path-2', - type: 'ProjectNamespace', parent_id: group1.id) + namespaces_table.create!( + name: 'splendiferous project', + path: 'project-path-2', + type: 'ProjectNamespace', + parent_id: group1.id + ) end let!(:project2) do - projects_table.create!(name: 'splendiferous project', path: 'project-path-2', - project_namespace_id: project_namespace2.id, namespace_id: group1.id) + projects_table.create!( + name: 'splendiferous project', + path: 'project-path-2', + project_namespace_id: project_namespace2.id, + namespace_id: group1.id + ) end # create valid project member records @@ -115,27 +131,55 @@ RSpec.describe Gitlab::BackgroundMigration::DestroyInvalidMembers, :migration, s end def create_invalid_project_member(id:, user_id:) - members_table.create!(id: id, user_id: user_id, source_id: non_existing_record_id, - access_level: Gitlab::Access::MAINTAINER, type: "ProjectMember", - source_type: "Project", notification_level: 3, member_namespace_id: nil) + members_table.create!( + id: id, + user_id: user_id, + source_id: non_existing_record_id, + access_level: Gitlab::Access::MAINTAINER, + type: "ProjectMember", + source_type: "Project", + notification_level: 3, + member_namespace_id: nil + ) end def create_valid_project_member(id:, user_id:, project:) - members_table.create!(id: id, user_id: user_id, source_id: project.id, - access_level: Gitlab::Access::MAINTAINER, type: "ProjectMember", source_type: "Project", - member_namespace_id: project.project_namespace_id, notification_level: 3) + members_table.create!( + id: id, + user_id: user_id, + source_id: project.id, + access_level: Gitlab::Access::MAINTAINER, + type: "ProjectMember", + source_type: "Project", + member_namespace_id: project.project_namespace_id, + notification_level: 3 + ) end def create_invalid_group_member(id:, user_id:) - members_table.create!(id: id, user_id: user_id, source_id: non_existing_record_id, - access_level: Gitlab::Access::MAINTAINER, type: "GroupMember", - source_type: "Namespace", notification_level: 3, member_namespace_id: nil) + members_table.create!( + id: id, + user_id: user_id, + source_id: non_existing_record_id, + access_level: Gitlab::Access::MAINTAINER, + type: "GroupMember", + source_type: "Namespace", + notification_level: 3, + member_namespace_id: nil + ) end def create_valid_group_member(id:, user_id:, group_id:) - members_table.create!(id: id, user_id: user_id, source_id: group_id, - access_level: Gitlab::Access::MAINTAINER, type: "GroupMember", - source_type: "Namespace", member_namespace_id: group_id, notification_level: 3) + members_table.create!( + id: id, + user_id: user_id, + source_id: group_id, + access_level: Gitlab::Access::MAINTAINER, + type: "GroupMember", + source_type: "Namespace", + member_namespace_id: group_id, + notification_level: 3 + ) end end # rubocop: enable RSpec/MultipleMemoizedHelpers diff --git a/spec/lib/gitlab/background_migration/destroy_invalid_project_members_spec.rb b/spec/lib/gitlab/background_migration/destroy_invalid_project_members_spec.rb index 029a6adf831..090c31049b4 100644 --- a/spec/lib/gitlab/background_migration/destroy_invalid_project_members_spec.rb +++ b/spec/lib/gitlab/background_migration/destroy_invalid_project_members_spec.rb @@ -3,7 +3,6 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::DestroyInvalidProjectMembers, :migration, schema: 20220901035725 do - # rubocop: disable Layout/LineLength # rubocop: disable RSpec/ScatteredLet let!(:migration_attrs) do { @@ -36,23 +35,33 @@ RSpec.describe Gitlab::BackgroundMigration::DestroyInvalidProjectMembers, :migra let!(:group1) { namespaces_table.create!(name: 'marvellous group 1', path: 'group-path-1', type: 'Group') } let!(:project_namespace1) do - namespaces_table.create!(name: 'fabulous project', path: 'project-path-1', type: 'ProjectNamespace', - parent_id: group1.id) + namespaces_table.create!( + name: 'fabulous project', path: 'project-path-1', type: 'ProjectNamespace', parent_id: group1.id + ) end let!(:project1) do - projects_table.create!(name: 'fabulous project', path: 'project-path-1', project_namespace_id: project_namespace1.id, - namespace_id: group1.id) + projects_table.create!( + name: 'fabulous project', + path: 'project-path-1', + project_namespace_id: project_namespace1.id, + namespace_id: group1.id + ) end let!(:project_namespace2) do - namespaces_table.create!(name: 'splendiferous project', path: 'project-path-2', type: 'ProjectNamespace', - parent_id: group1.id) + namespaces_table.create!( + name: 'splendiferous project', path: 'project-path-2', type: 'ProjectNamespace', parent_id: group1.id + ) end let!(:project2) do - projects_table.create!(name: 'splendiferous project', path: 'project-path-2', project_namespace_id: project_namespace2.id, - namespace_id: group1.id) + projects_table.create!( + name: 'splendiferous project', + path: 'project-path-2', + project_namespace_id: project_namespace2.id, + namespace_id: group1.id + ) end # create project member records, a mix of both valid and invalid @@ -72,7 +81,8 @@ RSpec.describe Gitlab::BackgroundMigration::DestroyInvalidProjectMembers, :migra end expect(queries.count).to eq(4) - expect(members_table.where(type: 'ProjectMember')).to match_array([project_member2, project_member3, project_member5]) + expect(members_table.where(type: 'ProjectMember')) + .to match_array([project_member2, project_member3, project_member5]) end it 'tracks timings of queries' do @@ -82,21 +92,33 @@ RSpec.describe Gitlab::BackgroundMigration::DestroyInvalidProjectMembers, :migra end it 'logs IDs of deleted records' do - expect(Gitlab::AppLogger).to receive(:info).with({ message: 'Removing invalid project member records', - deleted_count: 3, ids: [project_member1, project_member4, project_member6].map(&:id) }) + expect(Gitlab::AppLogger).to receive(:info).with({ + message: 'Removing invalid project member records', + deleted_count: 3, + ids: [project_member1, project_member4, project_member6].map(&:id) + }) perform_migration end def create_invalid_project_member(id:, user_id:) - members_table.create!(id: id, user_id: user_id, source_id: non_existing_record_id, access_level: Gitlab::Access::MAINTAINER, - type: "ProjectMember", source_type: "Project", notification_level: 3, member_namespace_id: nil) + members_table.create!( + id: id, user_id: user_id, source_id: non_existing_record_id, access_level: Gitlab::Access::MAINTAINER, + type: "ProjectMember", source_type: "Project", notification_level: 3, member_namespace_id: nil + ) end def create_valid_project_member(id:, user_id:, project:) - members_table.create!(id: id, user_id: user_id, source_id: project.id, access_level: Gitlab::Access::MAINTAINER, - type: "ProjectMember", source_type: "Project", member_namespace_id: project.project_namespace_id, notification_level: 3) + members_table.create!( + id: id, + user_id: user_id, + source_id: project.id, + access_level: Gitlab::Access::MAINTAINER, + type: "ProjectMember", + source_type: "Project", + member_namespace_id: project.project_namespace_id, + notification_level: 3 + ) end - # rubocop: enable Layout/LineLength # rubocop: enable RSpec/ScatteredLet end diff --git a/spec/lib/gitlab/background_migration/disable_legacy_open_source_licence_for_recent_public_projects_spec.rb b/spec/lib/gitlab/background_migration/disable_legacy_open_source_licence_for_recent_public_projects_spec.rb index 7edba8cf524..740a90e0494 100644 --- a/spec/lib/gitlab/background_migration/disable_legacy_open_source_licence_for_recent_public_projects_spec.rb +++ b/spec/lib/gitlab/background_migration/disable_legacy_open_source_licence_for_recent_public_projects_spec.rb @@ -73,14 +73,15 @@ RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenceForRec let(:project_settings_table) { table(:project_settings) } subject(:perform_migration) do - described_class.new(start_id: projects_table.minimum(:id), - end_id: projects_table.maximum(:id), - batch_table: :projects, - batch_column: :id, - sub_batch_size: 2, - pause_ms: 0, - connection: ActiveRecord::Base.connection) - .perform + described_class.new( + start_id: projects_table.minimum(:id), + end_id: projects_table.maximum(:id), + batch_table: :projects, + batch_column: :id, + sub_batch_size: 2, + pause_ms: 0, + connection: ActiveRecord::Base.connection + ).perform end before do @@ -94,7 +95,7 @@ RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenceForRec end it 'sets `legacy_open_source_license_available` attribute to false for public projects created after threshold time', - :aggregate_failures do + :aggregate_failures do record = ActiveRecord::QueryRecorder.new do expect { perform_migration } .to not_change { migrated_attribute(project_1.id) }.from(true) diff --git a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_inactive_public_projects_spec.rb b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_inactive_public_projects_spec.rb index f5a2dc91185..953eb09032f 100644 --- a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_inactive_public_projects_spec.rb +++ b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_inactive_public_projects_spec.rb @@ -8,14 +8,15 @@ RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForIna let(:project_settings_table) { table(:project_settings) } subject(:perform_migration) do - described_class.new(start_id: projects_table.minimum(:id), - end_id: projects_table.maximum(:id), - batch_table: :projects, - batch_column: :id, - sub_batch_size: 2, - pause_ms: 0, - connection: ActiveRecord::Base.connection) - .perform + described_class.new( + start_id: projects_table.minimum(:id), + end_id: projects_table.maximum(:id), + batch_table: :projects, + batch_column: :id, + sub_batch_size: 2, + pause_ms: 0, + connection: ActiveRecord::Base.connection + ).perform end let(:queries) { ActiveRecord::QueryRecorder.new { perform_migration } } @@ -27,32 +28,28 @@ RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForIna let(:project_namespace_5) { namespaces_table.create!(name: 'namespace', path: 'namespace-path-5', type: 'Project') } let(:project_1) do - projects_table - .create!( + projects_table.create!( name: 'proj-1', path: 'path-1', namespace_id: namespace_1.id, project_namespace_id: project_namespace_2.id, visibility_level: 0 ) end let(:project_2) do - projects_table - .create!( + projects_table.create!( name: 'proj-2', path: 'path-2', namespace_id: namespace_1.id, project_namespace_id: project_namespace_3.id, visibility_level: 10 ) end let(:project_3) do - projects_table - .create!( + projects_table.create!( name: 'proj-3', path: 'path-3', namespace_id: namespace_1.id, project_namespace_id: project_namespace_4.id, visibility_level: 20, last_activity_at: '2021-01-01' ) end let(:project_4) do - projects_table - .create!( + projects_table.create!( name: 'proj-4', path: 'path-4', namespace_id: namespace_1.id, project_namespace_id: project_namespace_5.id, visibility_level: 20, last_activity_at: '2022-01-01' ) @@ -66,7 +63,7 @@ RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForIna end it 'sets `legacy_open_source_license_available` attribute to false for inactive, public projects', - :aggregate_failures do + :aggregate_failures do expect(queries.count).to eq(5) expect(migrated_attribute(project_1.id)).to be_truthy diff --git a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb index d60874c3159..93913a2742b 100644 --- a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb +++ b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_no_issues_no_repo_projects_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForNoIssuesNoRepoProjects, - :migration, - schema: 20220722084543 do + :migration, + schema: 20220722084543 do let(:namespaces_table) { table(:namespaces) } let(:projects_table) { table(:projects) } let(:project_settings_table) { table(:project_settings) } @@ -12,18 +12,19 @@ RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForNoI let(:issues_table) { table(:issues) } subject(:perform_migration) do - described_class.new(start_id: projects_table.minimum(:id), - end_id: projects_table.maximum(:id), - batch_table: :projects, - batch_column: :id, - sub_batch_size: 2, - pause_ms: 0, - connection: ActiveRecord::Base.connection) - .perform + described_class.new( + start_id: projects_table.minimum(:id), + end_id: projects_table.maximum(:id), + batch_table: :projects, + batch_column: :id, + sub_batch_size: 2, + pause_ms: 0, + connection: ActiveRecord::Base.connection + ).perform end it 'sets `legacy_open_source_license_available` to false only for public projects with no issues and no repo', - :aggregate_failures do + :aggregate_failures do project_with_no_issues_no_repo = create_legacy_license_public_project('project-with-no-issues-no-repo') project_with_repo = create_legacy_license_public_project('project-with-repo', repo_size: 1) project_with_issues = create_legacy_license_public_project('project-with-issues', with_issue: true) @@ -41,13 +42,13 @@ RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForNoI def create_legacy_license_public_project(path, repo_size: 0, with_issue: false) namespace = namespaces_table.create!(name: "namespace-#{path}", path: "namespace-#{path}") - project_namespace = - namespaces_table.create!(name: "-project-namespace-#{path}", path: "project-namespace-#{path}", type: 'Project') - project = projects_table - .create!( - name: path, path: path, namespace_id: namespace.id, - project_namespace_id: project_namespace.id, visibility_level: 20 - ) + project_namespace = namespaces_table.create!( + name: "-project-namespace-#{path}", path: "project-namespace-#{path}", type: 'Project' + ) + project = projects_table.create!( + name: path, path: path, namespace_id: namespace.id, + project_namespace_id: project_namespace.id, visibility_level: 20 + ) project_statistics_table.create!(project_id: project.id, namespace_id: namespace.id, repository_size: repo_size) issues_table.create!(project_id: project.id, namespace_id: project.project_namespace_id) if with_issue diff --git a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_one_member_no_repo_projects_spec.rb b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_one_member_no_repo_projects_spec.rb index 0dba1d7c8a2..285e5ebbee2 100644 --- a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_one_member_no_repo_projects_spec.rb +++ b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_one_member_no_repo_projects_spec.rb @@ -3,8 +3,8 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForOneMemberNoRepoProjects, - :migration, - schema: 20220721031446 do + :migration, + schema: 20220721031446 do let(:namespaces_table) { table(:namespaces) } let(:projects_table) { table(:projects) } let(:project_settings_table) { table(:project_settings) } @@ -13,18 +13,19 @@ RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForOne let(:project_authorizations_table) { table(:project_authorizations) } subject(:perform_migration) do - described_class.new(start_id: projects_table.minimum(:id), - end_id: projects_table.maximum(:id), - batch_table: :projects, - batch_column: :id, - sub_batch_size: 2, - pause_ms: 0, - connection: ActiveRecord::Base.connection) - .perform + described_class.new( + start_id: projects_table.minimum(:id), + end_id: projects_table.maximum(:id), + batch_table: :projects, + batch_column: :id, + sub_batch_size: 2, + pause_ms: 0, + connection: ActiveRecord::Base.connection + ).perform end it 'sets `legacy_open_source_license_available` to false only for public projects with 1 member and no repo', - :aggregate_failures do + :aggregate_failures do project_with_no_repo_one_member = create_legacy_license_public_project('project-with-one-member-no-repo') project_with_repo_one_member = create_legacy_license_public_project('project-with-repo', repo_size: 1) project_with_no_repo_two_members = create_legacy_license_public_project('project-with-two-members', members: 2) @@ -42,13 +43,13 @@ RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForOne def create_legacy_license_public_project(path, repo_size: 0, members: 1) namespace = namespaces_table.create!(name: "namespace-#{path}", path: "namespace-#{path}") - project_namespace = - namespaces_table.create!(name: "-project-namespace-#{path}", path: "project-namespace-#{path}", type: 'Project') - project = projects_table - .create!( - name: path, path: path, namespace_id: namespace.id, - project_namespace_id: project_namespace.id, visibility_level: 20 - ) + project_namespace = namespaces_table.create!( + name: "-project-namespace-#{path}", path: "project-namespace-#{path}", type: 'Project' + ) + project = projects_table.create!( + name: path, path: path, namespace_id: namespace.id, + project_namespace_id: project_namespace.id, visibility_level: 20 + ) members.times do |member_id| user = users_table.create!(email: "user#{member_id}-project-#{project.id}@gitlab.com", projects_limit: 100) diff --git a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb index a153507837c..fedee9c5068 100644 --- a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb +++ b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_five_mb_spec.rb @@ -3,23 +3,24 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForProjectsLessThanFiveMb, - :migration, - schema: 20221018095434, - feature_category: :groups_and_projects do + :migration, + schema: 20221018095434, + feature_category: :groups_and_projects do let(:namespaces_table) { table(:namespaces) } let(:projects_table) { table(:projects) } let(:project_settings_table) { table(:project_settings) } let(:project_statistics_table) { table(:project_statistics) } subject(:perform_migration) do - described_class.new(start_id: project_settings_table.minimum(:project_id), - end_id: project_settings_table.maximum(:project_id), - batch_table: :project_settings, - batch_column: :project_id, - sub_batch_size: 2, - pause_ms: 0, - connection: ActiveRecord::Base.connection) - .perform + described_class.new( + start_id: project_settings_table.minimum(:project_id), + end_id: project_settings_table.maximum(:project_id), + batch_table: :project_settings, + batch_column: :project_id, + sub_batch_size: 2, + pause_ms: 0, + connection: ActiveRecord::Base.connection + ).perform end it 'sets `legacy_open_source_license_available` to false only for projects less than 5 MiB', :aggregate_failures do @@ -45,10 +46,12 @@ RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForPro def create_legacy_license_project_setting(repo_size:) path = "path-for-repo-size-#{repo_size}" namespace = namespaces_table.create!(name: "namespace-#{path}", path: "namespace-#{path}") - project_namespace = - namespaces_table.create!(name: "-project-namespace-#{path}", path: "project-namespace-#{path}", type: 'Project') - project = projects_table - .create!(name: path, path: path, namespace_id: namespace.id, project_namespace_id: project_namespace.id) + project_namespace = namespaces_table.create!( + name: "-project-namespace-#{path}", path: "project-namespace-#{path}", type: 'Project' + ) + project = projects_table.create!( + name: path, path: path, namespace_id: namespace.id, project_namespace_id: project_namespace.id + ) size_in_bytes = 1.megabyte * repo_size project_statistics_table.create!(project_id: project.id, namespace_id: namespace.id, repository_size: size_in_bytes) diff --git a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb index 2e6bc2f77ae..cf544c87b31 100644 --- a/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb +++ b/spec/lib/gitlab/background_migration/disable_legacy_open_source_license_for_projects_less_than_one_mb_spec.rb @@ -3,26 +3,27 @@ require 'spec_helper' RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForProjectsLessThanOneMb, - :migration, - schema: 20220906074449 do + :migration, + schema: 20220906074449 do let(:namespaces_table) { table(:namespaces) } let(:projects_table) { table(:projects) } let(:project_settings_table) { table(:project_settings) } let(:project_statistics_table) { table(:project_statistics) } subject(:perform_migration) do - described_class.new(start_id: project_settings_table.minimum(:project_id), - end_id: project_settings_table.maximum(:project_id), - batch_table: :project_settings, - batch_column: :project_id, - sub_batch_size: 2, - pause_ms: 0, - connection: ActiveRecord::Base.connection) - .perform + described_class.new( + start_id: project_settings_table.minimum(:project_id), + end_id: project_settings_table.maximum(:project_id), + batch_table: :project_settings, + batch_column: :project_id, + sub_batch_size: 2, + pause_ms: 0, + connection: ActiveRecord::Base.connection + ).perform end it 'sets `legacy_open_source_license_available` to false only for projects less than 1 MiB', - :aggregate_failures do + :aggregate_failures do project_setting_1_mb = create_legacy_license_project_setting(repo_size: 1) project_setting_2_mb = create_legacy_license_project_setting(repo_size: 2) project_setting_quarter_mb = create_legacy_license_project_setting(repo_size: 0.25) @@ -43,10 +44,12 @@ RSpec.describe Gitlab::BackgroundMigration::DisableLegacyOpenSourceLicenseForPro def create_legacy_license_project_setting(repo_size:) path = "path-for-repo-size-#{repo_size}" namespace = namespaces_table.create!(name: "namespace-#{path}", path: "namespace-#{path}") - project_namespace = - namespaces_table.create!(name: "-project-namespace-#{path}", path: "project-namespace-#{path}", type: 'Project') - project = projects_table - .create!(name: path, path: path, namespace_id: namespace.id, project_namespace_id: project_namespace.id) + project_namespace = namespaces_table.create!( + name: "-project-namespace-#{path}", path: "project-namespace-#{path}", type: 'Project' + ) + project = projects_table.create!( + name: path, path: path, namespace_id: namespace.id, project_namespace_id: project_namespace.id + ) size_in_bytes = 1.megabyte * repo_size project_statistics_table.create!(project_id: project.id, namespace_id: namespace.id, repository_size: size_in_bytes) diff --git a/spec/lib/gitlab/background_migration/expire_o_auth_tokens_spec.rb b/spec/lib/gitlab/background_migration/expire_o_auth_tokens_spec.rb index cffcda0a2ca..ba3aab03f2a 100644 --- a/spec/lib/gitlab/background_migration/expire_o_auth_tokens_spec.rb +++ b/spec/lib/gitlab/background_migration/expire_o_auth_tokens_spec.rb @@ -9,14 +9,15 @@ RSpec.describe Gitlab::BackgroundMigration::ExpireOAuthTokens, :migration, schem let(:table_name) { 'oauth_access_tokens' } subject(:perform_migration) do - described_class.new(start_id: 1, - end_id: 30, - batch_table: :oauth_access_tokens, - batch_column: :id, - sub_batch_size: 2, - pause_ms: 0, - connection: ActiveRecord::Base.connection) - .perform + described_class.new( + start_id: 1, + end_id: 30, + batch_table: :oauth_access_tokens, + batch_column: :id, + sub_batch_size: 2, + pause_ms: 0, + connection: ActiveRecord::Base.connection + ).perform end before do diff --git a/spec/lib/gitlab/background_migration/fix_incoherent_packages_size_on_project_statistics_spec.rb b/spec/lib/gitlab/background_migration/fix_incoherent_packages_size_on_project_statistics_spec.rb index f71b54a7eb4..2a53d39b6b1 100644 --- a/spec/lib/gitlab/background_migration/fix_incoherent_packages_size_on_project_statistics_spec.rb +++ b/spec/lib/gitlab/background_migration/fix_incoherent_packages_size_on_project_statistics_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' # rubocop: disable RSpec/MultipleMemoizedHelpers RSpec.describe Gitlab::BackgroundMigration::FixIncoherentPackagesSizeOnProjectStatistics, - feature_category: :package_registry do + feature_category: :package_registry do let(:project_statistics_table) { table(:project_statistics) } let(:packages_table) { table(:packages_packages) } let(:package_files_table) { table(:packages_package_files) } @@ -197,8 +197,8 @@ RSpec.describe Gitlab::BackgroundMigration::FixIncoherentPackagesSizeOnProjectSt context 'with incoherent packages_size' do it_behaves_like 'enqueuing a buffered updates', - incoherent_non_zero_statistics: 195, - incoherent_zero_statistics: 200 + incoherent_non_zero_statistics: 195, + incoherent_zero_statistics: 200 context 'with updates waiting on redis' do before do @@ -207,8 +207,8 @@ RSpec.describe Gitlab::BackgroundMigration::FixIncoherentPackagesSizeOnProjectSt end it_behaves_like 'enqueuing a buffered updates', - incoherent_non_zero_statistics: 195, - incoherent_zero_statistics: 200 + incoherent_non_zero_statistics: 195, + incoherent_zero_statistics: 200 end end diff --git a/spec/lib/gitlab/background_migration/legacy_upload_mover_spec.rb b/spec/lib/gitlab/background_migration/legacy_upload_mover_spec.rb index 71e9a568370..f4c5cd79863 100644 --- a/spec/lib/gitlab/background_migration/legacy_upload_mover_spec.rb +++ b/spec/lib/gitlab/background_migration/legacy_upload_mover_spec.rb @@ -18,9 +18,14 @@ RSpec.describe Gitlab::BackgroundMigration::LegacyUploadMover, :aggregate_failur let(:legacy_upload) { create_upload(note, filename) } def create_remote_upload(model, filename) - create(:upload, :attachment_upload, - path: "note/attachment/#{model.id}/#{filename}", secret: nil, - store: ObjectStorage::Store::REMOTE, model: model) + create( + :upload, + :attachment_upload, + path: "note/attachment/#{model.id}/#{filename}", + secret: nil, + store: ObjectStorage::Store::REMOTE, + model: model + ) end def create_upload(model, filename, with_file = true) @@ -147,14 +152,23 @@ RSpec.describe Gitlab::BackgroundMigration::LegacyUploadMover, :aggregate_failur end let(:legacy_upload) do - create(:upload, :with_file, :attachment_upload, - path: "uploads/-/system/note/attachment/#{note.id}/#{filename}", model: note) + create( + :upload, + :with_file, + :attachment_upload, + path: "uploads/-/system/note/attachment/#{note.id}/#{filename}", + model: note + ) end context 'when the file does not exist for the upload' do let(:legacy_upload) do - create(:upload, :attachment_upload, - path: "uploads/-/system/note/attachment/#{note.id}/#{filename}", model: note) + create( + :upload, + :attachment_upload, + path: "uploads/-/system/note/attachment/#{note.id}/#{filename}", + model: note + ) end it_behaves_like 'move error' @@ -162,8 +176,13 @@ RSpec.describe Gitlab::BackgroundMigration::LegacyUploadMover, :aggregate_failur context 'when the file does not exist on expected path' do let(:legacy_upload) do - create(:upload, :attachment_upload, :with_file, - path: "uploads/-/system/note/attachment/some_part/#{note.id}/#{filename}", model: note) + create( + :upload, + :attachment_upload, + :with_file, + path: "uploads/-/system/note/attachment/some_part/#{note.id}/#{filename}", + model: note + ) end it_behaves_like 'move error' @@ -171,8 +190,13 @@ RSpec.describe Gitlab::BackgroundMigration::LegacyUploadMover, :aggregate_failur context 'when the file path does not include system/note/attachment' do let(:legacy_upload) do - create(:upload, :attachment_upload, :with_file, - path: "uploads/-/system#{note.id}/#{filename}", model: note) + create( + :upload, + :attachment_upload, + :with_file, + path: "uploads/-/system#{note.id}/#{filename}", + model: note + ) end it_behaves_like 'move error' @@ -188,8 +212,14 @@ RSpec.describe Gitlab::BackgroundMigration::LegacyUploadMover, :aggregate_failur context 'when upload has mount_point nil' do let(:legacy_upload) do - create(:upload, :with_file, :attachment_upload, - path: "uploads/-/system/note/attachment/#{note.id}/#{filename}", model: note, mount_point: nil) + create( + :upload, + :with_file, + :attachment_upload, + path: "uploads/-/system/note/attachment/#{note.id}/#{filename}", + model: note, + mount_point: nil + ) end it_behaves_like 'migrates the file correctly', false diff --git a/vite.config.js b/vite.config.js index 6ff6cda0288..b0e4392a9dc 100644 --- a/vite.config.js +++ b/vite.config.js @@ -1,6 +1,5 @@ import path from 'path'; import { defineConfig } from 'vite'; -import svgLoader from 'vite-svg-loader'; import vue from '@vitejs/plugin-vue2'; import graphql from '@rollup/plugin-graphql'; import RubyPlugin from 'vite-plugin-ruby'; @@ -81,9 +80,6 @@ export default defineConfig({ }, }), graphql(), - svgLoader({ - defaultImport: 'raw', - }), viteCommonjs({ include: [path.resolve(javascriptsPath, 'locale/ensure_single_line.cjs')], }), diff --git a/yarn.lock b/yarn.lock index b4ecb9b9f6d..f35a635e1d8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2353,11 +2353,6 @@ resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-2.0.0.tgz#f544a148d3ab35801c1f633a7441fd87c2e484bf" integrity sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A== -"@trysound/sax@0.2.0": - version "0.2.0" - resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad" - integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA== - "@types/aria-query@^4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@types/aria-query/-/aria-query-4.2.0.tgz#14264692a9d6e2fa4db3df5e56e94b5e25647ac0" @@ -2838,7 +2833,7 @@ postcss "^8.4.14" source-map "^0.6.1" -"@vue/compiler-sfc@^3.2.20", "@vue/compiler-sfc@^3.2.47": +"@vue/compiler-sfc@^3.2.47": version "3.2.47" resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.47.tgz#1bdc36f6cdc1643f72e2c397eb1a398f5004ad3d" integrity sha512-rog05W+2IFfxjMcFw10tM9+f7i/+FFpZJJ5XHX72NP9eC2uRD+42M3pYcQqDXVYoj74kHMSEdQ/WmCjt8JFksQ== @@ -4702,17 +4697,6 @@ css-loader@^2.1.1: postcss-value-parser "^3.3.0" schema-utils "^1.0.0" -css-select@^4.1.3: - version "4.3.0" - resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b" - integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ== - dependencies: - boolbase "^1.0.0" - css-what "^6.0.1" - domhandler "^4.3.1" - domutils "^2.8.0" - nth-check "^2.0.1" - css-selector-parser@^1.3: version "1.3.0" resolved "https://registry.yarnpkg.com/css-selector-parser/-/css-selector-parser-1.3.0.tgz#5f1ad43e2d8eefbfdc304fcd39a521664943e3eb" @@ -4723,14 +4707,6 @@ css-shorthand-properties@^1.0.0: resolved "https://registry.yarnpkg.com/css-shorthand-properties/-/css-shorthand-properties-1.1.1.tgz#1c808e63553c283f289f2dd56fcee8f3337bd935" integrity sha512-Md+Juc7M3uOdbAFwOYlTrccIZ7oCFuzrhKYQjdeUEW/sE1hv17Jp/Bws+ReOPpGVBTYCBoYo+G17V5Qo8QQ75A== -css-tree@^1.1.2, css-tree@^1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d" - integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q== - dependencies: - mdn-data "2.0.14" - source-map "^0.6.1" - css-tree@^2.0.1, css-tree@^2.3.1: version "2.3.1" resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-2.3.1.tgz#10264ce1e5442e8572fc82fbe490644ff54b5c20" @@ -4748,11 +4724,6 @@ css-values@^0.1.0: ends-with "^0.2.0" postcss-value-parser "^3.3.0" -css-what@^6.0.1: - version "6.1.0" - resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4" - integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw== - cssesc@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/cssesc/-/cssesc-3.0.0.tgz#37741919903b868565e1c09ea747445cd18983ee" @@ -4763,13 +4734,6 @@ cssfontparser@^1.2.1: resolved "https://registry.yarnpkg.com/cssfontparser/-/cssfontparser-1.2.1.tgz#f4022fc8f9700c68029d542084afbaf425a3f3e3" integrity sha1-9AIvyPlwDGgCnVQghK+69CWj8+M= -csso@^4.2.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529" - integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA== - dependencies: - css-tree "^1.1.2" - cssom@^0.5.0: version "0.5.0" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.5.0.tgz#d254fa92cd8b6fbd83811b9fbaed34663cc17c36" @@ -5635,15 +5599,6 @@ dom-event-types@^1.0.0: resolved "https://registry.yarnpkg.com/dom-event-types/-/dom-event-types-1.0.0.tgz#5830a0a29e1bf837fe50a70cd80a597232813cae" integrity sha512-2G2Vwi2zXTHBGqXHsJ4+ak/iP0N8Ar+G8a7LiD2oup5o4sQWytwqqrZu/O6hIMV0KMID2PL69OhpshLO0n7UJQ== -dom-serializer@^1.0.1: - version "1.3.1" - resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.1.tgz#d845a1565d7c041a95e5dab62184ab41e3a519be" - integrity sha512-Pv2ZluG5ife96udGgEDovOOOA5UELkltfJpnIExPrAk1LTvecolUGn6lIaoLh86d83GiB86CjzciMd9BuRB71Q== - dependencies: - domelementtype "^2.0.1" - domhandler "^4.0.0" - entities "^2.0.0" - dom-walk@^0.1.0: version "0.1.2" resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.2.tgz#0c548bef048f4d1f2a97249002236060daa3fd84" @@ -5654,11 +5609,6 @@ domain-browser@^1.1.1: resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" integrity sha1-hnqksJP6oF8d4IwG9NeyH9+GmLw= -domelementtype@^2.0.1, domelementtype@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57" - integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A== - domexception@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" @@ -5673,13 +5623,6 @@ domexception@^4.0.0: dependencies: webidl-conversions "^7.0.0" -domhandler@^4.0.0, domhandler@^4.2.0, domhandler@^4.3.1: - version "4.3.1" - resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c" - integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ== - dependencies: - domelementtype "^2.2.0" - dommatrix@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/dommatrix/-/dommatrix-1.0.3.tgz#e7c18e8d6f3abdd1fef3dd4aa74c4d2e620a0525" @@ -5690,15 +5633,6 @@ dompurify@^3.0.5, dompurify@^3.0.6: resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.0.6.tgz#925ebd576d54a9531b5d76f0a5bef32548351dae" integrity sha512-ilkD8YEnnGh1zJ240uJsW7AzE+2qpbOUYjacomn3AvJ6J4JhKGSZ2nh4wUIXPZrEPppaCLx5jFe8T89Rk8tQ7w== -domutils@^2.8.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135" - integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A== - dependencies: - dom-serializer "^1.0.1" - domelementtype "^2.2.0" - domhandler "^4.2.0" - dropzone@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/dropzone/-/dropzone-4.2.0.tgz#fbe7acbb9918e0706489072ef663effeef8a79f3" @@ -5842,11 +5776,6 @@ enhanced-resolve@^4.5.0: memory-fs "^0.5.0" tapable "^1.0.0" -entities@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/entities/-/entities-2.1.0.tgz#992d3129cf7df6870b96c57858c249a120f8b8b5" - integrity sha512-hCx1oky9PFrJ611mf0ifBLBRW8lUUVRlFolb5gWRfIELabBlbp9xZvrqZLZAs+NxFnbfQoeGd8wDkygjg7U85w== - entities@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4" @@ -9350,11 +9279,6 @@ mdast-util-to-string@^3.0.0, mdast-util-to-string@^3.1.0: resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-3.1.0.tgz#56c506d065fbf769515235e577b5a261552d56e9" integrity sha512-n4Vypz/DZgwo0iMHLQL49dJzlp7YtAJP+N07MZHpjPf/5XJuHUWstviF4Mn2jEiR/GNmtnRRqnwsXExk3igfFA== -mdn-data@2.0.14: - version "2.0.14" - resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50" - integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow== - mdn-data@2.0.30: version "2.0.30" resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.30.tgz#ce4df6f80af6cfbe218ecd5c552ba13c4dfa08cc" @@ -10270,7 +10194,7 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" -nth-check@^2.0.1, nth-check@^2.1.1: +nth-check@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.1.1.tgz#c9eab428effce36cd6b92c924bdb000ef1f1ed1d" integrity sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w== @@ -12249,11 +12173,6 @@ ssri@^8.0.0: dependencies: minipass "^3.1.1" -stable@^0.1.8: - version "0.1.8" - resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf" - integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w== - stack-utils@^2.0.3: version "2.0.5" resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-2.0.5.tgz#d25265fca995154659dbbfba3b49254778d2fdd5" @@ -12583,19 +12502,6 @@ svg-tags@^1.0.0: resolved "https://registry.yarnpkg.com/svg-tags/-/svg-tags-1.0.0.tgz#58f71cee3bd519b59d4b2a843b6c7de64ac04764" integrity sha1-WPcc7jvVGbWdSyqEO2x95krAR2Q= -svgo@^2.7.0: - version "2.8.0" - resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24" - integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg== - dependencies: - "@trysound/sax" "0.2.0" - commander "^7.2.0" - css-select "^4.1.3" - css-tree "^1.1.3" - csso "^4.2.0" - picocolors "^1.0.0" - stable "^0.1.8" - swagger-cli@^4.0.4: version "4.0.4" resolved "https://registry.yarnpkg.com/swagger-cli/-/swagger-cli-4.0.4.tgz#c3f0b94277073c776b9bcc3ae7507b372f3ff414" @@ -13425,14 +13331,6 @@ vite-plugin-ruby@^3.2.2: debug "^4.3.4" fast-glob "^3.2.12" -vite-svg-loader@^3.6.0: - version "3.6.0" - resolved "https://registry.yarnpkg.com/vite-svg-loader/-/vite-svg-loader-3.6.0.tgz#71d246cba5e808c7f183a2a56a9dde6856bb0c92" - integrity sha512-bZJffcgCREW57kNkgMhuNqeDznWXyQwJ3wKrRhHLMMzwDnP5jr3vXW3cqsmquRR7VTP5mLdKj1/zzPPooGUuPw== - dependencies: - "@vue/compiler-sfc" "^3.2.20" - svgo "^2.7.0" - vite@^4.4.9: version "4.4.9" resolved "https://registry.yarnpkg.com/vite/-/vite-4.4.9.tgz#1402423f1a2f8d66fd8d15e351127c7236d29d3d" |