The Cart Is Not the Evidence
Four "free for one month" promotions look identical in the cart. The field that makes them temporary exists only in the billing payload — and a device field that is always populated was always populated with the wrong device.
The cart looked right. That was the problem in both cases.
Four Promotions That Look Like One
Four campaign discounts, each giving the customer a free period — one month on some, three on others. They run on an opt-out model. Nobody cancels anything at the end. The billing system has to enforce the term itself and resume charging when it expires.
From the Salesforce cart, all four variants are indistinguishable. Same behaviour, same free line, different label. The one thing that separates them — the duration of the discount term — exists only in the payload that goes to the billing system.
Leave that term field indefinite and the customer has a permanent free subscription.
No error appears in Salesforce. The order is valid. The discount applied. The price on screen is exactly what the campaign promised. The failure is an event that does not happen, several months later, in a system the tester was never asked to open.
Why the Cart Cannot Tell You
The Salesforce half of an opt-out promotion is finished the moment the discount lands on the line. Everything that makes it temporary lives downstream.
So the cart is a record of the promise, and the payload is the record of the mechanism. Testing the promise proves that the agent sees the right thing. It proves nothing about whether the thing ever ends.
Testers skip that payload unless it is explicitly in scope, and it usually is not — because from the requirement's point of view, four discounts that behave identically in the UI read as one test repeated four times.
They are not. They are four values in one field, and the only place that field is visible is the integration layer.
The Field That Was Always Populated
Different feature, same shape.
On a service downgrade with no replacement device, the cart and the order details showed a Device Brand Model. It was populated every time. It was the device model of the downgraded target product — not the router the customer already has and keeps.
Always filled in. Always the wrong source.
That is a defect built to survive review. Every check a checklist can express, it passes. Is the field populated? Yes. Is it a valid model name? Yes. Does it match the product on the order? Yes — which is precisely the bug, because on this journey the product on the order is not where the device comes from.
Catching it requires knowing that a downgrade without a shipment leaves the existing device in place. That is domain knowledge, not test technique. The technique only tells you where to point it.
What These Two Were Not
Neither was a rendering problem, and neither was a missing-data problem. In both, the field was present and well-formed.
What was wrong in both was provenance. One value was missing a constraint that lives in another system. One value was correct for a source that was not the right source.
And the second one carries a trap in its fix. Populating the device from the customer's active asset is conditional — it applies when no shipment is required. The path where a new device genuinely does ship must keep showing the new device. A conditional fix always has an opposite branch, and the opposite branch is where the regression goes.
Two Rules Worth Carrying
Verify the implementation of "temporary" at the layer that implements it. When business logic uses a word like temporary, trial, introductory or promotional, find the field that encodes the end and assert its value in the payload. The word describes intent; one field carries it.
Assert the source of a value, not the presence of one. For any auto-populated field, the test case says where the value should have come from, and the expected result names that source. "Device Brand Model is populated" is not an assertion. "Device Brand Model shows the customer's existing active device, not the ordered product" is.
Both rules cost the same thing: one extra question during analysis, asked before the test cases exist. Where does this value come from, and what makes it stop?
In your last set of test cases, how many expected results say a field is filled in — and how many say what it should be filled in with?