Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2024-01-02 12:07:21 +00:00
parent 885a1dc757
commit ecdd26856c
46 changed files with 273 additions and 223 deletions

View File

@ -1 +1 @@
144dca53fcf99bd9064cb2f6e2631f6367f0eafe
73920c7baa9ace55ba51d555e309897fd331c1b4

View File

@ -133,11 +133,11 @@ gem 'gitlab_omniauth-ldap', '~> 2.2.0', require: 'omniauth-ldap' # rubocop:todo
gem 'net-ldap', '~> 0.17.1' # rubocop:todo Gemfile/MissingFeatureCategory
# API
gem 'grape', '~> 2.0.0', feature_category: :api
gem 'grape', '~> 1.7.1', feature_category: :api
gem 'grape-entity', '~> 0.10.0', feature_category: :api
gem 'grape-swagger', '~> 2.0.0', group: [:development, :test], feature_category: :api
gem 'grape-swagger', '~> 1.6.1', group: [:development, :test], feature_category: :api
gem 'grape-swagger-entity', '~> 0.5.1', group: [:development, :test], feature_category: :api
gem 'grape-path-helpers', '~> 2.0.0', feature_category: :api
gem 'grape-path-helpers', '~> 1.7.1', feature_category: :api
gem 'rack-cors', '~> 2.0.1', require: 'rack/cors' # rubocop:todo Gemfile/MissingFeatureCategory
# GraphQL API

View File

@ -128,7 +128,7 @@
{"name":"doorkeeper-openid_connect","version":"1.8.7","platform":"ruby","checksum":"71edaf33118deefe25674ba3f8280c32835f057351f70e9beb222c0fd6b8e786"},
{"name":"dotenv","version":"2.7.6","platform":"ruby","checksum":"2451ed5e8e43776d7a787e51d6f8903b98e446146c7ad143d5678cc2c409d547"},
{"name":"dry-cli","version":"1.0.0","platform":"ruby","checksum":"28ead169f872954dd08910eb8ead59cf86cd18b4aab321e8eeefe945749569f0"},
{"name":"dry-core","version":"1.0.1","platform":"ruby","checksum":"f32f4245e0f54e787f3708584ed8f7545aaf8dd99072e36f169312468ec5450d"},
{"name":"dry-core","version":"1.0.0","platform":"ruby","checksum":"7a92099870967f0d2c9997950608cb8bb622dafeea20b2fe1dd49e9ba1d0f305"},
{"name":"dry-inflector","version":"1.0.0","platform":"ruby","checksum":"6ad22361ca2d6f3f001ae3037ffcfea01163f644280d13a9195d3c3a94dd1626"},
{"name":"dry-logic","version":"1.5.0","platform":"ruby","checksum":"99ed2180f1970c3d8247004f277a01dffbe8e82cf6680de9c7209312d86cd416"},
{"name":"dry-types","version":"1.7.1","platform":"ruby","checksum":"12165841145a18dd22151f143707b90c8093f71e5ae06ee0f2301f5321f8cdb8"},
@ -258,10 +258,10 @@
{"name":"googleapis-common-protos-types","version":"1.5.0","platform":"ruby","checksum":"5769cf7376abc86ef7f5897a4aaca1d5c5a3c49ddabeddd2c251fcf8155f858b"},
{"name":"googleauth","version":"1.3.0","platform":"ruby","checksum":"51dd7362353cf1e90a2d01e1fb94321ae3926c776d4dc4a79db65230217ffcc2"},
{"name":"gpgme","version":"2.0.23","platform":"ruby","checksum":"c87bbafdb8719da7c58ebcac08297aa1fb227022ac6cd2972829ba68adc91c04"},
{"name":"grape","version":"2.0.0","platform":"ruby","checksum":"3aeff94c17e84ccead4ff98833df691e7da0c108878cc128ca31f80c1047494a"},
{"name":"grape","version":"1.7.1","platform":"ruby","checksum":"6b679d8918ee3dc19b0da95a5069dc95a71a15cf5788f5f787bb2ededf58cbb6"},
{"name":"grape-entity","version":"0.10.0","platform":"ruby","checksum":"9aed1e7cbbc96d9e73f72e5f32c776d4ba8a5baf54c3acda2682008dba2b2cfe"},
{"name":"grape-path-helpers","version":"2.0.1","platform":"ruby","checksum":"ad5216e52c6e796738a9118087352ab4c962900dbad1d8f8c0f96e093c6702d7"},
{"name":"grape-swagger","version":"2.0.0","platform":"ruby","checksum":"28c1ddacc84b0e272387c87bba5d6c03db954b5680606d39aab321d5803ce011"},
{"name":"grape-path-helpers","version":"1.7.1","platform":"ruby","checksum":"2e27271a20d4073e3a3b2b955425c7f803e198be3ba8f6e59e3d59643c5381e2"},
{"name":"grape-swagger","version":"1.6.1","platform":"ruby","checksum":"0fd2d38476524b66e8d06de71e6c481d34286d895b12161f5df4427d66d5c69f"},
{"name":"grape-swagger-entity","version":"0.5.1","platform":"ruby","checksum":"f51e372d00ac96cf90d948f87b3f4eb287ab053976ca57ad503d442ad8605523"},
{"name":"grape_logging","version":"1.8.4","platform":"ruby","checksum":"efcc3e322dbd5d620a68f078733b7db043cf12680144cd03c982f14115c792d1"},
{"name":"graphiql-rails","version":"1.8.0","platform":"ruby","checksum":"02e2c5098be2c6c29219a0e9b2910a2cd3c494301587a3199a7c4484d8038ed1"},

View File

