Dispatch now prices rides with a basic model inspired by public information on Uber and Lyft (docs/pricing.md): base + per mile + per minute, times a per-zone surge multiplier from recent requests against available drivers, plus a booking fee, with a minimum. Riders get an upfront quote per ride type and book against it; drivers see and earn a configurable share (75%) of the fare. Rate cards are per market, chosen by pickup location: San Francisco (third-party 2026 rates) and Fairbanks, AK (its own UberX and UberXL rates, Comfort from Anchorage, no Black). Everything is configurable via PRICING_FILE or POST /test/reset. Tests use a simple test card by default so auction scenarios keep their numbers; new scenarios cover SF rates, Fairbanks rates and surge. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
23 lines
1 KiB
TypeScript
23 lines
1 KiB
TypeScript
import { defineScenario, tid } from '../support/e2e';
|
|
import { scaled } from '../support/pace';
|
|
import { alice, james, maria } from '../support/phones';
|
|
|
|
export default defineScenario('raises the price when a round runs out of time', () => {
|
|
cy.resetDispatch({ policy: { roundDurationMs: 3000 } });
|
|
cy.openPhones([alice, maria, james]);
|
|
cy.requestRide('alice', 'ferry', 'Ferry Building');
|
|
|
|
// Maria passes but James never answers, so round 1 lasts its full 3 s.
|
|
cy.pass('maria');
|
|
cy.phone('alice').find(tid('round-number')).should('have.text', 'Round 1');
|
|
|
|
cy.phone('alice').find(tid('round-number'), { timeout: scaled(8000) }).should('have.text', 'Round 2');
|
|
cy.phone('james').find(tid('offer-price')).should('have.text', '$9.35');
|
|
cy.accept('james');
|
|
|
|
cy.phone('alice').find(tid('ride-fare')).should('have.text', '$9.35');
|
|
cy.dispatchState().then(({ rides }) => {
|
|
expect(rides[0].rounds[0]).to.include({ price: 8.8, acceptedBy: null });
|
|
expect(rides[0].rounds[0].declined).to.deep.equal(['maria']);
|
|
});
|
|
});
|