Commit 5cf2d56c authored by Nikola Milojevic's avatar Nikola Milojevic

Merge branch 'tomquirk/337996-links-in-jira-error-messages' into 'master'

Add links to Jira-related error messages

See merge request gitlab-org/gitlab!72854
parents deee5630 c2f29f4a
......@@ -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
......
......@@ -156,7 +156,6 @@ export default {
},
];
},
getFilteredSearchValue() {
const { labels, search } = this.filterParams || {};
const filteredSearchValue = [];
......@@ -228,12 +227,13 @@ export default {
this.filterParams = filterParams;
},
},
alertSafeHtmlConfig: { ALLOW_TAGS: ['a'] },
};
</script>
<template>
<gl-alert v-if="errorMessage" class="gl-mt-3" variant="danger" :dismissible="false">
{{ errorMessage }}
<span v-safe-html:[$options.alertSafeHtmlConfig]="errorMessage"></span>
</gl-alert>
<issuable-list
v-else
......
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`ExternalIssuesListRoot error handling when request fails displays error alert with "API error" when API responds with "["API <a href=\\"gitlab.com\\">error</a>"]" 1`] = `"<span>API <a href=\\"gitlab.com\\">error</a></span>"`;
exports[`ExternalIssuesListRoot error handling when request fails displays error alert with "API error" when API responds with "["API error"]" 1`] = `"<span>API error</span>"`;
exports[`ExternalIssuesListRoot error handling when request fails displays error alert with "API" when API responds with "["API <script src=\\"hax0r.xyz\\">error</script>"]" 1`] = `"<span>API </span>"`;
exports[`ExternalIssuesListRoot error handling when request fails displays error alert with "An error occurred while loading issues" when API responds with "undefined" 1`] = `"<span>An error occurred while loading issues</span>"`;
exports[`ExternalIssuesListRoot when request succeeds renders issuable-list component with correct props 1`] = `
Object {
"currentPage": 1,
......
......@@ -63,6 +63,7 @@ describe('ExternalIssuesListRoot', () => {
const findIssuableList = () => wrapper.findComponent(IssuableList);
const findAlert = () => wrapper.findComponent(GlAlert);
const findAlertMessage = () => findAlert().find('span');
const createLabelFilterEvent = (data) => ({ type: 'labels', value: { data } });
const createSearchFilterEvent = (data) => ({ type: 'filtered-search-term', value: { data } });
......@@ -319,12 +320,14 @@ describe('ExternalIssuesListRoot', () => {
describe('when request fails', () => {
it.each`
APIErrors | expectedRenderedErrorMessage
${['API error']} | ${'API error'}
${undefined} | ${i18n.errorFetchingIssues}
APIErrors | expectedRenderedErrorText
${['API error']} | ${'API error'}
${['API <a href="gitlab.com">error</a>']} | ${'API error'}
${['API <script src="hax0r.xyz">error</script>']} | ${'API'}
${undefined} | ${i18n.errorFetchingIssues}
`(
'displays error alert with "$expectedRenderedErrorMessage" when API responds with "$APIErrors"',
async ({ APIErrors, expectedRenderedErrorMessage }) => {
'displays error alert with "$expectedRenderedErrorText" when API responds with "$APIErrors"',
async ({ APIErrors, expectedRenderedErrorText }) => {
jest.spyOn(axios, 'get');
mock
.onGet(mockProvide.issuesFetchPath)
......@@ -333,7 +336,8 @@ describe('ExternalIssuesListRoot', () => {
createComponent();
await waitForPromises();
expectErrorHandling(expectedRenderedErrorMessage);
expectErrorHandling(expectedRenderedErrorText);
expect(findAlertMessage().html()).toMatchSnapshot();
},
);
});
......
......@@ -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}"
......
......@@ -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
......
......@@ -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
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment