@@ -637,6 +637,33 @@ describe('runCreate', () => {
637637 ) . rejects . toMatchObject ( { exitCode : 5 , code : 'VALIDATION_ERROR' } ) ;
638638 expect ( fetchImpl ) . not . toHaveBeenCalled ( ) ;
639639 } ) ;
640+ it ( 'rejects a whitespace-only --password with VALIDATION_ERROR (exit 5), no network' , async ( ) => {
641+ const { credentialsPath } = makeCreds ( ) ;
642+ const fetchImpl = vi . fn ( async ( ) => {
643+ throw new Error ( 'should not hit network - validation must fire client-side' ) ;
644+ } ) ;
645+
646+ await expect (
647+ runCreate (
648+ {
649+ profile : 'default' ,
650+ output : 'json' ,
651+ debug : false ,
652+ type : 'frontend' ,
653+ name : 'Password Guard Project' ,
654+ targetUrl : 'https://example.com' ,
655+ password : ' ' ,
656+ } ,
657+ {
658+ credentialsPath,
659+ fetchImpl : fetchImpl as unknown as typeof fetch ,
660+ stdout : ( ) => { } ,
661+ stderr : ( ) => { } ,
662+ } ,
663+ ) ,
664+ ) . rejects . toMatchObject ( { exitCode : 5 , code : 'VALIDATION_ERROR' } ) ;
665+ expect ( fetchImpl ) . not . toHaveBeenCalled ( ) ;
666+ } ) ;
640667} ) ;
641668
642669// ---------------------------------------------------------------------------
@@ -739,6 +766,30 @@ describe('runUpdate', () => {
739766 expect ( fetchImpl ) . not . toHaveBeenCalled ( ) ;
740767 } ) ;
741768
769+ it ( 'rejects a whitespace-only --password with VALIDATION_ERROR (exit 5), no network' , async ( ) => {
770+ const { credentialsPath } = makeCreds ( ) ;
771+ const fetchImpl = vi . fn ( async ( ) => {
772+ throw new Error ( 'should not be called' ) ;
773+ } ) ;
774+ await expect (
775+ runUpdate (
776+ {
777+ profile : 'default' ,
778+ output : 'json' ,
779+ debug : false ,
780+ projectId : 'proj_abc' ,
781+ password : ' ' ,
782+ } ,
783+ {
784+ credentialsPath,
785+ fetchImpl : fetchImpl as unknown as typeof fetch ,
786+ stdout : ( ) => { } ,
787+ stderr : ( ) => { } ,
788+ } ,
789+ ) ,
790+ ) . rejects . toMatchObject ( { code : 'VALIDATION_ERROR' , exitCode : 5 } ) ;
791+ expect ( fetchImpl ) . not . toHaveBeenCalled ( ) ;
792+ } ) ;
742793 it ( 'P7 — dry-run returns canned shape without network call' , async ( ) => {
743794 resetDryRunBannerForTesting ( ) ;
744795 const { credentialsPath } = makeCreds ( ) ;
0 commit comments