const { test } = require('node:test') const assert = require('node:assert/strict') const fs = require('node:fs') const path = require('node:path') const ts = require('typescript') const source = fs.readFileSync(path.join(__dirname, '../src/appointment-call-guard.ts'), 'utf8') const compiled = ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS } }).outputText const target = { exports: {} } new Function('module', 'exports', compiled)(target, target.exports) const { installAppointmentCallGuard, assertCallPolicy } = target.exports for (const method of ['call', 'calls', 'groupCall']) { test(`${method}: current server policy controls every invocation`, async () => { const dispatched = [] const api = { [method]: async (params) => dispatched.push(params.type) } const register = installAppointmentCallGuard(api) await assert.rejects(api[method]({ type: 2 }), /请先打开/) let serverPolicy = { can_video_call: true, can_audio_call: true } let refreshes = 0 register(async (type) => { refreshes++; assertCallPolicy(serverPolicy, type) }) await api[method]({ type: 2 }) serverPolicy = { appointment_type: 'text', can_audio_call: false, can_video_call: false } await assert.rejects(api[method]({ type: 2 })) await assert.rejects(api[method]({ type: 1 })) assert.deepEqual(dispatched, [2]) assert.equal(refreshes, 3) }) test(`${method}: close or replacement rejects an in-flight authorization`, async () => { let resume let dispatched = 0 const api = { [method]: async () => dispatched++ } const register = installAppointmentCallGuard(api) const release = register(() => new Promise((resolve) => { resume = resolve })) const pending = api[method]({ type: 2 }) release() register(async () => {}) resume() await assert.rejects(pending, /已切换/) assert.equal(dispatched, 0) release() // Releasing the old window cannot remove the replacement guard. await api[method]({ type: 1 }) assert.equal(dispatched, 1) }) } test('strict booleans fail closed, audio and video permissions remain separate', () => { for (const value of [undefined, null, false, 0, 1, 'true', '1']) { assert.throws(() => assertCallPolicy({ can_video_call: value }, 2)) assert.throws(() => assertCallPolicy({ can_audio_call: value }, 1)) } assert.doesNotThrow(() => assertCallPolicy({ can_audio_call: true }, 1)) assert.throws(() => assertCallPolicy({ can_audio_call: true }, 2)) }) test('an awaiting caller cannot change the authorized media type', async () => { let resume let actual const api = { calls: async (params) => { actual = params.type } } const register = installAppointmentCallGuard(api) register(() => new Promise((resolve) => { resume = resolve })) const params = { type: 1 } const pending = api.calls(params) params.type = 2 resume() await pending assert.equal(actual, 1) })