97 lines
5.1 KiB
JavaScript
97 lines
5.1 KiB
JavaScript
const { test } = require('node:test')
|
|
const assert = require('node:assert/strict')
|
|
const fs = require('node:fs')
|
|
const vm = require('node:vm')
|
|
const ts = require('typescript')
|
|
|
|
const source = ts.createSourceFile('App.tsx', fs.readFileSync(require.resolve('../src/renderer/src/App.tsx'), 'utf8'), ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX)
|
|
const names = ['isRemotePlatformStatusPending', 'filteredPlatformOptions', 'platformFilterCounts']
|
|
const declarations = new Map()
|
|
function visit(node) {
|
|
if (ts.isVariableDeclaration(node) && names.includes(node.name.getText(source))) {
|
|
declarations.set(node.name.getText(source), node.getText(source))
|
|
}
|
|
ts.forEachChild(node, visit)
|
|
}
|
|
visit(source)
|
|
for (const name of names) assert.ok(declarations.has(name), `missing ${name}`)
|
|
const filterScript = ts.transpileModule(`${names.map(name => `const ${declarations.get(name)}`).join('\n')}
|
|
result = { counts: platformFilterCounts, ids: filteredPlatformOptions.map(platform => platform.id) }`, {
|
|
compilerOptions: { target: ts.ScriptTarget.ES2022 }
|
|
}).outputText
|
|
const controlSource = fs.readFileSync(require.resolve('../src/renderer/src/features/platforms/platformControl.ts'), 'utf8')
|
|
const control = {}
|
|
vm.runInNewContext(ts.transpileModule(controlSource, { compilerOptions: { module: ts.ModuleKind.CommonJS } }).outputText, {
|
|
exports: control,
|
|
require: name => {
|
|
assert.equal(name, '../../config/appConfig')
|
|
return { LMS_API_BASE_URL: 'http://unused.invalid' }
|
|
}
|
|
})
|
|
|
|
function classify(platformOptions, checkedIds = ['mini'], platformFilter = 'all') {
|
|
const context = {
|
|
platformOptions, platformFilter,
|
|
checkedRemotePlatformStatusIds: new Set(checkedIds),
|
|
isPlatformUnavailable: control.isPlatformUnavailable
|
|
}
|
|
vm.runInNewContext(filterScript, context)
|
|
return JSON.parse(JSON.stringify(context.result))
|
|
}
|
|
|
|
const simulation = { id: 'sim', platformKey: 'futuredrive-local-pc', state: 'ready', status: '사용 가능', action: '시작' }
|
|
const mini = { id: 'mini', platformKey: 'mkmini', state: 'ready', status: '사용 가능', action: '제어권 요청', connection: { headscaleOnline: true, agentHealthy: true } }
|
|
|
|
test('multiple vehicles of the same platform kind remain independently selectable', () => {
|
|
const second = { ...mini, id: 'mini-2', title: 'MK-mini #02' }
|
|
const platforms = [simulation, mini, second]
|
|
assert.deepEqual(classify(platforms, ['mini', 'mini-2']).ids, ['sim', 'mini', 'mini-2'])
|
|
assert.deepEqual(classify(platforms, ['mini', 'mini-2']).counts, { all: 3, available: 3, unavailable: 0 })
|
|
const disconnected = { ...mini, status: '연결 끊김', connection: { headscaleOnline: false, agentHealthy: false } }
|
|
assert.deepEqual(classify([simulation, disconnected, second], ['mini', 'mini-2'], 'available').ids, ['sim', 'mini-2'])
|
|
assert.deepEqual(classify([simulation, disconnected, second], ['mini', 'mini-2'], 'unavailable').ids, ['mini'])
|
|
})
|
|
|
|
test('disconnected ready platform counts as unavailable and appears only in that tab', () => {
|
|
const disconnected = { ...mini, status: '연결 끊김', connection: { headscaleOnline: false, agentHealthy: false } }
|
|
const platforms = [simulation, disconnected]
|
|
assert.deepEqual(classify(platforms), { counts: { all: 2, available: 1, unavailable: 1 }, ids: ['sim', 'mini'] })
|
|
assert.deepEqual(classify(platforms, ['mini'], 'available').ids, ['sim'])
|
|
assert.deepEqual(classify(platforms, ['mini'], 'unavailable').ids, ['mini'])
|
|
})
|
|
|
|
test('offline network, unhealthy agent and explicit unavailability all exclude ready platforms', () => {
|
|
for (const patch of [
|
|
{ connection: { headscaleOnline: false, agentHealthy: true } },
|
|
{ connection: { headscaleOnline: true, agentHealthy: false } },
|
|
{ connection: undefined, status: '연결 끊김' },
|
|
{ connection: undefined, status: '연결 불가' },
|
|
{ connection: undefined, action: '연결 불가' }
|
|
]) {
|
|
const platforms = [simulation, { ...mini, ...patch }]
|
|
assert.deepEqual(classify(platforms).counts, { all: 2, available: 1, unavailable: 1 })
|
|
assert.deepEqual(classify(platforms, ['mini'], 'unavailable').ids, ['mini'])
|
|
}
|
|
})
|
|
|
|
test('pending remote status remains in All without prematurely entering either availability tab', () => {
|
|
const platforms = [simulation, mini]
|
|
assert.deepEqual(classify(platforms, []).counts, { all: 2, available: 1, unavailable: 0 })
|
|
assert.deepEqual(classify(platforms, [], 'available').ids, ['sim'])
|
|
assert.deepEqual(classify(platforms, [], 'unavailable').ids, [])
|
|
})
|
|
|
|
test('reconnecting moves a platform back to available without changing All', () => {
|
|
assert.deepEqual(classify([simulation, mini]).counts, { all: 2, available: 2, unavailable: 0 })
|
|
assert.deepEqual(classify([simulation, mini], ['mini'], 'available').ids, ['sim', 'mini'])
|
|
assert.deepEqual(classify([simulation, mini], ['mini'], 'unavailable').ids, [])
|
|
})
|
|
|
|
test('locked, requested and reserved platform classifications are preserved', () => {
|
|
for (const state of ['locked', 'request', 'reserved']) {
|
|
const platforms = [simulation, { ...mini, state }]
|
|
assert.deepEqual(classify(platforms).counts, { all: 2, available: 1, unavailable: 1 })
|
|
assert.deepEqual(classify(platforms, ['mini'], 'unavailable').ids, ['mini'])
|
|
}
|
|
})
|