Skip to content

test(seller-agent): add MCP-level tool tests and cover force_account_status - #475

Open
sujanchalla0510 wants to merge 1 commit into
adcontextprotocol:mainfrom
sujanchalla0510:test/seller-agent-focused-tests
Open

test(seller-agent): add MCP-level tool tests and cover force_account_status#475
sujanchalla0510 wants to merge 1 commit into
adcontextprotocol:mainfrom
sujanchalla0510:test/seller-agent-focused-tests

Conversation

@sujanchalla0510

Copy link
Copy Markdown

Summary

Closes #140.

reference/seller-agent already had strong, honest state-machine coverage for most of the issue's acceptance bullets — added incrementally after #138 merged (see #195, #245, and follow-on work). Before writing anything I read cmd/seller-agent/main_test.go in full to avoid duplicating that work, and cross-checked it line-by-line against every bullet in the issue:

  • create media buy with and without creative assignments — already covered (TestCreateMediaBuy_WithoutCreatives, TestCreateMediaBuy_WithCreatives)
  • pending_creatives -> active via sync_creatives and update_media_buy — already covered
  • cancellation and double-cancel — already covered (TestCancellation, TestDoubleCancellation)
  • list_creatives filtering by creative ID and format ID — already covered
  • delivery simulation/reporting — already covered
  • custom comply_test_controller scenarios (seed_product, seed_pricing_option, force_create_media_buy_arm) — already covered

Two real gaps remained, which this PR fixes:

  1. force_account_status had zero test coverage. It's one of the seller's own TestControllerStore methods (b.forceAccountStatus), wired into comply_test_controller, and nothing exercised it.
  2. Every existing test calls backend methods directly (b.createMediaBuy(...), b.updateMediaBuy(...), etc.), which exercises the state machine but bypasses the actual adcp.Register / adcp.AddTool / adcp.RegisterTestController wiring main() uses to serve requests. A regression in tool names, or in how a request/response gets JSON-mapped onto the wire, would compile fine and pass every existing test — the npm storyboard runner would be the only thing to catch it, which is exactly what the issue says shouldn't be the only safety net.

What's added

  • Refactor (no behavior change): extracted newServer(b *backend) *mcp.Server out of main() so tests can stand up the exact server main() runs, over an in-memory MCP transport. Verified with git diff -b that this is a pure whitespace/extraction diff — no logic changed.
  • main_mcp_test.go (new): 10 tests that call the real registered tools by name with JSON arguments (the way an MCP client, including the storyboard runner, would), covering every bullet in the issue's acceptance list end-to-end: create_media_buy with/without creative assignments, pending_creatives -> active via sync_creatives and update_media_buy, cancel + double-cancel (asserting the specific NOT_CANCELLABLE code, not just "is an error"), list_creatives filtering by creative_id/format_id, delivery simulation+reporting via comply_test_controller (simulate_delivery) + get_media_buy_delivery, and the seed_product/force_create_media_buy_arm custom scenarios through the wire.
  • main_test.go: 2 new unit tests closing the one real gap — TestForceAccountStatus and TestForceAccountStatus_NotFound.

Verification that these tests catch real regressions, not just compile

Per this project's own bar for proving a test is load-bearing, I broke three separate pieces of real logic, confirmed the new tests failed for the right reason, then restored the fix and reconfirmed everything passes:

  1. Commented out acct.Status = status in forceAccountStatusTestForceAccountStatus failed (forceAccountStatus did not persist new status, got active).
  2. Disabled the double-cancel guard in updateMediaBuyTestMCP_CancelAndDoubleCancel failed (want NOT_CANCELLABLE on double-cancel, got "INVALID_TRANSITION") — and notably, the pre-existing TestDoubleCancellation kept passing, because it only asserts IsError, not the specific code. This is a concrete example of the MCP-level tests catching something the existing suite didn't.
  3. Zeroed out the spend term in simulateDelivery's weightedSpend call → both the new TestMCP_DeliverySimulationAndReporting and the pre-existing TestDeliveryReporting_SimulateDelivery/TestDeliveryReporting_SimulateDeliveryWeightsSpendByBudget correctly failed.

Acceptance criteria

  • cd reference/seller-agent && go test ./... — 44 tests, all passing, exercising every state transition in the issue (create/no-create, activation via both paths, cancel/double-cancel, filtering, delivery, and all three custom scenarios) without the npm storyboard runner.
  • Storyboard harness (scripts/ci/run_storyboard_reference_seller.sh from [codex] Add Go reference seller storyboard harness #138) is untouched and remains the end-to-end compliance check.

Validation

cd reference/seller-agent && go build ./... && go vet ./... && go test ./... -v
go build ./...   # repo root
go vet ./...     # repo root

All green. git status is clean — this PR touches exactly reference/seller-agent/cmd/seller-agent/{main.go,main_test.go,main_mcp_test.go}.

Note on scope

I did not add a general integration test for get_media_buys account-scoping, sync_accounts, or the standard force_media_buy_status/force_creative_status scenarios beyond what already existed, since those are outside the issue's explicit bullet list and already have direct or indirect coverage (TestForceMediaBuyStatus*, TestImpairmentsRequireMaterialCreativeImpactAndNewReopenID exercising forceCreativeStatus). Happy to extend if maintainers want broader coverage in the same pass.

…status

reference/seller-agent already had strong backend-method-level tests for
most of issue adcontextprotocol#140's acceptance list (create_media_buy, pending_creatives ->
active, cancel/double-cancel, list_creatives filtering, delivery reporting,
and the seed_product/seed_pricing_option/force_create_media_buy_arm custom
comply_test_controller scenarios), added incrementally after adcontextprotocol#138 merged.
Two real gaps remained:

- forceAccountStatus (the force_account_status compliance scenario) had no
  test at all.
- every existing test calls backend methods directly, bypassing the actual
  adcp.Register/adcp.AddTool/adcp.RegisterTestController wiring main() uses
  to serve requests — so a regression in tool names or request/response
  field mapping would only be caught by the npm storyboard runner.

Extract newServer(b *backend) *mcp.Server out of main() (pure refactor, no
behavior change) so tests can stand up the real registered server over an
in-memory MCP transport, and add main_mcp_test.go covering every bullet in
the issue through actual tool calls: create_media_buy with/without creative
assignments, pending_creatives -> active via sync_creatives and
update_media_buy, cancel + double-cancel (asserting the specific
NOT_CANCELLABLE code), list_creatives filtering by creative_id and
format_id, delivery simulation/reporting via comply_test_controller +
get_media_buy_delivery, and the seed_product/force_create_media_buy_arm
custom scenarios end to end.

Verified the new tests catch real regressions, not just compile: breaking
forceAccountStatus's status assignment, the double-cancel guard, and
simulateDelivery's spend accumulation each failed the corresponding new
test (the double-cancel and delivery breaks also exposed that the existing
tests check IsError/spend but not the specific error code the new MCP test
asserts), then restored and reconfirmed all tests pass.

Closes adcontextprotocol#140.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add focused tests for the Go reference seller

1 participant