Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2025-04-29 03:17:27 +00:00
parent d9427c7e4d
commit cdababc7b5
32 changed files with 316 additions and 132 deletions

View File

@ -414,10 +414,6 @@ export default {
'ee/app/assets/javascripts/sidebar/components/incidents/escalation_status.vue',
'ee/app/assets/javascripts/sidebar/components/weight/sidebar_weight_widget.vue',
'ee/app/assets/javascripts/tracing/details/tracing_details.vue',
'ee/app/assets/javascripts/usage_quotas/code_suggestions/components/code_suggestions_info_card.vue',
'ee/app/assets/javascripts/usage_quotas/code_suggestions/components/search_and_sort_bar.vue',
'ee/app/assets/javascripts/usage_quotas/seats/components/statistics_seats_card.vue',
'ee/app/assets/javascripts/usage_quotas/transfer/components/usage_by_month.vue',
'ee/app/assets/javascripts/vue_merge_request_widget/components/blocking_merge_requests/blocking_merge_request_body.vue',
'ee/app/assets/javascripts/vue_merge_request_widget/components/blocking_merge_requests/blocking_merge_requests_report.vue',
'ee/app/assets/javascripts/vue_merge_request_widget/components/checks/not_approved.vue',

View File

@ -315,7 +315,7 @@ gem 're2', '~> 2.15', feature_category: :shared
# Misc
gem 'semver_dialects', '~> 3.6', feature_category: :software_composition_analysis
gem 'semver_dialects', '~> 3.7', feature_category: :software_composition_analysis
gem 'version_sorter', '~> 2.3', feature_category: :shared
gem 'csv_builder', path: 'gems/csv_builder', feature_category: :shared

View File

@ -692,7 +692,7 @@
{"name":"securerandom","version":"0.4.1","platform":"ruby","checksum":"cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1"},
{"name":"seed-fu","version":"2.3.9","platform":"ruby","checksum":"6d902d12dc1b88a16d487506baacc93b3a92e3671fdd603110d1600d35fbf478"},
{"name":"selenium-webdriver","version":"4.27.0","platform":"ruby","checksum":"8821f4ad60b935cfcdc5954c0a6642d894e936250aece8bf37a6fcbebe5eb6e0"},
{"name":"semver_dialects","version":"3.6.0","platform":"ruby","checksum":"bb8a78037c6c748114267d0e00f0a19e2701a3837c00cc37336e8224bc8473a3"},
{"name":"semver_dialects","version":"3.7.0","platform":"ruby","checksum":"6110b05266f7c8ce7794869d4d9dd3e15c3e5878eb1ffe5f0cea00060141dd1e"},
{"name":"sentry-rails","version":"5.22.1","platform":"ruby","checksum":"23227608dc0e202de8cf96840a591e52bd7d6967ebaed6eb2da50a7d2a2d3fb7"},
{"name":"sentry-ruby","version":"5.22.1","platform":"ruby","checksum":"ed77bdd76da7a4c6a3de43dc6d19d3c0412b2675b014a2654bc5bafd4d5b3289"},
{"name":"sentry-sidekiq","version":"5.22.1","platform":"ruby","checksum":"bd7a3f915e58e13ea67251d9a458667fc4bee6dfbbd12614c47daa239e822a89"},

View File

@ -1781,7 +1781,7 @@ GEM
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
semver_dialects (3.6.0)
semver_dialects (3.7.0)
deb_version (~> 1.0.1)
pastel (~> 0.8.0)
thor (~> 1.3)
@ -2370,7 +2370,7 @@ DEPENDENCIES
sd_notify (~> 0.1.0)
seed-fu (~> 2.3.7)
selenium-webdriver (~> 4.21, >= 4.21.1)
semver_dialects (~> 3.6)
semver_dialects (~> 3.7)
sentry-rails (~> 5.22.0)
sentry-ruby (~> 5.22.0)
sentry-sidekiq (~> 5.22.0)

View File

@ -692,7 +692,7 @@
{"name":"securerandom","version":"0.4.1","platform":"ruby","checksum":"cc5193d414a4341b6e225f0cb4446aceca8e50d5e1888743fac16987638ea0b1"},
{"name":"seed-fu","version":"2.3.9","platform":"ruby","checksum":"6d902d12dc1b88a16d487506baacc93b3a92e3671fdd603110d1600d35fbf478"},
{"name":"selenium-webdriver","version":"4.27.0","platform":"ruby","checksum":"8821f4ad60b935cfcdc5954c0a6642d894e936250aece8bf37a6fcbebe5eb6e0"},
{"name":"semver_dialects","version":"3.6.0","platform":"ruby","checksum":"bb8a78037c6c748114267d0e00f0a19e2701a3837c00cc37336e8224bc8473a3"},
{"name":"semver_dialects","version":"3.7.0","platform":"ruby","checksum":"6110b05266f7c8ce7794869d4d9dd3e15c3e5878eb1ffe5f0cea00060141dd1e"},
{"name":"sentry-rails","version":"5.22.1","platform":"ruby","checksum":"23227608dc0e202de8cf96840a591e52bd7d6967ebaed6eb2da50a7d2a2d3fb7"},
{"name":"sentry-ruby","version":"5.22.1","platform":"ruby","checksum":"ed77bdd76da7a4c6a3de43dc6d19d3c0412b2675b014a2654bc5bafd4d5b3289"},
{"name":"sentry-sidekiq","version":"5.22.1","platform":"ruby","checksum":"bd7a3f915e58e13ea67251d9a458667fc4bee6dfbbd12614c47daa239e822a89"},

View File

@ -1781,7 +1781,7 @@ GEM
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 3.0)
websocket (~> 1.0)
semver_dialects (3.6.0)
semver_dialects (3.7.0)
deb_version (~> 1.0.1)
pastel (~> 0.8.0)
thor (~> 1.3)
@ -2370,7 +2370,7 @@ DEPENDENCIES
sd_notify (~> 0.1.0)
seed-fu (~> 2.3.7)
selenium-webdriver (~> 4.21, >= 4.21.1)
semver_dialects (~> 3.6)
semver_dialects (~> 3.7)
sentry-rails (~> 5.22.0)
sentry-ruby (~> 5.22.0)
sentry-sidekiq (~> 5.22.0)

