diff --git a/tests/domain/runtime-project-scheduler.test.ts b/tests/domain/runtime-project-scheduler.test.ts index a24b4dbc..8664574c 100644 --- a/tests/domain/runtime-project-scheduler.test.ts +++ b/tests/domain/runtime-project-scheduler.test.ts @@ -2,7 +2,9 @@ import { describe, expect, it } from "vitest"; import { applyControlEffectToResolvedState, + createActivateCameraRigOverrideControlEffect, createActorControlTargetRef, + createCameraRigControlTargetRef, createDefaultResolvedControlSource, createEmptyRuntimeResolvedControlState, createLightControlTargetRef, @@ -395,6 +397,87 @@ describe("runtime project scheduler", () => { ); }); + it("applies camera rig override scheduler effects over baseline control state and restores fallback when inactive", () => { + const cameraRigTarget = createCameraRigControlTargetRef( + "entity-camera-rig-main" + ); + const scheduler = createEmptyProjectScheduler(); + const sequences = createEmptyProjectSequenceLibrary(); + scheduler.routines["routine-overlook-camera"] = createProjectScheduleRoutine({ + id: "routine-overlook-camera", + title: "Overlook Camera", + target: cameraRigTarget, + startHour: 18, + endHour: 20, + effect: createActivateCameraRigOverrideControlEffect({ + target: cameraRigTarget + }) + }); + + const baselineResolved = applyControlEffectToResolvedState( + createEmptyRuntimeResolvedControlState(), + createClearCameraRigOverrideControlEffect({ + target: cameraRigTarget + }), + createDefaultResolvedControlSource() + ); + const activeSchedule = resolveRuntimeProjectScheduleState({ + scheduler, + sequences, + actorIds: [], + dayNumber: 1, + timeOfDayHours: 19 + }); + const activeResolved = applyRuntimeProjectScheduleToControlState( + baselineResolved, + activeSchedule, + baselineResolved + ); + const inactiveSchedule = resolveRuntimeProjectScheduleState({ + scheduler, + sequences, + actorIds: [], + dayNumber: 1, + timeOfDayHours: 9 + }); + const inactiveResolved = applyRuntimeProjectScheduleToControlState( + activeResolved, + inactiveSchedule, + baselineResolved + ); + + expect(activeSchedule.controls).toEqual([ + expect.objectContaining({ + routineId: "routine-overlook-camera", + title: "Overlook Camera", + resolutionKey: "state:cameraRigOverride:global:project" + }) + ]); + expect(activeResolved.discrete).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + type: "cameraRigOverride", + entityId: "entity-camera-rig-main", + source: { + kind: "scheduler", + scheduleId: "routine-overlook-camera" + } + }) + ]) + ); + expect(inactiveResolved.discrete).toEqual( + expect.arrayContaining([ + expect.objectContaining({ + type: "cameraRigOverride", + entityId: null, + source: { + kind: "default" + } + }) + ]) + ); + }); + it("resolves actor animation and deterministic follow-path state from the active routine window", () => { const actorTarget = createActorControlTargetRef("actor-patrol"); const scheduler = createEmptyProjectScheduler();