Files
vending-machine-game/tests/payment.test.js
T
HamedandClaude Opus 5.5 95a2ae851d Turn the game into a third-person Mashhad city game
Replace the linear forest walk with an open area of real western Mashhad
built from OpenStreetMap data, starting at Park Mellat. A father and child,
guided by the Robot Market robot, find vending machines at a park, school,
universities, a metro station and a mall, on foot or by car.

- Iran province briefing map; only Mashhad is unlocked
- Third-person camera, building collision, arcade car and ambient traffic
- Minimap and full city map with addresses, opening hours and A* routing
- Purchase scoring, missions with cash rewards, ranks and an end screen
- Map data build script (OSM + Natural Earth) and new logic tests

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 11:27:48 +03:30

48 lines
2.3 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import {createState, purchaseBlocker, priceAt, canAffordAnything, formatClock} from '../src/game-state.js';
import {createPayment, beginPayment, readyPayment, swipePayment, cancelPayment} from '../src/payment.js';
import {machineById, machines} from '../src/locations.js';
const park = machineById('mellat-park'), school = machineById('school-rahil'), uni = machineById('ferdowsi-university');
test('Payment charges once, only after ready and an explicit swipe', () => {
const state = createState(), payment = createPayment();
assert.ok(beginPayment(state, payment, park, 'juice'));
assert.equal(state.balance, 500);
assert.equal(swipePayment(state, payment), false, 'not ready yet');
assert.ok(readyPayment(payment));
assert.ok(swipePayment(state, payment));
assert.equal(state.balance, 465);
assert.equal(swipePayment(state, payment), false, 'no double charge');
assert.equal(state.purchases.length, 1);
assert.equal(beginPayment(state, createPayment(), park, 'water'), false, 'busy until delivery ends');
});
test('Cancel, closed machines, unknown products and low funds never charge', () => {
const state = createState(), payment = createPayment();
assert.ok(beginPayment(state, payment, park, 'cake'));
assert.ok(cancelPayment(state, payment));
assert.equal(state.balance, 500);
assert.equal(state.busy, false);
assert.equal(purchaseBlocker(state, park, 'not-a-product'), 'unknown');
assert.equal(purchaseBlocker(state, school, 'nuts'), 'unknown', 'school does not sell nuts');
state.minutes = 14 * 60;
assert.equal(purchaseBlocker(state, school, 'water'), 'closed');
state.minutes = 9 * 60;
state.balance = 10;
assert.equal(purchaseBlocker(state, park, 'water'), 'funds');
assert.equal(beginPayment(state, payment, park, 'water'), false);
});
test('Prices follow machine discounts and the clock is Persian', () => {
assert.equal(priceAt(uni, 'nuts'), 52);
assert.equal(priceAt(park, 'nuts'), 65);
assert.equal(formatClock(8 * 60 + 5), '۰۸:۰۵');
const state = createState();
state.balance = 5;
assert.equal(canAffordAnything(state, machines), false);
state.balance = 15;
assert.ok(canAffordAnything(state, machines));
});