'use strict'; const assert = require('node:assert/strict'); const path = require('node:path'); const { spawnSync } = require('node:child_process'); const test = require('node:test'); let fixture; function rendered() { if (!fixture) { const run = spawnSync(process.env.PHP_BINARY || 'php', [path.join(__dirname, 'ticket-native-render-harness.php')], { encoding: 'utf8' }); assert.equal(run.status, 0, run.stderr || run.stdout); fixture = JSON.parse(run.stdout); } return fixture; } test('page renders header creation action and one of each dialog, without eagerly reading conversations', () => { const { html, initial } = rendered(); assert.equal((html.match(/工单号<\/dt>
TK-00021<\/dd>/); }); test('ticket information owns the only status editor and closed tickets stay read-only', () => { const { open, closed } = rendered(); const sidebarCards = panel => { const sidebar = panel.match(/]*>([\s\S]*?)<\/aside>/)?.[1] || ''; return [...sidebar.matchAll(/
([\s\S]*?)<\/section>/g)].map(match => match[1]); }; const cards = sidebarCards(open.data.panel); assert.equal(cards.length, 2, 'only ticket information and internal notes remain'); const info = cards[0]; assert.match(info, /

工单信息<\/h3>/); assert.match(info, /data-aksrt-ticket-form="status"/); assert.match(info, /data-aksrt-ticket-assign/); assert.match(info, /保存工单信息/); assert.doesNotMatch(open.data.panel, /]*>处理工单<\/h3>/); assert.doesNotMatch(info, /aksrt-ticket-badge/); for (const [name, label] of [['status', '状态'], ['ticket_type_id', '部门'], ['admin_id', '跟进人']]) { const id = `aksrt-ticket-${name}-21`; assert.ok(info.includes(``)); assert.ok(info.includes(`