|
- import assert from 'node:assert/strict'
- import test from 'node:test'
-
- const webSource = new URL('../../unreal_tran_web/src/features/', import.meta.url)
- const fox = {
- sceneId: 'fox-scene-object', name: 'Fox', semantic: '实训装备',
- operable: true, interactionId: 'scene:fox', capabilities: ['select', 'inspect'],
- modelPartTargets: [{
- sceneId: 'fox-scene-object', interactionId: 'scene:fox/part/mesh',
- sourceInteractionId: 'model:fox-mesh', editorId: 'fox-mesh', name: 'Fox mesh',
- operable: true, visible: true, capabilities: ['select', 'inspect'],
- }],
- }
- const projectWith = objects => ({
- scenario: {
- publishedSceneId: 'content-scene-160',
- sceneResource: { sceneId: 'content-scene-160', snapshot: { objects } },
- },
- })
-
- for (const runtime of ['guide-legacy/demo-src', 'virtual-training-legacy/upstream']) {
- const {
- TRAINING_PROJECT_TARGETS, createTrainingProject, getTrainingProjectTargets,
- listTrainingSceneTargets, normalizeTrainingProject, validateTrainingProject,
- } = await import(new URL(`${runtime}/training-project-io.js`, webSource))
-
- test(`${runtime}: binding a published scene replaces all demo-machine targets`, () => {
- assert.deepEqual(getTrainingProjectTargets(projectWith([fox])).map(item => item.id), ['scene:fox', 'scene:fox/part/mesh'])
- assert.deepEqual(getTrainingProjectTargets(projectWith([])), [])
- assert.equal(getTrainingProjectTargets({}).length, TRAINING_PROJECT_TARGETS.length)
- const reservedId = TRAINING_PROJECT_TARGETS[0].id
- assert.deepEqual(getTrainingProjectTargets(projectWith([{ ...fox, interactionId: reservedId, modelPartTargets: [] }])).map(item => item.id), [reservedId])
- })
-
- test(`${runtime}: hidden and deleted roots exclude their parts and split children`, () => {
- for (const disabled of [{ visible: false }, { deleted: true }, { softDeleted: true }]) {
- const root = { ...fox, ...disabled, splitParts: [{ ...fox, sceneId: 'split', interactionId: 'scene:split' }] }
- assert.deepEqual(listTrainingSceneTargets({ objects: [root] }), [])
- const normalized = normalizeTrainingProject({ ...createTrainingProject(), ...projectWith([root]) })
- assert.deepEqual(getTrainingProjectTargets(normalized), [])
- assert.equal(normalized.scenario.sceneResource.snapshot.objects[0].visible, false)
- }
- })
-
- test(`${runtime}: part visibility and soft-delete overrides keep only the valid root`, () => {
- for (const disabled of [{ visible: false }, { deleted: true }, { softDeleted: true }]) {
- const root = { ...fox, modelPartTargets: [{ ...fox.modelPartTargets[0], ...disabled }] }
- assert.deepEqual(listTrainingSceneTargets({ objects: [root] }).map(item => item.id), ['scene:fox'])
- }
- const root = { ...fox, partOverrides: { 'scene:fox/part/mesh': { softDeleted: true } } }
- assert.deepEqual(listTrainingSceneTargets({ objects: [root] }).map(item => item.id), ['scene:fox'])
- })
-
- test(`${runtime}: formal semantic target ids follow backend operable/visible/deleted rules`, () => {
- const formal = {
- id: 'fox-formal', name: 'Fox',
- semantic: { operable: true, interactionId: 'scene:formal-fox', deviceId: 'FOX-001', capabilities: ['inspect'] },
- }
- const objects = [formal,
- { ...formal, id: 'hidden', visible: false },
- { ...formal, id: 'deleted', deleted: true },
- { id: 'not-operable', semantic: { interactionId: 'scene:locked', operable: false } },
- { id: 'missing-id', semantic: { operable: true } },
- ]
- const targets = listTrainingSceneTargets({ objects })
- assert.deepEqual(targets.map(item => item.id), ['scene:formal-fox'])
- assert.deepEqual(targets[0].modes, ['inspect'])
- assert.equal(targets[0].targetRef.deviceId, 'FOX-001')
- const normalized = normalizeTrainingProject({ ...createTrainingProject(), ...projectWith(objects) })
- assert.deepEqual(getTrainingProjectTargets(normalized).map(item => item.id), ['scene:formal-fox'])
- })
-
- test(`${runtime}: old demo steps stay invalid after binding, then real scene selections validate`, () => {
- const source = { ...createTrainingProject(), ...projectWith([fox]) }
- const invalid = validateTrainingProject(source)
- assert.ok(invalid.errors.some(item => item.path?.endsWith('.targetId')))
- source.steps = [{ ...source.steps[0], targetId: 'scene:fox', targetRef: { interactionId: 'scene:fox' }, mode: 'inspect' }]
- const normalized = normalizeTrainingProject(source)
- const result = validateTrainingProject(normalized)
- assert.equal(result.errors.some(item => item.path?.endsWith('.targetId')), false)
- assert.equal(normalized.steps[0].targetRef.sceneObjectId, 'fox-scene-object')
- })
- }
|