Commit 674344ea authored by Vitali Tatarintev's avatar Vitali Tatarintev Committed by Kamil Trzciński

Extract Sentry issue_details method

Extract `Sentry::Client#issue_details` into a separate module
parent ee9c3cb0
......@@ -3,6 +3,7 @@
module Sentry
class Client
include Sentry::Client::Projects
include Sentry::Client::Issue
Error = Class.new(StandardError)
MissingKeysError = Class.new(StandardError)
......@@ -23,12 +24,6 @@ module Sentry
@token = token
end
def issue_details(issue_id:)
issue = get_issue(issue_id: issue_id)
map_to_detailed_error(issue)
end
def issue_latest_event(issue_id:)
latest_event = get_issue_latest_event(issue_id: issue_id)
......@@ -107,10 +102,6 @@ module Sentry
}.compact
end
def get_issue(issue_id:)
http_get(issue_api_url(issue_id))[:body]
end
def get_issue_latest_event(issue_id:)
http_get(issue_latest_event_api_url(issue_id))[:body]
end
......@@ -145,13 +136,6 @@ module Sentry
raise Client::Error, message
end
def issue_api_url(issue_id)
issue_url = URI(@url)
issue_url.path = "/api/0/issues/#{issue_id}/"
issue_url
end
def issue_latest_event_api_url(issue_id)
latest_event_url = URI(@url)
latest_event_url.path = "/api/0/issues/#{issue_id}/events/latest/"
......@@ -212,42 +196,6 @@ module Sentry
stack_trace_entry.dig('stacktrace', 'frames')
end
def parse_gitlab_issue(plugin_issues)
return unless plugin_issues
gitlab_plugin = plugin_issues.detect { |item| item['id'] == 'gitlab' }
return unless gitlab_plugin
gitlab_plugin.dig('issue', 'url')
end
def map_to_detailed_error(issue)
Gitlab::ErrorTracking::DetailedError.new(
id: issue.fetch('id'),
first_seen: issue.fetch('firstSeen', nil),
last_seen: issue.fetch('lastSeen', nil),
title: issue.fetch('title', nil),
type: issue.fetch('type', nil),
user_count: issue.fetch('userCount', nil),
count: issue.fetch('count', nil),
message: issue.dig('metadata', 'value'),
culprit: issue.fetch('culprit', nil),
external_url: issue_url(issue.fetch('id')),
external_base_url: project_url,
short_id: issue.fetch('shortId', nil),
status: issue.fetch('status', nil),
frequency: issue.dig('stats', '24h'),
project_id: issue.dig('project', 'id'),
project_name: issue.dig('project', 'name'),
project_slug: issue.dig('project', 'slug'),
gitlab_issue: parse_gitlab_issue(issue.fetch('pluginIssues', nil)),
first_release_last_commit: issue.dig('firstRelease', 'lastCommit'),
last_release_last_commit: issue.dig('lastRelease', 'lastCommit'),
first_release_short_version: issue.dig('firstRelease', 'shortVersion'),
last_release_short_version: issue.dig('lastRelease', 'shortVersion')
)
end
def map_to_error(issue)
Gitlab::ErrorTracking::Error.new(
id: issue.fetch('id'),
......
# frozen_string_literal: true
module Sentry
class Client
module Issue
def issue_details(issue_id:)
issue = get_issue(issue_id: issue_id)
map_to_detailed_error(issue)
end
private
def get_issue(issue_id:)
http_get(issue_api_url(issue_id))[:body]
end
def issue_api_url(issue_id)
issue_url = URI(url)
issue_url.path = "/api/0/issues/#{CGI.escape(issue_id.to_s)}/"
issue_url
end
def parse_gitlab_issue(plugin_issues)
return unless plugin_issues
gitlab_plugin = plugin_issues.detect { |item| item['id'] == 'gitlab' }
return unless gitlab_plugin
gitlab_plugin.dig('issue', 'url')
end
def map_to_detailed_error(issue)
Gitlab::ErrorTracking::DetailedError.new(
id: issue.fetch('id'),
first_seen: issue.fetch('firstSeen', nil),
last_seen: issue.fetch('lastSeen', nil),
title: issue.fetch('title', nil),
type: issue.fetch('type', nil),
user_count: issue.fetch('userCount', nil),
count: issue.fetch('count', nil),
message: issue.dig('metadata', 'value'),
culprit: issue.fetch('culprit', nil),
external_url: issue_url(issue.fetch('id')),
external_base_url: project_url,
short_id: issue.fetch('shortId', nil),
status: issue.fetch('status', nil),
frequency: issue.dig('stats', '24h'),
project_id: issue.dig('project', 'id'),
project_name: issue.dig('project', 'name'),
project_slug: issue.dig('project', 'slug'),
gitlab_issue: parse_gitlab_issue(issue.fetch('pluginIssues', nil)),
first_release_last_commit: issue.dig('firstRelease', 'lastCommit'),
last_release_last_commit: issue.dig('lastRelease', 'lastCommit'),
first_release_short_version: issue.dig('firstRelease', 'shortVersion'),
last_release_short_version: issue.dig('lastRelease', 'shortVersion')
)
end
end
end
end
{
"activity": [
{
"data": {},
"dateCreated": "2018-11-06T21:19:55Z",
"id": "0",
"type": "first_seen",
"user": null
}
],
"annotations": [],
"assignedTo": null,
"count": "1",
"culprit": "raven.scripts.runner in main",
"firstRelease": {
"authors": [],
"commitCount": 0,
"data": {},
"dateCreated": "2018-11-06T21:19:55.146Z",
"dateReleased": null,
"deployCount": 0,
"firstEvent": "2018-11-06T21:19:55.271Z",
"lastCommit": null,
"lastDeploy": null,
"lastEvent": "2018-11-06T21:19:55.271Z",
"newGroups": 0,
"owner": null,
"projects": [
{
"name": "Pump Station",
"slug": "pump-station"
}
],
"ref": null,
"shortVersion": "1764232",
"url": null,
"version": "17642328ead24b51867165985996d04b29310337"
},
"firstSeen": "2018-11-06T21:19:55Z",
"hasSeen": false,
"id": "503504",
"isBookmarked": false,
"isPublic": false,
"isSubscribed": true,
"lastRelease": null,
"lastSeen": "2018-11-06T21:19:55Z",
"level": "error",
"logger": null,
"metadata": {
"title": "This is an example Python exception"
},
"numComments": 0,
"participants": [],
"permalink": "https://sentrytest.gitlab.com/sentry-org/sentry-project/issues/503504/",
"pluginActions": [],
"pluginContexts": [],
"pluginIssues": [
{
"id": "gitlab",
"issue": {
"url": "https://gitlab.com/gitlab-org/gitlab/issues/1"
}
}
],
"project": {
"id": "2",
"name": "Pump Station",
"slug": "pump-station"
},
"seenBy": [],
"shareId": null,
"shortId": "PUMP-STATION-1",
"stats": {
"24h": [
[
1541451600.0,
557
],
[
1541455200.0,
473
],
[
1541458800.0,
914
],
[
1541462400.0,
991
],
[
1541466000.0,
925
],
[
1541469600.0,
881
],
[
1541473200.0,
182
],
[
1541476800.0,
490
],
[
1541480400.0,
820
],
[
1541484000.0,
322
],
[
1541487600.0,
836
],
[
1541491200.0,
565
],
[
1541494800.0,
758
],
[
1541498400.0,
880
],
[
1541502000.0,
677
],
[
1541505600.0,
381
],
[
1541509200.0,
814
],
[
1541512800.0,
329
],
[
1541516400.0,
446
],
[
1541520000.0,
731
],
[
1541523600.0,
111
],
[
1541527200.0,
926
],
[
1541530800.0,
772
],
[
1541534400.0,
400
],
[
1541538000.0,
943
]
],
"30d": [
[
1538870400.0,
565
],
[
1538956800.0,
12862
],
[
1539043200.0,
15617
],
[
1539129600.0,
10809
],
[
1539216000.0,
15065
],
[
1539302400.0,
12927
],
[
1539388800.0,
12994
],
[
1539475200.0,
13139
],
[
1539561600.0,
11838
],
[
1539648000.0,
12088
],
[
1539734400.0,
12338
],
[
1539820800.0,
12768
],
[
1539907200.0,
12816
],
[
1539993600.0,
15356
],
[
1540080000.0,
10910
],
[
1540166400.0,
12306
],
[
1540252800.0,
12912
],
[
1540339200.0,
14700
],
[
1540425600.0,
11890
],
[
1540512000.0,
11684
],
[
1540598400.0,
13510
],
[
1540684800.0,
12625
],
[
1540771200.0,
12811
],
[
1540857600.0,
13180
],
[
1540944000.0,
14651
],
[
1541030400.0,
14161
],
[
1541116800.0,
12612
],
[
1541203200.0,
14316
],
[
1541289600.0,
14742
],
[
1541376000.0,
12505
],
[
1541462400.0,
14180
]
]
},
"status": "unresolved",
"statusDetails": {},
"subscriptionDetails": null,
"tags": [],
"title": "This is an example Python exception",
"type": "default",
"userCount": 0,
"userReportCount": 0
}
# frozen_string_literal: true
require 'spec_helper'
describe Sentry::Client::Issue do
include SentryClientHelpers
let(:token) { 'test-token' }
let(:client) { Sentry::Client.new(sentry_url, token) }
describe '#issue_details' do
let(:issue_sample_response) do
Gitlab::Utils.deep_indifferent_access(
JSON.parse(fixture_file('sentry/issue_sample_response.json'))
)
end
let(:issue_id) { 503504 }
let(:sentry_url) { 'https://sentrytest.gitlab.com/api/0' }
let(:sentry_request_url) { "#{sentry_url}/issues/#{issue_id}/" }
let!(:sentry_api_request) { stub_sentry_request(sentry_request_url, body: issue_sample_response) }
subject { client.issue_details(issue_id: issue_id) }
it_behaves_like 'calls sentry api'
it 'escapes issue ID' do
allow(CGI).to receive(:escape).and_call_original
subject
expect(CGI).to have_received(:escape).with(issue_id.to_s)
end
context 'error object created from sentry response' do
using RSpec::Parameterized::TableSyntax
where(:error_object, :sentry_response) do
:id | :id
:first_seen | :firstSeen
:last_seen | :lastSeen
:title | :title
:type | :type
:user_count | :userCount
:count | :count
:message | [:metadata, :value]
:culprit | :culprit
:short_id | :shortId
:status | :status
:frequency | [:stats, '24h']
:project_id | [:project, :id]
:project_name | [:project, :name]
:project_slug | [:project, :slug]
:first_release_last_commit | [:firstRelease, :lastCommit]
:last_release_last_commit | [:lastRelease, :lastCommit]
:first_release_short_version | [:firstRelease, :shortVersion]
:last_release_short_version | [:lastRelease, :shortVersion]
end
with_them do
it do
expect(subject.public_send(error_object)).to eq(issue_sample_response.dig(*sentry_response))
end
end
it 'has a correct external URL' do
expect(subject.external_url).to eq('https://sentrytest.gitlab.com/api/0/issues/503504')
end
it 'issue has a correct external base url' do
expect(subject.external_base_url).to eq('https://sentrytest.gitlab.com/api/0')
end
it 'has a correct GitLab issue url' do
expect(subject.gitlab_issue).to eq('https://gitlab.com/gitlab-org/gitlab/issues/1')
end
end
end
end
......@@ -14,12 +14,6 @@ describe Sentry::Client do
}
end
let(:issues_sample_response) do
Gitlab::Utils.deep_indifferent_access(
JSON.parse(fixture_file('sentry/issues_sample_response.json'))
)
end
subject(:client) { described_class.new(sentry_url, token) }
shared_examples 'issues has correct return type' do |klass|
......@@ -33,6 +27,12 @@ describe Sentry::Client do
end
describe '#list_issues' do
let(:issues_sample_response) do
Gitlab::Utils.deep_indifferent_access(
JSON.parse(fixture_file('sentry/issues_sample_response.json'))
)
end
let(:issue_status) { 'unresolved' }
let(:limit) { 20 }
let(:search_term) { '' }
......
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