Skip to content

Commit

Permalink
Update StripeClient to optionally take app_info in parameter
Browse files Browse the repository at this point in the history
This app_info will take precedence over the globally defined
Stripe.app_info
  • Loading branch information
JacekD98 committed Jan 27, 2025
1 parent 5304640 commit 00b4f86
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 3 deletions.
10 changes: 8 additions & 2 deletions lib/stripe/api_requestor.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ def initialize(config_arg = {})
else
raise ArgumentError, "Can't handle argument: #{config_arg}"
end

@app_info = config.app_info
end

attr_reader :config, :options
Expand Down Expand Up @@ -918,7 +920,7 @@ def self.maybe_gc_connection_managers

private def request_headers(method, api_mode, req_opts)
user_agent = "Stripe/#{api_mode} RubyBindings/#{Stripe::VERSION}"
user_agent += " " + format_app_info(Stripe.app_info) unless Stripe.app_info.nil?
user_agent += " " + format_app_info(fetch_app_info) unless fetch_app_info.nil?

headers = {
"User-Agent" => user_agent,
Expand Down Expand Up @@ -963,6 +965,10 @@ def self.maybe_gc_connection_managers
headers.update(req_opts[:headers])
end

private def fetch_app_info
@app_info || Stripe.app_info
end

private def log_request(context, num_retries)
Util.log_info("Request to Stripe API",
account: context.account,
Expand Down Expand Up @@ -1090,7 +1096,7 @@ def user_agent
"(#{RUBY_RELEASE_DATE})"

{
application: Stripe.app_info,
application: fetch_app_info,
bindings_version: Stripe::VERSION,
lang: "ruby",
lang_version: lang_version,
Expand Down
4 changes: 3 additions & 1 deletion lib/stripe/stripe_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ def initialize(api_key, # rubocop:todo Metrics/ParameterLists
uploads_base: nil,
connect_base: nil,
meter_events_base: nil,
client_id: nil)
client_id: nil,
app_info: nil,)
unless api_key
raise AuthenticationError, "No API key provided. " \
'Set your API key using "client = Stripe::StripeClient.new(<API-KEY>)". ' \
Expand All @@ -42,6 +43,7 @@ def initialize(api_key, # rubocop:todo Metrics/ParameterLists
connect_base: connect_base,
meter_events_base: meter_events_base,
client_id: client_id,
app_info: app_info
}.reject { |_k, v| v.nil? }

config = StripeConfiguration.client_init(config_opts)
Expand Down
39 changes: 39 additions & 0 deletions test/stripe/api_requestor_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -834,6 +834,45 @@ class RequestorTest < Test::Unit::TestCase
Stripe.app_info = old
end
end

should "send app_info if set on the APIRequestor's config" do
begin
old = Stripe.app_info
Stripe.app_info = nil

custom_config = Stripe::StripeConfiguration.setup do |c|
c.app_info = {
name: "MyAwesomePluginInConfig",
partner_id: "partner_4567",
url: "https://myawesomeplugininconfig.info",
version: "4.5.6",
}
end

stub_request(:post, "#{Stripe::DEFAULT_API_BASE}/v1/account")
.with do |req|
expect_user_agent = "Stripe/v1 RubyBindings/#{Stripe::VERSION}" \
"MyAwesomePluginInConfig/4.5.6 (https://myawesomeplugininconfig.info)"
assert_equal expect_user_agent, req.headers["User-Agent"]

data = JSON.parse(req.headers["X-Stripe-Client-User-Agent"], symbolize_names: true)
assert_equal({
name: "MyAwesomePluginInConfig",
partner_id: "partner_4567",
url: "https://myawesomeplugininconfig.info",
version: "4.5.6",
}, data[:application])

true
end
.to_return(body: JSON.generate(object: "account"))

client = APIRequestor.new(custom_config)
client.execute_request(:post, "/v1/account", :api)
ensure
Stripe.app_info = old
end
end
end

context "error handling" do
Expand Down
47 changes: 47 additions & 0 deletions test/stripe/stripe_client_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,20 @@ class StripeClientTest < Test::Unit::TestCase
@orig_stripe_account = Stripe.stripe_account
@orig_open_timeout = Stripe.open_timeout
@orig_api_version = Stripe.api_version
@orig_app_info = Stripe.app_info

Stripe.api_key = "DONT_USE_THIS_KEY"
Stripe.stripe_account = "DONT_USE_THIS_ACCOUNT"
Stripe.open_timeout = 30_000
Stripe.app_info = nil
end

teardown do
Stripe.api_key = @orig_api_key
Stripe.stripe_account = @orig_stripe_account
Stripe.open_timeout = @orig_open_timeout
Stripe.api_version = @orig_api_version
Stripe.app_info = @orig_app_info
end

should "use default config options" do
Expand Down Expand Up @@ -112,6 +115,50 @@ class StripeClientTest < Test::Unit::TestCase

refute_equal APIRequestor.active_requestor, client.instance_variable_get(:@requestor)
end

should "use client app_info over global app_info" do
Stripe.app_info = { name: "global_app", version: "1.2.3" }
client_app_info = { name: "client_app", version: "4.5.6" }
client = StripeClient.new("test_123", app_info: client_app_info)

req = nil
stub_request(:get, "#{Stripe::DEFAULT_API_BASE}/v1/customers/cus_123")
.with { |request| req = request }
.to_return(body: JSON.generate(object: "customer"))

client.v1.customers.retrieve("cus_123")

assert_match(/client_app\/4\.5\.6/, req.headers["User-Agent"])
assert_no_match(/global_app/, req.headers["User-Agent"])
end

should "fall back to global app_info when client app_info not provided" do
Stripe.app_info = { name: "global_app", version: "1.2.3" }
client = StripeClient.new("test_123")

req = nil
stub_request(:get, "#{Stripe::DEFAULT_API_BASE}/v1/customers/cus_123")
.with { |request| req = request }
.to_return(body: JSON.generate(object: "customer"))

client.v1.customers.retrieve("cus_123")

assert_match(%r{global_app/1\.2\.3}, req.headers["User-Agent"])
end

should "work with no app_info set" do
Stripe.app_info = nil
client = StripeClient.new("test_123")

req = nil
stub_request(:get, "#{Stripe::DEFAULT_API_BASE}/v1/customers/cus_123")
.with { |request| req = request }
.to_return(body: JSON.generate(object: "customer"))

client.v1.customers.retrieve("cus_123")

assert_no_match(%r{app/}, req.headers["User-Agent"])
end
end

context "#request" do
Expand Down

0 comments on commit 00b4f86

Please sign in to comment.