Files
FEDEO/frontend/tests/project-chat-setting.test.cjs

63 lines
3.3 KiB
JavaScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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')
const vue = require('vue')
const { renderToString } = require('@vue/server-renderer')
const { parse, compileScript } = require('@vue/compiler-sfc')
function component(filename, globals = {}) {
const { descriptor } = parse(fs.readFileSync(filename, 'utf8'), { filename })
const compiled = compileScript(descriptor, { id: filename, inlineTemplate: true }).content
const source = ts.transpileModule(compiled, { compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022, esModuleInterop: true } }).outputText
const context = vm.createContext({ exports: {}, require, ...globals })
vm.runInContext(source, context)
return context.exports.default
}
// Resolve the configured renderer, so accidentally wiring the unrelated "active" renderer fails this test.
const storeSource = fs.readFileSync(`${__dirname}/../stores/data.js`, 'utf8')
const store = ts.createSourceFile('data.js', storeSource, ts.ScriptTarget.Latest, true, ts.ScriptKind.JS)
let chatColumn
function visit(node) {
if (ts.isObjectLiteralExpression(node) && node.properties.some(property =>
ts.isPropertyAssignment(property) && property.name.getText(store) === 'key' && property.initializer.getText(store) === '"chatEnabled"')) chatColumn = node
ts.forEachChild(node, visit)
}
visit(store)
const rendererName = chatColumn.properties.find(property => property.name?.getText(store) === 'component').initializer.getText(store)
const rendererImport = store.statements.find(statement => ts.isImportDeclaration(statement) && statement.importClause?.name?.text === rendererName)
const renderer = component(path.resolve(__dirname, '..', rendererImport.moduleSpecifier.text.replace(/^~\//, '')))
const column = vm.runInNewContext(`(${chatColumn.getText(store)})`, { [rendererName]: renderer })
test('project list renders the actual chat setting, independently of an unrelated active flag', async () => {
for (const [row, expected] of [
[{ chatEnabled: true }, 'Ja'],
[{ chatEnabled: true, active: false }, 'Ja'],
[{ chatEnabled: false, active: true }, 'Nein'],
[{ chatEnabled: false }, 'Nein'],
[{ active: true }, '–'],
]) {
const html = await renderToString(vue.createSSRApp(column.component, { row }))
assert.match(html, new RegExp(`>${expected}</span>`), JSON.stringify(row))
}
})
test('project information shows Ja and Nein after loading the saved setting', async () => {
const information = component(`${__dirname}/../components/EntityShowSubInformation.vue`, {
useDataStore: () => ({ dataTypes: { projects: { templateColumns: [column] } } }),
useTempStore: () => ({}), useRouter: () => ({}),
})
for (const chatEnabled of [true, false]) {
const app = vue.createSSRApp(information, { item: { id: 1, chatEnabled }, topLevelType: 'projects', platform: 'default' })
app.component('UCard', { setup: (_, { slots }) => () => vue.h('section', slots.default?.()) })
app.component('UAlert', { render: () => null })
app.component('TelephonyCallButton', { render: () => null })
const html = await renderToString(app)
assert.match(html, /Projektchat aktiviert/)
assert.match(html, new RegExp(`>${chatEnabled ? 'Ja' : 'Nein'}</span>`))
}
})