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

Fix incorrect handling of additional request parameters #850

Merged
merged 9 commits into from
Aug 3, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 36 additions & 2 deletions stripe/api_resources/abstract/api_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -115,10 +115,27 @@ def _static_request(
stripe_account=None,
params=None,
):
params = None if params is None else params.copy()
api_key = util.read_special_variable(params, "api_key", api_key)
idempotency_key = util.read_special_variable(
params, "idempotency_key", idempotency_key
)
stripe_version = util.read_special_variable(
params, "stripe_version", stripe_version
)
stripe_account = util.read_special_variable(
params, "stripe_account", stripe_account
)
headers = util.read_special_variable(params, "headers", None)

requestor = api_requestor.APIRequestor(
api_key, api_version=stripe_version, account=stripe_account
)
headers = util.populate_headers(idempotency_key)

if idempotency_key is not None:
headers = {} if headers is None else headers.copy()
headers.update(util.populate_headers(idempotency_key))

response, api_key = requestor.request(method_, url_, params, headers)
return util.convert_to_stripe_object(
response, api_key, stripe_version, stripe_account, params
Expand All @@ -137,9 +154,26 @@ def _static_request_stream(
stripe_account=None,
params=None,
):
params = None if params is None else params.copy()
api_key = util.read_special_variable(params, "api_key", api_key)
idempotency_key = util.read_special_variable(
params, "idempotency_key", idempotency_key
)
stripe_version = util.read_special_variable(
params, "stripe_version", stripe_version
)
stripe_account = util.read_special_variable(
params, "stripe_account", stripe_account
)
headers = util.read_special_variable(params, "headers", None)

requestor = api_requestor.APIRequestor(
api_key, api_version=stripe_version, account=stripe_account
)
headers = util.populate_headers(idempotency_key)

if idempotency_key is not None:
headers = {} if headers is None else headers.copy()
headers.update(util.populate_headers(idempotency_key))

response, _ = requestor.request_stream(method_, url_, params, headers)
return response
13 changes: 13 additions & 0 deletions stripe/stripe_object.py
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,19 @@ def _request(
headers=None,
params=None,
):
params = None if params is None else params.copy()
api_key = util.read_special_variable(params, "api_key", api_key)
idempotency_key = util.read_special_variable(
params, "idempotency_key", idempotency_key
)
stripe_version = util.read_special_variable(
params, "stripe_version", stripe_version
)
stripe_account = util.read_special_variable(
params, "stripe_account", stripe_account
)
headers = util.read_special_variable(params, "headers", headers)

stripe_account = stripe_account or self.stripe_account
stripe_version = stripe_version or self.stripe_version
api_key = api_key or self.api_key
Expand Down
14 changes: 14 additions & 0 deletions stripe/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,20 @@ def populate_headers(idempotency_key):
return None


def read_special_variable(params, key_name, default_value):
value = default_value
params_value = None

if params is not None and key_name in params:
params_value = params[key_name]
del params[key_name]

if value is None:
value = params_value

return value


def merge_dicts(x, y):
z = x.copy()
z.update(y)
Expand Down
19 changes: 19 additions & 0 deletions tests/api_resources/abstract/test_api_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,25 @@ def test_retrieve_and_refresh(self, request_mock):
with pytest.raises(KeyError):
res["bobble"]

def test_request_with_special_fields_prefers_explicit(self, request_mock):
url = "/v1/myresources/foo"
request_mock.stub_request(
"get",
url,
{"id": "foo2", "bobble": "scrobble"},
)

self.MyResource._static_request(
"get",
"/v1/myresources/foo",
idempotency_key="explicit",
params={"idempotency_key": "params", "bobble": "scrobble"},
)

request_mock.assert_requested(
"get", url, {"bobble": "scrobble"}, {"Idempotency-Key": "explicit"}
)

def test_convert_to_stripe_object(self):
sample = {
"foo": "bar",
Expand Down
111 changes: 111 additions & 0 deletions tests/api_resources/abstract/test_custom_method.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,37 @@ def do_stream_stuff(self, idempotency_key=None, **params):
headers = util.populate_headers(idempotency_key)
return self.request_stream("post", url, params, headers)

@classmethod
def _cls_do_stuff_new_codegen(
cls,
id,
api_key=None,
stripe_version=None,
stripe_account=None,
**params
):
return cls._static_request(
"post",
"/v1/myresources/{id}/do_the_thing".format(
id=util.sanitize_id(id)
),
api_key=api_key,
stripe_version=stripe_version,
stripe_account=stripe_account,
params=params,
)

@util.class_method_variant("_cls_do_stuff_new_codegen")
def do_stuff_new_codegen(self, idempotency_key=None, **params):
return self._request(
"post",
"/v1/myresources/{id}/do_the_thing".format(
id=util.sanitize_id(self.get("id"))
),
idempotency_key=idempotency_key,
params=params,
)

def test_call_custom_method_class(self, request_mock):
request_mock.stub_request(
"post",
Expand Down Expand Up @@ -193,3 +224,83 @@ def test_call_custom_stream_method_instance(self, request_mock):
body_content = body_content.decode("utf-8")

assert body_content == "response body"

def test_call_custom_method_class_special_fields(self, request_mock):
request_mock.stub_request(
"post",
"/v1/myresources/mid/do_the_thing",
{"id": "mid", "thing_done": True},
rheaders={"request-id": "req_id"},
)

self.MyResource.do_stuff(
"mid",
foo="bar",
stripe_version="2017-08-15",
api_key="APIKEY",
idempotency_key="IdempotencyKey",
stripe_account="Acc",
)

request_mock.assert_requested(
"post",
"/v1/myresources/mid/do_the_thing",
{"foo": "bar"},
{"Idempotency-Key": "IdempotencyKey"},
)
request_mock.assert_api_version("2017-08-15")

def test_call_custom_method_class_newcodegen_special_fields(
self, request_mock
):
request_mock.stub_request(
"post",
"/v1/myresources/mid/do_the_thing",
{"id": "mid", "thing_done": True},
rheaders={"request-id": "req_id"},
)

self.MyResource.do_stuff_new_codegen(
"mid",
foo="bar",
stripe_version="2017-08-15",
api_key="APIKEY",
idempotency_key="IdempotencyKey",
stripe_account="Acc",
)

request_mock.assert_requested(
"post",
"/v1/myresources/mid/do_the_thing",
{"foo": "bar"},
{"Idempotency-Key": "IdempotencyKey"},
)
request_mock.assert_api_version("2017-08-15")

def test_call_custom_method_instance_newcodegen_special_fields(
self, request_mock
):
request_mock.stub_request(
"post",
"/v1/myresources/mid/do_the_thing",
{"id": "mid", "thing_done": True},
rheaders={"request-id": "req_id"},
)

obj = self.MyResource.construct_from({"id": "mid"}, "mykey")
obj.do_stuff_new_codegen(
foo="bar",
stripe_version="2017-08-15",
api_key="APIKEY",
idempotency_key="IdempotencyKey",
stripe_account="Acc",
headers={"extra_header": "val"},
)

request_mock.assert_requested(
"post",
"/v1/myresources/mid/do_the_thing",
{"foo": "bar"},
{"Idempotency-Key": "IdempotencyKey", "extra_header": "val"},
)
request_mock.assert_api_version("2017-08-15")
25 changes: 25 additions & 0 deletions tests/api_resources/abstract/test_deletable_api_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,3 +60,28 @@ def test_delete_instance(self, request_mock):

assert obj.last_response is not None
assert obj.last_response.request_id == "req_id"

def test_delete_with_all_special_fields(self, request_mock):
request_mock.stub_request(
"delete",
"/v1/mydeletables/foo",
{"id": "foo", "bobble": "new_scrobble"},
{"Idempotency-Key": "IdempotencyKey"},
)

self.MyDeletable.delete(
"foo",
stripe_version="2017-08-15",
api_key="APIKEY",
idempotency_key="IdempotencyKey",
stripe_account="Acc",
bobble="new_scrobble",
)

request_mock.assert_requested(
"delete",
"/v1/mydeletables/foo",
{"bobble": "new_scrobble"},
{"Idempotency-Key": "IdempotencyKey"},
)
request_mock.assert_api_version("2017-08-15")
26 changes: 26 additions & 0 deletions tests/api_resources/abstract/test_updateable_api_resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,3 +346,29 @@ def test_retrieve_and_update_with_stripe_version(self, request_mock, obj):
res.save()

request_mock.assert_api_version("2017-08-15")

def test_modify_with_all_special_fields(self, request_mock, obj):
request_mock.stub_request(
"post",
"/v1/myupdateables/foo",
{"id": "foo", "bobble": "new_scrobble"},
{"Idempotency-Key": "IdempotencyKey"},
)

self.MyUpdateable.modify(
"foo",
stripe_version="2017-08-15",
api_key="APIKEY",
idempotency_key="IdempotencyKey",
stripe_account="Acc",
bobble="new_scrobble",
headers={"extra_header": "val"},
)

request_mock.assert_requested(
"post",
"/v1/myupdateables/foo",
{"bobble": "new_scrobble"},
{"Idempotency-Key": "IdempotencyKey", "extra_header": "val"},
)
request_mock.assert_api_version("2017-08-15")