Add latest changes from gitlab-org/gitlab@master

This commit is contained in:
GitLab Bot 2021-11-01 18:12:42 +00:00
parent 7b9eeda432
commit 024e8b496d
33 changed files with 222 additions and 132 deletions

View File

@ -537,3 +537,5 @@ gem 'webauthn', '~> 2.3'
gem 'ipaddress', '~> 0.8.3'
gem 'parslet', '~> 1.8'
gem 'ipynbdiff', '0.3.6'

View File

@ -640,6 +640,9 @@ GEM
invisible_captcha (1.1.0)
rails (>= 4.2)
ipaddress (0.8.3)
ipynbdiff (0.3.6)
diffy (= 3.3.0)
json (= 2.5.1)
jaeger-client (1.1.0)
opentracing (~> 0.3)
thrift
@ -1501,6 +1504,7 @@ DEPENDENCIES
icalendar
invisible_captcha (~> 1.1.0)
ipaddress (~> 0.8.3)
ipynbdiff (= 0.3.6)
jira-ruby (~> 2.1.4)
js_regex (~> 3.7)
json (~> 2.5.1)

View File

@ -7,8 +7,8 @@ class JiraConnect::SubscriptionsController < JiraConnect::ApplicationController
next if p.directives.blank?
# rubocop: disable Lint/PercentStringArray
script_src_values = Array.wrap(p.directives['script-src']) | %w('self' https://connect-cdn.atl-paas.net https://unpkg.com/jquery@3.3.1/)
style_src_values = Array.wrap(p.directives['style-src']) | %w('self' 'unsafe-inline' https://unpkg.com/@atlaskit/)
script_src_values = Array.wrap(p.directives['script-src']) | %w('self' https://connect-cdn.atl-paas.net)
style_src_values = Array.wrap(p.directives['style-src']) | %w('self' 'unsafe-inline')
# rubocop: enable Lint/PercentStringArray
p.frame_ancestors :self, 'https://*.atlassian.net'

View File

@ -1,4 +1,5 @@
# frozen_string_literal: true
require 'ipynbdiff'
class BlobPresenter < Gitlab::View::Presenter::Delegated
include ApplicationHelper
@ -20,6 +21,17 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
)
end
def highlight_transformed(plain: nil)
load_all_blob_data
Gitlab::Highlight.highlight(
blob.path,
transformed_blob_data,
language: language,
plain: plain
)
end
def plain_data
return if blob.binary?
@ -107,4 +119,8 @@ class BlobPresenter < Gitlab::View::Presenter::Delegated
def language
blob.language_from_gitattributes
end
def transformed_blob_data
@transformed_blob ||= ( blob.path.ends_with?('.ipynb') && IpynbDiff.transform(blob.data, options: { include_metadata: false, cell_decorator: :percent }) ) || blob.data
end
end

View File

@ -67,9 +67,19 @@ module Jira
ServiceResponse.error(message: error_message(e))
end
def auth_docs_link_start
auth_docs_link_url = Rails.application.routes.url_helpers.help_page_path('integration/jira', anchor: 'authentication-in-jira')
'<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: auth_docs_link_url }
end
def config_docs_link_start
config_docs_link_url = Rails.application.routes.url_helpers.help_page_path('integration/jira/configure')
'<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: config_docs_link_url }
end
def error_message(error)
reportable_error_message(error) ||
s_('JiraRequest|An error occurred while requesting data from Jira. Check your Jira integration configuration and try again.')
s_('JiraRequest|An error occurred while requesting data from Jira. Check your %{docs_link_start}Jira integration configuration%{docs_link_end} and try again.').html_safe % { docs_link_start: config_docs_link_start, docs_link_end: '</a>'.html_safe }
end
# Returns a user-facing error message if possible, otherwise `nil`.
@ -93,11 +103,11 @@ module Jira
def reportable_jira_ruby_error_message(error)
case error.message
when 'Unauthorized'
s_('JiraRequest|The credentials for accessing Jira are not valid. Check your Jira integration credentials and try again.')
s_('JiraRequest|The credentials for accessing Jira are not valid. Check your %{docs_link_start}Jira integration credentials%{docs_link_end} and try again.').html_safe % { docs_link_start: auth_docs_link_start, docs_link_end: '</a>'.html_safe }
when 'Forbidden'
s_('JiraRequest|The credentials for accessing Jira are not allowed to access the data. Check your Jira integration credentials and try again.')
s_('JiraRequest|The credentials for accessing Jira are not allowed to access the data. Check your %{docs_link_start}Jira integration credentials%{docs_link_end} and try again.').html_safe % { docs_link_start: auth_docs_link_start, docs_link_end: '</a>'.html_safe }
when 'Bad Request'
s_('JiraRequest|An error occurred while requesting data from Jira. Check your Jira integration configuration and try again.')
s_('JiraRequest|An error occurred while requesting data from Jira. Check your %{docs_link_start}Jira integration configuration%{docs_link_end} and try again.').html_safe % { docs_link_start: config_docs_link_start, docs_link_end: '</a>'.html_safe }
when /errorMessages/
jira_ruby_json_error_message(error.message)
end
@ -111,7 +121,7 @@ module Jira
messages = Rails::Html::FullSanitizer.new.sanitize(messages).presence
return unless messages
s_('JiraRequest|An error occurred while requesting data from Jira: %{messages}. Check your Jira integration configuration and try again.') % { messages: messages }
s_('JiraRequest|An error occurred while requesting data from Jira: %{messages}. Check your %{docs_link_start}Jira integration configuration%{docs_link_end} and try again.').html_safe % { messages: messages, docs_link_start: config_docs_link_start, docs_link_end: '</a>'.html_safe }
rescue JSON::ParserError
end
end

View File

@ -8,6 +8,8 @@ sidekiq_pidfile="$app_root/tmp/pids/sidekiq-cluster.pid"
sidekiq_logfile="$app_root/log/sidekiq.log"
gitlab_user=$(ls -l config.ru | awk '{print $3}')
trap cleanup EXIT
warn()
{
echo "$@" 1>&2
@ -59,6 +61,11 @@ start_sidekiq()
${cmd} bin/sidekiq-cluster "${processes_args[@]}" -P $sidekiq_pidfile -e $RAILS_ENV "$@" 2>&1 | tee -a $sidekiq_logfile
}
cleanup()
{
stop
}
action="$1"
shift

View File

@ -0,0 +1,8 @@
---
name: jupyter_clean_diffs
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/71477
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/343433
milestone: '14.5'
type: development
group: group::incubation
default_enabled: false

View File

@ -10,10 +10,6 @@ Gitlab.ee do
end
end
unless Gitlab::Utils.to_boolean(ENV["GITLAB_LB_CONFIGURE_CONNECTION"], default: true)
ActiveRecord::Base.establish_connection(Gitlab::Database.main.db_config_with_default_pool_size)
end
Gitlab.ee do
if Gitlab::Runtime.sidekiq? && Gitlab::Geo.geo_database_configured?
Rails.configuration.geo_database['pool'] = Gitlab::Database.default_pool_size

View File

@ -0,0 +1,16 @@
# frozen_string_literal: true
class TmpIndexForDeleteIssueMergeRequestTaggingsRecords < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
INDEX_NAME = 'tmp_index_taggings_on_id_where_taggable_type_issue_mr'
INDEX_CONDITION = "taggable_type IN ('Issue', 'MergeRequest')"
def up
add_concurrent_index :taggings, :id, where: INDEX_CONDITION, name: INDEX_NAME # rubocop:disable Migration/PreventIndexCreation
end
def down
remove_concurrent_index_by_name :taggings, INDEX_NAME
end
end

View File

@ -0,0 +1,19 @@
# frozen_string_literal: true
class DeleteIssueMergeRequestTaggingsRecords < Gitlab::Database::Migration[1.0]
disable_ddl_transaction!
INDEX_NAME = 'tmp_index_taggings_on_id_where_taggable_type_issue_mr'
BATCH_SIZE = 3_000
TAGGABLE_TYPES = %w(Issue MergeRequest)
def up
sleep 2 while ActsAsTaggableOn::Tagging.where(taggable_type: TAGGABLE_TYPES).limit(BATCH_SIZE).delete_all > 0
remove_concurrent_index_by_name :taggings, INDEX_NAME
end
def down
end
end

View File

@ -0,0 +1 @@
bb28267d020cbc26614e4635c803af0168ab5606f3aadc40e1c0e0bc6d988254

View File

@ -0,0 +1 @@
27578f62b5cde4fdbfe79eb717404a5cef62b8c17170525428dbf81e6b394ce9

View File

@ -345,6 +345,12 @@ memory, disk, and CPU utilization.
[Read more about the node exporter](node_exporter.md).
### Puma exporter
The Puma exporter allows you to measure various Puma metrics.
[Read more about the Puma exporter](puma_exporter.md).
### Redis exporter
The Redis exporter allows you to measure various Redis metrics.

View File

@ -60,6 +60,9 @@ that have the same problem.
Primary keys problem will be tackled by our Database Team.
Status: As of October 2021 the primary keys in CI tables have been migrated to
big integers.
### The table is too large
There is more than a billion rows in `ci_builds` table. We store more than 2
@ -111,6 +114,12 @@ table that will accelerate SQL queries used to build
queues](https://gitlab.com/gitlab-org/gitlab/-/issues/322766) and we want to
explore them.
Status: the new architecture [has been implemented on GitLab.com](https://gitlab.com/groups/gitlab-org/-/epics/5909#note_680407908).
The following epic tracks making it generally available: [Make the new pending
builds architecture generally available](
https://gitlab.com/groups/gitlab-org/-/epics/6954).
### Moving big amounts of data is challenging
We store a significant amount of data in `ci_builds` table. Some of the columns
@ -127,6 +136,8 @@ columns, tables, partitions or database shards.
Effort to improve background migrations will be owned by our Database Team.
Status: In progress.
### Development velocity is negatively affected
Team members and the wider community members are struggling to contribute the
@ -168,7 +179,12 @@ target](https://gitlab.com/groups/gitlab-org/-/epics/5745) epic.
## Status
In progress.
|-------------|--------------|
| Created at | 21.01.2021 |
| Approved at | 26.04.2021 |
| Updated at | 28.10.2021 |
Status: In progress.
## Who
@ -180,7 +196,7 @@ Proposal:
|------------------------------|-------------------------|
| Author | Grzegorz Bizon |
| Architecture Evolution Coach | Kamil Trzciński |
| Engineering Leader | Darby Frey |
| Engineering Leader | Cheryl Li |
| Product Manager | Jackie Porter |
| Domain Expert / Verify | Fabio Pitino |
| Domain Expert / Database | Jose Finotto |
@ -190,7 +206,7 @@ DRIs:
| Role | Who
|------------------------------|------------------------|
| Leadership | Darby Frey |
| Leadership | Cheryl Li |
| Product | Jackie Porter |
| Engineering | Grzegorz Bizon |

View File

@ -29,7 +29,7 @@ Commits in a project's [wiki](../project/wiki/index.md#track-wiki-events) are no
### Charts
The data in the charts are updated soon after each commit in the default branch.
The data in the charts are queued. Background workers update the charts 10 minutes after each commit in the default branch. Depending on the size of the GitLab installation, it may take longer for data to refresh due to variations in the size of background job queues.
Available charts:

Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

View File

@ -20,6 +20,15 @@ rendered to HTML when viewed:
Interactive features, including JavaScript plots, don't work when viewed in
GitLab.
## Cleaner diffs
> [Introduced](https://gitlab.com/gitlab-org/gitlab/-/epics/6589) in GitLab 14.5
When commits include changes to Jupyter Notebook files, GitLab strips out the
noise and displays a cleaner version of the diff.
![Jupyter Notebook Clean Diff](img/jupyter_notebook_diff.png)
## Jupyter Git integration
Jupyter can be configured as an OAuth application with repository access, acting

View File

@ -488,7 +488,7 @@ module API
def handle_api_exception(exception)
if report_exception?(exception)
define_params_for_grape_middleware
Gitlab::ApplicationContext.push(user: current_user)
Gitlab::ApplicationContext.push(user: current_user, remote_ip: request.ip)
Gitlab::ErrorTracking.track_exception(exception)
end

View File

@ -59,20 +59,6 @@ module Gitlab
adapter_name.casecmp('postgresql') == 0
end
# TODO: To be removed with GITLAB_LB_CONFIGURE_CONNECTION
def db_config_with_default_pool_size
db_config_object = scope.connection_db_config
config = db_config_object
.configuration_hash
.merge(pool: Database.default_pool_size)
ActiveRecord::DatabaseConfigurations::HashConfig.new(
db_config_object.env_name,
db_config_object.name,
config
)
end
# Check whether the underlying database is in read-only mode
def db_read_only?
pg_is_in_recovery =

View File

@ -22,17 +22,10 @@ module Gitlab
def configure_connection
db_config_object = @model.connection_db_config
hash =
if Gitlab::Utils.to_boolean(ENV["GITLAB_LB_CONFIGURE_CONNECTION"], default: true)
db_config_object.configuration_hash.merge(
prepared_statements: false,
pool: Gitlab::Database.default_pool_size
)
else
db_config_object.configuration_hash.merge(
prepared_statements: false
)
end
hash = db_config_object.configuration_hash.merge(
prepared_statements: false,
pool: Gitlab::Database.default_pool_size
)
hash_config = ActiveRecord::DatabaseConfigurations::HashConfig.new(
db_config_object.env_name,

View File

@ -43,6 +43,8 @@ module Gitlab
# Ensure items are collected in the the batch
new_blob_lazy
old_blob_lazy
preprocess_before_diff(diff) if Feature.enabled?(:jupyter_clean_diffs, @project)
end
def position(position_marker, position_type: :text)
@ -448,6 +450,19 @@ module Gitlab
find_renderable_viewer_class(classes)
end
def preprocess_before_diff(diff)
return unless diff.new_path.ends_with? '.ipynb'
from = old_blob_lazy&.data
to = new_blob_lazy&.data
new_diff = IpynbDiff.diff(from, to,
diff_opts: { context: 5, include_diff_info: true },
transform_options: { cell_decorator: :percent } )
diff.diff = new_diff.scan(/.*\n/)[2..-1].join('') if new_diff
end
def alternate_viewer_class
return unless viewer.instance_of?(DiffViewer::Renamed)

View File

@ -152,6 +152,9 @@ module Gitlab
return [] unless blob
blob.load_all_data!
return blob.present.highlight_transformed.lines if Feature.enabled?(:jupyter_clean_diffs, @project)
blob.present.highlight.lines
end

View File

@ -31,9 +31,7 @@ module Gitlab
end
def each_object_to_import
project.merge_requests.with_state(:merged).find_each do |merge_request|
next if already_imported?(merge_request)
merge_requests_to_import.find_each do |merge_request|
Gitlab::GithubImport::ObjectCounter.increment(project, object_type, :fetched)
pull_request = client.pull_request(project.import_source, merge_request.iid)
@ -42,6 +40,17 @@ module Gitlab
mark_as_imported(merge_request)
end
end
private
# Returns only the merge requests that still have merged_by to be imported.
def merge_requests_to_import
project.merge_requests.id_not_in(already_imported_objects).with_state(:merged)
end
def already_imported_objects
Gitlab::Cache::Import::Caching.values_from_set(already_imported_cache_key)
end
end
end
end

View File

@ -86,7 +86,7 @@ module Gitlab
# Returns only the merge requests that still have reviews to be imported.
def merge_requests_to_import
project.merge_requests.where.not(id: already_imported_merge_requests) # rubocop: disable CodeReuse/ActiveRecord
project.merge_requests.id_not_in(already_imported_merge_requests)
end
def already_imported_merge_requests

View File

@ -19493,19 +19493,19 @@ msgstr ""
msgid "JiraRequest|An SSL error occurred while connecting to Jira: %{message}. Try your request again."
msgstr ""
msgid "JiraRequest|An error occurred while requesting data from Jira. Check your Jira integration configuration and try again."
msgid "JiraRequest|An error occurred while requesting data from Jira. Check your %{docs_link_start}Jira integration configuration%{docs_link_end} and try again."
msgstr ""
msgid "JiraRequest|An error occurred while requesting data from Jira: %{messages}. Check your Jira integration configuration and try again."
msgid "JiraRequest|An error occurred while requesting data from Jira: %{messages}. Check your %{docs_link_start}Jira integration configuration%{docs_link_end} and try again."
msgstr ""
msgid "JiraRequest|The Jira API URL for connecting to Jira is not valid. Check your Jira integration API URL and try again."
msgstr ""
msgid "JiraRequest|The credentials for accessing Jira are not allowed to access the data. Check your Jira integration credentials and try again."
msgid "JiraRequest|The credentials for accessing Jira are not allowed to access the data. Check your %{docs_link_start}Jira integration credentials%{docs_link_end} and try again."
msgstr ""
msgid "JiraRequest|The credentials for accessing Jira are not valid. Check your Jira integration credentials and try again."
msgid "JiraRequest|The credentials for accessing Jira are not valid. Check your %{docs_link_start}Jira integration credentials%{docs_link_end} and try again."
msgstr ""
msgid "JiraService| on branch %{branch_link}"

View File

@ -40,8 +40,8 @@ RSpec.describe 'Subscriptions Content Security Policy' do
visit jira_connect_subscriptions_path(jwt: jwt)
is_expected.to include("frame-ancestors 'self' https://*.atlassian.net")
is_expected.to include("script-src 'self' https://some-cdn.test https://connect-cdn.atl-paas.net https://unpkg.com/jquery@3.3.1/")
is_expected.to include("style-src 'self' https://some-cdn.test 'unsafe-inline' https://unpkg.com/@atlaskit/")
is_expected.to include("script-src 'self' https://some-cdn.test https://connect-cdn.atl-paas.net")
is_expected.to include("style-src 'self' https://some-cdn.test 'unsafe-inline'")
end
end
end

View File

@ -90,7 +90,10 @@ RSpec.describe Resolvers::Projects::JiraProjectsResolver do
end
it 'raises failure error' do
expect { resolve_jira_projects }.to raise_error('An error occurred while requesting data from Jira: Some failure. Check your Jira integration configuration and try again.')
config_docs_link_url = Rails.application.routes.url_helpers.help_page_path('integration/jira/configure')
docs_link_start = '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: config_docs_link_url }
error_message = 'An error occurred while requesting data from Jira: Some failure. Check your %{docs_link_start}Jira integration configuration</a> and try again.' % { docs_link_start: docs_link_start }
expect { resolve_jira_projects }.to raise_error(error_message)
end
end
end

View File

@ -7,13 +7,6 @@ RSpec.describe 'Database config initializer', :reestablished_active_record_base
load Rails.root.join('config/initializers/database_config.rb')
end
before do
allow(Gitlab::Runtime).to receive(:max_threads).and_return(max_threads)
stub_env('GITLAB_LB_CONFIGURE_CONNECTION', 'false')
end
let(:max_threads) { 8 }
it 'retains the correct database name for the connection' do
previous_db_name = Gitlab::Database.main.scope.connection.pool.db_config.name
@ -22,52 +15,7 @@ RSpec.describe 'Database config initializer', :reestablished_active_record_base
expect(Gitlab::Database.main.scope.connection.pool.db_config.name).to eq(previous_db_name)
end
context 'when no custom headroom is specified' do
it 'sets the pool size based on the number of worker threads' do
old = ActiveRecord::Base.connection_db_config.pool
expect(old).not_to eq(18)
expect { subject }
.to change { ActiveRecord::Base.connection_db_config.pool }
.from(old)
.to(18)
end
it 'overwrites custom pool settings' do
config = Gitlab::Database.main.config.merge(pool: 42)
allow(Gitlab::Database.main).to receive(:config).and_return(config)
subject
expect(ActiveRecord::Base.connection_db_config.pool).to eq(18)
end
context 'when GITLAB_LB_CONFIGURE_CONNECTION=true' do
before do
stub_env('GITLAB_LB_CONFIGURE_CONNECTION', 'true')
end
it 'does not overwrite custom pool settings' do
expect { subject }.not_to change { ActiveRecord::Base.connection_db_config.pool }
end
end
end
context "when specifying headroom through an ENV variable" do
let(:headroom) { 15 }
before do
stub_env("DB_POOL_HEADROOM", headroom)
end
it "adds headroom on top of the calculated size" do
old = ActiveRecord::Base.connection_db_config.pool
expect { subject }
.to change { ActiveRecord::Base.connection_db_config.pool }
.from(old)
.to(23)
end
it 'does not overwrite custom pool settings' do
expect { subject }.not_to change { ActiveRecord::Base.connection_db_config.pool }
end
end

View File

@ -112,20 +112,6 @@ RSpec.describe Gitlab::Database::Connection do
end
end
describe '#db_config_with_default_pool_size' do
it 'returns db_config with our default pool size' do
allow(Gitlab::Database).to receive(:default_pool_size).and_return(9)
expect(connection.db_config_with_default_pool_size.pool).to eq(9)
end
it 'returns db_config with the correct database name' do
db_name = connection.scope.connection.pool.db_config.name
expect(connection.db_config_with_default_pool_size.name).to eq(db_name)
end
end
describe '#db_read_only?' do
it 'detects a read-only database' do
allow(connection.scope.connection)

View File

@ -4,7 +4,8 @@ require 'spec_helper'
RSpec.describe Gitlab::GithubImport::Importer::PullRequestsMergedByImporter do
let(:client) { double }
let(:project) { create(:project, import_source: 'http://somegithub.com') }
let_it_be(:project) { create(:project, import_source: 'http://somegithub.com') }
subject { described_class.new(project, client) }
@ -27,14 +28,11 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestsMergedByImporter do
end
describe '#each_object_to_import', :clean_gitlab_redis_cache do
it 'fetchs the merged pull requests data' do
create(
:merged_merge_request,
iid: 999,
source_project: project,
target_project: project
)
let!(:merge_request) do
create(:merged_merge_request, iid: 999, source_project: project, target_project: project)
end
it 'fetches the merged pull requests data' do
pull_request = double
allow(client)
@ -48,5 +46,16 @@ RSpec.describe Gitlab::GithubImport::Importer::PullRequestsMergedByImporter do
subject.each_object_to_import {}
end
it 'skips cached merge requests' do
Gitlab::Cache::Import::Caching.set_add(
"github-importer/already-imported/#{project.id}/pull_requests_merged_by",
merge_request.id
)
expect(client).not_to receive(:pull_request)
subject.each_object_to_import {}
end
end
end

View File

@ -200,6 +200,28 @@ RSpec.describe API::API do
expect(response).to have_gitlab_http_status(:not_found)
end
end
context 'when there is an unhandled exception for an anonymous request' do
it 'logs all application context fields and the route' do
expect(described_class::LOG_FORMATTER).to receive(:call) do |_severity, _datetime, _, data|
expect(data.stringify_keys)
.to include('correlation_id' => an_instance_of(String),
'meta.caller_id' => 'GET /api/:version/broadcast_messages',
'meta.remote_ip' => an_instance_of(String),
'meta.client_id' => a_string_matching(%r{\Aip/.+}),
'meta.feature_category' => 'navigation',
'route' => '/api/:version/broadcast_messages')
expect(data.stringify_keys).not_to include('meta.project', 'meta.root_namespace', 'meta.user')
end
expect(BroadcastMessage).to receive(:all).and_raise('An error!')
get(api('/broadcast_messages'))
expect(response).to have_gitlab_http_status(:internal_server_error)
end
end
end
describe 'Marginalia comments' do

View File

@ -53,7 +53,7 @@ module TestEnv
'wip' => 'b9238ee',
'csv' => '3dd0896',
'v1.1.0' => 'b83d6e3',
'add-ipython-files' => 'f6b7a70',
'add-ipython-files' => 'c10c411',
'add-pdf-file' => 'e774ebd',
'squash-large-files' => '54cec52',
'add-pdf-text-binary' => '79faa7b',

View File

@ -26,11 +26,14 @@ RSpec.shared_examples 'a service that handles Jira API errors' do
expect(subject).to be_a(ServiceResponse)
expect(subject).to be_error
expect(subject.message).to include(expected_message)
expect(subject.message).to start_with(expected_message)
end
end
context 'when the JSON in JIRA::HTTPError is unsafe' do
config_docs_link_url = Rails.application.routes.url_helpers.help_page_path('integration/jira/configure')
let(:docs_link_start) { '<a href="%{url}" target="_blank" rel="noopener noreferrer">'.html_safe % { url: config_docs_link_url } }
before do
stub_client_and_raise(JIRA::HTTPError, error)
end
@ -39,7 +42,8 @@ RSpec.shared_examples 'a service that handles Jira API errors' do
let(:error) { '{"errorMessages":' }
it 'returns the default error message' do
expect(subject.message).to eq('An error occurred while requesting data from Jira. Check your Jira integration configuration and try again.')
error_message = 'An error occurred while requesting data from Jira. Check your %{docs_link_start}Jira integration configuration</a> and try again.' % { docs_link_start: docs_link_start }
expect(subject.message).to eq(error_message)
end
end
@ -47,7 +51,8 @@ RSpec.shared_examples 'a service that handles Jira API errors' do
let(:error) { '{"errorMessages":["<script>alert(true)</script>foo"]}' }
it 'sanitizes it' do
expect(subject.message).to eq('An error occurred while requesting data from Jira: foo. Check your Jira integration configuration and try again.')
error_message = 'An error occurred while requesting data from Jira: foo. Check your %{docs_link_start}Jira integration configuration</a> and try again.' % { docs_link_start: docs_link_start }
expect(subject.message).to eq(error_message)
end
end
end