Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn if idempotency_key is in params hash #545

Merged
merged 1 commit into from
May 26, 2017

Conversation

andrewyang-stripe
Copy link
Contributor

Fixes #544. Also add a test case to ensure that there's a warning in stderr when idempotency_key is in the params hash, and not in the opts hash.

@brandur-stripe
Copy link
Contributor

@andrewyang-stripe Thanks! I really like the test addition.

A couple notes:

  1. Remember how we talked about how this could potentially extend beyond just a create to an update or a save? Lets see if we can hoist this up a level so that those could have some coverage as well.
  2. Covering idempotency_key is good, but I think we also want to cover a few other common options like stripe_account and api_key (maybe check the code to make sure I didn't miss any others too).

ptal @andrewyang-stripe

@andrewyang-stripe
Copy link
Contributor Author

@brandur-stripe

  1. If I try to check the params hash one level deeper (https://github.com/stripe/stripe-ruby/blob/master/lib/stripe/api_operations/request.rb#L41), I don't think I would be able to test the changes because I use stub_request in the test cases. However, I did identify the update and save methods, which are both in lib/stripe/api_operations/save.rb.
  2. I only see stripe_account being used in methods that don't have both params and opts as parameters (e.g. https://github.com/stripe/stripe-ruby/blob/master/test/stripe/api_resource_test.rb#L299). So the only other important option I could identify is api_key and maybe content_type.

Perhaps I can create a helper method called self.validate_params in lib/stripe/util.rb so I won't have to repeat the same code across create, update, and save operations.

@brandur-stripe
Copy link
Contributor

If I try to check the params hash one level deeper (https://github.com/stripe/stripe-ruby/blob/master/lib/stripe/api_operations/request.rb#L41), I don't think I would be able to test the changes because I use stub_request in the test cases. However, I did identify the update and save methods, which are both in lib/stripe/api_operations/save.rb.

So in this case stub_request does not literally mean "stub the request method" :) It's actually stubbing out at a much lower level than our library's #request method.

I only see stripe_account being used in methods that don't have both params and opts as parameters (e.g. https://github.com/stripe/stripe-ruby/blob/master/test/stripe/api_resource_test.rb#L299). So the only other important option I could identify is api_key and maybe content_type.

As discussed IRL, although we only test it in the one place here, you're allowed to pass this in for any request, and it's as general as something like idempotency_key. Lets include it in our check list.

@andrewyang-stripe
Copy link
Contributor Author

I've figured out where to write the check for params. I also wrote a helper method validate_params! in lib/stripe/util.rb and more tests covering cases where a warning should and shouldn't be triggered.
ptal @brandur-stripe

ensure
$stderr = old_stderr
end
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good thinking, but I think having tests for both idempotency key and API key for create/update is a bit overkill. Let's take these two out okay?

Maybe you can generalize the name of the other with something like just refer to a general "opt" instead of api_key or idempotency_key specifically.

to_return(body: JSON.generate({ :count => 1, :data => [API_FIXTURES.fetch(:charge)] }))
Stripe::Charge.create(:amount => 50, :currency => 'usd', :card => { :number => nil })
end

should "putting idempotency_key correctly as an opt should not trigger a warning" do
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So the naming of these test cases should be readable from the "should".

"should putting idempotency_key correctly ..." doesn't make sense. Maybe something like "should trigger a warning ...".

@@ -5,6 +5,8 @@ module ClassMethods
OPTS_KEYS_TO_PERSIST = Set[:api_key, :api_base, :client, :stripe_account, :stripe_version]

def request(method, url, params={}, opts={})
Util.validate_params!(params)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that we're only going to be using this helper in one place, lets move it back to request.rb okay?

@@ -2,6 +2,8 @@

module Stripe
module Util
@invalid_params = Set.new [:idempotency_key, :api_key, :stripe_account]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Lets make this a constant and give it a slightly more descriptive name, okay? KNOWN_OPTS or something like that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, and can we also alphabetize the keys in the list and also move it to the private section of the class? You can use private_const :CONST to protect it.

@@ -213,6 +215,14 @@ def self.check_string_argument!(key)
key
end

def self.validate_params!(params)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we call this something a little more appropriate like warn_on_opts_in_params? Lets remove the bang (!) too. This is generally used to show that the method may throw an error, which isn't the case here.

@brandur-stripe
Copy link
Contributor

Added a couple change requests, but looking good. Thanks!

@andrewyang-stripe
Copy link
Contributor Author

Made the change requests.
ptal @brandur-stripe

Copy link
Contributor

@brandur-stripe brandur-stripe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the changes! I left a couple more comments, but I think we're almost there.

ensure
$stderr = old_stderr
end
end
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's get rid of this test too. I think just the two below give us enough coverage.

@@ -3,8 +3,19 @@ module APIOperations
module Request
module ClassMethods
OPTS_KEYS_TO_PERSIST = Set[:api_key, :api_base, :client, :stripe_account, :stripe_version]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this line gives us another hint for an opt that we can warn on! What do you think about adding stripe_version to the set?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should OPTS_KEYS_TO_PERSIST and KNOWN_OPTS be merged?

@@ -3,8 +3,19 @@ module APIOperations
module Request
module ClassMethods
OPTS_KEYS_TO_PERSIST = Set[:api_key, :api_base, :client, :stripe_account, :stripe_version]
KNOWN_OPTS = Set[:api_key, :idempotency_key, :stripe_account]

def warn_on_opts_in_params(params)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move both this method and the constant above down to a new private section in the file? Lets also put a private_constant :KNOWN_OPTS under the KNOWN_OPTS declaration.

@andrewyang-stripe andrewyang-stripe force-pushed the andrewyang-idempotency-key-param branch from fa6a046 to 10b7828 Compare May 26, 2017 17:08

private

KNOWN_OPTS = Set[:api_key, :idempotency_key, :stripe_account, :stripe_version]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think the private block will affect visibility for constants, so can put in the private_constant tag like we talked about?

@brandur-stripe
Copy link
Contributor

Very close!

ptal @andrew-stripe

@andrewyang-stripe andrewyang-stripe force-pushed the andrewyang-idempotency-key-param branch from 10b7828 to 7a9ae05 Compare May 26, 2017 19:52
@andrewyang-stripe
Copy link
Contributor Author

Fixed. ptal @brandur-stripe

@brandur-stripe
Copy link
Contributor

Great! After you rebase, then I think we're good to go.

@andrewyang-stripe andrewyang-stripe force-pushed the andrewyang-idempotency-key-param branch from 7a9ae05 to e66eac4 Compare May 26, 2017 20:30
@andrewyang-stripe andrewyang-stripe merged commit 855ce0c into master May 26, 2017
@andrewyang-stripe andrewyang-stripe deleted the andrewyang-idempotency-key-param branch May 26, 2017 20:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants