@@ -594,3 +594,91 @@ describe('Load3DConfiguration.configure forwards persisted + settings to load3d'
594594 expect ( load3d . setLightIntensity ) . toHaveBeenCalledWith ( 9 )
595595 } )
596596} )
597+
598+ describe ( 'Load3DConfiguration "none" model handling' , ( ) => {
599+ let load3d : Load3d
600+ let loadModelSpy : ReturnType < typeof vi . fn >
601+ let clearModelSpy : ReturnType < typeof vi . fn >
602+
603+ function makeLoad3dMock ( ) : Load3d {
604+ loadModelSpy = vi . fn ( ) . mockResolvedValue ( undefined )
605+ clearModelSpy = vi . fn ( )
606+ return {
607+ loadModel : loadModelSpy ,
608+ clearModel : clearModelSpy ,
609+ setUpDirection : vi . fn ( ) ,
610+ setMaterialMode : vi . fn ( ) ,
611+ setTargetSize : vi . fn ( ) ,
612+ setCameraState : vi . fn ( ) ,
613+ toggleGrid : vi . fn ( ) ,
614+ setBackgroundColor : vi . fn ( ) ,
615+ setBackgroundImage : vi . fn ( ) . mockResolvedValue ( undefined ) ,
616+ setBackgroundRenderMode : vi . fn ( ) ,
617+ toggleCamera : vi . fn ( ) ,
618+ setFOV : vi . fn ( ) ,
619+ setLightIntensity : vi . fn ( ) ,
620+ setHDRIIntensity : vi . fn ( ) ,
621+ setHDRIAsBackground : vi . fn ( ) ,
622+ setHDRIEnabled : vi . fn ( ) ,
623+ emitModelReady : vi . fn ( )
624+ } as unknown as Load3d
625+ }
626+
627+ async function flush ( ) {
628+ await new Promise < void > ( ( resolve ) => setTimeout ( resolve , 0 ) )
629+ }
630+
631+ beforeEach ( ( ) => {
632+ load3d = makeLoad3dMock ( )
633+ vi . mocked ( Load3dUtils . splitFilePath ) . mockReturnValue ( [ '' , 'model.glb' ] )
634+ vi . mocked ( Load3dUtils . getResourceURL ) . mockReturnValue ( '/view' )
635+ } )
636+
637+ afterEach ( ( ) => {
638+ vi . restoreAllMocks ( )
639+ } )
640+
641+ it ( 'does not load or clear a model when the initial widget value is "none"' , async ( ) => {
642+ const config = new Load3DConfiguration ( load3d )
643+ config . configure ( {
644+ modelWidget : { value : 'none' } as unknown as IBaseWidget ,
645+ loadFolder : 'input'
646+ } )
647+ await flush ( )
648+
649+ expect ( loadModelSpy ) . not . toHaveBeenCalled ( )
650+ expect ( clearModelSpy ) . not . toHaveBeenCalled ( )
651+ } )
652+
653+ it ( 'clears the model (and skips loadModel) when the widget value changes to "none"' , async ( ) => {
654+ const config = new Load3DConfiguration ( load3d )
655+ const widget = { value : 'model.glb' } as unknown as IBaseWidget
656+ config . configure ( { modelWidget : widget , loadFolder : 'input' } )
657+ await flush ( )
658+
659+ loadModelSpy . mockClear ( )
660+ clearModelSpy . mockClear ( )
661+
662+ widget . value = 'none'
663+ await flush ( )
664+
665+ expect ( clearModelSpy ) . toHaveBeenCalledTimes ( 1 )
666+ expect ( loadModelSpy ) . not . toHaveBeenCalled ( )
667+ } )
668+
669+ it ( 'loads a model when the widget value transitions from "none" to a real path' , async ( ) => {
670+ const config = new Load3DConfiguration ( load3d )
671+ const widget = { value : 'none' } as unknown as IBaseWidget
672+ config . configure ( { modelWidget : widget , loadFolder : 'input' } )
673+ await flush ( )
674+
675+ expect ( loadModelSpy ) . not . toHaveBeenCalled ( )
676+
677+ widget . value = 'model.glb'
678+ await flush ( )
679+
680+ expect ( loadModelSpy ) . toHaveBeenCalledWith ( expect . any ( String ) , 'model.glb' , {
681+ silentOnNotFound : false
682+ } )
683+ } )
684+ } )
0 commit comments