93 lines
3.7 KiB
JavaScript
93 lines
3.7 KiB
JavaScript
const { test } = require('node:test')
|
|
const assert = require('node:assert/strict')
|
|
const fs = require('node:fs')
|
|
const vm = require('node:vm')
|
|
const vue = require('vue')
|
|
const ts = require('../../backend/node_modules/typescript')
|
|
|
|
const deferred = () => {
|
|
let resolve
|
|
const promise = new Promise(done => { resolve = done })
|
|
return { promise, resolve }
|
|
}
|
|
const settle = () => new Promise(setImmediate)
|
|
|
|
function setup(api, apiBase = 'https://fedeo.example/backend') {
|
|
const auth = vue.reactive({ activeTenant: '1', user: { is_admin: true } })
|
|
const timers = new Map()
|
|
let timerId = 0
|
|
let mount
|
|
let unmount
|
|
const context = vm.createContext({
|
|
require, exports: {}, URL,
|
|
ref: vue.ref, computed: vue.computed, watch: vue.watch,
|
|
useAuthStore: () => auth,
|
|
useRuntimeConfig: () => ({ public: { apiBase } }),
|
|
useFiles: () => ({}), useToast: () => ({ add() {} }),
|
|
useNuxtApp: () => ({ $api: api }),
|
|
window: { location: { origin: 'https://fedeo.example' } },
|
|
onMounted: handler => { mount = handler },
|
|
onBeforeUnmount: handler => { unmount = handler },
|
|
setTimeout: handler => { timers.set(++timerId, handler); return timerId },
|
|
clearTimeout: id => timers.delete(id),
|
|
})
|
|
const source = fs.readFileSync(`${__dirname}/../pages/organisation/dokumentenablage.vue`, 'utf8').match(/<script setup lang="ts">([\s\S]*?)<\/script>/)[1]
|
|
vm.runInContext(ts.transpileModule(source, { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022, esModuleInterop: true } }).outputText, context)
|
|
return { auth, timers, mount, close: () => unmount(), run: code => vm.runInContext(code, context) }
|
|
}
|
|
|
|
test('scanner setup preserves absolute and relative backend prefixes', async t => {
|
|
for (const base of ['https://fedeo.example/backend/', '/backend']) {
|
|
const ui = setup(async () => ({ documents: [], total: 0 }), base)
|
|
t.after(ui.close)
|
|
ui.mount()
|
|
await settle()
|
|
assert.equal(ui.run('scannerUrl.value'), 'https://fedeo.example/backend/scanner-inbox/')
|
|
}
|
|
})
|
|
|
|
test('a slow response from the previous tenant cannot expose its documents', async t => {
|
|
const previous = deferred()
|
|
let calls = 0
|
|
const ui = setup(() => ++calls === 1 ? previous.promise : Promise.resolve({ documents: [{ id: 'tenant-2' }], total: 1 }))
|
|
t.after(ui.close)
|
|
ui.mount()
|
|
ui.auth.activeTenant = '2'
|
|
await settle()
|
|
previous.resolve({ documents: [{ id: 'tenant-1-secret' }], total: 1 })
|
|
await settle()
|
|
assert.equal(ui.run('documents.value[0].id'), 'tenant-2')
|
|
})
|
|
|
|
test('credential responses are discarded on tenant switches and passwords clear on closing', async t => {
|
|
const pending = deferred()
|
|
const ui = setup(url => url.endsWith('/credentials') ? pending.promise : Promise.resolve({ documents: [], total: 0, connection: null, path: '/scanner-inbox/' }))
|
|
t.after(ui.close)
|
|
ui.mount()
|
|
await ui.run('openSetup()')
|
|
const creation = ui.run('createCredentials()')
|
|
ui.auth.activeTenant = '2'
|
|
await settle()
|
|
pending.resolve({ connection: { username: 'previous-tenant', password: 'never-display', active: true }, path: '/scanner-inbox/' })
|
|
await creation
|
|
assert.equal(ui.run('password.value'), '')
|
|
assert.equal(ui.run('connection.value'), null)
|
|
assert.equal(ui.run('setupOpen.value'), false)
|
|
ui.run('setupOpen.value = true')
|
|
await settle()
|
|
ui.run('password.value = "shown-once"; setupOpen.value = false')
|
|
await settle()
|
|
assert.equal(ui.run('password.value'), '')
|
|
})
|
|
|
|
test('unmounting cancels polling and ignores in-flight responses', async () => {
|
|
const pending = deferred()
|
|
const ui = setup(() => pending.promise)
|
|
ui.mount()
|
|
ui.close()
|
|
pending.resolve({ documents: [{ id: 'late' }], total: 1 })
|
|
await settle()
|
|
assert.equal(ui.run('documents.value.length'), 0)
|
|
assert.equal(ui.timers.size, 0)
|
|
})
|