Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
94356b7dcd
commit
a9f80cbfe2
|
|
@ -3292,7 +3292,6 @@ Gitlab/BoundedContexts:
|
|||
- 'ee/app/services/llm/resolve_vulnerability_service.rb'
|
||||
- 'ee/app/services/llm/review_merge_request_service.rb'
|
||||
- 'ee/app/services/llm/summarize_new_merge_request_service.rb'
|
||||
- 'ee/app/services/member_roles/base_service.rb'
|
||||
- 'ee/app/services/member_roles/create_service.rb'
|
||||
- 'ee/app/services/member_roles/delete_service.rb'
|
||||
- 'ee/app/services/member_roles/update_service.rb'
|
||||
|
|
|
|||
|
|
@ -2,17 +2,6 @@
|
|||
# Cop supports --autocorrect.
|
||||
Layout/LineBreakAfterFinalMixin:
|
||||
Exclude:
|
||||
- 'app/graphql/resolvers/integrations/exclusions_resolver.rb'
|
||||
- 'app/graphql/resolvers/projects/deploy_key_resolver.rb'
|
||||
- 'app/policies/project_member_policy.rb'
|
||||
- 'app/serializers/cluster_serializer.rb'
|
||||
- 'app/serializers/container_repositories_serializer.rb'
|
||||
- 'app/serializers/feature_flag_serializer.rb'
|
||||
- 'app/serializers/pipeline_serializer.rb'
|
||||
- 'app/services/authorized_project_update/project_recalculate_service.rb'
|
||||
- 'app/services/batched_git_ref_updates/cleanup_scheduler_service.rb'
|
||||
- 'app/services/jira_connect_subscriptions/create_service.rb'
|
||||
- 'app/services/projects/transfer_service.rb'
|
||||
- 'app/workers/ci/delete_unit_tests_worker.rb'
|
||||
- 'app/workers/ci/pipeline_artifacts/expire_artifacts_worker.rb'
|
||||
- 'app/workers/ci/schedule_delete_objects_cron_worker.rb'
|
||||
|
|
@ -37,12 +26,6 @@ Layout/LineBreakAfterFinalMixin:
|
|||
- 'app/workers/stuck_export_jobs_worker.rb'
|
||||
- 'app/workers/user_status_cleanup/batch_worker.rb'
|
||||
- 'app/workers/users/create_statistics_worker.rb'
|
||||
- 'ee/app/graphql/subscriptions/ai_completion_response.rb'
|
||||
- 'ee/app/services/ee/ip_restrictions/update_service.rb'
|
||||
- 'ee/app/services/incident_management/oncall_rotations/edit_service.rb'
|
||||
- 'ee/app/services/incident_management/oncall_rotations/remove_participant_service.rb'
|
||||
- 'ee/app/services/llm/generate_description_service.rb'
|
||||
- 'ee/app/services/product_analytics/initialize_stack_service.rb'
|
||||
- 'ee/app/workers/active_user_count_threshold_worker.rb'
|
||||
- 'ee/app/workers/analytics/value_stream_dashboard/count_worker.rb'
|
||||
- 'ee/app/workers/arkose/blocked_users_report_worker.rb'
|
||||
|
|
@ -56,10 +39,3 @@ Layout/LineBreakAfterFinalMixin:
|
|||
- 'ee/app/workers/sync_seat_link_worker.rb'
|
||||
- 'ee/app/workers/vulnerabilities/historical_statistics/deletion_worker.rb'
|
||||
- 'ee/app/workers/vulnerabilities/statistics/schedule_worker.rb'
|
||||
- 'lib/banzai/filter/references/design_reference_filter.rb'
|
||||
- 'lib/feature.rb'
|
||||
- 'lib/gitlab/auth/current_user_mode.rb'
|
||||
- 'lib/gitlab/auth/otp/strategies/forti_token_cloud.rb'
|
||||
- 'lib/gitlab/ci/config/interpolation/config.rb'
|
||||
- 'lib/gitlab/cluster/rack_timeout_observer.rb'
|
||||
- 'lib/gitlab/etag_caching/router/graphql.rb'
|
||||
|
|
|
|||
|
|
@ -2247,7 +2247,6 @@ Layout/LineLength:
|
|||
- 'lib/security/ci_configuration/base_build_action.rb'
|
||||
- 'lib/security/ci_configuration/sast_build_action.rb'
|
||||
- 'lib/sidebars/groups/menus/packages_registries_menu.rb'
|
||||
- 'lib/sidebars/menu_item.rb'
|
||||
- 'lib/sidebars/projects/menus/repository_menu.rb'
|
||||
- 'lib/system_check/app/orphaned_group_members_check.rb'
|
||||
- 'lib/system_check/app/redis_version_check.rb'
|
||||
|
|
|
|||
|
|
@ -182,7 +182,6 @@ RSpec/BeEq:
|
|||
- 'ee/spec/lib/search/elastic/task_status_spec.rb'
|
||||
- 'ee/spec/lib/security/scan_result_policies/policy_violation_details_spec.rb'
|
||||
- 'ee/spec/lib/security/security_orchestration_policies/policy_scope_checker_spec.rb'
|
||||
- 'ee/spec/lib/sidebars/projects/menus/learn_gitlab_menu_spec.rb'
|
||||
- 'ee/spec/lib/telesign/transaction_callback_payload_spec.rb'
|
||||
- 'ee/spec/lib/telesign/transaction_callback_spec.rb'
|
||||
- 'ee/spec/lib/users/identity_verification/authorize_ci_spec.rb'
|
||||
|
|
|
|||
|
|
@ -432,7 +432,6 @@ RSpec/NamedSubject:
|
|||
- 'ee/spec/lib/repositories/project_push_rules_changes_auditor_spec.rb'
|
||||
- 'ee/spec/lib/sidebars/groups/menus/epics_menu_spec.rb'
|
||||
- 'ee/spec/lib/sidebars/groups/menus/work_item_epics_menu_spec.rb'
|
||||
- 'ee/spec/lib/sidebars/projects/menus/learn_gitlab_menu_spec.rb'
|
||||
- 'ee/spec/lib/sidebars/user_settings/menus/profile_billing_menu_spec.rb'
|
||||
- 'ee/spec/lib/system_check/geo/authorized_keys_check_spec.rb'
|
||||
- 'ee/spec/lib/system_check/geo/authorized_keys_flag_check_spec.rb'
|
||||
|
|
|
|||
|
|
@ -75,6 +75,7 @@ export default {
|
|||
return {
|
||||
isMouseIn: false,
|
||||
canClickPinButton: false,
|
||||
localPillCount: this.item.pill_count,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
|
@ -82,6 +83,11 @@ export default {
|
|||
if (this.item.pill_count_field) {
|
||||
return this.asyncCount[this.item.pill_count_field];
|
||||
}
|
||||
|
||||
if (this.item.pill_count_dynamic) {
|
||||
return this.localPillCount;
|
||||
}
|
||||
|
||||
return this.item.pill_count;
|
||||
},
|
||||
hasPill() {
|
||||
|
|
@ -213,11 +219,7 @@ export default {
|
|||
},
|
||||
updatePillValue({ value, itemId }) {
|
||||
if (this.item.id === itemId) {
|
||||
// https://gitlab.com/gitlab-org/gitlab/-/issues/428246
|
||||
// fixing this linting issue is causing the pills not to async update for learn gitlab nav item
|
||||
//
|
||||
// eslint-disable-next-line vue/no-mutating-props
|
||||
this.item.pill_count = value;
|
||||
this.localPillCount = value;
|
||||
}
|
||||
},
|
||||
},
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ module Resolvers
|
|||
module Integrations
|
||||
class ExclusionsResolver < BaseResolver
|
||||
include Gitlab::Graphql::Authorize::AuthorizeResource
|
||||
|
||||
type Types::Integrations::ExclusionType.connection_type, null: true
|
||||
|
||||
argument :integration_name, Types::Integrations::IntegrationTypeEnum,
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ module Resolvers
|
|||
module Projects
|
||||
class DeployKeyResolver < BaseResolver
|
||||
include LooksAhead
|
||||
|
||||
type Types::AccessLevels::DeployKeyType, null: true
|
||||
|
||||
def resolve_with_lookahead(**args)
|
||||
|
|
|
|||
|
|
@ -1631,7 +1631,7 @@ class MergeRequest < ApplicationRecord
|
|||
end
|
||||
|
||||
def visible_closing_issues_for(current_user = self.author)
|
||||
strong_memoize(:visible_closing_issues_for) do
|
||||
strong_memoize_with(:visible_closing_issues_for, current_user&.id) do
|
||||
visible_issues = if self.target_project.has_external_issue_tracker?
|
||||
closes_issues(current_user)
|
||||
else
|
||||
|
|
@ -1644,7 +1644,7 @@ class MergeRequest < ApplicationRecord
|
|||
records: visible_issues.select { |issue| issue.is_a?(Issue) },
|
||||
associations: :project
|
||||
).call
|
||||
# Exclude isues that have been cached but their project setting has been disabled, or they belong to a group
|
||||
# Exclude issues that have been cached but their project setting has been disabled, or they belong to a group
|
||||
visible_issues.select do |issue|
|
||||
!issue.is_a?(Issue) || issue.autoclose_by_merged_closing_merge_request?
|
||||
end
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
class ProjectMemberPolicy < BasePolicy
|
||||
include MemberPolicyHelpers
|
||||
|
||||
delegate { @subject.project }
|
||||
|
||||
condition(:target_is_holder_of_the_personal_namespace, scope: :subject) do
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
class ClusterSerializer < BaseSerializer
|
||||
include WithPagination
|
||||
|
||||
entity ClusterEntity
|
||||
|
||||
def represent_list(resource)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
class ContainerRepositoriesSerializer < BaseSerializer
|
||||
include WithPagination
|
||||
|
||||
entity ContainerRepositoryEntity
|
||||
|
||||
def represent_read_only(resource)
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
class FeatureFlagSerializer < BaseSerializer
|
||||
include WithPagination
|
||||
|
||||
entity FeatureFlagEntity
|
||||
|
||||
def represent(resource, opts = {})
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
class PipelineSerializer < BaseSerializer
|
||||
include WithPagination
|
||||
|
||||
entity PipelineDetailsEntity
|
||||
|
||||
# rubocop: disable CodeReuse/ActiveRecord
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ module AuthorizedProjectUpdate
|
|||
class ProjectRecalculateService
|
||||
# Service for refreshing all the authorizations to a particular project.
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
BATCH_SIZE = 1000
|
||||
|
||||
def initialize(project)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
module BatchedGitRefUpdates
|
||||
class CleanupSchedulerService
|
||||
include Gitlab::ExclusiveLeaseHelpers
|
||||
|
||||
MAX_PROJECTS = 10_000
|
||||
BATCH_SIZE = 100
|
||||
LOCK_TIMEOUT = 10.minutes
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
module JiraConnectSubscriptions
|
||||
class CreateService < ::JiraConnectSubscriptions::BaseService
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
MERGE_REQUEST_SYNC_BATCH_SIZE = 20
|
||||
MERGE_REQUEST_SYNC_BATCH_DELAY = 1.minute.freeze
|
||||
BATCH_SIZE = 1_000
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@
|
|||
module Projects
|
||||
class TransferService < BaseService
|
||||
include Gitlab::ShellAdapter
|
||||
|
||||
TransferError = Class.new(StandardError)
|
||||
|
||||
def log_project_transfer_success(project, new_namespace)
|
||||
|
|
|
|||
|
|
@ -14,9 +14,9 @@
|
|||
#performance-bar-root
|
||||
%template{ :shadowrootmode => "open" }
|
||||
= render 'peek/bar'
|
||||
= universal_stylesheet_link_tag 'application'
|
||||
= universal_stylesheet_link_tag 'application_utilities'
|
||||
= universal_stylesheet_link_tag 'tailwind'
|
||||
= universal_stylesheet_link_tag 'performance_bar'
|
||||
= universal_stylesheet_link_tag 'application', crossorigin: 'anonymous'
|
||||
= universal_stylesheet_link_tag 'application_utilities', crossorigin: 'anonymous'
|
||||
= universal_stylesheet_link_tag 'tailwind', crossorigin: 'anonymous'
|
||||
= universal_stylesheet_link_tag 'performance_bar', crossorigin: 'anonymous'
|
||||
= webpack_bundle_tag 'performance_bar'
|
||||
#graphiql-container Loading...
|
||||
|
|
|
|||
|
|
@ -1527,7 +1527,10 @@ Instead of:
|
|||
|
||||
## limitations
|
||||
|
||||
Do not use **limitations**. Use **known issues** instead.
|
||||
Do not use **Limitations** as a topic title. For more information,
|
||||
see [reference topic titles](../topic_types/reference.md#reference-topic-titles).
|
||||
|
||||
If you must, you can use the title **Known issues**.
|
||||
|
||||
## log in, log on
|
||||
|
||||
|
|
|
|||
|
|
@ -30,9 +30,11 @@ Reference topic titles are usually nouns.
|
|||
Avoid these topic titles:
|
||||
|
||||
- `Important notes`. Instead, incorporate this information
|
||||
closer to where it belongs. For example, this information might be a prerequisite
|
||||
closer to where it belongs. This information might be a prerequisite
|
||||
for a task, or information about a concept.
|
||||
- `Limitations`. Instead, move the content near other similar information.
|
||||
Content listed as limitations can often be considered prerequisite
|
||||
information about how a feature works.
|
||||
If you must, you can use the title `Known issues`.
|
||||
|
||||
## Example
|
||||
|
|
|
|||
|
|
@ -124,27 +124,6 @@ For GitLab Self-Managed instances, you can choose to run most of the GitLab secu
|
|||
|
||||
GitLab Self-Managed instances can also run the security scanners on a GitLab Runner [running inside OpenShift](../../install/openshift_and_gitlab/_index.md).
|
||||
|
||||
## Security report validation
|
||||
|
||||
GitLab 15.0 enforces validation of the security report artifacts before ingesting the vulnerabilities.
|
||||
This prevents ingestion of broken vulnerability data into the database. GitLab validates the
|
||||
artifacts against the [report schemas](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/tree/master/dist),
|
||||
according to the schema version declared in the report.
|
||||
|
||||
The pipeline's **Security** tab lists any report artifacts that failed validation, and the
|
||||
validation error message.
|
||||
|
||||
Validation depends on the schema version declared in the security report artifact:
|
||||
|
||||
- If your security report specifies a supported schema version, GitLab uses this version to validate.
|
||||
- If your security report uses a deprecated version, GitLab attempts validation against that version and adds a deprecation warning to the validation result.
|
||||
- If your security report uses a supported MAJOR-MINOR version of the report schema but the PATCH version doesn't match any vendored versions, GitLab attempts to validate it against latest vendored PATCH version of the schema.
|
||||
- Example: security report uses version 14.1.1 but the latest vendored version is 14.1.0. GitLab would validate against schema version 14.1.0.
|
||||
- If your security report uses a version that is not supported, GitLab attempts to validate it against the earliest schema version available in your installation but doesn't ingest the report.
|
||||
- If your security report does not specify a schema version, GitLab attempts to validate it against the earliest schema version available in GitLab. Because the `version` property is required, validation always fails in this case, but other validation errors may also be present.
|
||||
|
||||
You can always find supported and deprecated schema versions in the [source code](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/parsers/security/validators/schema_validator.rb).
|
||||
|
||||
## Security scanning configuration tips
|
||||
|
||||
Each GitLab security scanning tool has a default
|
||||
|
|
|
|||
|
|
@ -0,0 +1,38 @@
|
|||
---
|
||||
stage: Application Security Testing
|
||||
group: Static Analysis
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://handbook.gitlab.com/handbook/product/ux/technical-writing/#assignments
|
||||
title: Security report validation
|
||||
---
|
||||
|
||||
{{< details >}}
|
||||
|
||||
- Tier: Ultimate
|
||||
- Offering: GitLab.com, GitLab Self-Managed, GitLab Dedicated
|
||||
|
||||
{{< /details >}}
|
||||
|
||||
Security reports are validated before their content is added to the database. This prevents
|
||||
ingestion of broken vulnerability data into the database. Reports that fail validation are listed in
|
||||
the pipeline's **Security** tab with the validation error message.
|
||||
|
||||
Validation is done against the
|
||||
[report schemas](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/tree/master/dist),
|
||||
according to the schema version declared in the report:
|
||||
|
||||
- If the security report specifies a supported schema version, GitLab uses this version to validate.
|
||||
- If the security report uses a deprecated version, GitLab attempts validation against that version
|
||||
and adds a deprecation warning to the validation result.
|
||||
- If the security report uses a supported MAJOR-MINOR version of the report schema but the PATCH
|
||||
version doesn't match any vendored versions, GitLab attempts to validate it against latest
|
||||
vendored PATCH version of the schema.
|
||||
- Example: security report uses version 14.1.1 but the latest vendored version is 14.1.0. GitLab
|
||||
would validate against schema version 14.1.0.
|
||||
- If the security report uses a version that is not supported, GitLab attempts to validate it
|
||||
against the earliest schema version available in your installation but doesn't ingest the report.
|
||||
- If the security report does not specify a schema version, GitLab attempts to validate it against
|
||||
the earliest schema version available in GitLab. Because the `version` property is required,
|
||||
validation always fails in this case, but other validation errors may also be present.
|
||||
|
||||
For details of the supported and deprecated schema versions, view the
|
||||
[schema validator source code](https://gitlab.com/gitlab-org/gitlab/blob/master/lib/gitlab/ci/parsers/security/validators/schema_validator.rb).
|
||||
|
|
@ -30,6 +30,8 @@ features:
|
|||
1. Upgrade to GitLab 18.0 or later.
|
||||
1. Turn on the IDE features for your group or instance.
|
||||
|
||||
It may take up to 10 minutes for the change to take effect.
|
||||
|
||||
### For a group
|
||||
|
||||
On GitLab.com, you can turn GitLab Duo Core on or off for a top-level group, but not for a subgroup or project.
|
||||
|
|
@ -46,6 +48,8 @@ To turn GitLab Duo Core on or off for a top-level group on GitLab.com:
|
|||
1. Below **GitLab Duo Core**, select or clear the **Turn on IDE features** checkbox.
|
||||
1. Select **Save changes**.
|
||||
|
||||
It may take up to 10 minutes for the change to take effect.
|
||||
|
||||
### For an instance
|
||||
|
||||
On GitLab Self-Managed, you can turn GitLab Duo Core on or off for an instance.
|
||||
|
|
@ -339,7 +343,7 @@ To turn on GitLab Duo experiment and beta features for a top-level group:
|
|||
1. On the left sidebar, select **Search or go to** and find your group.
|
||||
1. Select **Settings > GitLab Duo**.
|
||||
1. Under **GitLab Duo** section, select **Change configuration**.
|
||||
1. Select **Turn on experiment and beta GitLab Duo features**.
|
||||
1. Select **Turn on experiment and beta GitLab Duo features**.
|
||||
1. Select **Save changes**.
|
||||
|
||||
{{< /tab >}}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ module Banzai
|
|||
class DesignReferenceFilter < AbstractReferenceFilter
|
||||
class Identifier
|
||||
include Comparable
|
||||
|
||||
attr_reader :issue_iid, :filename
|
||||
|
||||
def initialize(issue_iid:, filename:)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ module Feature
|
|||
class FlipperRecord < ActiveRecord::Base # rubocop:disable Rails/ApplicationRecord -- This class perfectly replaces
|
||||
# Flipper::Adapters::ActiveRecord::Model, which inherits ActiveRecord::Base
|
||||
include DatabaseReflection
|
||||
|
||||
self.abstract_class = true
|
||||
|
||||
# Bypass the load balancer by restoring the default behavior of `connection`
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ module Gitlab
|
|||
# e.g. on web access require re-authentication
|
||||
class CurrentUserMode
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
NotRequestedError = Class.new(StandardError)
|
||||
NonSidekiqEnvironmentError = Class.new(StandardError)
|
||||
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ module Gitlab
|
|||
module Strategies
|
||||
class FortiTokenCloud < Base
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
BASE_API_URL = 'https://ftc.fortinet.com:9696/api/v1'
|
||||
|
||||
def validate(otp_code)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ module Gitlab
|
|||
#
|
||||
class Config
|
||||
include Gitlab::Utils::StrongMemoize
|
||||
|
||||
##
|
||||
# Loading the YAML below would result in a hash having 12 nodes instead of 9,
|
||||
# because hash values are being counted before we recursively traverse them.
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ module Gitlab
|
|||
module Cluster
|
||||
class RackTimeoutObserver
|
||||
include ActionView::Helpers::SanitizeHelper
|
||||
|
||||
TRANSITION_STATES = %i[ready active].freeze
|
||||
|
||||
def initialize
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ module Gitlab
|
|||
module Router
|
||||
class Graphql
|
||||
extend EtagCaching::Router::Helpers
|
||||
|
||||
GRAPHQL_ETAG_RESOURCE_HEADER = 'X-GITLAB-GRAPHQL-RESOURCE-ETAG'
|
||||
|
||||
ROUTES = [
|
||||
|
|
|
|||
|
|
@ -4,12 +4,18 @@ module Sidebars
|
|||
class MenuItem
|
||||
include ::Sidebars::Concerns::LinkWithHtmlOptions
|
||||
|
||||
attr_reader :title, :link, :active_routes, :item_id, :container_html_options, :sprite_icon, :sprite_icon_html_options, :has_pill, :pill_count, :pill_count_field, :super_sidebar_parent, :avatar, :entity_id
|
||||
attr_reader :title, :link, :active_routes, :item_id, :container_html_options, :sprite_icon,
|
||||
:sprite_icon_html_options, :has_pill, :pill_count, :pill_count_field, :pill_count_dynamic, :super_sidebar_parent,
|
||||
:avatar, :entity_id
|
||||
attr_accessor :render
|
||||
alias_method :has_pill?, :has_pill
|
||||
|
||||
# rubocop: disable Metrics/ParameterLists
|
||||
def initialize(title:, link:, active_routes:, item_id: nil, container_html_options: {}, sprite_icon: nil, sprite_icon_html_options: {}, has_pill: false, pill_count: nil, pill_count_field: nil, super_sidebar_parent: nil, avatar: nil, entity_id: nil)
|
||||
def initialize(
|
||||
title:, link:, active_routes:, item_id: nil, container_html_options: {}, sprite_icon: nil,
|
||||
sprite_icon_html_options: {}, has_pill: false, pill_count_dynamic: false, pill_count: nil,
|
||||
pill_count_field: nil, super_sidebar_parent: nil, avatar: nil, entity_id: nil
|
||||
)
|
||||
@title = title
|
||||
@link = link
|
||||
@active_routes = active_routes
|
||||
|
|
@ -22,6 +28,7 @@ module Sidebars
|
|||
@has_pill = has_pill
|
||||
@pill_count = pill_count
|
||||
@pill_count_field = pill_count_field
|
||||
@pill_count_dynamic = pill_count_dynamic
|
||||
@super_sidebar_parent = super_sidebar_parent
|
||||
end
|
||||
# rubocop: enable Metrics/ParameterLists
|
||||
|
|
@ -41,15 +48,23 @@ module Sidebars
|
|||
entity_id: entity_id,
|
||||
link: link,
|
||||
active_routes: active_routes,
|
||||
pill_count: has_pill ? pill_count : nil,
|
||||
pill_count_field: has_pill ? pill_count_field : nil,
|
||||
link_classes: container_html_options[:class]
|
||||
# Check whether support is needed for the following properties,
|
||||
# in order to get feature parity with the HAML renderer
|
||||
# https://gitlab.com/gitlab-org/gitlab/-/issues/391864
|
||||
#
|
||||
# container_html_options
|
||||
}.compact
|
||||
}.merge(pill_attributes).compact
|
||||
end
|
||||
|
||||
def pill_attributes
|
||||
return {} unless has_pill?
|
||||
|
||||
{
|
||||
pill_count: pill_count,
|
||||
pill_count_field: pill_count_field,
|
||||
pill_count_dynamic: pill_count_dynamic
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -37,16 +37,13 @@ describe('Batch comments draft note component', () => {
|
|||
},
|
||||
};
|
||||
|
||||
const createComponent = (propsData = { draft }, glFeatures = {}) => {
|
||||
const createComponent = (propsData = { draft }) => {
|
||||
wrapper = shallowMount(DraftNote, {
|
||||
store,
|
||||
propsData,
|
||||
stubs: {
|
||||
NoteableNote: NoteableNoteStub,
|
||||
},
|
||||
provide: {
|
||||
glFeatures,
|
||||
},
|
||||
});
|
||||
|
||||
jest.spyOn(store, 'dispatch').mockImplementation();
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import RunnerListEmptyState from '~/ci/runner/components/runner_list_empty_state
|
|||
|
||||
describe('RunnerListEmptyState', () => {
|
||||
let wrapper;
|
||||
let glFeatures;
|
||||
|
||||
const findEmptySearchResult = () => wrapper.findComponent(EmptyResult);
|
||||
const findEmptyState = () => wrapper.findComponent(GlEmptyState);
|
||||
|
|
@ -48,14 +47,9 @@ describe('RunnerListEmptyState', () => {
|
|||
GlEmptyState,
|
||||
GlSprintf,
|
||||
},
|
||||
provide: { glFeatures },
|
||||
});
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
glFeatures = null;
|
||||
});
|
||||
|
||||
describe('when search is not filtered', () => {
|
||||
describe.each`
|
||||
newRunnerPath | registrationToken | expectedMessages
|
||||
|
|
|
|||
|
|
@ -75,18 +75,11 @@ describe('diffs/components/app', () => {
|
|||
|
||||
const codeQualityAndSastQueryHandlerSuccess = jest.fn().mockResolvedValue({});
|
||||
|
||||
const createComponent = ({ props = {}, provisions = {} } = {}) => {
|
||||
const createComponent = ({ props = {} } = {}) => {
|
||||
fakeApollo = createMockApollo([
|
||||
[getMRCodequalityAndSecurityReports, codeQualityAndSastQueryHandlerSuccess],
|
||||
]);
|
||||
|
||||
const provide = {
|
||||
...provisions,
|
||||
glFeatures: {
|
||||
...provisions.glFeatures,
|
||||
},
|
||||
};
|
||||
|
||||
wrapper = shallowMount(App, {
|
||||
apolloProvider: fakeApollo,
|
||||
propsData: {
|
||||
|
|
@ -99,7 +92,6 @@ describe('diffs/components/app', () => {
|
|||
changesEmptyStateIllustration: '',
|
||||
...props,
|
||||
},
|
||||
provide,
|
||||
store: createDiffsStore(),
|
||||
pinia,
|
||||
});
|
||||
|
|
|
|||
|
|
@ -33,16 +33,13 @@ describe('DiffContent', () => {
|
|||
diffFile: getDiffFileMock(),
|
||||
};
|
||||
|
||||
const createComponent = ({ props, provide } = {}) => {
|
||||
const glFeatures = provide ? { ...provide.glFeatures } : {};
|
||||
|
||||
const createComponent = ({ props } = {}) => {
|
||||
wrapper = shallowMount(DiffContentComponent, {
|
||||
propsData: {
|
||||
...defaultProps,
|
||||
...props,
|
||||
},
|
||||
pinia,
|
||||
provide: { glFeatures },
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -38,15 +38,12 @@ describe('Environments detail header component', () => {
|
|||
['Destroy', findDestroyButton],
|
||||
];
|
||||
|
||||
const createWrapper = ({ props, glFeatures = {} }) => {
|
||||
const createWrapper = ({ props }) => {
|
||||
wrapper = shallowMountExtended(EnvironmentsDetailHeader, {
|
||||
stubs: {
|
||||
GlSprintf,
|
||||
TimeAgo,
|
||||
},
|
||||
provide: {
|
||||
glFeatures,
|
||||
},
|
||||
directives: {
|
||||
GlTooltip: createMockDirective('gl-tooltip'),
|
||||
},
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ const handleEnterSpy = jest.fn();
|
|||
/** @type {import('helpers/vue_test_utils_helper').ExtendedWrapper} */
|
||||
let wrapper;
|
||||
|
||||
const createComponent = ({ props = {}, glFeatures = {} } = {}) => {
|
||||
const createComponent = ({ props = {} } = {}) => {
|
||||
wrapper = mountExtended(MembersTokenSelect, {
|
||||
propsData: {
|
||||
ariaLabelledby: label,
|
||||
|
|
@ -25,7 +25,6 @@ const createComponent = ({ props = {}, glFeatures = {} } = {}) => {
|
|||
placeholder,
|
||||
...props,
|
||||
},
|
||||
provide: { glFeatures },
|
||||
});
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -75,7 +75,9 @@ describe('NavItem component', () => {
|
|||
};
|
||||
|
||||
it('updates the pill count', async () => {
|
||||
createWrapper({ item: { id: itemIdForUpdate, pill_count: initialPillValue } });
|
||||
createWrapper({
|
||||
item: { id: itemIdForUpdate, pill_count: initialPillValue, pill_count_dynamic: true },
|
||||
});
|
||||
|
||||
await triggerPillValueUpdate();
|
||||
|
||||
|
|
@ -83,7 +85,9 @@ describe('NavItem component', () => {
|
|||
});
|
||||
|
||||
it('does not update the pill count for non matching item id', async () => {
|
||||
createWrapper({ item: { id: '_non_matching_id_', pill_count: initialPillValue } });
|
||||
createWrapper({
|
||||
item: { id: '_non_matching_id_', pill_count: initialPillValue, pill_count_dynamic: true },
|
||||
});
|
||||
|
||||
await triggerPillValueUpdate();
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ describe('Blob Simple Viewer component', () => {
|
|||
isBlameLinkHidden = false,
|
||||
isRawContent = false,
|
||||
propsData = {},
|
||||
glFeatures = {},
|
||||
} = {}) {
|
||||
fakeApollo = createMockApollo([[blameDataQuery, blameDataQueryHandlerSuccess]]);
|
||||
|
||||
|
|
@ -39,7 +38,6 @@ describe('Blob Simple Viewer component', () => {
|
|||
apolloProvider: fakeApollo,
|
||||
provide: {
|
||||
blobHash,
|
||||
glFeatures,
|
||||
},
|
||||
propsData: {
|
||||
content,
|
||||
|
|
|
|||
|
|
@ -71,7 +71,8 @@ RSpec.describe Sidebars::Menu, feature_category: :navigation do
|
|||
title: "Not active",
|
||||
link: "foo3",
|
||||
is_active: false,
|
||||
pill_count: 10
|
||||
pill_count: 10,
|
||||
pill_count_dynamic: false
|
||||
}
|
||||
]
|
||||
})
|
||||
|
|
|
|||
|
|
@ -1348,6 +1348,7 @@ RSpec.describe MergeRequest, factory_default: :keep, feature_category: :code_rev
|
|||
subject.cache_merge_request_closes_issues!
|
||||
|
||||
expect(subject.visible_closing_issues_for(guest)).to match_array([issue_1, issue_2])
|
||||
expect(subject.visible_closing_issues_for(nil)).to be_empty
|
||||
end
|
||||
|
||||
it 'shows only allowed issues to developer' do
|
||||
|
|
@ -1356,6 +1357,30 @@ RSpec.describe MergeRequest, factory_default: :keep, feature_category: :code_rev
|
|||
subject.cache_merge_request_closes_issues!
|
||||
|
||||
expect(subject.visible_closing_issues_for(developer)).to match_array([issue_1, confidential_issue, issue_2])
|
||||
expect(subject.visible_closing_issues_for(nil)).to be_empty
|
||||
end
|
||||
|
||||
it 'isolates cache per user so each role sees its own issues' do
|
||||
project.add_guest(guest)
|
||||
project.add_developer(developer)
|
||||
subject.cache_merge_request_closes_issues!
|
||||
|
||||
# Call in one order
|
||||
developer_view_first = subject.visible_closing_issues_for(developer)
|
||||
guest_view_first = subject.visible_closing_issues_for(guest)
|
||||
|
||||
expect(developer_view_first).to match_array([issue_1, issue_2, confidential_issue])
|
||||
expect(guest_view_first).to match_array([issue_1, issue_2])
|
||||
|
||||
# Reset memoization
|
||||
subject.clear_memoization(:visible_closing_issues_for) # Specific to strong_memoize
|
||||
|
||||
# Call in reverse order on the same instance after clearing memoization
|
||||
guest_view_second = subject.visible_closing_issues_for(guest)
|
||||
developer_view_second = subject.visible_closing_issues_for(developer)
|
||||
|
||||
expect(guest_view_second).to match_array([issue_1, issue_2])
|
||||
expect(developer_view_second).to match_array([issue_1, issue_2, confidential_issue])
|
||||
end
|
||||
|
||||
context 'when external issue tracker is enabled' do
|
||||
|
|
|
|||
|
|
@ -7,6 +7,10 @@ module Features
|
|||
def invite_member(names, role: 'Guest', expires_at: nil, use_exact_text_match: true)
|
||||
click_on 'Invite members'
|
||||
|
||||
invite_with_opened_modal(names, role: role, expires_at: expires_at, use_exact_text_match: use_exact_text_match)
|
||||
end
|
||||
|
||||
def invite_with_opened_modal(names, role: 'Guest', expires_at: nil, use_exact_text_match: true)
|
||||
page.within invite_modal_selector do
|
||||
select_members(names)
|
||||
choose_options(role, expires_at, use_exact_text_match)
|
||||
|
|
|
|||
Loading…
Reference in New Issue