firebase-admin 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +3 -0
- data/.rubocop.yml +13 -0
- data/.rubocop_todo.yml +49 -0
- data/.tool-versions +1 -0
- data/Gemfile +3 -0
- data/Gemfile.lock +84 -0
- data/LICENSE +21 -0
- data/README.md +22 -0
- data/firebase-admin.gemspec +27 -0
- data/lib/faraday/loud_logger.rb +75 -0
- data/lib/faraday/raise_http_exception.rb +61 -0
- data/lib/firebase-admin.rb +32 -0
- data/lib/firebase-admin/api.rb +29 -0
- data/lib/firebase-admin/client.rb +11 -0
- data/lib/firebase-admin/client/accounts.rb +159 -0
- data/lib/firebase-admin/configuration.rb +78 -0
- data/lib/firebase-admin/connection.rb +30 -0
- data/lib/firebase-admin/error.rb +28 -0
- data/lib/firebase-admin/request.rb +44 -0
- data/lib/firebase-admin/version.rb +3 -0
- data/spec/faraday/raise_http_exceptions_spec.rb +73 -0
- data/spec/firebase-admin/api_spec.rb +134 -0
- data/spec/firebase-admin/client/accounts_spec.rb +23 -0
- data/spec/firebase-admin/client_spec.rb +10 -0
- data/spec/firebase_admin_spec.rb +94 -0
- data/spec/fixtures/400_error.json +13 -0
- data/spec/fixtures/bad_gateway.html +1 -0
- data/spec/fixtures/create_account.json +6 -0
- data/spec/fixtures/gateway_timeout.html +1 -0
- data/spec/spec_helper.rb +72 -0
- metadata +223 -0
@@ -0,0 +1,11 @@
|
|
1
|
+
module FirebaseAdmin
|
2
|
+
# Wrapper for the Firebase Admin REST API
|
3
|
+
#
|
4
|
+
# @note All methods have been separated into modules and follow the same grouping used in http://???
|
5
|
+
# @see http://???
|
6
|
+
class Client < API
|
7
|
+
Dir[File.expand_path('client/*.rb', __dir__)].sort.each { |f| require f }
|
8
|
+
|
9
|
+
include FirebaseAdmin::Client::Accounts
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,159 @@
|
|
1
|
+
require 'jwt'
|
2
|
+
|
3
|
+
module FirebaseAdmin
|
4
|
+
class Client
|
5
|
+
# Defines methods related to accounts
|
6
|
+
module Accounts
|
7
|
+
# Create a new account
|
8
|
+
#
|
9
|
+
# @param params [Hash] A customizable set of params
|
10
|
+
# @option options [String] :email
|
11
|
+
# @option options [String] :password
|
12
|
+
# @option options [String] :phoneNumber
|
13
|
+
# @option options [String] :displayName
|
14
|
+
# @option options [String] :photoUrl
|
15
|
+
# @option options [String] :customAttributes
|
16
|
+
# @option customAttributes [String] :roles
|
17
|
+
#
|
18
|
+
# @return [Resource]
|
19
|
+
# @see https://firebase.google.com/docs/reference/rest/auth#section-create-email-password
|
20
|
+
#
|
21
|
+
# @example
|
22
|
+
# FirebaseAdmin.create_account(
|
23
|
+
# :email => "lebron@lakers.com",
|
24
|
+
# :password => "super-secret",
|
25
|
+
# :phoneNumber => "+5555555555",
|
26
|
+
# :displayName => "LeBron James",
|
27
|
+
# :photoUrl => "http://www.example.com/photo.jpg",
|
28
|
+
# :customAttributes => {
|
29
|
+
# :roles => ['admin']
|
30
|
+
# }
|
31
|
+
# )
|
32
|
+
def create_account(params)
|
33
|
+
post("v1/projects/#{project_id}/accounts", params)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Update an existing account
|
37
|
+
#
|
38
|
+
# @param params [Hash] A customizable set of params
|
39
|
+
# @option options [String] :email
|
40
|
+
# @option options [String] :password
|
41
|
+
# @option options [String] :phoneNumber
|
42
|
+
# @option options [String] :displayName
|
43
|
+
# @option options [String] :photoUrl
|
44
|
+
# @option options [String] :customAttributes
|
45
|
+
# @option customAttributes [String] :roles
|
46
|
+
#
|
47
|
+
# @return [Resource]
|
48
|
+
# @see https://firebase.google.com/docs/reference/rest/auth
|
49
|
+
#
|
50
|
+
# @example
|
51
|
+
# FirebaseAdmin.update_account(
|
52
|
+
# email: "lebron@lakers.com",
|
53
|
+
# password: "super-secret",
|
54
|
+
# phoneNumber: "+5555555555",
|
55
|
+
# displayName: "LeBron James",
|
56
|
+
# photoUrl: "http://www.example.com/photo.jpg",
|
57
|
+
# localId: "1234",
|
58
|
+
# customAttributes: {
|
59
|
+
# :roles => ['admin']
|
60
|
+
# }
|
61
|
+
# )
|
62
|
+
def update_account(params)
|
63
|
+
post("v1/projects/#{project_id}/accounts:update", params)
|
64
|
+
end
|
65
|
+
|
66
|
+
# Sign in with a password
|
67
|
+
#
|
68
|
+
# @param params [Hash] A customizable set of params
|
69
|
+
# @option options [String] :email
|
70
|
+
# @option options [String] :password
|
71
|
+
#
|
72
|
+
# @return [Resource]
|
73
|
+
# @see https://firebase.google.com/docs/reference/rest/auth
|
74
|
+
#
|
75
|
+
# @example
|
76
|
+
# FirebaseAdmin.sign_in_with_password(
|
77
|
+
# email: "lebron@lakers.com",
|
78
|
+
# password: "super-secret"
|
79
|
+
# )
|
80
|
+
def sign_in_with_password(params)
|
81
|
+
post('v1/accounts:signInWithPassword', params)
|
82
|
+
end
|
83
|
+
|
84
|
+
# Sign in with custom token
|
85
|
+
#
|
86
|
+
# @param token [String] A custom token
|
87
|
+
#
|
88
|
+
# @return [Resource] with idToken
|
89
|
+
#
|
90
|
+
# @example
|
91
|
+
# FirebaseAdmin.sign_in_with_custom_token("...")
|
92
|
+
def sign_in_with_custom_token(token)
|
93
|
+
post('v1/accounts:signInWithCustomToken', { token: token, returnSecureToken: true })
|
94
|
+
end
|
95
|
+
|
96
|
+
# Create a custom JWT token for a UID
|
97
|
+
#
|
98
|
+
# @param uid [String] The uid of a user
|
99
|
+
#
|
100
|
+
# @return [String]
|
101
|
+
# @see https://firebase.google.com/docs/reference/rest/auth
|
102
|
+
#
|
103
|
+
# @example
|
104
|
+
# FirebaseAdmin.create_custom_token('...')
|
105
|
+
def create_custom_token(uid)
|
106
|
+
credentials = default_credentials
|
107
|
+
|
108
|
+
service_account_email = credentials.fetch('client_email', ENV['GOOGLE_CLIENT_EMAIL'])
|
109
|
+
private_key = OpenSSL::PKey::RSA.new credentials.fetch('private_key', ENV['GOOGLE_PRIVATE_KEY'])
|
110
|
+
|
111
|
+
now_seconds = Time.now.to_i
|
112
|
+
payload = {
|
113
|
+
iss: service_account_email,
|
114
|
+
sub: service_account_email,
|
115
|
+
aud: 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',
|
116
|
+
iat: now_seconds,
|
117
|
+
exp: now_seconds + (60 * 60), # Maximum expiration time is one hour
|
118
|
+
uid: uid
|
119
|
+
}
|
120
|
+
JWT.encode(payload, private_key, 'RS256')
|
121
|
+
end
|
122
|
+
|
123
|
+
# Get user by email/phone/uid
|
124
|
+
#
|
125
|
+
# @param key [String] either :email or :phone
|
126
|
+
# @param value [String] the value to search for
|
127
|
+
#
|
128
|
+
# @return [Resource]
|
129
|
+
#
|
130
|
+
# @example
|
131
|
+
# FirebaseAdmin.get_user_by(:email, "lebron@lakers.com")
|
132
|
+
def get_user_by(key, value)
|
133
|
+
params = {}
|
134
|
+
params[key] = Array(value)
|
135
|
+
response = post('v1/accounts:lookup', params)
|
136
|
+
(response[:users] || []).first
|
137
|
+
end
|
138
|
+
|
139
|
+
# Reset emulator
|
140
|
+
#
|
141
|
+
# @return [Resource]
|
142
|
+
# @see https://firebase.google.com/docs/reference/rest/auth
|
143
|
+
#
|
144
|
+
# @example
|
145
|
+
# FirebaseAdmin.reset()
|
146
|
+
def reset
|
147
|
+
delete("emulator/v1/projects/#{project_id}/accounts")
|
148
|
+
end
|
149
|
+
|
150
|
+
private
|
151
|
+
|
152
|
+
def default_credentials
|
153
|
+
return {} if ENV['GOOGLE_APPLICATION_CREDENTIALS'].nil?
|
154
|
+
|
155
|
+
JSON.parse(File.read(ENV['GOOGLE_APPLICATION_CREDENTIALS']))
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
require File.expand_path('version', __dir__)
|
3
|
+
|
4
|
+
module FirebaseAdmin
|
5
|
+
# Defines constants and methods related to configuration
|
6
|
+
module Configuration
|
7
|
+
# An array of valid keys in the options hash when configuring a {FirebaseAdmin::API}
|
8
|
+
VALID_OPTIONS_KEYS = %i[
|
9
|
+
access_token
|
10
|
+
adapter
|
11
|
+
connection_options
|
12
|
+
endpoint
|
13
|
+
user_agent
|
14
|
+
project_id
|
15
|
+
loud_logger
|
16
|
+
].freeze
|
17
|
+
|
18
|
+
# By default, don't set a user access token
|
19
|
+
DEFAULT_ACCESS_TOKEN = 'owner'.freeze
|
20
|
+
|
21
|
+
# The adapter that will be used to connect if none is set
|
22
|
+
#
|
23
|
+
# @note The default faraday adapter is Net::HTTP.
|
24
|
+
DEFAULT_ADAPTER = Faraday.default_adapter
|
25
|
+
|
26
|
+
# By default, don't set any connection options
|
27
|
+
DEFAULT_CONNECTION_OPTIONS = {}.freeze
|
28
|
+
|
29
|
+
# The endpoint that will be used to connect if none is set
|
30
|
+
#
|
31
|
+
# @note There is no reason to use any other endpoint at this time
|
32
|
+
DEFAULT_ENDPOINT = 'https://identitytoolkit.googleapis.com/'.freeze
|
33
|
+
|
34
|
+
# The response format appended to the path and sent in the 'Accept' header if none is set
|
35
|
+
#
|
36
|
+
# @note JSON is the only available format at this time
|
37
|
+
DEFAULT_FORMAT = :json
|
38
|
+
|
39
|
+
# The user agent that will be sent to the API endpoint if none is set
|
40
|
+
DEFAULT_USER_AGENT = "Firebase Admin Ruby Gem #{FirebaseAdmin::VERSION}".freeze
|
41
|
+
|
42
|
+
DEFAULT_PROJECT_ID = ''.freeze
|
43
|
+
|
44
|
+
# By default, don't turn on loud logging
|
45
|
+
DEFAULT_LOUD_LOGGER = nil
|
46
|
+
|
47
|
+
# @private
|
48
|
+
attr_accessor(*VALID_OPTIONS_KEYS)
|
49
|
+
|
50
|
+
# When this module is extended, set all configuration options to their default values
|
51
|
+
def self.extended(base)
|
52
|
+
base.reset
|
53
|
+
end
|
54
|
+
|
55
|
+
# Convenience method to allow configuration options to be set in a block
|
56
|
+
def configure
|
57
|
+
yield self
|
58
|
+
end
|
59
|
+
|
60
|
+
# Create a hash of options and their values
|
61
|
+
def options
|
62
|
+
VALID_OPTIONS_KEYS.inject({}) do |option, key|
|
63
|
+
option.merge!(key => send(key))
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# Reset all configuration options to defaults
|
68
|
+
def reset
|
69
|
+
self.access_token = DEFAULT_ACCESS_TOKEN
|
70
|
+
self.adapter = DEFAULT_ADAPTER
|
71
|
+
self.connection_options = DEFAULT_CONNECTION_OPTIONS
|
72
|
+
self.endpoint = DEFAULT_ENDPOINT
|
73
|
+
self.user_agent = DEFAULT_USER_AGENT
|
74
|
+
self.project_id = DEFAULT_PROJECT_ID
|
75
|
+
self.loud_logger = DEFAULT_LOUD_LOGGER
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'faraday_middleware'
|
2
|
+
Dir[File.expand_path('../faraday/*.rb', __dir__)].sort.each { |f| require f }
|
3
|
+
|
4
|
+
module FirebaseAdmin
|
5
|
+
# @private
|
6
|
+
module Connection
|
7
|
+
private
|
8
|
+
|
9
|
+
def connection
|
10
|
+
options = {
|
11
|
+
headers: {
|
12
|
+
'Content-Type' => 'application/json; charset=utf-8',
|
13
|
+
'Accept' => 'application/json; charset=utf-8',
|
14
|
+
'User-Agent' => user_agent
|
15
|
+
},
|
16
|
+
url: endpoint
|
17
|
+
}.merge(connection_options)
|
18
|
+
|
19
|
+
Faraday::Connection.new(options) do |connection|
|
20
|
+
connection.authorization :Bearer, access_token if access_token
|
21
|
+
connection.use Faraday::Request::UrlEncoded
|
22
|
+
connection.use FaradayMiddleware::Mashify
|
23
|
+
connection.use Faraday::Response::ParseJson
|
24
|
+
connection.use FaradayMiddleware::RaiseHttpException
|
25
|
+
connection.use FaradayMiddleware::LoudLogger if loud_logger
|
26
|
+
connection.adapter(adapter)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module FirebaseAdmin
|
2
|
+
# Custom error class for rescuing from all Firebase errors
|
3
|
+
class Error < StandardError; end
|
4
|
+
|
5
|
+
# Raised when Firebase returns the HTTP status code 400
|
6
|
+
class BadRequest < Error; end
|
7
|
+
|
8
|
+
# Raised when Firebase returns the HTTP status code 404
|
9
|
+
class NotFound < Error; end
|
10
|
+
|
11
|
+
# Raised when Firebase returns the HTTP status code 429
|
12
|
+
class TooManyRequests < Error; end
|
13
|
+
|
14
|
+
# Raised when Firebase returns the HTTP status code 500
|
15
|
+
class InternalServerError < Error; end
|
16
|
+
|
17
|
+
# Raised when Firebase returns the HTTP status code 502
|
18
|
+
class BadGateway < Error; end
|
19
|
+
|
20
|
+
# Raised when Firebase returns the HTTP status code 503
|
21
|
+
class ServiceUnavailable < Error; end
|
22
|
+
|
23
|
+
# Raised when Firebase returns the HTTP status code 504
|
24
|
+
class GatewayTimeout < Error; end
|
25
|
+
|
26
|
+
# Raised when Firebase returns the HTTP status code 429
|
27
|
+
class RateLimitExceeded < Error; end
|
28
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'addressable/uri'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module FirebaseAdmin
|
5
|
+
# Defines HTTP request methods
|
6
|
+
module Request
|
7
|
+
# Perform an HTTP GET request
|
8
|
+
def get(path, options = {})
|
9
|
+
request(:get, path, options)
|
10
|
+
end
|
11
|
+
|
12
|
+
# Perform an HTTP POST request
|
13
|
+
def post(path, options = {})
|
14
|
+
request(:post, path, options)
|
15
|
+
end
|
16
|
+
|
17
|
+
# Perform an HTTP PUT request
|
18
|
+
def put(path, options = {})
|
19
|
+
request(:put, path, options)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Perform an HTTP DELETE request
|
23
|
+
def delete(path, options = {})
|
24
|
+
request(:delete, path, options)
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
# Perform an HTTP request
|
30
|
+
def request(method, path, options)
|
31
|
+
response = connection.send(method) do |request|
|
32
|
+
case method
|
33
|
+
when :post, :put
|
34
|
+
request.path = Addressable::URI.escape(path)
|
35
|
+
request.body = options.to_json unless options.empty?
|
36
|
+
|
37
|
+
else
|
38
|
+
request.url(Addressable::URI.escape(path), options)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
response.body
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require File.expand_path('../spec_helper', __dir__)
|
4
|
+
|
5
|
+
describe Faraday::Response do
|
6
|
+
before do
|
7
|
+
@client = FirebaseAdmin::Client.new(project_id: 'test-project')
|
8
|
+
end
|
9
|
+
|
10
|
+
{
|
11
|
+
400 => FirebaseAdmin::BadRequest,
|
12
|
+
404 => FirebaseAdmin::NotFound,
|
13
|
+
429 => FirebaseAdmin::TooManyRequests,
|
14
|
+
500 => FirebaseAdmin::InternalServerError,
|
15
|
+
503 => FirebaseAdmin::ServiceUnavailable
|
16
|
+
}.each do |status, exception|
|
17
|
+
context "when HTTP status is #{status}" do
|
18
|
+
before do
|
19
|
+
stub_post('v1/projects/test-project/accounts')
|
20
|
+
.to_return(status: status)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should raise #{exception.name} error" do
|
24
|
+
expect do
|
25
|
+
@client.create_account({})
|
26
|
+
end.to raise_error(exception)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'when a 400 is raised' do
|
32
|
+
before do
|
33
|
+
stub_post('v1/projects/test-project/accounts')
|
34
|
+
.to_return(body: fixture('400_error.json'), status: 400)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should return the body error message' do
|
38
|
+
expect do
|
39
|
+
@client.create_account({})
|
40
|
+
end.to raise_error(FirebaseAdmin::BadRequest, /INVALID_PHONE_NUMBER : Invalid format\./)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
context 'when a 502 is raised with an HTML response' do
|
45
|
+
before do
|
46
|
+
stub_post('v1/projects/test-project/accounts').to_return(
|
47
|
+
body: fixture('bad_gateway.html'),
|
48
|
+
status: 502
|
49
|
+
)
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'should raise an FirebaseAdmin::BadGateway' do
|
53
|
+
expect do
|
54
|
+
@client.create_account({})
|
55
|
+
end.to raise_error(FirebaseAdmin::BadGateway)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context 'when a 504 is raised with an HTML response' do
|
60
|
+
before do
|
61
|
+
stub_post('v1/projects/test-project/accounts').to_return(
|
62
|
+
body: fixture('gateway_timeout.html'),
|
63
|
+
status: 504
|
64
|
+
)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should raise an FirebaseAdmin::GatewayTimeout' do
|
68
|
+
expect do
|
69
|
+
@client.create_account({})
|
70
|
+
end.to raise_error(FirebaseAdmin::GatewayTimeout)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,134 @@
|
|
1
|
+
require File.expand_path('../spec_helper', __dir__)
|
2
|
+
|
3
|
+
describe FirebaseAdmin::API do
|
4
|
+
before do
|
5
|
+
@keys = FirebaseAdmin::Configuration::VALID_OPTIONS_KEYS
|
6
|
+
end
|
7
|
+
|
8
|
+
context 'with module configuration' do
|
9
|
+
before do
|
10
|
+
FirebaseAdmin.configure do |config|
|
11
|
+
@keys.each do |key|
|
12
|
+
config.send("#{key}=", key)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
after do
|
18
|
+
FirebaseAdmin.reset
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should inherit module configuration' do
|
22
|
+
api = FirebaseAdmin::API.new
|
23
|
+
@keys.each do |key|
|
24
|
+
expect(api.send(key)).to eq(key)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context 'with class configuration' do
|
29
|
+
before do
|
30
|
+
@configuration = {
|
31
|
+
access_token: 'AT',
|
32
|
+
adapter: :typhoeus,
|
33
|
+
connection_options: { ssl: { verify: true } },
|
34
|
+
endpoint: 'http://tumblr.com/',
|
35
|
+
user_agent: 'Custom User Agent',
|
36
|
+
project_id: 'test-project',
|
37
|
+
loud_logger: true
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
context 'during initialization' do
|
42
|
+
it 'should override module configuration' do
|
43
|
+
api = FirebaseAdmin::API.new(@configuration)
|
44
|
+
@keys.each do |key|
|
45
|
+
expect(api.send(key)).to eq(@configuration[key])
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
context 'after initialization' do
|
51
|
+
let(:api) { FirebaseAdmin::API.new }
|
52
|
+
|
53
|
+
before do
|
54
|
+
@configuration.each do |key, value|
|
55
|
+
api.send("#{key}=", value)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'should override module configuration after initialization' do
|
60
|
+
@keys.each do |key|
|
61
|
+
expect(api.send(key)).to eq(@configuration[key])
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe '#connection' do
|
66
|
+
it 'should use the connection_options' do
|
67
|
+
expect(Faraday::Connection).to receive(:new).with(include(ssl: { verify: true }))
|
68
|
+
api.send(:connection)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#config' do
|
76
|
+
subject { FirebaseAdmin::API.new }
|
77
|
+
|
78
|
+
let(:config) do
|
79
|
+
c = {}
|
80
|
+
@keys.each { |key| c[key] = key }
|
81
|
+
c
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'returns a hash representing the configuration' do
|
85
|
+
@keys.each do |key|
|
86
|
+
subject.send("#{key}=", key)
|
87
|
+
end
|
88
|
+
expect(subject.config).to eq(config)
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe 'loud_logger param' do
|
93
|
+
before do
|
94
|
+
@client = FirebaseAdmin::Client.new(project_id: 'test-project', loud_logger: true)
|
95
|
+
end
|
96
|
+
|
97
|
+
context 'outputs to STDOUT with faraday logs when enabled' do
|
98
|
+
before do
|
99
|
+
stub_post('v1/projects/test-project/accounts')
|
100
|
+
.to_return(body: fixture('create_account.json'), headers: { content_type: 'application/json; charset=utf-8' })
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should return the body error message' do
|
104
|
+
output = capture_output do
|
105
|
+
@client.create_account({})
|
106
|
+
end
|
107
|
+
|
108
|
+
expect(output).to include 'INFO -- : Started POST request to: '
|
109
|
+
expect(output).to include 'DEBUG -- : Response Headers:'
|
110
|
+
expect(output).to include "User-Agent : Firebase Admin Ruby Gem #{FirebaseAdmin::VERSION}"
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context 'shows STDOUT output when errors occur' do
|
115
|
+
before do
|
116
|
+
stub_post('v1/projects/test-project/accounts')
|
117
|
+
.to_return(body: '{"error":{"message": "Bad words are bad."}}', status: 400)
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should return the body error message' do
|
121
|
+
output = capture_output do
|
122
|
+
@client.create_account({})
|
123
|
+
rescue StandardError
|
124
|
+
nil
|
125
|
+
end
|
126
|
+
|
127
|
+
expect(output).to include 'INFO -- : Started POST request to: '
|
128
|
+
expect(output).to include 'DEBUG -- : Response Headers:'
|
129
|
+
expect(output).to include "User-Agent : Firebase Admin Ruby Gem #{FirebaseAdmin::VERSION}"
|
130
|
+
expect(output).to include '{"error":{"message": "Bad words are bad."}}'
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|