bugsnag-api 2.0.1 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +5 -5
- data/.buildkite/pipeline.yml +6 -0
- data/.github/ISSUE_TEMPLATE/A.md +14 -0
- data/.github/ISSUE_TEMPLATE/bug_report.md +47 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +24 -0
- data/.github/PULL_REQUEST_TEMPLATE.md +16 -0
- data/.github/support.md +19 -0
- data/.github/workflows/tests.yml +53 -0
- data/.rubocop.yml +4 -0
- data/.rubocop_todo.yml +271 -0
- data/CHANGELOG.md +34 -0
- data/CONTRIBUTING.md +1 -1
- data/Gemfile +9 -0
- data/README.md +77 -2
- data/bugsnag-api.gemspec +48 -6
- data/config/.gitignore +1 -0
- data/docker-compose.yml +9 -0
- data/dockerfiles/Dockerfile.audit +5 -0
- data/lib/bugsnag/api/client/collaborators.rb +1 -2
- data/lib/bugsnag/api/client/comments.rb +1 -1
- data/lib/bugsnag/api/client/currentuser.rb +0 -1
- data/lib/bugsnag/api/client/errors.rb +12 -11
- data/lib/bugsnag/api/client/eventfields.rb +1 -2
- data/lib/bugsnag/api/client/events.rb +1 -2
- data/lib/bugsnag/api/client/organizations.rb +1 -2
- data/lib/bugsnag/api/client/pivots.rb +1 -2
- data/lib/bugsnag/api/client/projects.rb +2 -3
- data/lib/bugsnag/api/client/releases.rb +38 -0
- data/lib/bugsnag/api/client/stability.rb +16 -0
- data/lib/bugsnag/api/client/trends.rb +8 -5
- data/lib/bugsnag/api/client.rb +23 -3
- data/lib/bugsnag/api/configuration.rb +1 -1
- data/lib/bugsnag/api/error.rb +1 -1
- data/lib/bugsnag/api/response/raise_error.rb +0 -2
- data/lib/bugsnag/api/version.rb +1 -1
- data/scripts/license_finder.sh +4 -0
- data/spec/bugsnag/api/client/releases_spec.rb +184 -0
- data/spec/bugsnag/api/client/stability_spec.rb +32 -0
- data/spec/bugsnag/api/client_spec.rb +69 -7
- data/spec/bugsnag/api_spec.rb +2 -0
- data/spec/cassettes/Bugsnag_Api_Client/_get/handles_query_params.yml +13 -21
- data/spec/cassettes/Bugsnag_Api_Client/_last_response/caches_the_last_agent_response.yml +13 -21
- data/spec/cassettes/Bugsnag_Api_Client_Collaborators/_invitecollaborator/creates_and_returns_a_collaborator.yml +14 -26
- data/spec/cassettes/Bugsnag_Api_Client_Collaborators/_invitecollaborator/invites_multiple_collaborators.yml +14 -26
- data/spec/cassettes/Bugsnag_Api_Client_Collaborators/given_a_collaborator_exists/_collaborator/returns_a_collaborator.yml +29 -53
- data/spec/cassettes/Bugsnag_Api_Client_Collaborators/given_a_collaborator_exists/_collaborators/returns_a_list_of_all_organization_collaborators.yml +30 -55
- data/spec/cassettes/Bugsnag_Api_Client_Collaborators/given_a_collaborator_exists/_collaborators/returns_a_list_of_all_project_collaborators.yml +30 -55
- data/spec/cassettes/Bugsnag_Api_Client_Collaborators/given_a_collaborator_exists/_collaborators/throws_an_argument_error_if_neither_org_id_or_project_id_are_provided.yml +14 -26
- data/spec/cassettes/Bugsnag_Api_Client_Collaborators/given_a_collaborator_exists/_delete_collaborator/deletes_a_collaborator.yml +14 -26
- data/spec/cassettes/Bugsnag_Api_Client_Collaborators/given_a_collaborator_exists/_update_collaborator_permissions/updates_and_returns_the_collaborator.yml +29 -53
- data/spec/cassettes/Bugsnag_Api_Client_Collaborators/given_a_collaborator_exists/_view_collaborator_projects/returns_a_list_of_projects_belonging_to_the_collaborator.yml +49 -55
- data/spec/cassettes/Bugsnag_Api_Client_Comments/_create_comment/creates_a_comment_on_the_error.yml +17 -29
- data/spec/cassettes/Bugsnag_Api_Client_Comments/given_a_comment_has_been_created/_comment/retrieves_the_comment_specified.yml +32 -56
- data/spec/cassettes/Bugsnag_Api_Client_Comments/given_a_comment_has_been_created/_comments/retrieves_all_comments_on_an_error.yml +33 -57
- data/spec/cassettes/Bugsnag_Api_Client_Comments/given_a_comment_has_been_created/_delete_comment/deletes_the_comment_and_returns_true.yml +17 -29
- data/spec/cassettes/Bugsnag_Api_Client_Comments/given_a_comment_has_been_created/_update_comment/updates_the_message_on_a_comment.yml +32 -56
- data/spec/cassettes/Bugsnag_Api_Client_CurrentUser/_list_organizations/when_using_auth_token/returns_the_organization_the_auth_token_belongs_to.yml +14 -27
- data/spec/cassettes/Bugsnag_Api_Client_CurrentUser/_list_organizations/when_using_user_credentials/returns_users_organizations.yml +17 -31
- data/spec/cassettes/Bugsnag_Api_Client_CurrentUser/_list_projects/when_using_auth_token/lists_current_user_s_projects_in_the_organization.yml +34 -28
- data/spec/cassettes/Bugsnag_Api_Client_CurrentUser/_list_projects/when_using_user_credentials/lists_current_user_s_projects_in_the_organization.yml +37 -32
- data/spec/cassettes/Bugsnag_Api_Client_Errors/_error/returns_a_single_error.yml +14 -28
- data/spec/cassettes/Bugsnag_Api_Client_Errors/_errors/returns_errors_on_the_project.yml +16 -30
- data/spec/cassettes/Bugsnag_Api_Client_Errors/_update_errors/updates_and_returns_the_updated_errors.yml +13 -25
- data/spec/cassettes/Bugsnag_Api_Client_Events/_error_events/lists_all_error_events.yml +19 -30
- data/spec/cassettes/Bugsnag_Api_Client_Events/_event/returns_the_specified_event.yml +16 -199
- data/spec/cassettes/Bugsnag_Api_Client_Events/_events/returns_the_a_list_of_project_errors.yml +19 -30
- data/spec/cassettes/Bugsnag_Api_Client_Events/_latest_event/returns_the_last_event_on_an_error.yml +16 -199
- data/spec/cassettes/Bugsnag_Api_Client_Organizations/_create_organization/creates_a_new_organization.yml +17 -30
- data/spec/cassettes/Bugsnag_Api_Client_Organizations/with_organization/_delete_organization/deletes_the_organization.yml +32 -58
- data/spec/cassettes/Bugsnag_Api_Client_Organizations/with_organization/_organization/returns_the_requested_organization.yml +35 -61
- data/spec/cassettes/Bugsnag_Api_Client_Organizations/with_organization/_update_organization/updates_and_returns_the_organization.yml +35 -61
- data/spec/cassettes/Bugsnag_Api_Client_Projects/_create_project/creates_a_new_project.yml +14 -26
- data/spec/cassettes/Bugsnag_Api_Client_Projects/given_a_project/_delete_project/deletes_the_project.yml +26 -50
- data/spec/cassettes/Bugsnag_Api_Client_Projects/given_a_project/_project/returns_the_requested_project.yml +29 -53
- data/spec/cassettes/Bugsnag_Api_Client_Projects/given_a_project/_regenerate_api_key/removes_the_current_api_key_and_replaces_it_with_a_new_api_key.yml +29 -53
- data/spec/cassettes/Bugsnag_Api_Client_Projects/given_a_project/_update_project/updates_and_returns_the_project.yml +29 -53
- data/spec/cassettes/Bugsnag_Api_Client_Releases/_release/gets_a_single_release.yml +87 -0
- data/spec/cassettes/Bugsnag_Api_Client_Releases/_release_groups/accepts_parameters.yml +90 -0
- data/spec/cassettes/Bugsnag_Api_Client_Releases/_release_groups/gets_releases_in_a_release_group.yml +87 -0
- data/spec/cassettes/Bugsnag_Api_Client_Releases/_releases/accepts_parameters.yml +92 -0
- data/spec/cassettes/Bugsnag_Api_Client_Releases/_releases/gets_as_list_of_releases.yml +91 -0
- data/spec/cassettes/Bugsnag_Api_Client_Stability/_stability_trend/gets_the_stability_trend.yml +87 -0
- data/spec/cassettes/Bugsnag_Api_Client_Trends/_trends_buckets/returns_a_list_of_error_trends_in_bucket_form.yml +14 -26
- data/spec/cassettes/Bugsnag_Api_Client_Trends/_trends_buckets/returns_a_list_of_project_trends_in_bucket_form.yml +14 -26
- data/spec/cassettes/Bugsnag_Api_Client_Trends/_trends_resolution/returns_a_list_of_project_trends_in_resolution_form.yml +14 -26
- data/spec/cassettes/Bugsnag_Api_Client_Trends/_trends_resolution/returns_a_list_of_trends_in_resolution_form.yml +14 -26
- data/spec/spec_helper.rb +35 -7
- metadata +67 -24
- data/.travis.yml +0 -17
data/bugsnag-api.gemspec
CHANGED
|
@@ -18,13 +18,55 @@ Gem::Specification.new do |spec|
|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
|
19
19
|
spec.require_paths = ["lib"]
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
if RUBY_VERSION < "2.2.0"
|
|
22
|
+
spec.add_dependency "sawyer", '0.8.1'
|
|
23
|
+
|
|
24
|
+
spec.add_development_dependency "rake", "< 12.0.0"
|
|
25
|
+
spec.add_development_dependency "rubocop", "0.41.2"
|
|
26
|
+
spec.add_development_dependency "faker", "1.3.0"
|
|
27
|
+
|
|
28
|
+
# i18n is used by faker
|
|
29
|
+
spec.add_development_dependency "i18n", "< 1.0.0"
|
|
30
|
+
|
|
31
|
+
# crack is used by webmock
|
|
32
|
+
spec.add_development_dependency "crack", "< 0.4.5"
|
|
33
|
+
else
|
|
34
|
+
spec.add_dependency "sawyer", '~> 0.8.1'
|
|
35
|
+
|
|
36
|
+
spec.add_development_dependency "rake"
|
|
37
|
+
spec.add_development_dependency "rubocop", "~> 0.52.1"
|
|
38
|
+
spec.add_development_dependency "faker", "> 1.7.3"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
if RUBY_VERSION < "2.0.0"
|
|
42
|
+
spec.add_development_dependency "webmock", "2.3.2"
|
|
43
|
+
spec.add_development_dependency "addressable", "2.3.6"
|
|
44
|
+
|
|
45
|
+
# hashdiff is used by webmock
|
|
46
|
+
spec.add_development_dependency "hashdiff", "< 0.3.8"
|
|
47
|
+
|
|
48
|
+
# parser is used by rubocop
|
|
49
|
+
spec.add_development_dependency "parser", "< 2.5.0"
|
|
50
|
+
else
|
|
51
|
+
spec.add_development_dependency "webmock", "> 2.3.2"
|
|
52
|
+
spec.add_development_dependency "addressable", "> 2.3.6"
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
if RUBY_VERSION < "2.0.0"
|
|
56
|
+
spec.add_development_dependency "json", "< 2.0.0"
|
|
57
|
+
elsif RUBY_VERSION < "2.3.0"
|
|
58
|
+
spec.add_development_dependency "json", "< 2.6.0"
|
|
59
|
+
else
|
|
60
|
+
spec.add_development_dependency "json"
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# public_suffix is used by addressable & sawyer
|
|
64
|
+
if RUBY_VERSION < "2.0.0"
|
|
65
|
+
spec.add_development_dependency "public_suffix", "< 1.5.0"
|
|
66
|
+
elsif RUBY_VERSION < "2.1.0"
|
|
67
|
+
spec.add_development_dependency "public_suffix", "< 3.0.0"
|
|
68
|
+
end
|
|
22
69
|
|
|
23
|
-
spec.add_development_dependency "rake"
|
|
24
70
|
spec.add_development_dependency "rspec", "~> 3.0"
|
|
25
|
-
spec.add_development_dependency "webmock", RUBY_VERSION <= '2.0.0' ? '2.3.2': '>2.3.2'
|
|
26
|
-
spec.add_development_dependency "addressable", RUBY_VERSION <= '2.0.0' ? '2.3.6': '>2.3.6'
|
|
27
|
-
spec.add_development_dependency "faker", RUBY_VERSION <= '2.0.0' ? '1.3.0' : '>1.7.3'
|
|
28
71
|
spec.add_development_dependency "vcr", "~> 2.9"
|
|
29
|
-
spec.add_development_dependency "json"
|
|
30
72
|
end
|
data/config/.gitignore
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
global.yml
|
data/docker-compose.yml
ADDED
|
@@ -19,7 +19,7 @@ module Bugsnag
|
|
|
19
19
|
# @argument project_id [String] ID of project to get collaborators from (conflicts with org_id)
|
|
20
20
|
# @argument org_id [String] ID of organization to get collaborators from (conflicts with project_id)
|
|
21
21
|
#
|
|
22
|
-
# @option per_page [Number] Amount of results per-page
|
|
22
|
+
# @option per_page [Number] Amount of results per-page
|
|
23
23
|
# @return [Array<Sawyer::Resource>] List of Collaborators
|
|
24
24
|
# @see http://docs.bugsnagapiv2.apiary.io/#reference/organizations/collaborators/list-collaborators
|
|
25
25
|
# @see http://docs.bugsnagapiv2.apiary.io/#reference/organizations/collaborators/list-collaborators-on-a-project
|
|
@@ -84,4 +84,3 @@ module Bugsnag
|
|
|
84
84
|
end
|
|
85
85
|
end
|
|
86
86
|
end
|
|
87
|
-
|
|
@@ -8,6 +8,8 @@ module Bugsnag
|
|
|
8
8
|
module Errors
|
|
9
9
|
# List the Errors on a Project
|
|
10
10
|
#
|
|
11
|
+
# @argument id [String] optional ID of error to retrieve
|
|
12
|
+
#
|
|
11
13
|
# @option base [String] Only Error Events occuring before this time will be returned
|
|
12
14
|
# @option sort [String] Which field to sort by, one of: last_seen, first_seen, users, events, unsorted
|
|
13
15
|
# @option direction [String] Which direction to sort the result by, one of: asc, desc
|
|
@@ -15,16 +17,14 @@ module Bugsnag
|
|
|
15
17
|
# @return [Array<Sawyer::Resource>] List of Project Errors
|
|
16
18
|
# @see http://docs.bugsnagapiv2.apiary.io/#reference/errors/errors/list-the-errors-on-a-project
|
|
17
19
|
def errors(project_id, id=nil, options = {})
|
|
18
|
-
|
|
20
|
+
if id.nil?
|
|
21
|
+
paginate "projects/#{project_id}/errors", options
|
|
22
|
+
else
|
|
23
|
+
get "projects/#{project_id}/errors/#{id}", options
|
|
24
|
+
end
|
|
19
25
|
end
|
|
20
26
|
|
|
21
|
-
|
|
22
|
-
#
|
|
23
|
-
# @return [Sawyer::Resource] Requested Error
|
|
24
|
-
# @see http://docs.bugsnagapiv2.apiary.io/#reference/errors/errors/view-an-error
|
|
25
|
-
def error(project_id, id, options = {})
|
|
26
|
-
get "projects/#{project_id}/errors/#{id}", options
|
|
27
|
-
end
|
|
27
|
+
alias error errors
|
|
28
28
|
|
|
29
29
|
# Update an Error
|
|
30
30
|
#
|
|
@@ -42,7 +42,9 @@ module Bugsnag
|
|
|
42
42
|
when String
|
|
43
43
|
patch "projects/#{project_id}/errors/#{ids}", options.merge({:operation => operation})
|
|
44
44
|
when Array
|
|
45
|
-
|
|
45
|
+
defaults = {:operation => operation, :query => {:error_ids => ids.join(' ')}}
|
|
46
|
+
merged_opts = deep_merge(defaults, options)
|
|
47
|
+
patch "projects/#{project_id}/errors", merged_opts
|
|
46
48
|
else
|
|
47
49
|
raise ArgumentError, "ids must be a String or an Array"
|
|
48
50
|
end
|
|
@@ -53,7 +55,7 @@ module Bugsnag
|
|
|
53
55
|
# @argument error_id [String] ID of error to delete (conflicts with project_id)
|
|
54
56
|
# @argument project_id [String] Id of project to delete all errors from (conflicts with error_id)
|
|
55
57
|
#
|
|
56
|
-
# @return
|
|
58
|
+
# @return
|
|
57
59
|
# @see http://docs.bugsnagapiv2.apiary.io/#reference/errors/errors/delete-an-error
|
|
58
60
|
def delete_errors(project_id, error_id=nil, options = {})
|
|
59
61
|
if !error_id.nil?
|
|
@@ -66,4 +68,3 @@ module Bugsnag
|
|
|
66
68
|
end
|
|
67
69
|
end
|
|
68
70
|
end
|
|
69
|
-
|
|
@@ -38,7 +38,7 @@ module Bugsnag
|
|
|
38
38
|
|
|
39
39
|
# Delete a custom Event Field
|
|
40
40
|
#
|
|
41
|
-
# @return
|
|
41
|
+
# @return
|
|
42
42
|
# @see http://docs.bugsnagapiv2.apiary.io/#reference/projects/event-fields/delete-a-custom-event-field
|
|
43
43
|
def delete_event_field(project_id, display_id, options = {})
|
|
44
44
|
boolean_from_resposne :delete, "project/#{project_id}/event_fields/#{display_id}", options
|
|
@@ -47,4 +47,3 @@ module Bugsnag
|
|
|
47
47
|
end
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
|
-
|
|
@@ -16,7 +16,7 @@ module Bugsnag
|
|
|
16
16
|
|
|
17
17
|
# Delete an Event
|
|
18
18
|
#
|
|
19
|
-
# @return
|
|
19
|
+
# @return
|
|
20
20
|
# @see http://docs.bugsnagapiv2.apiary.io/#reference/errors/events/delete-an-event
|
|
21
21
|
def delete_event(project_id, id, options = {})
|
|
22
22
|
boolean_from_response :delete, "projects/#{project_id}/events/#{id}", options
|
|
@@ -57,4 +57,3 @@ module Bugsnag
|
|
|
57
57
|
end
|
|
58
58
|
end
|
|
59
59
|
end
|
|
60
|
-
|
|
@@ -34,7 +34,7 @@ module Bugsnag
|
|
|
34
34
|
|
|
35
35
|
# Delete an Organization
|
|
36
36
|
#
|
|
37
|
-
# @return
|
|
37
|
+
# @return
|
|
38
38
|
# @see http://docs.bugsnagapiv2.apiary.io/#reference/organizations/organizations/delete-an-organization
|
|
39
39
|
def delete_organization(id, options = {})
|
|
40
40
|
boolean_from_response :delete, "organizations/#{id}", options
|
|
@@ -43,4 +43,3 @@ module Bugsnag
|
|
|
43
43
|
end
|
|
44
44
|
end
|
|
45
45
|
end
|
|
46
|
-
|
|
@@ -26,7 +26,7 @@ module Bugsnag
|
|
|
26
26
|
#
|
|
27
27
|
# @option filters [Object] An optional filter object, see http://docs.bugsnagapiv2.apiary.io/#introduction/filtering
|
|
28
28
|
# @option sort [String] Sorting method
|
|
29
|
-
# @option base [String] Only Events occuring before this time will be used
|
|
29
|
+
# @option base [String] Only Events occuring before this time will be used
|
|
30
30
|
# @return [Array<Sawyer::Resource>] List of values for the Pivots requested
|
|
31
31
|
# @see http://docs.bugsnagapiv2.apiary.io/#reference/errors/pivots/list-values-of-a-pivot-on-an-error
|
|
32
32
|
def pivot_values(project_id, ef_display_id, error_id=nil, options = {})
|
|
@@ -40,4 +40,3 @@ module Bugsnag
|
|
|
40
40
|
end
|
|
41
41
|
end
|
|
42
42
|
end
|
|
43
|
-
|
|
@@ -42,7 +42,7 @@ module Bugsnag
|
|
|
42
42
|
|
|
43
43
|
# Regenerate a Project's notifier API key
|
|
44
44
|
#
|
|
45
|
-
# @return
|
|
45
|
+
# @return
|
|
46
46
|
# @see http://docs.bugsnagapiv2.apiary.io/#reference/projects/projects/regenerate-a-project's-notifier-api-key
|
|
47
47
|
def regenerate_api_key(id, options = {})
|
|
48
48
|
delete "projects/#{id}/api_key", options
|
|
@@ -50,7 +50,7 @@ module Bugsnag
|
|
|
50
50
|
|
|
51
51
|
# Delete a Project
|
|
52
52
|
#
|
|
53
|
-
# @return
|
|
53
|
+
# @return
|
|
54
54
|
# @see http://docs.bugsnagapiv2.apiary.io/#reference/organizations/organizations/delete-an-organization
|
|
55
55
|
def delete_project(id, options = {})
|
|
56
56
|
boolean_from_response :delete, "projects/#{id}", options
|
|
@@ -59,4 +59,3 @@ module Bugsnag
|
|
|
59
59
|
end
|
|
60
60
|
end
|
|
61
61
|
end
|
|
62
|
-
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
module Bugsnag
|
|
2
|
+
module Api
|
|
3
|
+
class Client
|
|
4
|
+
# Methods for the Releases API
|
|
5
|
+
module Releases
|
|
6
|
+
# List the Releases in a Project
|
|
7
|
+
#
|
|
8
|
+
# @option release_stage [String] Only Releases with this release stage will be returned
|
|
9
|
+
# @option base [String] Only Releases created before this time will be returned
|
|
10
|
+
# @option sort [String] How to sort the results, one of: timestamp, percent_of_sessions
|
|
11
|
+
# @option offset [Number] The pagination offset
|
|
12
|
+
# @option per_page [Number] The number of results to return per page
|
|
13
|
+
# @return [Array<Sawyer::Resource>] List of Events for the specified Error
|
|
14
|
+
# @see https://bugsnagapiv2.docs.apiary.io/#reference/projects/releases/list-releases-on-a-project
|
|
15
|
+
def releases(project_id, options = {})
|
|
16
|
+
get "projects/#{project_id}/releases", options
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# View a single Release
|
|
20
|
+
#
|
|
21
|
+
# @see https://bugsnagapiv2.docs.apiary.io/#reference/projects/releases/view-a-release
|
|
22
|
+
def release(project_id, release_id, options = {})
|
|
23
|
+
get "projects/#{project_id}/releases/#{release_id}", options
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# List the Releases in a Release Group
|
|
27
|
+
#
|
|
28
|
+
# @option per_page [Number] The number of results to return per page
|
|
29
|
+
# @option page_token [String] Value from the next relation in the Link response header to obtain the next page of results
|
|
30
|
+
# @return [Array<Sawyer::Resource>] List of Releases for the specified Release Group
|
|
31
|
+
# @see https://bugsnagapiv2.docs.apiary.io/#reference/projects/releases/list-releases-on-a-release-group
|
|
32
|
+
def releases_in_group(release_group_id, options = {})
|
|
33
|
+
get "release_groups/#{release_group_id}/releases", options
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
module Bugsnag
|
|
2
|
+
module Api
|
|
3
|
+
class Client
|
|
4
|
+
# Methods for the Stability API
|
|
5
|
+
module Stability
|
|
6
|
+
# View the stability trend for a project
|
|
7
|
+
#
|
|
8
|
+
# @return [Sawyer::Resource] Stability trend
|
|
9
|
+
# @see https://bugsnagapiv2.docs.apiary.io/#reference/projects/stability-trend/view-the-stability-trend-for-a-project
|
|
10
|
+
def stability_trend(id, options = {})
|
|
11
|
+
get "projects/#{id}/stability_trend", options
|
|
12
|
+
end
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -12,10 +12,12 @@ module Bugsnag
|
|
|
12
12
|
# @return [Array<Sawyer::Resource>] List of Trends as requested
|
|
13
13
|
# @see http://docs.bugsnagapiv2.apiary.io/#reference/errors/trends/list-the-trends-for-an-error-(buckets)
|
|
14
14
|
def trends_buckets(project_id, buckets_count, error_id=nil, options = {})
|
|
15
|
+
defaults = {:query => {:buckets_count => buckets_count}}
|
|
16
|
+
merged_opts = deep_merge(defaults, options)
|
|
15
17
|
if !error_id.nil?
|
|
16
|
-
get "projects/#{project_id}/errors/#{error_id}/trend",
|
|
18
|
+
get "projects/#{project_id}/errors/#{error_id}/trend", merged_opts
|
|
17
19
|
else
|
|
18
|
-
get "projects/#{project_id}/trend",
|
|
20
|
+
get "projects/#{project_id}/trend", merged_opts
|
|
19
21
|
end
|
|
20
22
|
end
|
|
21
23
|
|
|
@@ -25,14 +27,15 @@ module Bugsnag
|
|
|
25
27
|
# @return [Array<Sawyer::Resource>] List of Trends as requested
|
|
26
28
|
# @see http://docs.bugsnagapiv2.apiary.io/#reference/errors/trends/list-the-trends-for-an-error-(buckets)
|
|
27
29
|
def trends_resolution(project_id, resolution, error_id=nil, options = {})
|
|
30
|
+
defaults = {:query => {:resolution => resolution}}
|
|
31
|
+
merged_opts = deep_merge(defaults, options)
|
|
28
32
|
if !error_id.nil?
|
|
29
|
-
get "projects/#{project_id}/errors/#{error_id}/trend",
|
|
33
|
+
get "projects/#{project_id}/errors/#{error_id}/trend", merged_opts
|
|
30
34
|
else
|
|
31
|
-
get "projects/#{project_id}/trend",
|
|
35
|
+
get "projects/#{project_id}/trend", merged_opts
|
|
32
36
|
end
|
|
33
37
|
end
|
|
34
38
|
end
|
|
35
39
|
end
|
|
36
40
|
end
|
|
37
41
|
end
|
|
38
|
-
|
data/lib/bugsnag/api/client.rb
CHANGED
|
@@ -10,6 +10,10 @@ require "bugsnag/api/client/events"
|
|
|
10
10
|
require "bugsnag/api/client/pivots"
|
|
11
11
|
require "bugsnag/api/client/trends"
|
|
12
12
|
require "bugsnag/api/client/comments"
|
|
13
|
+
require "bugsnag/api/client/stability"
|
|
14
|
+
require "bugsnag/api/client/releases"
|
|
15
|
+
|
|
16
|
+
require "base64"
|
|
13
17
|
|
|
14
18
|
module Bugsnag
|
|
15
19
|
module Api
|
|
@@ -28,6 +32,8 @@ module Bugsnag
|
|
|
28
32
|
include Bugsnag::Api::Client::Pivots
|
|
29
33
|
include Bugsnag::Api::Client::Trends
|
|
30
34
|
include Bugsnag::Api::Client::Comments
|
|
35
|
+
include Bugsnag::Api::Client::Stability
|
|
36
|
+
include Bugsnag::Api::Client::Releases
|
|
31
37
|
|
|
32
38
|
# Header keys that can be passed in options hash to {#get},{#head}
|
|
33
39
|
CONVENIENCE_HEADERS = Set.new([:accept, :content_type])
|
|
@@ -143,6 +149,18 @@ module Bugsnag
|
|
|
143
149
|
!!configuration.auth_token
|
|
144
150
|
end
|
|
145
151
|
|
|
152
|
+
# Merges hashes together cleanly, favouring RHS values
|
|
153
|
+
#
|
|
154
|
+
# @return [Hash]
|
|
155
|
+
def deep_merge(l_hash, r_hash)
|
|
156
|
+
l_hash.merge(r_hash) do |_key, l_val, r_val|
|
|
157
|
+
if l_val.is_a?(Hash) && r_val.is_a?(Hash)
|
|
158
|
+
deep_merge(l_val, r_val)
|
|
159
|
+
else
|
|
160
|
+
r_val
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
146
164
|
|
|
147
165
|
private
|
|
148
166
|
def agent
|
|
@@ -153,9 +171,11 @@ module Bugsnag
|
|
|
153
171
|
http.headers[:user_agent] = configuration.user_agent
|
|
154
172
|
|
|
155
173
|
if basic_authenticated?
|
|
156
|
-
|
|
174
|
+
credentials = Base64.strict_encode64("#{configuration.email}:#{configuration.password}")
|
|
175
|
+
|
|
176
|
+
http.headers[:Authorization] = "Basic #{credentials}"
|
|
157
177
|
elsif token_authenticated?
|
|
158
|
-
http.
|
|
178
|
+
http.headers[:Authorization] = "token #{configuration.auth_token}"
|
|
159
179
|
end
|
|
160
180
|
end
|
|
161
181
|
end
|
|
@@ -173,7 +193,7 @@ module Bugsnag
|
|
|
173
193
|
end
|
|
174
194
|
end
|
|
175
195
|
|
|
176
|
-
@last_response = response = agent.call(method,
|
|
196
|
+
@last_response = response = agent.call(method, path.to_s, data, options)
|
|
177
197
|
response.data
|
|
178
198
|
end
|
|
179
199
|
|
|
@@ -45,7 +45,7 @@ module Bugsnag
|
|
|
45
45
|
|
|
46
46
|
# Load configuration from hash
|
|
47
47
|
def load(options = {})
|
|
48
|
-
options.each {|k,v| self.send("#{k}=", v) if self.respond_to?("#{k}=") && !v.nil?}
|
|
48
|
+
options.each { |k,v| self.send("#{k}=", v) if self.respond_to?("#{k}=") && !v.nil?}
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
51
|
end
|
data/lib/bugsnag/api/error.rb
CHANGED
|
@@ -3,7 +3,7 @@ module Bugsnag
|
|
|
3
3
|
# Custom error class for rescuing from all Bugsnag API errors
|
|
4
4
|
class Error < StandardError
|
|
5
5
|
|
|
6
|
-
# Returns the appropriate
|
|
6
|
+
# Returns the appropriate Bugsnag::Api::Error subclass based
|
|
7
7
|
# on status and response message
|
|
8
8
|
#
|
|
9
9
|
# @param [Hash] response HTTP response
|
|
@@ -9,8 +9,6 @@ module Bugsnag
|
|
|
9
9
|
# This class raises an Bugsnag-flavored exception based
|
|
10
10
|
# HTTP status codes returned by the API
|
|
11
11
|
class RaiseError < Faraday::Response::Middleware
|
|
12
|
-
|
|
13
|
-
private
|
|
14
12
|
def on_complete(response)
|
|
15
13
|
if error = Bugsnag::Api::Error.from_response(response)
|
|
16
14
|
raise error
|
data/lib/bugsnag/api/version.rb
CHANGED
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Bugsnag::Api::Client::Releases do
|
|
4
|
+
before do
|
|
5
|
+
@client = auth_token_client
|
|
6
|
+
@project_id = test_bugsnag_project_id
|
|
7
|
+
@release_id = test_bugsnag_release_id
|
|
8
|
+
@release_group_id = test_bugsnag_release_group_id
|
|
9
|
+
|
|
10
|
+
Bugsnag::Api.reset!
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe ".releases", :vcr do
|
|
14
|
+
it "gets as list of releases" do
|
|
15
|
+
releases = @client.releases(@project_id)
|
|
16
|
+
|
|
17
|
+
expect(releases).to be_an_instance_of(Array)
|
|
18
|
+
|
|
19
|
+
releases.map!(&:to_h)
|
|
20
|
+
|
|
21
|
+
expect(releases.first[:id]).to eq(@release_id)
|
|
22
|
+
expect(releases.first[:project_id]).to eq(@project_id)
|
|
23
|
+
expect(releases.first[:release_group_id]).to eq(@release_group_id)
|
|
24
|
+
|
|
25
|
+
expect(releases).to all have_key(:id)
|
|
26
|
+
expect(releases).to all have_key(:project_id)
|
|
27
|
+
expect(releases).to all have_key(:release_group_id)
|
|
28
|
+
expect(releases).to all have_key(:release_time)
|
|
29
|
+
expect(releases).to all have_key(:release_source)
|
|
30
|
+
expect(releases).to all have_key(:app_version)
|
|
31
|
+
expect(releases).to all have_key(:app_version_code)
|
|
32
|
+
expect(releases).to all have_key(:app_bundle_version)
|
|
33
|
+
expect(releases).to all have_key(:build_label)
|
|
34
|
+
expect(releases).to all have_key(:builder_name)
|
|
35
|
+
expect(releases).to all have_key(:build_tool)
|
|
36
|
+
expect(releases).to all have_key(:errors_introduced_count)
|
|
37
|
+
expect(releases).to all have_key(:errors_seen_count)
|
|
38
|
+
expect(releases).to all have_key(:sessions_count_in_last_24h)
|
|
39
|
+
expect(releases).to all have_key(:total_sessions_count)
|
|
40
|
+
expect(releases).to all have_key(:unhandled_sessions_count)
|
|
41
|
+
expect(releases).to all have_key(:accumulative_daily_users_seen)
|
|
42
|
+
expect(releases).to all have_key(:accumulative_daily_users_with_unhandled)
|
|
43
|
+
expect(releases).to all have_key(:metadata)
|
|
44
|
+
expect(releases).to all have_key(:release_stage)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
it "accepts parameters" do
|
|
48
|
+
releases = @client.releases(
|
|
49
|
+
@project_id,
|
|
50
|
+
{
|
|
51
|
+
release_stage: 'development',
|
|
52
|
+
base: '2021-07-21T12:00:00Z',
|
|
53
|
+
sort: 'percent_of_sessions',
|
|
54
|
+
offset: 0,
|
|
55
|
+
per_page: 1
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
|
|
59
|
+
expect(releases).to be_an_instance_of(Array)
|
|
60
|
+
|
|
61
|
+
releases.map!(&:to_h)
|
|
62
|
+
|
|
63
|
+
expect(releases.first[:id]).to eq(@release_id)
|
|
64
|
+
expect(releases.first[:project_id]).to eq(@project_id)
|
|
65
|
+
expect(releases.first[:release_group_id]).to eq(@release_group_id)
|
|
66
|
+
|
|
67
|
+
expect(releases).to all have_key(:id)
|
|
68
|
+
expect(releases).to all have_key(:project_id)
|
|
69
|
+
expect(releases).to all have_key(:release_group_id)
|
|
70
|
+
expect(releases).to all have_key(:release_time)
|
|
71
|
+
expect(releases).to all have_key(:release_source)
|
|
72
|
+
expect(releases).to all have_key(:app_version)
|
|
73
|
+
expect(releases).to all have_key(:app_version_code)
|
|
74
|
+
expect(releases).to all have_key(:app_bundle_version)
|
|
75
|
+
expect(releases).to all have_key(:build_label)
|
|
76
|
+
expect(releases).to all have_key(:builder_name)
|
|
77
|
+
expect(releases).to all have_key(:build_tool)
|
|
78
|
+
expect(releases).to all have_key(:errors_introduced_count)
|
|
79
|
+
expect(releases).to all have_key(:errors_seen_count)
|
|
80
|
+
expect(releases).to all have_key(:sessions_count_in_last_24h)
|
|
81
|
+
expect(releases).to all have_key(:total_sessions_count)
|
|
82
|
+
expect(releases).to all have_key(:unhandled_sessions_count)
|
|
83
|
+
expect(releases).to all have_key(:accumulative_daily_users_seen)
|
|
84
|
+
expect(releases).to all have_key(:accumulative_daily_users_with_unhandled)
|
|
85
|
+
expect(releases).to all have_key(:metadata)
|
|
86
|
+
expect(releases).to all have_key(:release_stage)
|
|
87
|
+
end
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
describe ".release", :vcr do
|
|
91
|
+
it "gets a single release" do
|
|
92
|
+
release = @client.release(@project_id, @release_id)
|
|
93
|
+
|
|
94
|
+
expect(release.id).to eq(@release_id)
|
|
95
|
+
expect(release.project_id).to eq(@project_id)
|
|
96
|
+
expect(release.release_group_id).to eq(@release_group_id)
|
|
97
|
+
expect(release.release_time).not_to be_nil
|
|
98
|
+
expect(release.release_source).not_to be_nil
|
|
99
|
+
expect(release.app_version).not_to be_nil
|
|
100
|
+
expect(release.app_version_code).not_to be_nil
|
|
101
|
+
expect(release.app_bundle_version).not_to be_nil
|
|
102
|
+
expect(release.build_label).not_to be_nil
|
|
103
|
+
expect(release.builder_name).not_to be_nil
|
|
104
|
+
expect(release.build_tool).not_to be_nil
|
|
105
|
+
expect(release.errors_introduced_count).not_to be_nil
|
|
106
|
+
expect(release.errors_seen_count).not_to be_nil
|
|
107
|
+
expect(release.sessions_count_in_last_24h).not_to be_nil
|
|
108
|
+
expect(release.total_sessions_count).not_to be_nil
|
|
109
|
+
expect(release.unhandled_sessions_count).not_to be_nil
|
|
110
|
+
expect(release.accumulative_daily_users_seen).not_to be_nil
|
|
111
|
+
expect(release.accumulative_daily_users_with_unhandled).not_to be_nil
|
|
112
|
+
expect(release.metadata).not_to be_nil
|
|
113
|
+
expect(release.release_stage).not_to be_nil
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
describe ".release_groups", :vcr do
|
|
118
|
+
it "gets releases in a release group" do
|
|
119
|
+
releases = @client.releases_in_group(@release_group_id)
|
|
120
|
+
|
|
121
|
+
expect(releases).to be_an_instance_of(Array)
|
|
122
|
+
|
|
123
|
+
releases.map!(&:to_h)
|
|
124
|
+
|
|
125
|
+
expect(releases.first[:id]).to eq(@release_id)
|
|
126
|
+
expect(releases.first[:project_id]).to eq(@project_id)
|
|
127
|
+
expect(releases.first[:release_group_id]).to eq(@release_group_id)
|
|
128
|
+
|
|
129
|
+
expect(releases).to all have_key(:id)
|
|
130
|
+
expect(releases).to all have_key(:project_id)
|
|
131
|
+
expect(releases).to all have_key(:release_group_id)
|
|
132
|
+
expect(releases).to all have_key(:release_time)
|
|
133
|
+
expect(releases).to all have_key(:release_source)
|
|
134
|
+
expect(releases).to all have_key(:app_version)
|
|
135
|
+
expect(releases).to all have_key(:app_version_code)
|
|
136
|
+
expect(releases).to all have_key(:app_bundle_version)
|
|
137
|
+
expect(releases).to all have_key(:build_label)
|
|
138
|
+
expect(releases).to all have_key(:builder_name)
|
|
139
|
+
expect(releases).to all have_key(:build_tool)
|
|
140
|
+
expect(releases).to all have_key(:errors_introduced_count)
|
|
141
|
+
expect(releases).to all have_key(:errors_seen_count)
|
|
142
|
+
expect(releases).to all have_key(:sessions_count_in_last_24h)
|
|
143
|
+
expect(releases).to all have_key(:total_sessions_count)
|
|
144
|
+
expect(releases).to all have_key(:unhandled_sessions_count)
|
|
145
|
+
expect(releases).to all have_key(:accumulative_daily_users_seen)
|
|
146
|
+
expect(releases).to all have_key(:accumulative_daily_users_with_unhandled)
|
|
147
|
+
expect(releases).to all have_key(:metadata)
|
|
148
|
+
expect(releases).to all have_key(:release_stage)
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
it "accepts parameters" do
|
|
152
|
+
releases = @client.releases_in_group(@release_group_id, { per_page: 1 })
|
|
153
|
+
|
|
154
|
+
expect(releases).to be_an_instance_of(Array)
|
|
155
|
+
|
|
156
|
+
releases.map!(&:to_h)
|
|
157
|
+
|
|
158
|
+
expect(releases.first[:id]).to eq(@release_id)
|
|
159
|
+
expect(releases.first[:project_id]).to eq(@project_id)
|
|
160
|
+
expect(releases.first[:release_group_id]).to eq(@release_group_id)
|
|
161
|
+
|
|
162
|
+
expect(releases).to all have_key(:id)
|
|
163
|
+
expect(releases).to all have_key(:project_id)
|
|
164
|
+
expect(releases).to all have_key(:release_group_id)
|
|
165
|
+
expect(releases).to all have_key(:release_time)
|
|
166
|
+
expect(releases).to all have_key(:release_source)
|
|
167
|
+
expect(releases).to all have_key(:app_version)
|
|
168
|
+
expect(releases).to all have_key(:app_version_code)
|
|
169
|
+
expect(releases).to all have_key(:app_bundle_version)
|
|
170
|
+
expect(releases).to all have_key(:build_label)
|
|
171
|
+
expect(releases).to all have_key(:builder_name)
|
|
172
|
+
expect(releases).to all have_key(:build_tool)
|
|
173
|
+
expect(releases).to all have_key(:errors_introduced_count)
|
|
174
|
+
expect(releases).to all have_key(:errors_seen_count)
|
|
175
|
+
expect(releases).to all have_key(:sessions_count_in_last_24h)
|
|
176
|
+
expect(releases).to all have_key(:total_sessions_count)
|
|
177
|
+
expect(releases).to all have_key(:unhandled_sessions_count)
|
|
178
|
+
expect(releases).to all have_key(:accumulative_daily_users_seen)
|
|
179
|
+
expect(releases).to all have_key(:accumulative_daily_users_with_unhandled)
|
|
180
|
+
expect(releases).to all have_key(:metadata)
|
|
181
|
+
expect(releases).to all have_key(:release_stage)
|
|
182
|
+
end
|
|
183
|
+
end
|
|
184
|
+
end
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
require "spec_helper"
|
|
2
|
+
|
|
3
|
+
describe Bugsnag::Api::Client::Stability do
|
|
4
|
+
before do
|
|
5
|
+
@client = auth_token_client
|
|
6
|
+
@project_id = test_bugsnag_project_id
|
|
7
|
+
|
|
8
|
+
Bugsnag::Api.reset!
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
describe ".stability_trend", :vcr do
|
|
12
|
+
it "gets the stability trend" do
|
|
13
|
+
stability_trend = @client.stability_trend(@project_id)
|
|
14
|
+
|
|
15
|
+
expect(stability_trend.project_id).to eq(@project_id)
|
|
16
|
+
expect(stability_trend.release_stage_name).not_to be_nil
|
|
17
|
+
expect(stability_trend.timeline_points).to be_an_instance_of(Array)
|
|
18
|
+
|
|
19
|
+
# convert each "Sawyer::Resource" to a hash so we can use the "have_key" matcher
|
|
20
|
+
timeline_points = stability_trend.timeline_points.map(&:to_h)
|
|
21
|
+
|
|
22
|
+
expect(timeline_points).to all have_key(:bucket_start)
|
|
23
|
+
expect(timeline_points).to all have_key(:bucket_end)
|
|
24
|
+
expect(timeline_points).to all have_key(:total_sessions_count)
|
|
25
|
+
expect(timeline_points).to all have_key(:unhandled_sessions_count)
|
|
26
|
+
expect(timeline_points).to all have_key(:users_seen)
|
|
27
|
+
expect(timeline_points).to all have_key(:users_with_unhandled)
|
|
28
|
+
|
|
29
|
+
assert_requested(:get, bugsnag_url("/projects/#{@project_id}/stability_trend"))
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
end
|