Skip to content
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
title: Support `EventNotification`s with singleton related objects
pr_url: https://github.com/stripe/stripe-python/pull/1904
jira_tickets_closed:
- RUN_DEVSDK-2825
---
1 change: 1 addition & 0 deletions stripe/v2/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from stripe.v2.core._event import (
EventNotification as EventNotification,
RelatedObject as RelatedObject,
RelatedSingletonObject as RelatedSingletonObject,
Reason as Reason,
ReasonRequest as ReasonRequest,
)
Expand Down
12 changes: 12 additions & 0 deletions stripe/v2/core/_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,18 @@ def __repr__(self) -> str:
return f"<RelatedObject id={self.id} type={self.type} url={self.url}>"


class RelatedSingletonObject:
type: str
url: str

def __init__(self, d) -> None:
self.type = d["type"]
self.url = d["url"]

def __repr__(self) -> str:
return f"<RelatedSingletonObject type={self.type} url={self.url}>"


class EventNotification:
"""
EventNotification represents the json that's delivered from an Event Destination. It's a basic struct-like object with a few convenience methods. Use `fetch_event()` to get the full event object.
Expand Down
10 changes: 10 additions & 0 deletions tests/test_exports.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ def test_can_import_webhook_members() -> None:
)


def test_can_import_event_notification_members() -> None:
from stripe.v2.core import (
EventNotification, # pyright: ignore[reportUnusedImport]
Reason, # pyright: ignore[reportUnusedImport]
ReasonRequest, # pyright: ignore[reportUnusedImport]
RelatedObject, # pyright: ignore[reportUnusedImport]
RelatedSingletonObject, # pyright: ignore[reportUnusedImport]
)


def test_can_import_abstract() -> None:
from stripe import (
APIResource, # pyright: ignore[reportUnusedImport]
Expand Down
19 changes: 18 additions & 1 deletion tests/test_v2_event.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,11 @@
V1BillingMeterErrorReportTriggeredEventNotification,
V1BillingMeterErrorReportTriggeredEvent,
)
from stripe.v2.core._event import EventNotification, UnknownEventNotification
from stripe.v2.core._event import (
EventNotification,
RelatedSingletonObject,
UnknownEventNotification,
)
from stripe.events._event_classes import ALL_EVENT_NOTIFICATIONS
from stripe._webhook import WebhookPayload, WebhookSignature
from tests.test_webhook import DUMMY_WEBHOOK_SECRET
Expand Down Expand Up @@ -198,6 +202,19 @@ def test_parses_unknown_event_notif(self, parse_event_notif: EventParser):
assert type(event) is UnknownEventNotification
assert event.related_object

def test_related_singleton_object_omits_id(self):
"""
events whose related object is a singleton get a `RelatedSingletonObject`,
which has no `id` at all (instead of a perpetually-`None` one)
"""
related_object = RelatedSingletonObject(
{"type": "balance", "url": "/v1/balance"}
)

assert related_object.type == "balance"
assert related_object.url == "/v1/balance"
assert not hasattr(related_object, "id")

def test_raise_on_v1_payload(self, parse_event_notif: EventParser):
v1_payload = json.dumps(
{
Expand Down