const test = require('node:test') const assert = require('node:assert/strict') const fs = require('node:fs') const path = require('node:path') const vm = require('node:vm') const ts = require('typescript') // Exercise the exported client against the platform network/storage seam. No // frontend E2E framework or production authentication bypass is introduced. function client(network, options = {}) { const storage = new Map() let loginNumber = 0 const taro = { login: async () => ({ code: `login-${++loginNumber}` }), getStorageSync: key => storage.get(key), setStorageSync: (key, value) => storage.set(key, value), removeStorageSync: key => { if (options.storageRemovalFails) throw new Error('storage unavailable'); storage.delete(key) }, request: network, } const source = fs.readFileSync(path.join(__dirname, '../src/services/practice.ts'), 'utf8') const js = ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2020, esModuleInterop: true } }).outputText const exports = {} vm.runInNewContext(js, { exports, require: name => { assert.equal(name, '@tarojs/taro'); return taro }, __API_BASE_URL__: 'https://local-test.invalid' }) return exports } const ok = data => ({ statusCode: 200, data }) const session = token => ok({ token, expiresAt: '2099-01-01T00:00:00Z' }) const failure = (status, code) => ({ statusCode: status, data: { error: { code, message: code } } }) // Same public API calls as the pages: a renewed token cannot change a submitted // form or create a fresh operation, including when platform storage removal fails. test('expired sessions renew and retain the exact submission', async () => { let exchange = 0 const payloads = [] const service = client(async request => { if (request.url.endsWith('/session')) return session(`token-${++exchange}`) payloads.push(request.data) if (request.header.Authorization === 'Bearer token-1') return failure(401, 'unauthorized') return ok({ id: 'record-1' }) }, { storageRemovalFails: true }) const input = { projectId: 'p', date: '2026-09-28', minutes: 90, note: '', requestId: 'same-submission-1' } assert.equal((await service.api.saveRecord(input)).id, 'record-1') assert.equal(exchange, 2) assert.deepEqual(payloads, [input, input]) }) test('uncertain save stays recoverable and an explicit retry keeps its key', async () => { let lost = true const payloads = [] const service = client(async request => { if (request.url.endsWith('/session')) return session('token') payloads.push(request.data) if (lost) { lost = false; throw new Error('response lost') } return ok({ id: 'record-1' }) }) const pending = { input: { projectId: 'p', date: '2026-09-28', minutes: 90, note: 'keep this', requestId: service.submissionID() } } service.retainPendingRecord(pending) await assert.rejects(service.api.saveRecord(pending.input), error => error.status === 0) const resumed = service.getPendingRecord() assert.equal(resumed, pending) assert.equal((await service.api.saveRecord(resumed.input)).id, 'record-1') assert.equal(payloads[0].requestId, payloads[1].requestId) service.clearPendingRecord(resumed) assert.equal(service.getPendingRecord(), undefined) assert.notEqual(service.submissionID(), pending.input.requestId) }) test('failed loads stay errors and only confirmed writes notify visible pages', async () => { let failWrite = true const service = client(async request => { if (request.url.endsWith('/session')) return session('token') if (request.method === 'GET') return failure(503, 'service_unavailable') if (failWrite) { failWrite = false; return failure(503, 'service_unavailable') } return ok({ id: 'record-1' }) }) let changes = 0 const stop = service.onPracticeChange(() => { changes++ }) await assert.rejects(service.api.records(), error => error.status === 503) await assert.rejects(service.api.saveRecord({}), error => error.status === 503) assert.equal(changes, 0) await service.api.saveRecord({}) assert.equal(changes, 1) stop() })