Skip to content

Commit 6cc834c

Browse files
committed
test(hello_seller): add smoke coverage for four new rc.1+ stub methods
Add dispatch-path smoke tests for get_media_buys, list_creative_formats, list_creatives, and provide_performance_feedback, plus a validate_platform assertion that HelloSeller passes with zero soft-warns. Addresses pre-PR code-reviewer finding: zero coverage for the new stubs left regression paths silent. Also align class docstring to say 'soft-required' consistently with the module docstring and section comment. https://claude.ai/code/session_01SQEG3PCARK4eKHBbqu4fTS
1 parent dfdd8f5 commit 6cc834c

2 files changed

Lines changed: 81 additions & 2 deletions

File tree

examples/hello_seller.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,9 +88,10 @@ class HelloSeller(DecisioningPlatform):
8888
Implements all nine required methods of ``sales-non-guaranteed``: the
8989
five hard-required (``get_products``, ``create_media_buy``,
9090
``update_media_buy``, ``sync_creatives``, ``get_media_buy_delivery``)
91-
and the four required by the SalesPlatform Protocol in v6.0 rc.1+
91+
and the four soft-required by the SalesPlatform Protocol in v6.0 rc.1+
9292
(``get_media_buys``, ``list_creative_formats``, ``list_creatives``,
93-
``provide_performance_feedback``).
93+
``provide_performance_feedback``;
94+
see :data:`~adcp.decisioning.dispatch.RECOMMENDED_METHODS_PER_SPECIALISM`).
9495
9596
``validate_platform`` runs at boot and fails fast on any missing
9697
hard-required method; it soft-warns (or hard-fails in strict mode) for

tests/test_hello_seller_integration.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -256,3 +256,81 @@ async def test_advertised_tools_class_attribute_set(
256256
assert "update_media_buy" in PlatformHandler.advertised_tools
257257
assert "sync_creatives" in PlatformHandler.advertised_tools
258258
assert "get_media_buy_delivery" in PlatformHandler.advertised_tools
259+
260+
261+
@pytest.mark.asyncio
262+
async def test_get_media_buys_returns_empty_list(handler: PlatformHandler) -> None:
263+
"""Smoke: stub returns valid wire shape for get_media_buys."""
264+
from adcp.types import GetMediaBuysRequest
265+
266+
req = GetMediaBuysRequest(account={"account_id": "buyer-1"})
267+
resp = await handler.get_media_buys(req, ToolContext())
268+
assert isinstance(resp, dict)
269+
assert resp["media_buys"] == []
270+
271+
272+
@pytest.mark.asyncio
273+
async def test_list_creative_formats_returns_empty_list(handler: PlatformHandler) -> None:
274+
"""Smoke: stub returns valid wire shape for list_creative_formats."""
275+
from adcp.types import ListCreativeFormatsRequest
276+
277+
req = ListCreativeFormatsRequest()
278+
resp = await handler.list_creative_formats(req, ToolContext())
279+
assert isinstance(resp, dict)
280+
assert resp["formats"] == []
281+
282+
283+
@pytest.mark.asyncio
284+
async def test_list_creatives_returns_empty_list(handler: PlatformHandler) -> None:
285+
"""Smoke: stub returns valid wire shape for list_creatives."""
286+
from adcp.types import ListCreativesRequest
287+
288+
req = ListCreativesRequest(account={"account_id": "buyer-1"})
289+
resp = await handler.list_creatives(req, ToolContext())
290+
assert isinstance(resp, dict)
291+
assert resp["creatives"] == []
292+
293+
294+
@pytest.mark.asyncio
295+
async def test_provide_performance_feedback_acknowledges(handler: PlatformHandler) -> None:
296+
"""Smoke: stub returns success acknowledgment for provide_performance_feedback."""
297+
from adcp.types import ProvidePerformanceFeedbackRequest
298+
299+
req = ProvidePerformanceFeedbackRequest(
300+
account={"account_id": "buyer-1"},
301+
media_buy_id="mb_test",
302+
idempotency_key="perf-feedback-test-key-001",
303+
measurement_period={"start": "2026-05-01T00:00:00Z", "end": "2026-05-31T23:59:59Z"},
304+
performance_index=1.0,
305+
feedback=[],
306+
)
307+
resp = await handler.provide_performance_feedback(req, ToolContext())
308+
assert isinstance(resp, dict)
309+
assert resp["success"] is True
310+
311+
312+
@pytest.mark.asyncio
313+
async def test_validate_platform_no_soft_warns_on_hello_seller() -> None:
314+
"""HelloSeller passes validate_platform without any soft-warn for the
315+
four RECOMMENDED_METHODS_PER_SPECIALISM methods."""
316+
import warnings
317+
318+
from adcp.decisioning.dispatch import validate_platform
319+
320+
with warnings.catch_warnings(record=True) as w:
321+
warnings.simplefilter("always")
322+
validate_platform(_hello.HelloSeller())
323+
soft_warns = [
324+
x
325+
for x in w
326+
if any(
327+
m in str(x.message)
328+
for m in [
329+
"get_media_buys",
330+
"list_creative_formats",
331+
"list_creatives",
332+
"provide_performance_feedback",
333+
]
334+
)
335+
]
336+
assert soft_warns == [], f"Unexpected soft-warns: {[str(x.message) for x in soft_warns]}"

0 commit comments

Comments
 (0)