View File

@ -206,7 +206,7 @@ export default {
:id="$options.modalId"
:ref="$options.modalId"
:title="$options.i18n.createBranchRule"
:action-primary-text="$options.i18n.createProtectedBranch"
:action-primary-text="$options.i18n.createBranchRule"
@primary="addBranchRule({ name: $event })"
/>
<gl-modal

View File

@ -18,6 +18,7 @@ import blobInfoQuery from 'shared_queries/repository/blob_info.query.graphql';
import highlightMixin from '~/repository/mixins/highlight_mixin';
import projectInfoQuery from 'ee_else_ce/repository/queries/project_info.query.graphql';
import eventHub from '~/notes/event_hub';
import { InternalEvents } from '~/tracking';
import getRefMixin from '../mixins/get_ref';
import { getRefType } from '../utils/ref_type';
import {
@ -26,11 +27,14 @@ import {
LFS_STORAGE,
LEGACY_FILE_TYPES,
EMPTY_FILE,
EVENT_FILE_SIZE_LIMIT_EXCEEDED,
} from '../constants';
import BlobButtonGroup from './blob_button_group.vue';
import ForkSuggestion from './fork_suggestion.vue';
import { loadViewer } from './blob_viewers';
const trackingMixin = InternalEvents.mixin();
export default {
components: {
BlobHeader,
@ -42,7 +46,7 @@ export default {
CodeIntelligence,
AiGenie: () => import('ee_component/ai/components/ai_genie.vue'),
},
mixins: [getRefMixin, highlightMixin, glFeatureFlagMixin()],
mixins: [getRefMixin, highlightMixin, glFeatureFlagMixin(), trackingMixin],
inject: {
originalBranch: {
default: '',
@ -95,6 +99,13 @@ export default {
const urlHash = getLocationHash(); // If there is a code line hash in the URL we render with the simple viewer
const useSimpleViewer = usePlain || urlHash?.startsWith('L') || !this.hasRichViewer;
if (this.isTooLarge) {
this.trackEvent(EVENT_FILE_SIZE_LIMIT_EXCEEDED, {
label: this.blobInfo.language,
property: this.blobInfo.size,
});
}
if (this.isUnsupportedLanguage(this.blobInfo.language) && this.isTooLarge) return;
this.initHighlightWorker(this.blobInfo, this.isUsingLfs);
this.switchViewer(useSimpleViewer ? SIMPLE_BLOB_VIEWER : RICH_BLOB_VIEWER); // By default, if present, use the rich viewer to render

View File

@ -101,3 +101,4 @@ export const POLLING_INTERVAL_BACKOFF = 2;
export const CONFLICTS_MODAL_ID = 'fork-sync-conflicts-modal';
export const FORK_UPDATED_EVENT = 'fork:updated';
export const EVENT_FILE_SIZE_LIMIT_EXCEEDED = 'repository_file_size_limit_exceeded';

View File

@ -1,5 +1,6 @@
<script>
import { colorFromDefaultPalette } from '@gitlab/ui/dist/utils/charts/theme';
import { colorFromDefaultPalette, colorFromDarkPalette } from '@gitlab/ui/dist/utils/charts/theme';
import { darkModeEnabled } from '~/lib/utils/color_utils';
import { roundOffFloat } from '~/lib/utils/common_utils';
import { formatNumber } from '~/locale';
@ -31,7 +32,9 @@ export default {
const percentage = section.value / this.sectionsCombinedValue;
return {
...section,
backgroundColor: section.color ?? colorFromDefaultPalette(index),
backgroundColor:
section.color ??
(darkModeEnabled() ? colorFromDarkPalette(index) : colorFromDefaultPalette(index)),
cssPercentage: `${roundOffFloat(percentage * 100, 4)}%`,
srLabelPercentage: formatNumber(percentage, {
style: 'percent',

View File

@ -212,7 +212,6 @@ class SnippetsFinder < UnionFinder
def hide_created_by_banned_user(snippets)
# if admin -> return all snippets, if not-admin -> filter out snippets by banned user
return snippets if can?(current_user, :read_all_resources)
return snippets unless Feature.enabled?(:hide_snippets_of_banned_users)
snippets.without_created_by_banned_user
end

View File

@ -387,7 +387,7 @@ class Snippet < ApplicationRecord
end
def hidden_due_to_author_ban?
Feature.enabled?(:hide_snippets_of_banned_users) && author.banned?
author.banned?
end
end

View File

@ -4,8 +4,7 @@ module Ci
module Pipelines
class ClearPersistentRefService < CreatePersistentRefService
def execute
Rails.cache.delete(pipeline_persistent_ref_cache_key) if Feature.enabled?(:ci_only_one_persistent_ref_creation,
pipeline.project)
Rails.cache.delete(pipeline_persistent_ref_cache_key)
if Feature.enabled?(:pipeline_delete_gitaly_refs_in_batches, pipeline.project)
pipeline.persistent_ref.async_delete

View File

@ -11,20 +11,14 @@ module Ci
end
def execute
if Feature.enabled?(:ci_only_one_persistent_ref_creation, pipeline.project)
# NOTE: caching here is to prevent overwhelming calls to Gitaly API
# triggered by the job transition to `running` in the same pipeline
Rails.cache.fetch(pipeline_persistent_ref_cache_key, expires_in: TIMEOUT) do
next true if persistent_ref.exist?
next true if persistent_ref.create
# NOTE: caching here is to prevent overwhelming calls to Gitaly API
# triggered by the job transition to `running` in the same pipeline
Rails.cache.fetch(pipeline_persistent_ref_cache_key, expires_in: TIMEOUT) do
next true if persistent_ref.exist?
next true if persistent_ref.create
pipeline.drop!(:pipeline_ref_creation_failure)
false
end
else
return if persistent_ref.exist?
persistent_ref.create
pipeline.drop!(:pipeline_ref_creation_failure)
false
end
end

View File

@ -0,0 +1,22 @@
---
description: Repository file viewer limit exceeded
internal_events: true
action: repository_file_size_limit_exceeded
identifiers:
- project
- namespace
- user
additional_properties:
label:
description: File type (e.g. js, json, sql, py, csv)
property:
description: File size (bytes)
product_group: source_code
product_categories:
- source_code_management
milestone: '18.0'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/189149
tiers:
- free
- premium
- ultimate

View File

@ -1,8 +0,0 @@
---
name: hide_snippets_of_banned_users
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/134048
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/425391
milestone: '16.6'
type: development
group: group::authorization
default_enabled: false

View File

@ -1,9 +0,0 @@
---
name: ci_only_one_persistent_ref_creation
feature_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/493356
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/182565
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/527014
milestone: '17.11'
group: group::ci platform
type: gitlab_com_derisk
default_enabled: false

View File

@ -0,0 +1,23 @@
---
key_path: counts.count_total_repository_file_size_limit_exceeded
description: Count of file size limit exceeded occurrences
product_group: source_code
product_categories:
- source_code_management
performance_indicator_type: []
value_type: number
status: active
milestone: '18.0'
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/189149
time_frame:
- 28d
- 7d
- all
data_source: internal_events
data_category: optional
tiers:
- free
- premium
- ultimate
events:
- name: repository_file_size_limit_exceeded

View File

@ -0,0 +1,79 @@
# frozen_string_literal: true
class AddIncidentToRelatedLinksRestrictions < Gitlab::Database::Migration[2.2]
milestone '18.0'
BASE_TYPES = {
issue: 0,
incident: 1,
task: 4,
objective: 5,
key_result: 6,
epic: 7
}.freeze
class WorkItemType < MigrationRecord
self.table_name = 'work_item_types'
end
class RelatedLinkRestriction < MigrationRecord
self.table_name = 'work_item_related_link_restrictions'
end
restrict_gitlab_migration gitlab_schema: :gitlab_main
disable_ddl_transaction!
def up
work_item_types = fetch_work_item_types
missing_types = work_item_types.select { |_key, value| value.nil? }.keys
return say("Required WorkItemType records are missing: #{missing_types.join(', ')}") unless missing_types.empty?
incident = work_item_types[:incident]
epic = work_item_types[:epic]
issue = work_item_types[:issue]
task = work_item_types[:task]
objective = work_item_types[:objective]
key_result = work_item_types[:key_result]
restrictions = [
{ source_type_id: epic.id, target_type_id: incident.id, link_type: 0 },
{ source_type_id: issue.id, target_type_id: incident.id, link_type: 0 },
{ source_type_id: task.id, target_type_id: incident.id, link_type: 0 },
{ source_type_id: objective.id, target_type_id: incident.id, link_type: 0 },
{ source_type_id: key_result.id, target_type_id: incident.id, link_type: 0 },
{ source_type_id: incident.id, target_type_id: incident.id, link_type: 0 },
{ source_type_id: epic.id, target_type_id: incident.id, link_type: 1 },
{ source_type_id: issue.id, target_type_id: incident.id, link_type: 1 },
{ source_type_id: task.id, target_type_id: incident.id, link_type: 1 },
{ source_type_id: objective.id, target_type_id: incident.id, link_type: 1 },
{ source_type_id: key_result.id, target_type_id: incident.id, link_type: 1 },
{ source_type_id: incident.id, target_type_id: incident.id, link_type: 1 },
{ source_type_id: incident.id, target_type_id: epic.id, link_type: 1 },
{ source_type_id: incident.id, target_type_id: issue.id, link_type: 1 },
{ source_type_id: incident.id, target_type_id: task.id, link_type: 1 },
{ source_type_id: incident.id, target_type_id: objective.id, link_type: 1 },
{ source_type_id: incident.id, target_type_id: key_result.id, link_type: 1 }
]
RelatedLinkRestriction.upsert_all(
restrictions,
unique_by: :index_work_item_link_restrictions_on_source_link_type_target
)
end
def down
incident = WorkItemType.find_by(base_type: BASE_TYPES[:incident])
return unless incident
RelatedLinkRestriction.where(source_type_id: incident.id).delete_all
RelatedLinkRestriction.where(target_type_id: incident.id).delete_all
end
private
def fetch_work_item_types
BASE_TYPES.transform_values { |base_type| WorkItemType.find_by(base_type: base_type) }
end
end

View File

@ -0,0 +1 @@
8be92c3fdb3c177a76ac12976bb94c2e89501ae2628e27ae7f1bcdd47f9e6857

View File

@ -68,6 +68,12 @@ gitlab-advanced-sast:
SEARCH_MAX_DEPTH: 20
SAST_ANALYZER_IMAGE_TAG: '2'
SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/gitlab-advanced-sast:$SAST_ANALYZER_IMAGE_TAG$SAST_IMAGE_SUFFIX"
cache:
key: "scan-metrics-$CI_COMMIT_REF_SLUG"
fallback_keys:
- "scan-metrics-$CI_DEFAULT_BRANCH"
paths:
- "scan_metrics.csv"
rules:
- if: $SAST_DISABLED == 'true' || $SAST_DISABLED == '1'
when: never

View File

@ -65,6 +65,12 @@ gitlab-advanced-sast:
SEARCH_MAX_DEPTH: 20
SAST_ANALYZER_IMAGE_TAG: 2
SAST_ANALYZER_IMAGE: "$SECURE_ANALYZERS_PREFIX/gitlab-advanced-sast:$SAST_ANALYZER_IMAGE_TAG$SAST_IMAGE_SUFFIX"
cache:
key: "scan-metrics-$CI_COMMIT_REF_SLUG"
fallback_keys:
- "scan-metrics-$CI_DEFAULT_BRANCH"
paths:
- "scan_metrics.csv"
rules:
- if: $SAST_DISABLED == 'true' || $SAST_DISABLED == '1'
when: never

View File

@ -14,44 +14,66 @@ module Gitlab
task = find_or_create_type(::WorkItems::Type::TYPE_NAMES[:task])
objective = find_or_create_type(::WorkItems::Type::TYPE_NAMES[:objective])
key_result = find_or_create_type(::WorkItems::Type::TYPE_NAMES[:key_result])
incident = find_or_create_type(::WorkItems::Type::TYPE_NAMES[:incident])
restrictions = [
# Source can relate to target and target can relate to source
{ source_type_id: epic.id, target_type_id: epic.id, link_type: 0 },
{ source_type_id: epic.id, target_type_id: issue.id, link_type: 0 },
{ source_type_id: epic.id, target_type_id: task.id, link_type: 0 },
{ source_type_id: epic.id, target_type_id: objective.id, link_type: 0 },
{ source_type_id: epic.id, target_type_id: key_result.id, link_type: 0 },
{ source_type_id: epic.id, target_type_id: incident.id, link_type: 0 },
{ source_type_id: issue.id, target_type_id: issue.id, link_type: 0 },
{ source_type_id: issue.id, target_type_id: task.id, link_type: 0 },
{ source_type_id: issue.id, target_type_id: objective.id, link_type: 0 },
{ source_type_id: issue.id, target_type_id: key_result.id, link_type: 0 },
{ source_type_id: issue.id, target_type_id: incident.id, link_type: 0 },
{ source_type_id: task.id, target_type_id: task.id, link_type: 0 },
{ source_type_id: task.id, target_type_id: objective.id, link_type: 0 },
{ source_type_id: task.id, target_type_id: key_result.id, link_type: 0 },
{ source_type_id: task.id, target_type_id: incident.id, link_type: 0 },
{ source_type_id: objective.id, target_type_id: objective.id, link_type: 0 },
{ source_type_id: objective.id, target_type_id: key_result.id, link_type: 0 },
{ source_type_id: objective.id, target_type_id: incident.id, link_type: 0 },
{ source_type_id: key_result.id, target_type_id: key_result.id, link_type: 0 },
{ source_type_id: key_result.id, target_type_id: incident.id, link_type: 0 },
{ source_type_id: incident.id, target_type_id: incident.id, link_type: 0 },
{ source_type_id: incident.id, target_type_id: issue.id, link_type: 0 },
{ source_type_id: incident.id, target_type_id: task.id, link_type: 0 },
{ source_type_id: incident.id, target_type_id: objective.id, link_type: 0 },
{ source_type_id: incident.id, target_type_id: key_result.id, link_type: 0 },
{ source_type_id: incident.id, target_type_id: epic.id, link_type: 0 },
# Source can block target and target can be blocked by source
{ source_type_id: epic.id, target_type_id: epic.id, link_type: 1 },
{ source_type_id: epic.id, target_type_id: issue.id, link_type: 1 },
{ source_type_id: epic.id, target_type_id: task.id, link_type: 1 },
{ source_type_id: epic.id, target_type_id: objective.id, link_type: 1 },
{ source_type_id: epic.id, target_type_id: key_result.id, link_type: 1 },
{ source_type_id: epic.id, target_type_id: incident.id, link_type: 1 },
{ source_type_id: issue.id, target_type_id: issue.id, link_type: 1 },
{ source_type_id: issue.id, target_type_id: epic.id, link_type: 1 },
{ source_type_id: issue.id, target_type_id: task.id, link_type: 1 },
{ source_type_id: issue.id, target_type_id: objective.id, link_type: 1 },
{ source_type_id: issue.id, target_type_id: key_result.id, link_type: 1 },
{ source_type_id: issue.id, target_type_id: incident.id, link_type: 1 },
{ source_type_id: task.id, target_type_id: task.id, link_type: 1 },
{ source_type_id: task.id, target_type_id: epic.id, link_type: 1 },
{ source_type_id: task.id, target_type_id: issue.id, link_type: 1 },
{ source_type_id: task.id, target_type_id: objective.id, link_type: 1 },
{ source_type_id: task.id, target_type_id: key_result.id, link_type: 1 },
{ source_type_id: task.id, target_type_id: incident.id, link_type: 1 },
{ source_type_id: objective.id, target_type_id: objective.id, link_type: 1 },
{ source_type_id: objective.id, target_type_id: key_result.id, link_type: 1 },
{ source_type_id: objective.id, target_type_id: incident.id, link_type: 1 },
{ source_type_id: key_result.id, target_type_id: key_result.id, link_type: 1 },
{ source_type_id: key_result.id, target_type_id: objective.id, link_type: 1 }
{ source_type_id: key_result.id, target_type_id: objective.id, link_type: 1 },
{ source_type_id: key_result.id, target_type_id: incident.id, link_type: 1 },
{ source_type_id: incident.id, target_type_id: incident.id, link_type: 1 },
{ source_type_id: incident.id, target_type_id: epic.id, link_type: 1 },
{ source_type_id: incident.id, target_type_id: issue.id, link_type: 1 },
{ source_type_id: incident.id, target_type_id: task.id, link_type: 1 },
{ source_type_id: incident.id, target_type_id: objective.id, link_type: 1 },
{ source_type_id: incident.id, target_type_id: key_result.id, link_type: 1 }
]
::WorkItems::RelatedLinkRestriction.upsert_all(

View File

@ -349,23 +349,6 @@ RSpec.describe SnippetsFinder do
expect(snippets).to be_empty
end
context 'when hide_snippets_of_banned_users feature flag is off' do
before do
stub_feature_flags(hide_snippets_of_banned_users: false)
end
it 'returns banned snippets for non-admin users' do
snippets = described_class.new(
user,
ids: [banned_public_personal_snippet.id, banned_public_project_snippet.id]
).execute
expect(snippets).to contain_exactly(
banned_public_personal_snippet, banned_public_project_snippet
)
end
end
end
context 'when the user cannot read cross project' do

View File

@ -154,7 +154,7 @@ describe('Branch rules app', () => {
disabled: true,
variant: 'confirm',
},
text: 'Create protected branch',
text: 'Create branch rule',
},
});
});

View File

@ -43,6 +43,7 @@ import {
projectMock,
getProjectMockWithOverrides,
} from 'ee_else_ce_jest/repository/mock_data';
import { mockTracking } from 'helpers/tracking_helper';
jest.mock('~/repository/components/blob_viewers');
jest.mock('~/lib/utils/url_utility');
@ -53,6 +54,7 @@ jest.mock('~/alert');
let wrapper;
let blobInfoMockResolver;
let projectInfoMockResolver;
let trackingSpy;
Vue.use(Vuex);
@ -135,6 +137,7 @@ const createComponent = async (mockData = {}, mountFn = shallowMount, mockRoute
},
}),
);
trackingSpy = mockTracking(undefined, wrapper.element, jest.spyOn);
await waitForPromises();
};
@ -420,7 +423,7 @@ describe('Blob content viewer component', () => {
language | size | tooLarge | renderError | expectedTooLarge
${'ruby'} | ${100} | ${false} | ${null} | ${false}
${'ruby'} | ${FILE_SIZE_3MB} | ${false} | ${null} | ${true}
${'nyan'} | ${null} | ${true} | ${null} | ${true}
${'nyan'} | ${FILE_SIZE_3MB} | ${true} | ${null} | ${true}
${'nyan'} | ${null} | ${false} | ${'collapsed'} | ${true}
`(
'correctly handles file size limits when language=$language, size=$size, tooLarge=$tooLarge, renderError=$renderError',
@ -438,6 +441,13 @@ describe('Blob content viewer component', () => {
},
});
if (tooLarge) {
expect(trackingSpy).toHaveBeenCalledWith(undefined, 'view_source', {
label: 'repository_file_size_limit_exceeded',
property: { label: language, property: size },
});
}
await waitForPromises();
expect(loadViewer).toHaveBeenCalledWith('text', false, expectedTooLarge);
},

View File

@ -1,6 +1,7 @@
import { GRAY_100 } from '@gitlab/ui/src/tokens/build/js/tokens';
import { shallowMountExtended } from 'helpers/vue_test_utils_helper';
import SectionedPercentageBar from '~/usage_quotas/components/sectioned_percentage_bar.vue';
import * as ColorUtils from '~/lib/utils/color_utils';
describe('SectionedPercentageBar', () => {
let wrapper;
@ -183,4 +184,18 @@ describe('SectionedPercentageBar', () => {
expect(section2.attributes('style')).toContain('background-color: rgb(177, 79, 24);');
});
});
describe('dark mode', () => {
it('uses a different color palette', () => {
jest.spyOn(ColorUtils, 'darkModeEnabled').mockImplementation(() => true);
createComponent();
const section1 = wrapper.findByTestId(PERCENTAGE_BAR_SECTION_TESTID_PREFIX + SECTION_1);
const section2 = wrapper.findByTestId(PERCENTAGE_BAR_SECTION_TESTID_PREFIX + SECTION_2);
expect(section1.attributes('style')).toContain('background-color: rgb(97, 122, 226);');
expect(section2.attributes('style')).toContain('background-color: rgb(224, 126, 65);');
});
});
});

View File

@ -0,0 +1,84 @@
# frozen_string_literal: true
require 'spec_helper'
require_migration!
TOTAL_RESTRICTIONS = 51
SOURCE_INCIDENT_RESTRICTIONS = 7
TARGET_INCIDENT_RESTRICTIONS = 12
PRE_MIGRATION_RESTRICTIONS = 34
RSpec.describe AddIncidentToRelatedLinksRestrictions, feature_category: :database, migration_version: 20250310182907 do
let(:migration) { described_class.new }
let(:work_item_types) { table(:work_item_types) }
let(:related_link_restrictions) { table(:work_item_related_link_restrictions) }
let(:base_types) do
{
issue: 0,
incident: 1,
task: 4,
objective: 5,
key_result: 6,
epic: 7
}
end
let(:work_item_type_ids) do
base_types.transform_values { |base_type| work_item_types.find_by!(base_type: base_type).id }
end
describe '#up' do
it 'creates related link restrictions for incidents' do
migration.up
expect(related_link_restrictions.count).to eq(TOTAL_RESTRICTIONS)
expect(
related_link_restrictions.exists?(
source_type_id: work_item_type_ids[:issue],
target_type_id: work_item_type_ids[:incident],
link_type: 0
)
).to be_truthy
expect(
related_link_restrictions.where(source_type_id: work_item_type_ids[:incident]).count
).to eq(SOURCE_INCIDENT_RESTRICTIONS)
expect(
related_link_restrictions.where(target_type_id: work_item_type_ids[:incident]).count
).to eq(TARGET_INCIDENT_RESTRICTIONS)
end
end
describe '#down' do
before do
migration.up
end
it 'removes all incident-related restrictions' do
expect(related_link_restrictions.count).to eq(TOTAL_RESTRICTIONS)
migration.down
expect(related_link_restrictions.count).to eq(PRE_MIGRATION_RESTRICTIONS)
expect(
related_link_restrictions.where(source_type_id: work_item_type_ids[:incident]).count
).to eq(0)
expect(
related_link_restrictions.where(target_type_id: work_item_type_ids[:incident]).count
).to eq(0)
expect(
related_link_restrictions.exists?(
source_type_id: work_item_type_ids[:incident],
target_type_id: work_item_type_ids[:issue],
link_type: 0
)
).to be_falsey
end
end
end

View File

@ -1017,14 +1017,6 @@ RSpec.describe Snippet, feature_category: :source_code_management do
let_it_be(:author) { build(:user, :banned) }
it { is_expected.to eq(true) }
context 'when the `hide_snippets_of_banned_users` feature flag is disabled' do
before do
stub_feature_flags(hide_snippets_of_banned_users: false)
end
it { is_expected.to eq(false) }
end
end
end
end

View File

@ -36,13 +36,13 @@ RSpec.describe WorkItems::RelatedWorkItemLink, type: :model, feature_category: :
using RSpec::Parameterized::TableSyntax
where(:source_type_sym, :target_types, :valid) do
:incident | [:incident, :test_case, :issue, :task, :ticket] | false
:ticket | [:incident, :test_case, :issue, :task, :ticket] | false
:test_case | [:incident, :test_case, :issue, :task, :ticket] | false
:task | [:incident, :test_case, :ticket] | false
:issue | [:incident, :test_case, :ticket] | false
:task | [:task, :issue] | true
:issue | [:task, :issue] | true
:ticket | [:test_case, :issue, :task, :ticket] | false
:test_case | [:test_case, :issue, :task, :ticket] | false
:task | [:test_case, :ticket] | false
:issue | [:test_case, :ticket] | false
:task | [:task, :issue, :incident] | true
:issue | [:task, :issue, :incident] | true
:incident | [:incident, :issue, :task] | true
end
with_them do

View File

@ -37,49 +37,4 @@ RSpec.describe Ci::Pipelines::CreatePersistentRefService, :use_clean_rails_memor
.and change { pipeline.status }.to('failed')
end
end
context 'when ff ci_only_one_persistent_ref_creation is disabled' do
before do
stub_feature_flags(ci_only_one_persistent_ref_creation: false)
end
it 'creates persistent ref' do
expect { service.execute }
.to change { pipeline.persistent_ref.exist? }.from(false).to(true)
.and not_change { pipeline.status }
expect(pipeline.persistent_ref).to receive(:exist?).and_call_original
expect(pipeline.persistent_ref).not_to receive(:create)
service.execute
end
context 'when persistent ref is already created' do
before do
pipeline.persistent_ref.create # rubocop:disable Rails/SaveBang -- not ActiveRecord
end
it 'does not create persistent ref and caches true' do
expect { service.execute }
.to not_change { pipeline.persistent_ref.exist? }.from(true)
.and not_change { pipeline.status }
expect(pipeline.persistent_ref).to receive(:exist?).and_call_original
expect(pipeline.persistent_ref).not_to receive(:create)
service.execute
end
end
context 'when persistent ref creation raises error' do
it 'drops the pipeline and caches false' do
expect(pipeline.persistent_ref).to receive(:create_ref).and_raise('Error')
expect { service.execute }
.to not_change { pipeline.persistent_ref.exist? }.from(false)
.and not_change { pipeline.status }
expect(pipeline.persistent_ref).to receive(:exist?).and_call_original
expect(pipeline.persistent_ref).to receive(:create)
service.execute
end
end
end
end

View File

@ -3,7 +3,7 @@
RSpec.shared_examples 'work item related links restrictions importer' do
shared_examples_for 'adds restrictions' do
it "adds all restrictions if they don't exist" do
expect { subject }.to change { WorkItems::RelatedLinkRestriction.count }.from(0).to(34)
expect { subject }.to change { WorkItems::RelatedLinkRestriction.count }.from(0).to(56)
end
end
@ -33,7 +33,7 @@ RSpec.shared_examples 'work item related links restrictions importer' do
expect { subject }.to make_queries_matching(/INSERT/, 1).and(
change { WorkItems::RelatedLinkRestriction.count }.by(1)
)
expect(WorkItems::RelatedLinkRestriction.count).to eq(34)
expect(WorkItems::RelatedLinkRestriction.count).to eq(56)
end
end
end