Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
2e46fff2
Commit
2e46fff2
authored
Dec 10, 2019
by
Vitali Tatarintev
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Extract Sentry list_projects
Extract Sentry::Client#list_projects into a separate module
parent
9761c317
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
231 additions
and
150 deletions
+231
-150
lib/sentry/client.rb
lib/sentry/client.rb
+2
-37
lib/sentry/client/projects.rb
lib/sentry/client/projects.rb
+46
-0
spec/lib/sentry/client/projects_spec.rb
spec/lib/sentry/client/projects_spec.rb
+183
-0
spec/lib/sentry/client_spec.rb
spec/lib/sentry/client_spec.rb
+0
-113
No files found.
lib/sentry/client.rb
View file @
2e46fff2
...
@@ -2,6 +2,8 @@
...
@@ -2,6 +2,8 @@
module
Sentry
module
Sentry
class
Client
class
Client
include
Sentry
::
Client
::
Projects
Error
=
Class
.
new
(
StandardError
)
Error
=
Class
.
new
(
StandardError
)
MissingKeysError
=
Class
.
new
(
StandardError
)
MissingKeysError
=
Class
.
new
(
StandardError
)
ResponseInvalidSizeError
=
Class
.
new
(
StandardError
)
ResponseInvalidSizeError
=
Class
.
new
(
StandardError
)
...
@@ -49,14 +51,6 @@ module Sentry
...
@@ -49,14 +51,6 @@ module Sentry
end
end
end
end
def
list_projects
projects
=
get_projects
handle_mapping_exceptions
do
map_to_projects
(
projects
)
end
end
private
private
def
validate_size
(
issues
)
def
validate_size
(
issues
)
...
@@ -121,10 +115,6 @@ module Sentry
...
@@ -121,10 +115,6 @@ module Sentry
http_get
(
issue_latest_event_api_url
(
issue_id
))[
:body
]
http_get
(
issue_latest_event_api_url
(
issue_id
))[
:body
]
end
end
def
get_projects
http_get
(
projects_api_url
)[
:body
]
end
def
handle_request_exceptions
def
handle_request_exceptions
yield
yield
rescue
Gitlab
::
HTTP
::
Error
=>
e
rescue
Gitlab
::
HTTP
::
Error
=>
e
...
@@ -155,13 +145,6 @@ module Sentry
...
@@ -155,13 +145,6 @@ module Sentry
raise
Client
::
Error
,
message
raise
Client
::
Error
,
message
end
end
def
projects_api_url
projects_url
=
URI
(
@url
)
projects_url
.
path
=
'/api/0/projects/'
projects_url
end
def
issue_api_url
(
issue_id
)
def
issue_api_url
(
issue_id
)
issue_url
=
URI
(
@url
)
issue_url
=
URI
(
@url
)
issue_url
.
path
=
"/api/0/issues/
#{
issue_id
}
/"
issue_url
.
path
=
"/api/0/issues/
#{
issue_id
}
/"
...
@@ -187,10 +170,6 @@ module Sentry
...
@@ -187,10 +170,6 @@ module Sentry
issues
.
map
(
&
method
(
:map_to_error
))
issues
.
map
(
&
method
(
:map_to_error
))
end
end
def
map_to_projects
(
projects
)
projects
.
map
(
&
method
(
:map_to_project
))
end
def
issue_url
(
id
)
def
issue_url
(
id
)
issues_url
=
@url
+
"/issues/
#{
id
}
"
issues_url
=
@url
+
"/issues/
#{
id
}
"
...
@@ -289,19 +268,5 @@ module Sentry
...
@@ -289,19 +268,5 @@ module Sentry
project_slug:
issue
.
dig
(
'project'
,
'slug'
)
project_slug:
issue
.
dig
(
'project'
,
'slug'
)
)
)
end
end
def
map_to_project
(
project
)
organization
=
project
.
fetch
(
'organization'
)
Gitlab
::
ErrorTracking
::
Project
.
new
(
id:
project
.
fetch
(
'id'
,
nil
),
name:
project
.
fetch
(
'name'
),
slug:
project
.
fetch
(
'slug'
),
status:
project
.
dig
(
'status'
),
organization_name:
organization
.
fetch
(
'name'
),
organization_id:
organization
.
fetch
(
'id'
,
nil
),
organization_slug:
organization
.
fetch
(
'slug'
)
)
end
end
end
end
end
lib/sentry/client/projects.rb
0 → 100644
View file @
2e46fff2
# frozen_string_literal: true
module
Sentry
class
Client
module
Projects
def
list_projects
projects
=
get_projects
handle_mapping_exceptions
do
map_to_projects
(
projects
)
end
end
private
def
get_projects
http_get
(
projects_api_url
)[
:body
]
end
def
projects_api_url
projects_url
=
URI
(
url
)
projects_url
.
path
=
'/api/0/projects/'
projects_url
end
def
map_to_projects
(
projects
)
projects
.
map
(
&
method
(
:map_to_project
))
end
def
map_to_project
(
project
)
organization
=
project
.
fetch
(
'organization'
)
Gitlab
::
ErrorTracking
::
Project
.
new
(
id:
project
.
fetch
(
'id'
,
nil
),
name:
project
.
fetch
(
'name'
),
slug:
project
.
fetch
(
'slug'
),
status:
project
.
dig
(
'status'
),
organization_name:
organization
.
fetch
(
'name'
),
organization_id:
organization
.
fetch
(
'id'
,
nil
),
organization_slug:
organization
.
fetch
(
'slug'
)
)
end
end
end
end
spec/lib/sentry/client/projects_spec.rb
0 → 100644
View file @
2e46fff2
# frozen_string_literal: true
require
'spec_helper'
describe
Sentry
::
Client
::
Projects
do
let
(
:sentry_url
)
{
'https://sentrytest.gitlab.com/api/0/projects/sentry-org/sentry-project'
}
let
(
:token
)
{
'test-token'
}
let
(
:client
)
{
Sentry
::
Client
.
new
(
sentry_url
,
token
)
}
let
(
:projects_sample_response
)
do
Gitlab
::
Utils
.
deep_indifferent_access
(
JSON
.
parse
(
fixture_file
(
'sentry/list_projects_sample_response.json'
))
)
end
# Requires sentry_api_request and subject to be defined
shared_examples
'calls sentry api'
do
it
'calls sentry api'
do
subject
expect
(
sentry_api_request
).
to
have_been_requested
end
end
shared_examples
'has correct return type'
do
|
klass
|
it
"returns objects of type
#{
klass
}
"
do
expect
(
subject
).
to
all
(
be_a
(
klass
)
)
end
end
shared_examples
'has correct length'
do
|
length
|
it
{
expect
(
subject
.
length
).
to
eq
(
length
)
}
end
# Requires sentry_api_url and subject to be defined
shared_examples
'no redirects'
do
let
(
:redirect_to
)
{
'https://redirected.example.com'
}
let
(
:other_url
)
{
'https://other.example.org'
}
let!
(
:redirected_req_stub
)
{
stub_sentry_request
(
other_url
)
}
let!
(
:redirect_req_stub
)
do
stub_sentry_request
(
sentry_api_url
,
status:
302
,
headers:
{
location:
redirect_to
}
)
end
it
'does not follow redirects'
do
expect
{
subject
}.
to
raise_exception
(
Sentry
::
Client
::
Error
,
'Sentry response status code: 302'
)
expect
(
redirect_req_stub
).
to
have_been_requested
expect
(
redirected_req_stub
).
not_to
have_been_requested
end
end
shared_examples
'maps exceptions'
do
exceptions
=
{
Gitlab
::
HTTP
::
Error
=>
'Error when connecting to Sentry'
,
Net
::
OpenTimeout
=>
'Connection to Sentry timed out'
,
SocketError
=>
'Received SocketError when trying to connect to Sentry'
,
OpenSSL
::
SSL
::
SSLError
=>
'Sentry returned invalid SSL data'
,
Errno
::
ECONNREFUSED
=>
'Connection refused'
,
StandardError
=>
'Sentry request failed due to StandardError'
}
exceptions
.
each
do
|
exception
,
message
|
context
"
#{
exception
}
"
do
before
do
stub_request
(
:get
,
sentry_request_url
).
to_raise
(
exception
)
end
it
do
expect
{
subject
}
.
to
raise_exception
(
Sentry
::
Client
::
Error
,
message
)
end
end
end
end
describe
'#list_projects'
do
let
(
:sentry_list_projects_url
)
{
'https://sentrytest.gitlab.com/api/0/projects/'
}
let
(
:sentry_api_response
)
{
projects_sample_response
}
let!
(
:sentry_api_request
)
{
stub_sentry_request
(
sentry_list_projects_url
,
body:
sentry_api_response
)
}
subject
{
client
.
list_projects
}
it_behaves_like
'calls sentry api'
it_behaves_like
'has correct return type'
,
Gitlab
::
ErrorTracking
::
Project
it_behaves_like
'has correct length'
,
2
context
'essential keys missing in API response'
do
let
(
:sentry_api_response
)
do
projects_sample_response
[
0
...
1
].
map
do
|
project
|
project
.
except
(
:slug
)
end
end
it
'raises exception'
do
expect
{
subject
}.
to
raise_error
(
Sentry
::
Client
::
MissingKeysError
,
'Sentry API response is missing keys. key not found: "slug"'
)
end
end
context
'optional keys missing in sentry response'
do
let
(
:sentry_api_response
)
do
projects_sample_response
[
0
...
1
].
map
do
|
project
|
project
[
:organization
].
delete
(
:id
)
project
.
delete
(
:id
)
project
.
except
(
:status
)
end
end
it_behaves_like
'calls sentry api'
it_behaves_like
'has correct return type'
,
Gitlab
::
ErrorTracking
::
Project
it_behaves_like
'has correct length'
,
1
end
context
'error object created from sentry response'
do
using
RSpec
::
Parameterized
::
TableSyntax
where
(
:sentry_project_object
,
:sentry_response
)
do
:id
|
:id
:name
|
:name
:status
|
:status
:slug
|
:slug
:organization_name
|
[
:organization
,
:name
]
:organization_id
|
[
:organization
,
:id
]
:organization_slug
|
[
:organization
,
:slug
]
end
with_them
do
it
do
expect
(
subject
[
0
].
public_send
(
sentry_project_object
)).
to
(
eq
(
sentry_api_response
[
0
].
dig
(
*
sentry_response
))
)
end
end
end
context
'redirects'
do
let
(
:sentry_api_url
)
{
sentry_list_projects_url
}
it_behaves_like
'no redirects'
end
# Sentry API returns 404 if there are extra slashes in the URL!
context
'extra slashes in URL'
do
let
(
:sentry_url
)
{
'https://sentrytest.gitlab.com/api//0/projects//'
}
let!
(
:valid_req_stub
)
do
stub_sentry_request
(
sentry_list_projects_url
)
end
it
'removes extra slashes in api url'
do
expect
(
Gitlab
::
HTTP
).
to
receive
(
:get
).
with
(
URI
(
sentry_list_projects_url
),
anything
).
and_call_original
subject
expect
(
valid_req_stub
).
to
have_been_requested
end
end
context
'when exception is raised'
do
let
(
:sentry_request_url
)
{
sentry_list_projects_url
}
it_behaves_like
'maps exceptions'
end
end
private
def
stub_sentry_request
(
url
,
body:
{},
status:
200
,
headers:
{})
stub_request
(
:get
,
url
)
.
to_return
(
status:
status
,
headers:
{
'Content-Type'
=>
'application/json'
}.
merge
(
headers
),
body:
body
.
to_json
)
end
end
spec/lib/sentry/client_spec.rb
View file @
2e46fff2
...
@@ -18,12 +18,6 @@ describe Sentry::Client do
...
@@ -18,12 +18,6 @@ describe Sentry::Client do
)
)
end
end
let
(
:projects_sample_response
)
do
Gitlab
::
Utils
.
deep_indifferent_access
(
JSON
.
parse
(
fixture_file
(
'sentry/list_projects_sample_response.json'
))
)
end
subject
(
:client
)
{
described_class
.
new
(
sentry_url
,
token
)
}
subject
(
:client
)
{
described_class
.
new
(
sentry_url
,
token
)
}
# Requires sentry_api_url and subject to be defined
# Requires sentry_api_url and subject to be defined
...
@@ -48,22 +42,12 @@ describe Sentry::Client do
...
@@ -48,22 +42,12 @@ describe Sentry::Client do
end
end
end
end
shared_examples
'has correct return type'
do
|
klass
|
it
"returns objects of type
#{
klass
}
"
do
expect
(
subject
).
to
all
(
be_a
(
klass
)
)
end
end
shared_examples
'issues has correct return type'
do
|
klass
|
shared_examples
'issues has correct return type'
do
|
klass
|
it
"returns objects of type
#{
klass
}
"
do
it
"returns objects of type
#{
klass
}
"
do
expect
(
subject
[
:issues
]).
to
all
(
be_a
(
klass
)
)
expect
(
subject
[
:issues
]).
to
all
(
be_a
(
klass
)
)
end
end
end
end
shared_examples
'has correct length'
do
|
length
|
it
{
expect
(
subject
.
length
).
to
eq
(
length
)
}
end
shared_examples
'issues has correct length'
do
|
length
|
shared_examples
'issues has correct length'
do
|
length
|
it
{
expect
(
subject
[
:issues
].
length
).
to
eq
(
length
)
}
it
{
expect
(
subject
[
:issues
].
length
).
to
eq
(
length
)
}
end
end
...
@@ -288,103 +272,6 @@ describe Sentry::Client do
...
@@ -288,103 +272,6 @@ describe Sentry::Client do
end
end
end
end
describe
'#list_projects'
do
let
(
:sentry_list_projects_url
)
{
'https://sentrytest.gitlab.com/api/0/projects/'
}
let
(
:sentry_api_response
)
{
projects_sample_response
}
let!
(
:sentry_api_request
)
{
stub_sentry_request
(
sentry_list_projects_url
,
body:
sentry_api_response
)
}
subject
{
client
.
list_projects
}
it_behaves_like
'calls sentry api'
it_behaves_like
'has correct return type'
,
Gitlab
::
ErrorTracking
::
Project
it_behaves_like
'has correct length'
,
2
context
'essential keys missing in API response'
do
let
(
:sentry_api_response
)
do
projects_sample_response
[
0
...
1
].
map
do
|
project
|
project
.
except
(
:slug
)
end
end
it
'raises exception'
do
expect
{
subject
}.
to
raise_error
(
Sentry
::
Client
::
MissingKeysError
,
'Sentry API response is missing keys. key not found: "slug"'
)
end
end
context
'optional keys missing in sentry response'
do
let
(
:sentry_api_response
)
do
projects_sample_response
[
0
...
1
].
map
do
|
project
|
project
[
:organization
].
delete
(
:id
)
project
.
delete
(
:id
)
project
.
except
(
:status
)
end
end
it_behaves_like
'calls sentry api'
it_behaves_like
'has correct return type'
,
Gitlab
::
ErrorTracking
::
Project
it_behaves_like
'has correct length'
,
1
end
context
'error object created from sentry response'
do
using
RSpec
::
Parameterized
::
TableSyntax
where
(
:sentry_project_object
,
:sentry_response
)
do
:id
|
:id
:name
|
:name
:status
|
:status
:slug
|
:slug
:organization_name
|
[
:organization
,
:name
]
:organization_id
|
[
:organization
,
:id
]
:organization_slug
|
[
:organization
,
:slug
]
end
with_them
do
it
do
expect
(
subject
[
0
].
public_send
(
sentry_project_object
)).
to
(
eq
(
sentry_api_response
[
0
].
dig
(
*
sentry_response
))
)
end
end
end
context
'redirects'
do
let
(
:sentry_api_url
)
{
sentry_list_projects_url
}
it_behaves_like
'no redirects'
end
# Sentry API returns 404 if there are extra slashes in the URL!
context
'extra slashes in URL'
do
let
(
:sentry_url
)
{
'https://sentrytest.gitlab.com/api//0/projects//'
}
let
(
:client
)
{
described_class
.
new
(
sentry_url
,
token
)
}
let!
(
:valid_req_stub
)
do
stub_sentry_request
(
sentry_list_projects_url
)
end
it
'removes extra slashes in api url'
do
expect
(
Gitlab
::
HTTP
).
to
receive
(
:get
).
with
(
URI
(
sentry_list_projects_url
),
anything
).
and_call_original
subject
expect
(
valid_req_stub
).
to
have_been_requested
end
end
context
'when exception is raised'
do
let
(
:sentry_request_url
)
{
sentry_list_projects_url
}
it_behaves_like
'maps exceptions'
end
end
private
private
def
stub_sentry_request
(
url
,
body:
{},
status:
200
,
headers:
{})
def
stub_sentry_request
(
url
,
body:
{},
status:
200
,
headers:
{})
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment