from __future__ import annotations import json from pytest_httpx import HTTPXMock from ebay_client.account.client import AccountClient from ebay_client.core.auth.models import OAuthToken from ebay_client.core.http.transport import ApiTransport from ebay_client.feed.client import FeedClient from ebay_client.fulfillment.client import FulfillmentClient from ebay_client.generated.account.models import Programs 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 class DummyOAuthClient: def get_valid_token(self, *, scopes: list[str] | None = None) -> OAuthToken: return OAuthToken(access_token="test-token", scope=" ".join(scopes or [])) def build_transport() -> ApiTransport: return ApiTransport(base_url="https://api.ebay.com", oauth_client=DummyOAuthClient()) def test_notification_wrapper_returns_pydantic_model(httpx_mock: HTTPXMock) -> None: httpx_mock.add_response( method="GET", url="https://api.ebay.com/commerce/notification/v1/topic?limit=10", json={"topics": [{"topicId": "MARKETPLACE_ACCOUNT_DELETION", "description": "topic"}], "total": 1}, ) client = NotificationClient(build_transport()) result = client.get_topics(limit=10) assert isinstance(result, TopicSearchResponse) assert result.total == 1 assert result.topics and result.topics[0].topicId == "MARKETPLACE_ACCOUNT_DELETION" request = httpx_mock.get_requests()[0] assert request.headers["Authorization"] == "Bearer test-token" def test_notification_wrapper_serializes_typed_request_model(httpx_mock: HTTPXMock) -> None: httpx_mock.add_response( method="POST", url="https://api.ebay.com/commerce/notification/v1/destination", json={}, status_code=201, ) client = NotificationClient(build_transport()) payload = DestinationRequest( name="main-destination", status="ENABLED", deliveryConfig=DeliveryConfig( endpoint="https://example.test/webhook", verificationToken="verification_token_1234567890123456", ), ) client.create_destination(payload) request = httpx_mock.get_requests()[0] body = json.loads(request.content.decode("utf-8")) assert body["name"] == "main-destination" 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", url="https://api.ebay.com/sell/inventory/v1/inventory_item/SKU-1", json={"sku": "SKU-1"}, ) client = InventoryClient(build_transport()) result = client.get_inventory_item("SKU-1") assert isinstance(result, InventoryItemWithSkuLocaleGroupid) assert result.sku == "SKU-1" def test_fulfillment_wrapper_returns_order_model(httpx_mock: HTTPXMock) -> None: httpx_mock.add_response( method="GET", url="https://api.ebay.com/sell/fulfillment/v1/order/ORDER-1", json={"orderId": "ORDER-1"}, ) client = FulfillmentClient(build_transport()) result = client.get_order("ORDER-1") assert isinstance(result, Order) assert result.orderId == "ORDER-1" def test_account_wrapper_returns_programs_model(httpx_mock: HTTPXMock) -> None: httpx_mock.add_response( method="GET", url="https://api.ebay.com/sell/account/v1/program/get_opted_in_programs", json={"programs": [{"programType": "OUT_OF_STOCK_CONTROL"}]}, ) client = AccountClient(build_transport()) result = client.get_opted_in_programs() assert isinstance(result, Programs) assert result.programs and result.programs[0].programType == "OUT_OF_STOCK_CONTROL" def test_feed_wrapper_returns_task_collection_model(httpx_mock: HTTPXMock) -> None: httpx_mock.add_response( method="GET", url="https://api.ebay.com/sell/feed/v1/task?feed_type=LMS_ORDER_REPORT", json={"tasks": [{"taskId": "TASK-1"}], "total": 1}, ) client = FeedClient(build_transport()) result = client.get_tasks(feed_type="LMS_ORDER_REPORT") assert isinstance(result, TaskCollection) assert result.total == 1 assert result.tasks and result.tasks[0].taskId == "TASK-1"