diff --git a/ebay_client/account/client.py b/ebay_client/account/client.py index 19e7abf..9202d97 100644 --- a/ebay_client/account/client.py +++ b/ebay_client/account/client.py @@ -2,10 +2,19 @@ from __future__ import annotations from ebay_client.core.http.transport import ApiTransport from ebay_client.generated.account.models import ( + FulfillmentPolicy, + FulfillmentPolicyRequest, FulfillmentPolicyResponse, + PaymentPolicy, + PaymentPolicyRequest, PaymentPolicyResponse, Programs, + ReturnPolicy, + ReturnPolicyRequest, ReturnPolicyResponse, + SetFulfillmentPolicyResponse, + SetPaymentPolicyResponse, + SetReturnPolicyResponse, SellingPrivileges, ) @@ -27,6 +36,54 @@ class AccountClient: params={"marketplace_id": marketplace_id}, ) + def create_fulfillment_policy(self, payload: FulfillmentPolicyRequest) -> SetFulfillmentPolicyResponse: + return self.transport.request_model( + SetFulfillmentPolicyResponse, + "POST", + "/sell/account/v1/fulfillment_policy/", + scopes=[ACCOUNT_SCOPE], + headers={"Content-Type": "application/json"}, + json_body=payload.model_dump(by_alias=True, exclude_none=True), + ) + + def get_fulfillment_policy(self, fulfillment_policy_id: str) -> FulfillmentPolicy: + return self.transport.request_model( + FulfillmentPolicy, + "GET", + f"/sell/account/v1/fulfillment_policy/{fulfillment_policy_id}", + scope_options=ACCOUNT_READ_SCOPE_OPTIONS, + ) + + def update_fulfillment_policy( + self, + fulfillment_policy_id: str, + payload: FulfillmentPolicyRequest, + ) -> SetFulfillmentPolicyResponse: + return self.transport.request_model( + SetFulfillmentPolicyResponse, + "PUT", + f"/sell/account/v1/fulfillment_policy/{fulfillment_policy_id}", + scopes=[ACCOUNT_SCOPE], + headers={"Content-Type": "application/json"}, + json_body=payload.model_dump(by_alias=True, exclude_none=True), + ) + + def delete_fulfillment_policy(self, fulfillment_policy_id: str) -> None: + self.transport.request_json( + "DELETE", + f"/sell/account/v1/fulfillment_policy/{fulfillment_policy_id}", + scopes=[ACCOUNT_SCOPE], + ) + + def get_fulfillment_policy_by_name(self, *, marketplace_id: str, name: str) -> FulfillmentPolicy: + return self.transport.request_model( + FulfillmentPolicy, + "GET", + "/sell/account/v1/fulfillment_policy/get_by_policy_name", + scope_options=ACCOUNT_READ_SCOPE_OPTIONS, + params={"marketplace_id": marketplace_id, "name": name}, + ) + def get_payment_policies(self, *, marketplace_id: str) -> PaymentPolicyResponse: return self.transport.request_model( PaymentPolicyResponse, @@ -36,6 +93,50 @@ class AccountClient: params={"marketplace_id": marketplace_id}, ) + def create_payment_policy(self, payload: PaymentPolicyRequest) -> SetPaymentPolicyResponse: + return self.transport.request_model( + SetPaymentPolicyResponse, + "POST", + "/sell/account/v1/payment_policy", + scopes=[ACCOUNT_SCOPE], + headers={"Content-Type": "application/json"}, + json_body=payload.model_dump(by_alias=True, exclude_none=True), + ) + + def get_payment_policy(self, payment_policy_id: str) -> PaymentPolicy: + return self.transport.request_model( + PaymentPolicy, + "GET", + f"/sell/account/v1/payment_policy/{payment_policy_id}", + scope_options=ACCOUNT_READ_SCOPE_OPTIONS, + ) + + def update_payment_policy(self, payment_policy_id: str, payload: PaymentPolicyRequest) -> SetPaymentPolicyResponse: + return self.transport.request_model( + SetPaymentPolicyResponse, + "PUT", + f"/sell/account/v1/payment_policy/{payment_policy_id}", + scopes=[ACCOUNT_SCOPE], + headers={"Content-Type": "application/json"}, + json_body=payload.model_dump(by_alias=True, exclude_none=True), + ) + + def delete_payment_policy(self, payment_policy_id: str) -> None: + self.transport.request_json( + "DELETE", + f"/sell/account/v1/payment_policy/{payment_policy_id}", + scopes=[ACCOUNT_SCOPE], + ) + + def get_payment_policy_by_name(self, *, marketplace_id: str, name: str) -> PaymentPolicy: + return self.transport.request_model( + PaymentPolicy, + "GET", + "/sell/account/v1/payment_policy/get_by_policy_name", + scope_options=ACCOUNT_READ_SCOPE_OPTIONS, + params={"marketplace_id": marketplace_id, "name": name}, + ) + def get_return_policies(self, *, marketplace_id: str) -> ReturnPolicyResponse: return self.transport.request_model( ReturnPolicyResponse, @@ -45,6 +146,50 @@ class AccountClient: params={"marketplace_id": marketplace_id}, ) + def create_return_policy(self, payload: ReturnPolicyRequest) -> SetReturnPolicyResponse: + return self.transport.request_model( + SetReturnPolicyResponse, + "POST", + "/sell/account/v1/return_policy", + scopes=[ACCOUNT_SCOPE], + headers={"Content-Type": "application/json"}, + json_body=payload.model_dump(by_alias=True, exclude_none=True), + ) + + def get_return_policy(self, return_policy_id: str) -> ReturnPolicy: + return self.transport.request_model( + ReturnPolicy, + "GET", + f"/sell/account/v1/return_policy/{return_policy_id}", + scope_options=ACCOUNT_READ_SCOPE_OPTIONS, + ) + + def update_return_policy(self, return_policy_id: str, payload: ReturnPolicyRequest) -> SetReturnPolicyResponse: + return self.transport.request_model( + SetReturnPolicyResponse, + "PUT", + f"/sell/account/v1/return_policy/{return_policy_id}", + scopes=[ACCOUNT_SCOPE], + headers={"Content-Type": "application/json"}, + json_body=payload.model_dump(by_alias=True, exclude_none=True), + ) + + def delete_return_policy(self, return_policy_id: str) -> None: + self.transport.request_json( + "DELETE", + f"/sell/account/v1/return_policy/{return_policy_id}", + scopes=[ACCOUNT_SCOPE], + ) + + def get_return_policy_by_name(self, *, marketplace_id: str, name: str) -> ReturnPolicy: + return self.transport.request_model( + ReturnPolicy, + "GET", + "/sell/account/v1/return_policy/get_by_policy_name", + scope_options=ACCOUNT_READ_SCOPE_OPTIONS, + params={"marketplace_id": marketplace_id, "name": name}, + ) + def get_privileges(self) -> SellingPrivileges: return self.transport.request_model( SellingPrivileges, diff --git a/tests/test_public_wrappers.py b/tests/test_public_wrappers.py index 6b35509..e256366 100644 --- a/tests/test_public_wrappers.py +++ b/tests/test_public_wrappers.py @@ -9,7 +9,15 @@ 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.account.models import ( + FulfillmentPolicy, + FulfillmentPolicyRequest, + PaymentPolicy, + PaymentPolicyRequest, + Programs, + ReturnPolicy, + ReturnPolicyRequest, +) from ebay_client.generated.feed.models import TaskCollection from ebay_client.generated.fulfillment.models import Order from ebay_client.generated.inventory.models import InventoryItemWithSkuLocaleGroupid @@ -290,6 +298,99 @@ def test_account_wrapper_returns_programs_model(httpx_mock: HTTPXMock) -> None: assert result.programs and result.programs[0].programType == "OUT_OF_STOCK_CONTROL" +def test_account_wrapper_returns_policy_models_by_id_and_name(httpx_mock: HTTPXMock) -> None: + httpx_mock.add_response( + method="GET", + url="https://api.ebay.com/sell/account/v1/fulfillment_policy/FULFILL-1", + json={"fulfillmentPolicyId": "FULFILL-1", "name": "Fast shipping"}, + ) + httpx_mock.add_response( + method="GET", + url="https://api.ebay.com/sell/account/v1/payment_policy/get_by_policy_name?marketplace_id=EBAY_US&name=Default%20payment", + json={"paymentPolicyId": "PAY-1", "name": "Default payment"}, + ) + httpx_mock.add_response( + method="GET", + url="https://api.ebay.com/sell/account/v1/return_policy/get_by_policy_name?marketplace_id=EBAY_US&name=30%20day%20returns", + json={"returnPolicyId": "RET-1", "name": "30 day returns"}, + ) + + client = AccountClient(build_transport()) + fulfillment = client.get_fulfillment_policy("FULFILL-1") + payment = client.get_payment_policy_by_name(marketplace_id="EBAY_US", name="Default payment") + returns = client.get_return_policy_by_name(marketplace_id="EBAY_US", name="30 day returns") + + assert isinstance(fulfillment, FulfillmentPolicy) + assert fulfillment.fulfillmentPolicyId == "FULFILL-1" + assert isinstance(payment, PaymentPolicy) + assert payment.paymentPolicyId == "PAY-1" + assert isinstance(returns, ReturnPolicy) + assert returns.returnPolicyId == "RET-1" + + +def test_account_wrapper_serializes_policy_requests_and_delete(httpx_mock: HTTPXMock) -> None: + httpx_mock.add_response( + method="POST", + url="https://api.ebay.com/sell/account/v1/payment_policy", + json={"paymentPolicyId": "PAY-NEW"}, + status_code=201, + ) + httpx_mock.add_response( + method="PUT", + url="https://api.ebay.com/sell/account/v1/fulfillment_policy/FULFILL-1", + json={"fulfillmentPolicyId": "FULFILL-1"}, + status_code=200, + ) + httpx_mock.add_response( + method="DELETE", + url="https://api.ebay.com/sell/account/v1/return_policy/RET-1", + status_code=204, + ) + + client = AccountClient(build_transport()) + payment_payload = PaymentPolicyRequest(name="Default payment") + fulfillment_payload = FulfillmentPolicyRequest(name="Fast shipping") + + created_payment = client.create_payment_policy(payment_payload) + updated_fulfillment = client.update_fulfillment_policy("FULFILL-1", fulfillment_payload) + client.delete_return_policy("RET-1") + + assert created_payment.paymentPolicyId == "PAY-NEW" + assert updated_fulfillment.fulfillmentPolicyId == "FULFILL-1" + + create_request = httpx_mock.get_requests()[0] + create_body = json.loads(create_request.content.decode("utf-8")) + assert create_body["name"] == "Default payment" + + update_request = httpx_mock.get_requests()[1] + update_body = json.loads(update_request.content.decode("utf-8")) + assert update_body["name"] == "Fast shipping" + + +def test_account_wrapper_supports_return_policy_create_and_update(httpx_mock: HTTPXMock) -> None: + httpx_mock.add_response( + method="POST", + url="https://api.ebay.com/sell/account/v1/return_policy", + json={"returnPolicyId": "RET-NEW"}, + status_code=201, + ) + httpx_mock.add_response( + method="PUT", + url="https://api.ebay.com/sell/account/v1/return_policy/RET-NEW", + json={"returnPolicyId": "RET-NEW"}, + status_code=200, + ) + + client = AccountClient(build_transport()) + payload = ReturnPolicyRequest(name="30 day returns") + + created = client.create_return_policy(payload) + updated = client.update_return_policy("RET-NEW", payload) + + assert created.returnPolicyId == "RET-NEW" + assert updated.returnPolicyId == "RET-NEW" + + def test_feed_wrapper_returns_task_collection_model(httpx_mock: HTTPXMock) -> None: httpx_mock.add_response( method="GET",