@ -501,7 +501,7 @@ GEM
jwt (>= 2.5)
dotenv (2.7.6)
dry-cli (1.0.0)
dry-core (1.0.1)
dry-core (1.0.0)
concurrent-ruby (~> 1.0)
zeitwerk (~> 2.6)
dry-inflector (1.0.0)
@ -815,24 +815,23 @@ GEM
signet (>= 0.16, < 2.a)
gpgme (2.0.23)
mini_portile2 (~> 2.7)
grape (2.0.0)
activesupport (>= 5)
grape (1.7.1)
activesupport
builder
dry-types (>= 1.1)
mustermann-grape (~> 1.0.0)
rack (>= 1.3.0)
rack (>= 1.3.0, < 3)
rack-accept
grape-entity (0.10.0)
activesupport (>= 3.0.0)
multi_json (>= 1.3.2)
grape-path-helpers (2.0.1)
grape-path-helpers (1.7.1)
activesupport
grape (~> 2.0)
grape (~> 1.3)
rake (> 12)
ruby2_keywords (~> 0.0.2)
grape-swagger (2.0.0)
grape (>= 1.7, < 3.0)
rack-test (~> 2)
grape-swagger (1.6.1)
grape (~> 1.3)
grape-swagger-entity (0.5.1)
grape-entity (>= 0.6.0)
grape-swagger (>= 1.2.0)
@ -1922,10 +1921,10 @@ DEPENDENCIES
google-cloud-storage (~> 1.45.0)
google-protobuf (~> 3.25, >= 3.25.1)
gpgme (~> 2.0.23)
grape (~> 2.0.0)
grape (~> 1.7.1)
grape-entity (~> 0.10.0)
grape-path-helpers (~> 2.0.0)
grape-swagger (~> 2.0.0)
grape-path-helpers (~> 1.7.1)
grape-swagger (~> 1.6.1)
grape-swagger-entity (~> 0.5.1)
grape_logging (~> 1.8)
graphiql-rails (~> 1.8.0)

View File

@ -38,6 +38,6 @@ module ConfirmEmailWarning
end
def email_to_display
html_escape(email)
ERB::Util.html_escape(email)
end
end

View File

@ -175,7 +175,7 @@ class SearchController < ApplicationController
return false unless commit.present?
link = search_path(safe_params.merge(force_search_results: true))
flash[:notice] = html_escape(_("You have been redirected to the only result; see the %{a_start}search results%{a_end} instead.")) % { a_start: "<a href=\"#{link}\"><u>".html_safe, a_end: '</u></a>'.html_safe }
flash[:notice] = ERB::Util.html_escape(_("You have been redirected to the only result; see the %{a_start}search results%{a_end} instead.")) % { a_start: "<a href=\"#{link}\"><u>".html_safe, a_end: '</u></a>'.html_safe }
redirect_to project_commit_path(@project, commit)
true

View File

