* @license Unlicense https://unlicense.org/ * @link https://github.com/ksolo/Torn-Vault-Tracker */ declare(strict_types=1); // Make USER_KEYS available without including config.php (it would force a // real DB connection). if (!defined('USER_KEYS')) { define( 'USER_KEYS', [ 'zarathos' => 'test-key-not-used', 'symos' => 'test-key-not-used', ] ); } require_once __DIR__ . '/../includes/exceptions.php'; require_once __DIR__ . '/../includes/utilities.php'; /** * Print a failure message to STDERR and exit with status 1. * * @param string $message Human-readable failure description. * * @return never */ function fail(string $message): void { fwrite(STDERR, "FAIL: $message\n"); exit(1); } /** * Lightweight assertion helper that mirrors PHPUnit's assertSame(). * * @param mixed $expected The expected value. * @param mixed $actual The actual value. * @param string $label Human-readable label for failure messages. * * @return void */ function assertSame($expected, $actual, string $label): void { if ($expected !== $actual) { $exp = var_export($expected, true); $act = var_export($actual, true); fail("$label: expected $exp, got $act"); } } // In-memory DB so we don't touch the user's vault.db. $pdo = new PDO('sqlite::memory:'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $pdo->exec( 'CREATE TABLE vault ( id TEXT PRIMARY KEY, user TEXT NOT NULL, timestamp INTEGER NOT NULL, description TEXT NOT NULL, amount REAL NOT NULL )' ); $insertStmt = $pdo->prepare( 'INSERT INTO vault (id, user, timestamp, description, amount) ' . 'VALUES (:id, :user, :timestamp, :description, :amount) ' . 'ON CONFLICT(id) DO NOTHING' ); // Load the golden file. $fixturePath = __DIR__ . '/../backup/api-sample-new.json'; if (!is_readable($fixturePath)) { fail("Fixture not readable at $fixturePath"); } $fixture = json_decode(file_get_contents($fixturePath), true); if (!is_array($fixture) || !isset($fixture['log'])) { fail('Fixture is missing the log array.'); } processLogEntries($fixture['log'], 'zarathos', $insertStmt); // 100 entries in the fixture. $count = (int)$pdo->query('SELECT COUNT(*) FROM vault')->fetchColumn(); assertSame(100, $count, 'row count'); // Spot-check first entry (newest, withdraw) and last (oldest, deposit). $rows = $pdo->query('SELECT id, user, timestamp, description, amount FROM vault ORDER BY timestamp DESC')->fetchAll(PDO::FETCH_ASSOC); $first = $rows[0]; assertSame('c1pEDQ7jl3kuBHV4NqDI', $first['id'], 'first.id'); assertSame('zarathos', $first['user'], 'first.user'); assertSame(1785325489, (int)$first['timestamp'], 'first.timestamp'); assertSame('Vault withdraw', $first['description'], 'first.description'); assertSame(-498870964, (int)$first['amount'], 'first.amount'); $last = $rows[count($rows) - 1]; assertSame('8m5jrUKTiKk0SB4MxzIy', $last['id'], 'last.id'); assertSame(1714350415, (int)$last['timestamp'], 'last.timestamp'); assertSame('Vault deposit', $last['description'], 'last.description'); assertSame(231492, (int)$last['amount'], 'last.amount'); // Re-running with the same fixture inserts zero new rows (idempotency). processLogEntries($fixture['log'], 'zarathos', $insertStmt); $count2 = (int)$pdo->query('SELECT COUNT(*) FROM vault')->fetchColumn(); assertSame(100, $count2, 'row count after re-run'); echo "OK: processLogEntries v2 golden-file test passed (100 entries).\n";