69 lines
2.9 KiB
JavaScript
69 lines
2.9 KiB
JavaScript
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)
|
|
})
|