bugsnag-api 2.0.0 → 2.1.0
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 +42 -7
- data/config/.gitignore +1 -0
- data/docker-compose.yml +9 -0
- data/dockerfiles/Dockerfile.audit +5 -0
- data/lib/bugsnag/api/client.rb +18 -1
- 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/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 +14 -5
- metadata +66 -37
- data/.travis.yml +0 -20
|
@@ -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
|
-
|
|
@@ -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
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require "spec_helper"
|
|
1
2
|
require "json"
|
|
2
3
|
|
|
3
4
|
describe Bugsnag::Api::Client do
|
|
@@ -45,7 +46,7 @@ describe Bugsnag::Api::Client do
|
|
|
45
46
|
|
|
46
47
|
it "handles query params", :vcr do
|
|
47
48
|
Bugsnag::Api.get bugsnag_url("/"), :foo => "bar"
|
|
48
|
-
assert_requested :get, "
|
|
49
|
+
assert_requested :get, bugsnag_url("?foo=bar")
|
|
49
50
|
end
|
|
50
51
|
|
|
51
52
|
it "handles headers" do
|
|
@@ -81,20 +82,81 @@ describe Bugsnag::Api::Client do
|
|
|
81
82
|
end
|
|
82
83
|
end
|
|
83
84
|
|
|
85
|
+
describe ".deep_merge" do
|
|
86
|
+
it "returns a merged hash" do
|
|
87
|
+
client = Bugsnag::Api::Client.new(:auth_token => "example")
|
|
88
|
+
lhs = {
|
|
89
|
+
:foo => "foo"
|
|
90
|
+
}
|
|
91
|
+
rhs = {
|
|
92
|
+
:bar => "bar"
|
|
93
|
+
}
|
|
94
|
+
merged = client.deep_merge(lhs, rhs)
|
|
95
|
+
expect(merged).to_not eq(lhs)
|
|
96
|
+
expect(merged).to_not eq(rhs)
|
|
97
|
+
expect(merged).to eq({
|
|
98
|
+
:foo => "foo",
|
|
99
|
+
:bar => "bar"
|
|
100
|
+
})
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
it "favors rhs over lhs" do
|
|
104
|
+
client = Bugsnag::Api::Client.new(:auth_token => "example")
|
|
105
|
+
lhs = {
|
|
106
|
+
:foo => "foo"
|
|
107
|
+
}
|
|
108
|
+
rhs = {
|
|
109
|
+
:foo => "bar"
|
|
110
|
+
}
|
|
111
|
+
merged = client.deep_merge(lhs, rhs)
|
|
112
|
+
expect(merged).to eq({:foo => "bar"})
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
it "recursively merges hashes" do
|
|
116
|
+
client = Bugsnag::Api::Client.new(:auth_token => "example")
|
|
117
|
+
lhs = {
|
|
118
|
+
:foo => {
|
|
119
|
+
:bar => "bar"
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
rhs = {
|
|
123
|
+
:foo => {
|
|
124
|
+
:foobar => "foobar"
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
merged = client.deep_merge(lhs, rhs)
|
|
128
|
+
expect(merged).to eq(
|
|
129
|
+
{:foo => {
|
|
130
|
+
:bar => "bar",
|
|
131
|
+
:foobar => "foobar"
|
|
132
|
+
}
|
|
133
|
+
})
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
84
137
|
context "error handling" do
|
|
138
|
+
|
|
139
|
+
before do
|
|
140
|
+
VCR.turn_off!
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
after do
|
|
144
|
+
VCR.turn_on!
|
|
145
|
+
end
|
|
146
|
+
|
|
85
147
|
it "raises on 404" do
|
|
86
148
|
stub_get('/booya').to_return(:status => 404)
|
|
87
|
-
expect { Bugsnag::Api.get('/booya') }.to raise_error(Bugsnag::Api::NotFound)
|
|
149
|
+
expect { Bugsnag::Api.get(bugsnag_url('/booya')) }.to raise_error(Bugsnag::Api::NotFound)
|
|
88
150
|
end
|
|
89
151
|
|
|
90
152
|
it "raises on 429" do
|
|
91
153
|
stub_get('/test').to_return(:status => 429)
|
|
92
|
-
expect { Bugsnag::Api.get('/test') }.to raise_error(Bugsnag::Api::RateLimitExceeded)
|
|
154
|
+
expect { Bugsnag::Api.get(bugsnag_url('/test')) }.to raise_error(Bugsnag::Api::RateLimitExceeded)
|
|
93
155
|
end
|
|
94
156
|
|
|
95
157
|
it "raises on 500" do
|
|
96
158
|
stub_get('/boom').to_return(:status => 500)
|
|
97
|
-
expect { Bugsnag::Api.get('/boom') }.to raise_error(Bugsnag::Api::InternalServerError)
|
|
159
|
+
expect { Bugsnag::Api.get(bugsnag_url('/boom')) }.to raise_error(Bugsnag::Api::InternalServerError)
|
|
98
160
|
end
|
|
99
161
|
|
|
100
162
|
it "includes an error" do
|
|
@@ -106,7 +168,7 @@ describe Bugsnag::Api::Client do
|
|
|
106
168
|
},
|
|
107
169
|
:body => {:error => "Comments must contain a message"}.to_json
|
|
108
170
|
begin
|
|
109
|
-
Bugsnag::Api.get('/boom')
|
|
171
|
+
Bugsnag::Api.get(bugsnag_url('/boom'))
|
|
110
172
|
rescue Bugsnag::Api::UnprocessableEntity => e
|
|
111
173
|
expect(e.message).to include("Error: Comments must contain a message")
|
|
112
174
|
end
|
|
@@ -119,7 +181,7 @@ describe Bugsnag::Api::Client do
|
|
|
119
181
|
:content_type => "application/json",
|
|
120
182
|
},
|
|
121
183
|
:body => {:message => "I'm a teapot"}.to_json
|
|
122
|
-
expect { Bugsnag::Api.get('/user') }.to raise_error(Bugsnag::Api::ClientError)
|
|
184
|
+
expect { Bugsnag::Api.get(bugsnag_url('/user')) }.to raise_error(Bugsnag::Api::ClientError)
|
|
123
185
|
end
|
|
124
186
|
|
|
125
187
|
it "raises on unknown server errors" do
|
|
@@ -129,7 +191,7 @@ describe Bugsnag::Api::Client do
|
|
|
129
191
|
:content_type => "application/json",
|
|
130
192
|
},
|
|
131
193
|
:body => {:message => "Bandwidth exceeded"}.to_json
|
|
132
|
-
expect { Bugsnag::Api.get('/user') }.to raise_error(Bugsnag::Api::ServerError)
|
|
194
|
+
expect { Bugsnag::Api.get(bugsnag_url('/user')) }.to raise_error(Bugsnag::Api::ServerError)
|
|
133
195
|
end
|
|
134
196
|
end
|
|
135
197
|
end
|