Fares arrive. Without a pass a ride costs $1.00 to unlock plus 15¢ a minute; a day pass includes the unlock and the first 30 minutes of every ride. The pull request represents “no pass” as a missing pass (null, nil or None) and reads each term with a default; the platform’s account screen shows the terms of whatever Pass choosePass returns, and choosePass is still a stub. Newer app versions may send pass kinds this version doesn’t know yet.
Every rider without a pass unlocks for free, and the account screen tells them they have a day pass. A pass kind this version doesn’t know is priced as no pass, so its holders are overcharged without anyone hearing about it.
Reproduce
startRideFlow(dock, false, "none"), then unlock("B-204") and endRide("B-204", 40). The receipt should say pay as you go, $7.00; today it says $6.00.
Acceptance criteria
- A ride without a pass costs $1.00 plus 15¢ a minute; with a day pass the unlock and the first 30 minutes are included.
- The receipt and the platform’s account screen show the same terms for the same pass kind: “none” is pay as you go, “day” is a day pass.
- An unknown pass kind is rejected, by choosePass and so by startRideFlow, with “unknown pass: <kind>”; it is never priced as no pass.
- NULL-OBJECT-101’s rules still hold: nothing is felt with haptics off, and failures never pulse.
Notes
- A ride case prints “locked B-204: <label>, <minutes> min, <fare>” after the unlock, then what was felt; a rejected start prints “rejected (<reason>)”.
- Account cases hand the chosen pass to the platform’s account screen, which prints “<label>: <free> free minutes, <fee> to unlock”.
- Keep the names and signatures of the functions the checker calls, including the pass chooser. Don’t change the account screen or the nudge: they are the platform team’s code.