test: cover the cart capability (cart.md) - #108
Open
vishkaty wants to merge 1 commit into
Open
Conversation
The suite has no cart coverage today. The reference server implements and
advertises dev.ucp.shopping.cart, so the capability is testable, and cart.md
states business obligations that no existing module asserts.
This adds four assertions, each traced to a MUST:
cart.md:66 cart contents win over overlapping fields in the checkout
payload on conversion
cart.md:72-74 a second conversion of the same cart returns the existing
incomplete checkout rather than creating a new one
cart.md:185 cancel returns the cart state as it was before deletion
discount.md:143 discount codes applied to a cart carry forward to the
checkout the cart converts into
Kept server agnostic: line items are compared as a bag of item id and quantity
rather than by server assigned identifiers, the conversion identity check
compares checkout ids rather than totals arithmetic, both 200 and 201 are
accepted where the specification does not pin a status, and the discount
assertion accepts any of the three wire signals a conformant business may use.
The module gates on the capability being advertised and skips honestly
otherwise, since cart is not in conformance_input.json required_capabilities.
Two nearby rules are deliberately not asserted. cart.md:176 (full replacement)
binds the platform rather than the business, so it is not an obligation this
suite can hold a merchant to. cart.md:186 (subsequent operations return
not_found) is a SHOULD, so the status after cancel is not asserted.
Testing. Against the reference server at the pinned ucp-sdk 0.4.6, the four
assertions pass, and each was shown to fail on its own by mutating the server:
taking line items from the request payload fails the first, disabling the
existing checkout lookup fails the second, emptying the cart before returning it
from cancel fails the third, and dropping cart discounts on conversion fails the
fourth. Removing the capability from the advertised profile makes all four skip
rather than fail. ruff check and ruff format are clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
cart_test.py, covering the cart capability. The suite has no cartcoverage today: the string
dev.ucp.shopping.cartappears nowhere in therepository, and the only occurrence of the word is one English usage in a
fulfillment_structure_test.pydocstring. The reference server implements andadvertises the capability, so it is testable now.
Four assertions, each traced to a MUST, each verified on the wire:
cart.md:66cart.md:72-74cart.md:185discount.md:143Line references are to
release/2026-04-08, the version this suite targets.Kept server agnostic
Issues #101 to #103 point out that assertions elsewhere encode the reference
merchant rather than the specification, so this module avoids that by
construction:
server assigned identifiers
fixture_ctx, so nothing is hardcodedbusiness may use: the echoed code, an
appliedentry, or a negativediscounttotal, becausediscount.md:145lets a business drop a code thatis no longer valid at checkout time
The module gates on the capability being advertised and skips honestly
otherwise, since cart is deliberately not in
conformance_input.jsonrequired_capabilities. The discount assertion additionally skips unless thediscount capability declares it extends cart, which
discount.md:59permits itnot to.
Deliberately not asserted
Two nearby rules look assertable and are not, which is worth stating so the
omission does not read as an oversight:
cart.md:176("full replacement") binds the platform, not the business.The business side sentence carries no RFC 2119 keyword, so this suite cannot
hold a merchant to it.
cart.md:186(subsequent operations returnnot_found) is a SHOULD, sothe status after cancel is not asserted.
Testing
Against the reference server at the pinned
ucp-sdk==0.4.6, run exactly as theworkflow runs it: 4 passed.
Each assertion was then shown to fail on its own, by mutating the reference
server and re-running. Each mutation failed exactly one assertion and nothing
else:
Removing cart from the advertised profile makes all four skip rather than fail.
ruff checkandruff format --checkare clean.Whole suite run for a control: unchanged.
order_test.pyfails two tests bothbefore and after this change, on a pristine tree with a fresh database and this
file absent, so those are pre-existing and unrelated.
Note on #107
This lands as a top level
cart_test.py, which is what the current workflowpicks up (
for test_file in *_test.py). #107 relocates every module intoshopping/<capability>/. Its diff has no cart content, so there is no overlap,but if it merges first this file should move to
shopping/cart/cart_test.py.Happy to rebase it that way, or to hold this until #107 lands, whichever suits.