@ -2,13 +2,6 @@
module Ci
module BuildsHelper
def sidebar_build_class(build, current_build)
build_class = []
build_class << 'active' if build.id === current_build.id
build_class << 'retried' if build.retried?
build_class.join(' ')
end
def build_failed_issue_options
{
title: _("Job Failed #%{build_id}") % { build_id: @build.id },

View File

@ -24,7 +24,7 @@ module FormHelper
# user"), use the message as-is
message = error.message if custom_message.include?(attribute)
message = html_escape_once(message).html_safe
message = ERB::Util.html_escape_once(message).html_safe
message = tag.span(message, class: 'str-truncated-100') if truncate.include?(attribute)
message = append_help_page_link(message, error.options) if error.options[:help_page_url].present?

View File

@ -20,7 +20,7 @@ module Groups::GroupMembersHelper
end
def group_member_header_subtext(group)
html_escape(_("You're viewing members of %{strong_start}%{group_name}%{strong_end}.").html_safe) % {
ERB::Util.html_escape(_("You're viewing members of %{strong_start}%{group_name}%{strong_end}.").html_safe) % {
group_name: group.name,
strong_start: '<strong>'.html_safe,
strong_end: '</strong>'.html_safe

View File

@ -56,7 +56,7 @@ module ImportHelper
link_url = 'https://github.com/settings/tokens'
link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: link_url }
html_escape(_('Create and provide your GitHub %{link_start}Personal Access Token%{link_end}. You will need to select the %{code_open}repo%{code_close} scope, so we can display a list of your public and private repositories which are available to import.')) % { link_start: link_start, link_end: '</a>'.html_safe, code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
ERB::Util.html_escape(_('Create and provide your GitHub %{link_start}Personal Access Token%{link_end}. You will need to select the %{code_open}repo%{code_close} scope, so we can display a list of your public and private repositories which are available to import.')) % { link_start: link_start, link_end: '</a>'.html_safe, code_open: '<code>'.html_safe, code_close: '</code>'.html_safe }
end
def import_configure_github_admin_message

View File

@ -253,13 +253,13 @@ module MergeRequestsHelper
end
branch = if merge_request.for_fork?
html_escape(_('%{fork_icon} %{source_project_path}:%{source_branch}')) % { fork_icon: fork_icon.html_safe, source_project_path: merge_request.source_project_path, source_branch: merge_request.source_branch }
ERB::Util.html_escape(_('%{fork_icon} %{source_project_path}:%{source_branch}')) % { fork_icon: fork_icon.html_safe, source_project_path: merge_request.source_project_path, source_branch: merge_request.source_branch }
else
merge_request.source_branch
end
branch_title = if merge_request.for_fork?
html_escape(_('%{source_project_path}:%{source_branch}')) % { source_project_path: merge_request.source_project_path, source_branch: merge_request.source_branch }
ERB::Util.html_escape(_('%{source_project_path}:%{source_branch}')) % { source_project_path: merge_request.source_project_path, source_branch: merge_request.source_branch }
else
merge_request.source_branch
end

View File

@ -12,7 +12,7 @@ module MirrorHelper
docs_link_url = help_page_path('topics/git/lfs/index')
docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: docs_link_url }
html_escape(_('Git LFS objects will be synced if LFS is %{docs_link_start}enabled for the project%{docs_link_end}. Push mirrors will %{strong_open}not%{strong_close} sync LFS objects over SSH.')) %
ERB::Util.html_escape(_('Git LFS objects will be synced if LFS is %{docs_link_start}enabled for the project%{docs_link_end}. Push mirrors will %{strong_open}not%{strong_close} sync LFS objects over SSH.')) %
{ docs_link_start: docs_link_start, docs_link_end: '</a>'.html_safe, strong_open: '<strong>'.html_safe, strong_close: '</strong>'.html_safe }
end

View File

@ -19,7 +19,7 @@ module Projects::ProjectMembersHelper
if can?(current_user, :admin_project_member, project)
share_project_description(project)
else
html_escape(_("Members can be added by project " \
ERB::Util.html_escape(_("Members can be added by project " \
"%{i_open}Maintainers%{i_close} or %{i_open}Owners%{i_close}")) % {
i_open: '<i>'.html_safe, i_close: '</i>'.html_safe
}
@ -41,7 +41,7 @@ module Projects::ProjectMembersHelper
_("You can invite a new member to %{project_name}.")
end
html_escape(description) % { project_name: tag.strong(project.name) }
ERB::Util.html_escape(description) % { project_name: tag.strong(project.name) }
end
def project_members_serialized(project, members)

View File

@ -191,7 +191,7 @@ module ProjectsHelper
end
def autodeploy_flash_notice(branch_name)
html_escape(_("Branch %{branch_name} was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}")) %
ERB::Util.html_escape(_("Branch %{branch_name} was created. To set up auto deploy, choose a GitLab CI Yaml template and commit your changes. %{link_to_autodeploy_doc}")) %
{ branch_name: tag.strong(truncate(sanitize(branch_name))), link_to_autodeploy_doc: link_to_autodeploy_doc }
end
@ -252,7 +252,7 @@ module ProjectsHelper
_('Your account is authenticated with SSO or SAML. To %{push_pull_link_start}push and pull%{link_end} over %{protocol} with Git using this account, you must %{set_up_pat_link_start}set up a Personal Access Token%{link_end} to use instead of a password. For more information, see %{clone_with_https_link_start}Clone with HTTPS%{link_end}.')
end
html_escape(message) % {
ERB::Util.html_escape(message) % {
push_pull_link_start: push_pull_link_start,
protocol: gitlab_config.protocol.upcase,
clone_with_https_link_start: clone_with_https_link_start,
@ -768,7 +768,7 @@ module ProjectsHelper
message = _("You're about to reduce the visibility of the project %{strong_start}%{project_name}%{strong_end} in %{strong_start}%{group_name}%{strong_end}.")
end
html_escape(message) % { strong_start: strong_start, strong_end: strong_end, project_name: project.name, group_name: project.group ? project.group.name : nil }
ERB::Util.html_escape(message) % { strong_start: strong_start, strong_end: strong_end, project_name: project.name, group_name: project.group ? project.group.name : nil }
end
def visibility_confirm_modal_data(project, target_form_id = nil)

View File

@ -41,7 +41,7 @@ module ReminderEmailsHelper
body = invitation_reminder_body_text(reminder_index)
(format == :html ? html_escape(body) : body) % options
(format == :html ? ERB::Util.html_escape(body) : body) % options
end
def invitation_reminder_accept_link(token, format: nil)

View File

@ -3,8 +3,8 @@
module SafeFormatHelper
# Returns a HTML-safe String.
#
# @param [String] format is escaped via `html_escape_once`
# @param [Array<Hash>] args are escaped via `html_escape` if they are not marked as HTML-safe
# @param [String] format is escaped via `ERB::Util.html_escape_once`
# @param [Array<Hash>] args are escaped via `ERB::Util.html_escape` if they are not marked as HTML-safe
#
# @example
# safe_format('See %{user_input}', user_input: '<b>bold</b>')

View File

@ -136,15 +136,15 @@ module SearchHelper
# - group
# - group: nil, project: nil
if project
html_escape(_("We couldn't find any %{scope} matching %{term} in project %{project}")) % options.merge(
ERB::Util.html_escape(_("We couldn't find any %{scope} matching %{term} in project %{project}")) % options.merge(
project: link_to(project.full_name, project_path(project), target: '_blank', rel: 'noopener noreferrer').html_safe
)
elsif group
html_escape(_("We couldn't find any %{scope} matching %{term} in group %{group}")) % options.merge(
ERB::Util.html_escape(_("We couldn't find any %{scope} matching %{term} in group %{group}")) % options.merge(
group: link_to(group.full_name, group_path(group), target: '_blank', rel: 'noopener noreferrer').html_safe
)
else
html_escape(_("We couldn't find any %{scope} matching %{term}")) % options
ERB::Util.html_escape(_("We couldn't find any %{scope} matching %{term}")) % options
end
end

View File

@ -326,7 +326,7 @@ module UsersHelper
job_title = '<span itemprop="jobTitle">'.html_safe + job_title + "</span>".html_safe
organization = '<span itemprop="worksFor">'.html_safe + organization + "</span>".html_safe
html_escape(s_('Profile|%{job_title} at %{organization}')) % { job_title: job_title, organization: organization }
ERB::Util.html_escape(s_('Profile|%{job_title} at %{organization}')) % { job_title: job_title, organization: organization }
else
s_('Profile|%{job_title} at %{organization}') % { job_title: job_title, organization: organization }
end

View File

@ -15,6 +15,6 @@ module WikiPageVersionHelper
name = "<strong>".html_safe + wiki_page_version.author_name + "</strong>".html_safe
link_start = "<a href='".html_safe + wiki_page_version_author_url(wiki_page_version) + "'>".html_safe
html_escape(_("Last edited by %{link_start}%{avatar} %{name}%{link_end}")) % { avatar: avatar, name: name, link_start: link_start, link_end: '</a>'.html_safe }
ERB::Util.html_escape(_("Last edited by %{link_start}%{avatar} %{name}%{link_end}")) % { avatar: avatar, name: name, link_start: link_start, link_end: '</a>'.html_safe }
end
end

View File

@ -31,10 +31,10 @@ module RestrictedSignup
def error_message
{
admin: {
allowlist: html_escape_once(_("Go to the 'Admin area &gt; Sign-up restrictions', and check 'Allowed domains for sign-ups'.")).html_safe,
denylist: html_escape_once(_("Go to the 'Admin area &gt; Sign-up restrictions', and check the 'Domain denylist'.")).html_safe,
restricted: html_escape_once(_("Go to the 'Admin area &gt; Sign-up restrictions', and check 'Email restrictions for sign-ups'.")).html_safe,
group_setting: html_escape_once(_("Go to the groups 'Settings &gt; General' page, and check 'Restrict membership by email domain'.")).html_safe
allowlist: ERB::Util.html_escape_once(_("Go to the 'Admin area &gt; Sign-up restrictions', and check 'Allowed domains for sign-ups'.")).html_safe,
denylist: ERB::Util.html_escape_once(_("Go to the 'Admin area &gt; Sign-up restrictions', and check the 'Domain denylist'.")).html_safe,
restricted: ERB::Util.html_escape_once(_("Go to the 'Admin area &gt; Sign-up restrictions', and check 'Email restrictions for sign-ups'.")).html_safe,
group_setting: ERB::Util.html_escape_once(_("Go to the groups 'Settings &gt; General' page, and check 'Restrict membership by email domain'.")).html_safe
},
nonadmin: {
allowlist: error_nonadmin,

View File

@ -22,14 +22,15 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
)
end
def highlight(to: nil, plain: nil)
def highlight(to: nil, plain: nil, used_on: :blob)
load_all_blob_data
Gitlab::Highlight.highlight(
blob.path,
blob_data(to),
language: blob_language,
plain: plain
plain: plain,
used_on: used_on
)
end

View File

@ -155,11 +155,11 @@ class BuildDetailsEntity < Ci::JobEntity
# We do not return the invalid_dependencies for all scenarios see https://gitlab.com/gitlab-org/gitlab/-/issues/287772#note_914406387
punctuation = invalid_dependencies.empty? ? '.' : ': '
_("This job could not start because it could not retrieve the needed artifacts%{punctuation}%{invalid_dependencies}") %
{ invalid_dependencies: html_escape(invalid_dependencies), punctuation: punctuation }
{ invalid_dependencies: ERB::Util.html_escape(invalid_dependencies), punctuation: punctuation }
end
def help_message(docs_url, troubleshooting_url)
html_escape(_("Learn more about <a href=\"#{docs_url}\">dependencies</a> and <a href=\"#{troubleshooting_url}\">common causes</a> of this error.</a>".html_safe))
ERB::Util.html_escape(_("Learn more about <a href=\"#{docs_url}\">dependencies</a> and <a href=\"#{troubleshooting_url}\">common causes</a> of this error.</a>".html_safe))
end
end

View File

@ -8,7 +8,8 @@
= f.label :email
= f.email_field :email, class: "form-control gl-form-input", required: true, autocomplete: 'off', title: _('Please provide a valid email address.'), value: nil
.form-text.gl-text-secondary
= _('Requires your primary GitLab email address.')
- emails_link = link_to('', profile_emails_url, target: '_blank', rel: 'noopener noreferrer')
= safe_format(s_('Requires your primary GitLab email address. If you want to confirm a secondary email address, go to %{emails_link_start}Emails%{emails_link_end}'), tag_pair(emails_link, :emails_link_start, :emails_link_end))
%div
- if recaptcha_enabled?

View File

@ -6,4 +6,4 @@ introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/135451
milestone: '16.6'
queued_migration_version: 20231030071209
finalize_after: '2023-12-23'
finalized_by: # version of the migration that ensured this bbm
finalized_by: 20231114015857

View File

@ -15,4 +15,4 @@ swap:
e\. g\.: for example
i\.e\.: that is
i\. e\.: that is
via: "Use 'with', 'through', or 'by using' instead."
via: "with', 'through', or 'by using"

View File

@ -1210,10 +1210,9 @@ For more information on synchronizing users and groups between LDAP and GitLab,
## Move from LDAP to SAML
1. [Configure SAML](../../../integration/saml.md). Add `auto_link_ldap_user` to:
1. [Add SAML configuration](../../../integration/saml.md) to:
- [`gitlab.rb` for Linux package installations](../../../integration/saml.html?tab=Linux+package+%28Omnibus%29).
- [`values.yml` for Helm chart installations](../../../integration/saml.html?tab=Helm+chart+%28Kubernetes%29).
For more information, see the [initial settings for all providers](../../../integration/omniauth.md#configure-initial-settings).
1. Optional. [Disable the LDAP auth from the sign-in page](#disable-ldap-web-sign-in).

View File

@ -180,6 +180,8 @@ The following metrics are available:
| `gitlab_connection_pool_size` | Gauge | 16.7 | Size of connection pool |
| `gitlab_connection_pool_available_count` | Gauge | 16.7 | Number of available connections in the pool |
| `gitlab_security_policies_scan_result_process_duration_seconds` | Histogram | 16.7 | The amount of time to process scan result policies |
| `gitlab_highlight_usage` | Counter | 16.8 | The number of times `Gitlab::Highlight` is used | `used_on` |
| `dependency_linker_usage` | Counter | 16.8 | The number of times dependency linker is used | `used_on` |
## Metrics controlled by a feature flag

View File

@ -554,6 +554,7 @@ Parameters:
| `bio` | No | User's biography |
| `can_create_group` | No | User can create top-level groups - true or false |
| `color_scheme_id` | No | User's color scheme for the file viewer (for more information, see the [user preference documentation](../user/profile/preferences.md#change-the-syntax-highlighting-theme)) |
| `commit_email` | No | User's commit email address |
| `email` | Yes | Email |
| `extern_uid` | No | External UID |
| `external` | No | Flags the user as external - true or false (default) |
@ -568,7 +569,9 @@ Parameters:
| `password` | No | Password |
| `private_profile` | No | User's profile is private - true or false. The default value is determined by [this](../administration/settings/account_and_limit_settings.md#set-profiles-of-new-users-to-private-by-default) setting. |
| `projects_limit` | No | Number of projects user can create |
| `pronouns` | No | User's pronouns |
| `provider` | No | External provider name |
| `public_email` | No | User's public email address |
| `reset_password` | No | Send user password reset link - true or false(default) |
| `shared_runners_minutes_limit` **(PREMIUM ALL)** | No | Can be set by administrators only. Maximum number of monthly compute minutes for this user. Can be `nil` (default; inherit system default), `0` (unlimited), or `> 0`. |
| `skip_confirmation` | No | Skip confirmation - true or false (default) |

View File

@ -322,13 +322,13 @@ The `repository_xray` report collects information about your repository for use
> [Moved](https://gitlab.com/groups/gitlab-org/-/epics/2098) from GitLab Ultimate to GitLab Free in 13.3.
The `sast` report collects [SAST vulnerabilities](../../user/application_security/sast/index.md). The collected SAST
report uploads to GitLab as an artifact.
The `sast` report collects [SAST vulnerabilities](../../user/application_security/sast/index.md).
The collected SAST report uploads to GitLab as an artifact.
GitLab can display the results of one or more reports in:
For more information, see:
- The merge request [SAST widget](../../user/application_security/sast/index.md).
- The [security dashboard](../../user/application_security/security_dashboard/index.md).
- [View SAST results](../../user/application_security/sast/index.md#view-sast-results)
- [SAST output](../../user/application_security/sast/index.md#output)
## `artifacts:reports:secret_detection`

View File

@ -288,7 +288,7 @@ The report is a JSON document that combines vulnerabilities with possible remedi
This documentation gives an overview of the report JSON format,
as well as recommendations and examples to help integrators set its fields.
The format is extensively described in the documentation of
[SAST](../../user/application_security/sast/index.md#reports-json-format),
[SAST](../../user/application_security/sast/index.md#output),
[DAST](../../user/application_security/dast/proxy-based.md#reports),
[Dependency Scanning](../../user/application_security/dependency_scanning/index.md#reports-json-format),
and [Container Scanning](../../user/application_security/container_scanning/index.md#reports-json-format)

View File

@ -87,7 +87,7 @@ and complete an integration with the Secure stage.
- Read about [job artifacts](../../ci/jobs/job_artifacts.md).
- Your report artifact must be in one of our currently supported formats.
For more information, see the [documentation on reports](secure.md#report).
- Documentation for [SAST reports](../../user/application_security/sast/index.md#reports-json-format).
- Documentation for [SAST output](../../user/application_security/sast/index.md#output).
- Documentation for [Dependency Scanning reports](../../user/application_security/dependency_scanning/index.md#reports-json-format).
- Documentation for [Container Scanning reports](../../user/application_security/container_scanning/index.md#reports-json-format).
- See this [example secure job definition that also defines the artifact created](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/gitlab/ci/templates/Jobs/Container-Scanning.gitlab-ci.yml).

View File

@ -54,7 +54,7 @@ support the following features:
- [Scan projects](index.md#supported-languages-and-frameworks)
- [Multi-project support](index.md#multi-project-support)
- [Offline support](index.md#running-sast-in-an-offline-environment)
- [Emits JSON report format](index.md#reports-json-format)
- [Output results in JSON report format](index.md#output)
- [SELinux support](index.md#running-sast-in-selinux)
## Post analyzers

View File

@ -28,7 +28,7 @@ You can disable predefined rules for any SAST analyzer.
When you disable a rule:
- Most analyzers still scan for the vulnerability. The results are removed as a processing step after the scan completes, and they don't appear in the [`gl-sast-report.json` artifact](index.md#reports-json-format).
- Most analyzers still scan for the vulnerability. The results are removed as a processing step after the scan completes, and they don't appear in the [`gl-sast-report.json` artifact](index.md#output).
- Findings for the disabled rule no longer appear in the [pipeline security tab](../index.md#pipeline-security-tab).
- Existing findings for the disabled rule on the default branch are marked as [`No longer detected`](../vulnerability_report/index.md#activity-filter) in the [vulnerability report](../index.md#vulnerability-report).
@ -196,7 +196,7 @@ rule that you wish to modify.
| `value` | The value of the identifier used by the predefined rule. |
You can look up the correct values for `type` and `value` by viewing the
[`gl-sast-report.json`](index.md#reports-json-format) produced by the analyzer.
[`gl-sast-report.json`](index.md#output) produced by the analyzer.
You can download this file as a job artifact from the analyzer's CI job.
For example, the snippet below shows a finding from a `semgrep` rule with three

View File

@ -220,7 +220,7 @@ as shown in the following table:
| Automatically scan code with [appropriate analyzers](#supported-languages-and-frameworks) | **{check-circle}** | **{check-circle}** |
| [Configure SAST scanners](#configuration) | **{check-circle}** | **{check-circle}** |
| [Customize SAST settings](#available-cicd-variables) | **{check-circle}** | **{check-circle}** |
| Download [JSON Report](#reports-json-format) | **{check-circle}** | **{check-circle}** |
| Download [SAST output](#output) | **{check-circle}** | **{check-circle}** |
| See new findings in merge request widget | **{dotted-circle}** | **{check-circle}** |
| See new findings in merge request changes | **{dotted-circle}** | **{check-circle}** |
| [Manage vulnerabilities](../vulnerabilities/index.md) | **{dotted-circle}** | **{check-circle}** |
@ -230,13 +230,25 @@ as shown in the following table:
| [Detect False Positives](#false-positive-detection) | **{dotted-circle}** | **{check-circle}** |
| [Track moved vulnerabilities](#advanced-vulnerability-tracking) | **{dotted-circle}** | **{check-circle}** |
## Output
SAST outputs the file `gl-sast-report.json` as a job artifact. The file contains details of all
detected vulnerabilities. You can
[download](../../../ci/jobs/job_artifacts.md#download-job-artifacts) the file for processing
outside GitLab.
For more information, see:
- [SAST report file schema](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/sast-report-format.json)
- [Example SAST report file](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep/-/blob/main/qa/expect/js/default/gl-sast-report.json)
## View SAST results
SAST results are shown in the:
The [SAST report file](#output) is processed by GitLab and the details are shown in the UI:
- Merge request widget
- Merge request changes view
- Vulnerability Report
- Vulnerability report
### Merge request widget **(ULTIMATE ALL)**
@ -647,21 +659,6 @@ variables:
SAST_EXPERIMENTAL_FEATURES: "true"
```
## Reports JSON format
SAST outputs a report file in JSON format. The report file contains details of all found vulnerabilities.
To download the report file, you can either:
- Download the file from the CI/CD pipelines page.
- In the pipelines tab on merge requests, set [`artifacts: paths`](../../../ci/yaml/index.md#artifactspaths) to `gl-sast-report.json`.
For information, see [Download job artifacts](../../../ci/jobs/job_artifacts.md#download-job-artifacts).
For details of the report file's schema, see
[SAST report file schema](https://gitlab.com/gitlab-org/security-products/security-report-schemas/-/blob/master/dist/sast-report-format.json).
For an example SAST report file, see [`gl-sast-report.json`](https://gitlab.com/gitlab-org/security-products/analyzers/semgrep/-/blob/main/qa/expect/js/default/gl-sast-report.json) example.
## Running SAST in an offline environment
For self-managed GitLab instances in an environment with limited, restricted, or intermittent access

View File

@ -56,17 +56,17 @@ If you operate a cloud or SaaS product and you're interested in partnering with
Different features are available in different [GitLab tiers](https://about.gitlab.com/pricing/).
| Capability | In Free & Premium | In Ultimate |
|:---------------------------------------------------------------- |:-----------------------|:-----------------------|
| [Configure Secret Detection scanner](#enable-secret-detection) | **{check-circle}** Yes | **{check-circle}** Yes |
| [Customize Secret Detection settings](#configure-scan-settings) | **{check-circle}** Yes | **{check-circle}** Yes |
| Download [JSON Report](../sast/index.md#reports-json-format) | **{check-circle}** Yes | **{check-circle}** Yes |
| Capability | In Free & Premium | In Ultimate |
|:-----------------------------------------------------------------------------------------------------|:-----------------------|:-----------------------|
| [Configure Secret Detection scanner](#enable-secret-detection) | **{check-circle}** Yes | **{check-circle}** Yes |
| [Customize Secret Detection settings](#configure-scan-settings) | **{check-circle}** Yes | **{check-circle}** Yes |
| Download [SAST output](../sast/index.md#output) | **{check-circle}** Yes | **{check-circle}** Yes |
| [Check text for potential secrets](#warnings-for-potential-leaks-in-text-content) before it's posted | **{check-circle}** Yes | **{check-circle}** Yes |
| See new findings in the merge request widget | **{dotted-circle}** No | **{check-circle}** Yes |
| View identified secrets in the pipelines' **Security** tab | **{dotted-circle}** No | **{check-circle}** Yes |
| [Manage vulnerabilities](../vulnerability_report/index.md) | **{dotted-circle}** No | **{check-circle}** Yes |
| [Access the Security Dashboard](../security_dashboard/index.md) | **{dotted-circle}** No | **{check-circle}** Yes |
| [Customize Secret Detection rulesets](#custom-rulesets) | **{dotted-circle}** No | **{check-circle}** Yes |
| See new findings in the merge request widget | **{dotted-circle}** No | **{check-circle}** Yes |
| View identified secrets in the pipelines' **Security** tab | **{dotted-circle}** No | **{check-circle}** Yes |
| [Manage vulnerabilities](../vulnerability_report/index.md) | **{dotted-circle}** No | **{check-circle}** Yes |
| [Access the Security Dashboard](../security_dashboard/index.md) | **{dotted-circle}** No | **{check-circle}** Yes |
| [Customize Secret Detection rulesets](#custom-rulesets) | **{dotted-circle}** No | **{check-circle}** Yes |
## Coverage

View File

@ -54,3 +54,7 @@ xray:
- The added rules restrict the job to the default branch only. Restricting the job this way ensures development changes do not impact the baseline X-Ray data used for production code suggestions.
After the initial x-ray job completes and uploads the repository analysis reports, no further action is required. Repository X-Ray automatically enriches all code generation requests from that point forward.
The X-Ray data for your project updates each time a CI/CD pipeline containing the `xray`
job is run. To learn more about pipeline configuration and triggers, see the
[pipelines documentation](../../../../ci/pipelines/merge_request_pipelines.md).

View File

@ -22,11 +22,19 @@ module Gitlab
LINKERS.find { |linker| linker.support?(blob_name) }
end
def self.link(blob_name, plain_text, highlighted_text)
def self.link(blob_name, plain_text, highlighted_text, used_on: :blob)
linker = linker(blob_name)
return highlighted_text unless linker
usage_counter.increment(used_on: used_on)
linker.link(plain_text, highlighted_text)
end
def self.usage_counter
Gitlab::Metrics.counter(
:dependency_linker_usage,
'The number of times dependency linker is used'
)
end
end
end

View File

@ -90,7 +90,8 @@ module Gitlab
rich_line = syntax_highlighter(diff_line).highlight(
diff_line.text(prefix: false),
plain: plain,
context: { line_number: diff_line.line }
context: { line_number: diff_line.line },
used_on: :diff
)
# Only update text if line is found. This will prevent
@ -143,7 +144,7 @@ module Gitlab
blob.load_all_data!
blob.present.highlight.lines
blob.present.highlight(used_on: :diff).lines
end
def blobs_too_large?

View File

@ -2,9 +2,9 @@
module Gitlab
class Highlight
def self.highlight(blob_name, blob_content, language: nil, plain: false, context: {})
def self.highlight(blob_name, blob_content, language: nil, plain: false, context: {}, used_on: :blob)
new(blob_name, blob_content, language: language)
.highlight(blob_content, continue: false, plain: plain, context: context)
.highlight(blob_content, continue: false, plain: plain, context: context, used_on: used_on)
end
def self.too_large?(size)
@ -18,15 +18,19 @@ module Gitlab
@language = language
@blob_name = blob_name
@blob_content = blob_content
@gitlab_highlight_usage_counter = Gitlab::Metrics.counter(
:gitlab_highlight_usage,
'The number of times Gitlab::Highlight is used'
)
end
def highlight(text, continue: false, plain: false, context: {})
def highlight(text, continue: false, plain: false, context: {}, used_on: :blob)
@context = context
plain ||= self.class.too_large?(text.length)
highlighted_text = highlight_text(text, continue: continue, plain: plain)
highlighted_text = link_dependencies(text, highlighted_text) if blob_name
highlighted_text = highlight_text(text, continue: continue, plain: plain, used_on: used_on)
highlighted_text = link_dependencies(text, highlighted_text, used_on: used_on) if blob_name
highlighted_text
end
@ -54,7 +58,9 @@ module Gitlab
Rouge::Lexer.find_fancy(@language)
end
def highlight_text(text, continue: true, plain: false)
def highlight_text(text, continue: true, plain: false, used_on: :blob)
@gitlab_highlight_usage_counter.increment(used_on: used_on)
if plain
highlight_plain(text)
else
@ -77,8 +83,8 @@ module Gitlab
highlight_plain(text)
end
def link_dependencies(text, highlighted_text)
Gitlab::DependencyLinker.link(blob_name, text, highlighted_text)
def link_dependencies(text, highlighted_text, used_on: :blob)
Gitlab::DependencyLinker.link(blob_name, text, highlighted_text, used_on: used_on)
end
end
end

View File

@ -41079,7 +41079,7 @@ msgstr ""
msgid "Requires you to deploy or set up cloud-hosted Sentry."
msgstr ""
msgid "Requires your primary GitLab email address."
msgid "Requires your primary GitLab email address. If you want to confirm a secondary email address, go to %{emails_link_start}Emails%{emails_link_end}"
msgstr ""
msgid "Resend"

View File

@ -3,28 +3,6 @@
require 'spec_helper'
RSpec.describe Ci::BuildsHelper, feature_category: :continuous_integration do
describe '#sidebar_build_class' do
using RSpec::Parameterized::TableSyntax
where(:build_id, :current_build_id, :retried, :expected_result) do
1 | 1 | true | 'active retried'
1 | 1 | false | 'active'
1 | 2 | false | ''
1 | 2 | true | 'retried'
end
let(:build) { instance_double(Ci::Build, retried?: retried, id: build_id) }
let(:current_build) { instance_double(Ci::Build, retried?: true, id: current_build_id ) }
subject { helper.sidebar_build_class(build, current_build) }
with_them do
it 'builds sidebar html class' do
expect(subject).to eq(expected_result)
end
end
end
describe '#build_failed_issue_options' do
subject { helper.build_failed_issue_options }

View File

@ -1,6 +1,6 @@
# frozen_string_literal: true
require 'fast_spec_helper'
require 'spec_helper'
RSpec.describe Gitlab::DependencyLinker do
describe '.link' do
@ -107,5 +107,16 @@ RSpec.describe Gitlab::DependencyLinker do
described_class.link(blob_name, nil, nil)
end
it 'increments usage counter based on specified used_on', :prometheus do
allow(described_class::GemfileLinker).to receive(:link)
described_class.link('Gemfile', nil, nil, used_on: :diff)
dependency_linker_usage_counter = Gitlab::Metrics.registry.get(:dependency_linker_usage)
expect(dependency_linker_usage_counter.get(used_on: :diff)).to eq(1)
expect(dependency_linker_usage_counter.get(used_on: :blob)).to eq(0)
end
end
end

View File

@ -25,119 +25,131 @@ RSpec.describe Gitlab::Diff::Highlight, feature_category: :source_code_managemen
end
describe '#highlight' do
context "with a diff file" do
let(:subject) { described_class.new(diff_file, repository: project.repository).highlight }
shared_examples_for 'diff highlighter' do
context "with a diff file" do
let(:subject) { described_class.new(diff_file, repository: project.repository).highlight }
it 'returns Gitlab::Diff::Line elements' do
expect(subject.first).to be_an_instance_of(Gitlab::Diff::Line)
it 'returns Gitlab::Diff::Line elements' do
expect(subject.first).to be_an_instance_of(Gitlab::Diff::Line)
end
it 'does not modify "match" lines' do
expect(subject[0].text).to eq('@@ -6,12 +6,18 @@ module Popen')
expect(subject[22].text).to eq('@@ -19,6 +25,7 @@ module Popen')
end
it 'highlights and marks unchanged lines' do
code = %{ <span id="LC7" class="line" lang="ruby"> <span class="k">def</span> <span class="nf">popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kp">nil</span><span class="p">)</span></span>\n}
expect(subject[2].rich_text).to eq(code)
end
it 'highlights and marks removed lines' do
code = %(-<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="s2">"System commands must be given as an array of strings"</span></span>\n)
expect(subject[4].rich_text).to eq(code)
end
it 'highlights and marks added lines' do
code = %(+<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="no"><span class="idiff left addition">RuntimeError</span></span><span class="p"><span class="idiff addition">,</span></span><span class="idiff right addition"> </span><span class="s2">"System commands must be given as an array of strings"</span></span>\n)
expect(subject[5].rich_text).to eq(code)
end
context 'when no diff_refs' do
before do
allow(diff_file).to receive(:diff_refs).and_return(nil)
end
context 'when no inline diffs' do
it_behaves_like 'without inline diffs'
end
end
end
it 'does not modify "match" lines' do
expect(subject[0].text).to eq('@@ -6,12 +6,18 @@ module Popen')
expect(subject[22].text).to eq('@@ -19,6 +25,7 @@ module Popen')
end
context "with diff lines" do
let(:subject) { described_class.new(diff_file.diff_lines, repository: project.repository).highlight }
it 'highlights and marks unchanged lines' do
code = %{ <span id="LC7" class="line" lang="ruby"> <span class="k">def</span> <span class="nf">popen</span><span class="p">(</span><span class="n">cmd</span><span class="p">,</span> <span class="n">path</span><span class="o">=</span><span class="kp">nil</span><span class="p">)</span></span>\n}
it 'returns Gitlab::Diff::Line elements' do
expect(subject.first).to be_an_instance_of(Gitlab::Diff::Line)
end
expect(subject[2].rich_text).to eq(code)
end
it 'does not modify "match" lines' do
expect(subject[0].text).to eq('@@ -6,12 +6,18 @@ module Popen')
expect(subject[22].text).to eq('@@ -19,6 +25,7 @@ module Popen')
end
it 'highlights and marks removed lines' do
code = %(-<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="s2">"System commands must be given as an array of strings"</span></span>\n)
it 'marks unchanged lines' do
code = %q{ def popen(cmd, path=nil)}
expect(subject[4].rich_text).to eq(code)
end
expect(subject[2].text).to eq(code)
expect(subject[2].text).not_to be_html_safe
end
it 'highlights and marks added lines' do
code = %(+<span id="LC9" class="line" lang="ruby"> <span class="k">raise</span> <span class="no"><span class="idiff left addition">RuntimeError</span></span><span class="p"><span class="idiff addition">,</span></span><span class="idiff right addition"> </span><span class="s2">"System commands must be given as an array of strings"</span></span>\n)
it 'marks removed lines' do
code = %q(- raise "System commands must be given as an array of strings")
expect(subject[5].rich_text).to eq(code)
end
expect(subject[4].text).to eq(code)
expect(subject[4].text).not_to be_html_safe
end
context 'when no diff_refs' do
before do
allow(diff_file).to receive(:diff_refs).and_return(nil)
it 'marks added lines' do
code = %q(+ raise <span class="idiff left right addition">RuntimeError, </span>&quot;System commands must be given as an array of strings&quot;)
expect(subject[5].rich_text).to eq(code)
expect(subject[5].rich_text).to be_html_safe
end
context 'when the inline diff marker has an invalid range' do
before do
allow_any_instance_of(Gitlab::Diff::InlineDiffMarker).to receive(:mark).and_raise(RangeError)
end
it 'keeps the original rich line' do
allow(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception)
code = %q(+ raise RuntimeError, "System commands must be given as an array of strings")
expect(subject[5].text).to eq(code)
expect(subject[5].text).not_to be_html_safe
end
it 'reports to Sentry if configured' do
expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).and_call_original
expect { subject }.to raise_exception(RangeError)
end
end
context 'when no inline diffs' do
it_behaves_like 'without inline diffs'
end
end
end
context "with diff lines" do
let(:subject) { described_class.new(diff_file.diff_lines, repository: project.repository).highlight }
context 'when blob is too large' do
let(:subject) { described_class.new(diff_file, repository: project.repository).highlight }
it 'returns Gitlab::Diff::Line elements' do
expect(subject.first).to be_an_instance_of(Gitlab::Diff::Line)
end
it 'does not modify "match" lines' do
expect(subject[0].text).to eq('@@ -6,12 +6,18 @@ module Popen')
expect(subject[22].text).to eq('@@ -19,6 +25,7 @@ module Popen')
end
it 'marks unchanged lines' do
code = %q{ def popen(cmd, path=nil)}
expect(subject[2].text).to eq(code)
expect(subject[2].text).not_to be_html_safe
end
it 'marks removed lines' do
code = %q(- raise "System commands must be given as an array of strings")
expect(subject[4].text).to eq(code)
expect(subject[4].text).not_to be_html_safe
end
it 'marks added lines' do
code = %q(+ raise <span class="idiff left right addition">RuntimeError, </span>&quot;System commands must be given as an array of strings&quot;)
expect(subject[5].rich_text).to eq(code)
expect(subject[5].rich_text).to be_html_safe
end
context 'when the inline diff marker has an invalid range' do
before do
allow_any_instance_of(Gitlab::Diff::InlineDiffMarker).to receive(:mark).and_raise(RangeError)
allow(Gitlab::Highlight).to receive(:too_large?).and_return(true)
end
it 'keeps the original rich line' do
allow(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception)
it 'blobs are highlighted as plain text without loading all data' do
expect(diff_file.blob).not_to receive(:load_all_data!)
code = %q(+ raise RuntimeError, "System commands must be given as an array of strings")
expect(subject[5].text).to eq(code)
expect(subject[5].text).not_to be_html_safe
expect(subject[2].rich_text).to eq(%{ <span id="LC7" class="line" lang=""> def popen(cmd, path=nil)</span>\n})
expect(subject[2].rich_text).to be_html_safe
end
it 'reports to Sentry if configured' do
expect(Gitlab::ErrorTracking).to receive(:track_and_raise_for_dev_exception).and_call_original
expect { subject }.to raise_exception(RangeError)
end
end
context 'when no inline diffs' do
it_behaves_like 'without inline diffs'
end
end
context 'when blob is too large' do
let(:subject) { described_class.new(diff_file, repository: project.repository).highlight }
it_behaves_like 'diff highlighter'
context 'when diff_line_syntax_highlighting feature flag is disabled' do
before do
allow(Gitlab::Highlight).to receive(:too_large?).and_return(true)
stub_feature_flags(diff_line_syntax_highlighting: false)
end
it 'blobs are highlighted as plain text without loading all data' do
expect(diff_file.blob).not_to receive(:load_all_data!)
expect(subject[2].rich_text).to eq(%{ <span id="LC7" class="line" lang=""> def popen(cmd, path=nil)</span>\n})
expect(subject[2].rich_text).to be_html_safe
end
it_behaves_like 'diff highlighter'
end
end
end

View File

@ -116,7 +116,7 @@ RSpec.describe Gitlab::Highlight do
it 'links dependencies via DependencyLinker' do
expect(Gitlab::DependencyLinker).to receive(:link)
.with('file.name', 'Contents', anything).and_call_original
.with('file.name', 'Contents', anything, used_on: :blob).and_call_original
described_class.highlight('file.name', 'Contents')
end
@ -133,5 +133,32 @@ RSpec.describe Gitlab::Highlight do
highlight
end
end
it 'increments usage counter', :prometheus do
described_class.highlight(file_name, content)
gitlab_highlight_usage_counter = Gitlab::Metrics.registry.get(:gitlab_highlight_usage)
expect(gitlab_highlight_usage_counter.get(used_on: :blob)).to eq(1)
expect(gitlab_highlight_usage_counter.get(used_on: :diff)).to eq(0)
end
context 'when used_on is specified' do
it 'increments usage counter', :prometheus do
described_class.highlight(file_name, content, used_on: :diff)
gitlab_highlight_usage_counter = Gitlab::Metrics.registry.get(:gitlab_highlight_usage)
expect(gitlab_highlight_usage_counter.get(used_on: :diff)).to eq(1)
expect(gitlab_highlight_usage_counter.get(used_on: :blob)).to eq(0)
end
it 'links dependencies via DependencyLinker' do
expect(Gitlab::DependencyLinker).to receive(:link)
.with(file_name, content, anything, used_on: :diff).and_call_original
described_class.highlight(file_name, content, used_on: :diff)
end
end
end
end

View File

@ -312,13 +312,13 @@ RSpec.describe BlobPresenter do
let(:git_blob) { blob.__getobj__ }
it 'returns highlighted content' do
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'ruby')
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'ruby', used_on: :blob)
presenter.highlight
end
it 'returns plain content when :plain is true' do
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: true, language: 'ruby')
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: true, language: 'ruby', used_on: :blob)
presenter.highlight(plain: true)
end
@ -331,7 +331,7 @@ RSpec.describe BlobPresenter do
end
it 'returns limited highlighted content' do
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', "line one\n", plain: nil, language: 'ruby')
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', "line one\n", plain: nil, language: 'ruby', used_on: :blob)
presenter.highlight(to: 1)
end
@ -343,11 +343,19 @@ RSpec.describe BlobPresenter do
end
it 'passes language to inner call' do
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'ruby')
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'ruby', used_on: :blob)
presenter.highlight
end
end
context 'when used_on param is present' do
it 'returns highlighted content' do
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'ruby', used_on: :diff)
presenter.highlight(used_on: :diff)
end
end
end
describe '#highlight_and_trim' do

View File

@ -14,7 +14,7 @@ RSpec.describe Blobs::NotebookPresenter do
subject(:presenter) { described_class.new(blob, current_user: user) }
it 'highlight receives markdown' do
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'md')
expect(Gitlab::Highlight).to receive(:highlight).with('files/ruby/regex.rb', git_blob.data, plain: nil, language: 'md', used_on: :blob)
presenter.highlight
end