Ask
We need a test plan for two WebMCP filter changes, written from the spec alone before the implementation exists
Goal and context
We are adding two optional filters to the read-only WebMCP tools Pumasi exposes to a coding agent running in the user's browser. We want the tests designed by someone who has not seen, and will not see, the implementation. The implementer will get your plan and must make every case pass; cases the spec cannot support should be flagged rather than guessed at. What the spec decides: `find_offers` is a same-origin POST that today takes one optional free-text `query` (max 200 chars) and returns the active Offers whose title, summary, description, category, or tags contain the query as a case-insensitive substring. It gains two optional inputs: `category`, one of eight fixed keys (`engineering`, `product`, `design`, `writing`, `research`, `marketing`, `career`, `business`), and `workType`, one of five fixed keys (`review`, `create`, `analyze`, `transform`, `plan`). All three inputs are combined with AND. The free-text search now also matches the human-readable labels of category and work type, so a query of the Korean label for `review` matches an Offer whose work type is `review`. Every returned Offer gains six fields: `category`, `categoryLabel`, `workType`, `workTypeLabel`, `whoItsFor` (non-empty string), `notFor` (string or null). Unknown input fields, or a `category`/`workType` outside the fixed keys, are rejected with HTTP 400 and the error code `invalid_input`. `list_open_requests` is a GET whose query string today may contain only `action=list_open_requests`; any other key, or a repeated key, is HTTP 400 `invalid_query`. It gains optional `category` and `workType` query parameters with the same fixed keys, combined with AND, and returns Open Requests with `workType`, `categoryLabel`, and `workTypeLabel` added. Any other key, any repeated key, or an out-of-range value remains 400 `invalid_query`. This endpoint works signed-out. Fixtures you can rely on: two seeded Offers exist. One is category `product`, work type `review`; the other is category `engineering`, work type `create`. Both have a non-null `notFor`. Open Requests can be created in tests by an authenticated Member through the existing creation path, which after this change requires a `category` and `workType` from the fixed keys. Test layers available: `tests/integration/*.test.ts` run against a real Postgres with the Next.js route handlers invoked directly; `tests/e2e/*.spec.ts` are Playwright and can read the tools the page registers on `document.modelContext`. There are existing files `tests/integration/offer-catalog.test.ts` and `tests/e2e/product-flow.spec.ts` that exercise the current tools. The acceptance criteria the plan must cover: `find_offers` with `workType: "review"` returns only the product Offer, with `"create"` only the engineering Offer, with `category: "design"` none; `category` plus `query` together behave as AND; each returned Offer carries the six fields; `list_open_requests` filtered by category returns only matching Open Requests; an unknown key or out-of-range value returns 400 `invalid_query`; the registered `find_offers` tool's input schema on `/offers` exposes the two optional enum fields.
Result you want
A Markdown test plan with these sections. 1. **Cases.** A numbered list. Each case has: the layer (integration or e2e), the exact input (HTTP method, body or query string, signed-in or signed-out), the expected status and the exact assertions on the response, and the sentence of the spec it verifies. Group cases by endpoint. Include negative cases for every rejection rule, boundary cases for the AND combination (each filter alone, pairs, all three), and at least one case for the label-matching rule. 2. **Cases the spec cannot support.** Anything you wanted to test but the spec leaves undefined (for example ordering of results, behaviour when both `query` and a filter match nothing, case sensitivity of keys). One line each, with what decision would make it testable. 3. **Fixture needs.** Any Open Request or Offer state the cases require beyond the two seeded Offers, described as data, not as code. 4. **Coverage note.** Which acceptance criteria are covered by which case numbers, so we can see gaps at a glance. Do not write test code. Do not propose implementation. Aim for the smallest set of cases that still covers every rule; padding with near-duplicates makes the plan worse.
Reference notes
Existing tool registration for `find_offers` (input schema today): ```ts const findOffersInputSchema = z.object({ query: z.string().trim().max(200).optional() }).strict(); ``` Existing GET query guard (today allows only `action`): ```ts function queryAction(request, schema) { const searchParams = new URL(request.url).searchParams; const values = searchParams.getAll("action"); if ([...searchParams.keys()].some((key) => key !== "action") || values.length !== 1) { throw new InvalidQueryError(); } ... } ``` Error shape for every rejection: `{ "error": { "code": string, "message": string } }`. ---
Details
- Response
- One answer
- Credits
- 500
The Request is public. Only the Member who asked and the Member who answers see the Result.