Add NotificationClient methods for config and subscription management with tests
This commit is contained in:
parent
8f31f433d2
commit
1a9f924764
3 changed files with 243 additions and 0 deletions
|
|
@ -69,6 +69,8 @@ class ApiTransport:
|
|||
response = self.request(method, path, **kwargs)
|
||||
if response.status_code == 204:
|
||||
return None
|
||||
if not response.content or not response.content.strip():
|
||||
return None
|
||||
try:
|
||||
return response.json()
|
||||
except ValueError as exc:
|
||||
|
|
|
|||
|
|
@ -2,10 +2,16 @@ from __future__ import annotations
|
|||
|
||||
from ebay_client.core.http.transport import ApiTransport
|
||||
from ebay_client.generated.notification.models import (
|
||||
Config,
|
||||
CreateSubscriptionFilterRequest,
|
||||
CreateSubscriptionRequest,
|
||||
Destination,
|
||||
DestinationRequest,
|
||||
DestinationSearchResponse,
|
||||
PublicKey,
|
||||
Subscription,
|
||||
SubscriptionFilter,
|
||||
UpdateSubscriptionRequest,
|
||||
SubscriptionSearchResponse,
|
||||
Topic,
|
||||
TopicSearchResponse,
|
||||
|
|
@ -20,6 +26,23 @@ class NotificationClient:
|
|||
def __init__(self, transport: ApiTransport) -> None:
|
||||
self.transport = transport
|
||||
|
||||
def get_config(self) -> Config:
|
||||
return self.transport.request_model(
|
||||
Config,
|
||||
"GET",
|
||||
"/commerce/notification/v1/config",
|
||||
scopes=[NOTIFICATION_SCOPE],
|
||||
)
|
||||
|
||||
def update_config(self, payload: Config) -> None:
|
||||
self.transport.request_json(
|
||||
"PUT",
|
||||
"/commerce/notification/v1/config",
|
||||
scopes=[NOTIFICATION_SCOPE],
|
||||
headers={"Content-Type": "application/json"},
|
||||
json_body=payload.model_dump(by_alias=True, exclude_none=True),
|
||||
)
|
||||
|
||||
def get_topics(self, *, limit: int | None = None, continuation_token: str | None = None) -> TopicSearchResponse:
|
||||
return self.transport.request_model(
|
||||
TopicSearchResponse,
|
||||
|
|
@ -55,6 +78,30 @@ class NotificationClient:
|
|||
json_body=payload.model_dump(by_alias=True, exclude_none=True),
|
||||
)
|
||||
|
||||
def get_destination(self, destination_id: str) -> Destination:
|
||||
return self.transport.request_model(
|
||||
Destination,
|
||||
"GET",
|
||||
f"/commerce/notification/v1/destination/{destination_id}",
|
||||
scopes=[NOTIFICATION_SCOPE],
|
||||
)
|
||||
|
||||
def update_destination(self, destination_id: str, payload: DestinationRequest) -> None:
|
||||
self.transport.request_json(
|
||||
"PUT",
|
||||
f"/commerce/notification/v1/destination/{destination_id}",
|
||||
scopes=[NOTIFICATION_SCOPE],
|
||||
headers={"Content-Type": "application/json"},
|
||||
json_body=payload.model_dump(by_alias=True, exclude_none=True),
|
||||
)
|
||||
|
||||
def delete_destination(self, destination_id: str) -> None:
|
||||
self.transport.request_json(
|
||||
"DELETE",
|
||||
f"/commerce/notification/v1/destination/{destination_id}",
|
||||
scopes=[NOTIFICATION_SCOPE],
|
||||
)
|
||||
|
||||
def get_subscriptions(self, *, limit: int | None = None, continuation_token: str | None = None) -> SubscriptionSearchResponse:
|
||||
return self.transport.request_model(
|
||||
SubscriptionSearchResponse,
|
||||
|
|
@ -73,6 +120,72 @@ class NotificationClient:
|
|||
json_body=payload.model_dump(by_alias=True, exclude_none=True),
|
||||
)
|
||||
|
||||
def get_subscription(self, subscription_id: str) -> Subscription:
|
||||
return self.transport.request_model(
|
||||
Subscription,
|
||||
"GET",
|
||||
f"/commerce/notification/v1/subscription/{subscription_id}",
|
||||
scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_READ_SCOPE],
|
||||
)
|
||||
|
||||
def update_subscription(self, subscription_id: str, payload: UpdateSubscriptionRequest) -> None:
|
||||
self.transport.request_json(
|
||||
"PUT",
|
||||
f"/commerce/notification/v1/subscription/{subscription_id}",
|
||||
scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
|
||||
headers={"Content-Type": "application/json"},
|
||||
json_body=payload.model_dump(by_alias=True, exclude_none=True),
|
||||
)
|
||||
|
||||
def delete_subscription(self, subscription_id: str) -> None:
|
||||
self.transport.request_json(
|
||||
"DELETE",
|
||||
f"/commerce/notification/v1/subscription/{subscription_id}",
|
||||
scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
|
||||
)
|
||||
|
||||
def create_subscription_filter(
|
||||
self,
|
||||
subscription_id: str,
|
||||
payload: CreateSubscriptionFilterRequest,
|
||||
) -> dict[str, object] | None:
|
||||
return self.transport.request_json(
|
||||
"POST",
|
||||
f"/commerce/notification/v1/subscription/{subscription_id}/filter",
|
||||
scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
|
||||
headers={"Content-Type": "application/json"},
|
||||
json_body=payload.model_dump(by_alias=True, exclude_none=True),
|
||||
)
|
||||
|
||||
def get_subscription_filter(self, subscription_id: str, filter_id: str) -> SubscriptionFilter:
|
||||
return self.transport.request_model(
|
||||
SubscriptionFilter,
|
||||
"GET",
|
||||
f"/commerce/notification/v1/subscription/{subscription_id}/filter/{filter_id}",
|
||||
scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_READ_SCOPE],
|
||||
)
|
||||
|
||||
def delete_subscription_filter(self, subscription_id: str, filter_id: str) -> None:
|
||||
self.transport.request_json(
|
||||
"DELETE",
|
||||
f"/commerce/notification/v1/subscription/{subscription_id}/filter/{filter_id}",
|
||||
scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
|
||||
)
|
||||
|
||||
def disable_subscription(self, subscription_id: str) -> None:
|
||||
self.transport.request_json(
|
||||
"POST",
|
||||
f"/commerce/notification/v1/subscription/{subscription_id}/disable",
|
||||
scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
|
||||
)
|
||||
|
||||
def enable_subscription(self, subscription_id: str) -> None:
|
||||
self.transport.request_json(
|
||||
"POST",
|
||||
f"/commerce/notification/v1/subscription/{subscription_id}/enable",
|
||||
scopes=[NOTIFICATION_SCOPE, NOTIFICATION_SUBSCRIPTION_SCOPE],
|
||||
)
|
||||
|
||||
def test_subscription(self, subscription_id: str) -> None:
|
||||
self.transport.request_json(
|
||||
"POST",
|
||||
|
|
|
|||
|
|
@ -14,9 +14,16 @@ from ebay_client.generated.feed.models import TaskCollection
|
|||
from ebay_client.generated.fulfillment.models import Order
|
||||
from ebay_client.generated.inventory.models import InventoryItemWithSkuLocaleGroupid
|
||||
from ebay_client.generated.notification.models import (
|
||||
Config,
|
||||
CreateSubscriptionFilterRequest,
|
||||
CreateSubscriptionRequest,
|
||||
DeliveryConfig,
|
||||
Subscription,
|
||||
SubscriptionFilter,
|
||||
SubscriptionPayloadDetail,
|
||||
DestinationRequest,
|
||||
TopicSearchResponse,
|
||||
UpdateSubscriptionRequest,
|
||||
)
|
||||
from ebay_client.inventory.client import InventoryClient
|
||||
from ebay_client.notification.client import NotificationClient
|
||||
|
|
@ -74,6 +81,127 @@ def test_notification_wrapper_serializes_typed_request_model(httpx_mock: HTTPXMo
|
|||
assert body["deliveryConfig"]["endpoint"] == "https://example.test/webhook"
|
||||
|
||||
|
||||
def test_notification_config_wrapper_round_trip(httpx_mock: HTTPXMock) -> None:
|
||||
httpx_mock.add_response(
|
||||
method="GET",
|
||||
url="https://api.ebay.com/commerce/notification/v1/config",
|
||||
json={"alertEmail": "alerts@example.test"},
|
||||
)
|
||||
httpx_mock.add_response(
|
||||
method="PUT",
|
||||
url="https://api.ebay.com/commerce/notification/v1/config",
|
||||
status_code=204,
|
||||
)
|
||||
|
||||
client = NotificationClient(build_transport())
|
||||
config = client.get_config()
|
||||
client.update_config(Config(alertEmail="ops@example.test"))
|
||||
|
||||
assert isinstance(config, Config)
|
||||
assert config.alertEmail == "alerts@example.test"
|
||||
request = httpx_mock.get_requests()[1]
|
||||
body = json.loads(request.content.decode("utf-8"))
|
||||
assert body["alertEmail"] == "ops@example.test"
|
||||
|
||||
|
||||
def test_notification_subscription_wrapper_serializes_and_returns_models(httpx_mock: HTTPXMock) -> None:
|
||||
httpx_mock.add_response(
|
||||
method="POST",
|
||||
url="https://api.ebay.com/commerce/notification/v1/subscription",
|
||||
json={},
|
||||
status_code=201,
|
||||
)
|
||||
httpx_mock.add_response(
|
||||
method="GET",
|
||||
url="https://api.ebay.com/commerce/notification/v1/subscription/SUB-1",
|
||||
json={"subscriptionId": "SUB-1", "topicId": "TOPIC-1", "status": "ENABLED"},
|
||||
)
|
||||
httpx_mock.add_response(
|
||||
method="PUT",
|
||||
url="https://api.ebay.com/commerce/notification/v1/subscription/SUB-1",
|
||||
status_code=204,
|
||||
)
|
||||
httpx_mock.add_response(
|
||||
method="POST",
|
||||
url="https://api.ebay.com/commerce/notification/v1/subscription/SUB-1/enable",
|
||||
status_code=204,
|
||||
)
|
||||
httpx_mock.add_response(
|
||||
method="POST",
|
||||
url="https://api.ebay.com/commerce/notification/v1/subscription/SUB-1/test",
|
||||
status_code=202,
|
||||
)
|
||||
|
||||
client = NotificationClient(build_transport())
|
||||
create_payload = CreateSubscriptionRequest(
|
||||
destinationId="DEST-1",
|
||||
topicId="TOPIC-1",
|
||||
status="DISABLED",
|
||||
payload=SubscriptionPayloadDetail(
|
||||
deliveryProtocol="HTTPS",
|
||||
format="JSON",
|
||||
schemaVersion="1.0",
|
||||
),
|
||||
)
|
||||
update_payload = UpdateSubscriptionRequest(status="ENABLED", destinationId="DEST-1")
|
||||
|
||||
client.create_subscription(create_payload)
|
||||
subscription = client.get_subscription("SUB-1")
|
||||
client.update_subscription("SUB-1", update_payload)
|
||||
client.enable_subscription("SUB-1")
|
||||
client.test_subscription("SUB-1")
|
||||
|
||||
assert isinstance(subscription, Subscription)
|
||||
assert subscription.subscriptionId == "SUB-1"
|
||||
create_request = httpx_mock.get_requests()[0]
|
||||
create_body = json.loads(create_request.content.decode("utf-8"))
|
||||
assert create_body["destinationId"] == "DEST-1"
|
||||
assert create_body["payload"]["deliveryProtocol"] == "HTTPS"
|
||||
update_request = httpx_mock.get_requests()[2]
|
||||
update_body = json.loads(update_request.content.decode("utf-8"))
|
||||
assert update_body == {"destinationId": "DEST-1", "status": "ENABLED"}
|
||||
|
||||
|
||||
def test_notification_subscription_filter_wrapper_serializes_and_returns_model(httpx_mock: HTTPXMock) -> None:
|
||||
httpx_mock.add_response(
|
||||
method="POST",
|
||||
url="https://api.ebay.com/commerce/notification/v1/subscription/SUB-1/filter",
|
||||
json={},
|
||||
status_code=201,
|
||||
)
|
||||
httpx_mock.add_response(
|
||||
method="GET",
|
||||
url="https://api.ebay.com/commerce/notification/v1/subscription/SUB-1/filter/FILTER-1",
|
||||
json={"filterId": "FILTER-1", "subscriptionId": "SUB-1", "filterStatus": "ENABLED"},
|
||||
)
|
||||
httpx_mock.add_response(
|
||||
method="DELETE",
|
||||
url="https://api.ebay.com/commerce/notification/v1/subscription/SUB-1/filter/FILTER-1",
|
||||
status_code=204,
|
||||
)
|
||||
|
||||
client = NotificationClient(build_transport())
|
||||
payload = CreateSubscriptionFilterRequest(
|
||||
filterSchema={
|
||||
"properties": {
|
||||
"data": {
|
||||
"type": "object",
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
client.create_subscription_filter("SUB-1", payload)
|
||||
subscription_filter = client.get_subscription_filter("SUB-1", "FILTER-1")
|
||||
client.delete_subscription_filter("SUB-1", "FILTER-1")
|
||||
|
||||
assert isinstance(subscription_filter, SubscriptionFilter)
|
||||
assert subscription_filter.filterId == "FILTER-1"
|
||||
request = httpx_mock.get_requests()[0]
|
||||
body = json.loads(request.content.decode("utf-8"))
|
||||
assert body["filterSchema"]["properties"]["data"]["type"] == "object"
|
||||
|
||||
|
||||
def test_inventory_wrapper_returns_inventory_item_model(httpx_mock: HTTPXMock) -> None:
|
||||
httpx_mock.add_response(
|
||||
method="GET",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue