1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
|
from stripe._error import InvalidRequestError
from urllib.parse import quote_plus
from typing import TypeVar, ClassVar, Any
from typing_extensions import Protocol
from stripe._api_resource import APIResource
T = TypeVar("T", bound=APIResource[Any])
class APIResourceTestHelpers(Protocol[T]):
"""
The base type for the TestHelper nested classes.
Handles request URL generation for test_helper custom methods.
Should be used in combination with the @test_helpers decorator.
@test_helpers
class Foo(APIResource):
class TestHelpers(APIResourceTestHelpers):
"""
_resource_cls: ClassVar[Any]
resource: T
def __init__(self, resource):
self.resource = resource
@classmethod
def _static_request(cls, *args, **kwargs):
return cls._resource_cls._static_request(*args, **kwargs)
@classmethod
async def _static_request_async(cls, *args, **kwargs):
return await cls._resource_cls._static_request_async(*args, **kwargs)
@classmethod
def _static_request_stream(cls, *args, **kwargs):
return cls._resource_cls._static_request_stream(*args, **kwargs)
@classmethod
def class_url(cls):
if cls == APIResourceTestHelpers:
raise NotImplementedError(
"APIResourceTestHelpers is an abstract class. You should perform "
"actions on its subclasses (e.g. Charge, Customer)"
)
# Namespaces are separated in object names with periods (.) and in URLs
# with forward slashes (/), so replace the former with the latter.
base = cls._resource_cls.OBJECT_NAME.replace(".", "/")
return "/v1/test_helpers/%ss" % (base,)
def instance_url(self):
id = getattr(self.resource, "id", None)
if not isinstance(id, str):
raise InvalidRequestError(
"Could not determine which URL to request: %s instance "
"has invalid ID: %r, %s. ID should be of type `str` (or"
" `unicode`)" % (type(self).__name__, id, type(id)),
"id",
)
base = self.class_url()
extn = quote_plus(id)
return "%s/%s" % (base, extn)
|