@@ -677,3 +677,97 @@ describe('validate: multi-challenge', () => {
677677 expect ( output ) . toContain ( 'Amount is valid integer string (Got: 1.50)' )
678678 } )
679679} )
680+
681+ describe ( 'validate: payment methods coverage' , ( ) => {
682+ test (
683+ 'every method in Constants.Methods produces a payment result' ,
684+ { timeout : 15_000 } ,
685+ async ( ) => {
686+ const methods = Object . values ( Constants . Methods )
687+ const challenges = methods . map ( ( method ) => ( {
688+ id : `${ method } -id` ,
689+ realm : 'localhost' ,
690+ method,
691+ intent : 'charge' ,
692+ request : { amount : '100' , currency : 'usd' , methodDetails : { } } ,
693+ expires : new Date ( Date . now ( ) + 300_000 ) . toISOString ( ) ,
694+ } ) ) as Challenge . Challenge [ ]
695+
696+ const header = challenges . map ( ( c ) => Challenge . serialize ( c ) ) . join ( ', ' )
697+ const server = await testServer ( ( req , res ) => {
698+ const url = new URL ( req . url ! , 'http://localhost' )
699+ if ( url . pathname === '/openapi.json' ) {
700+ res . setHeader ( 'Content-Type' , 'application/json' )
701+ res . end (
702+ JSON . stringify ( {
703+ openapi : '3.1.0' ,
704+ info : { title : 'T' , version : '1' } ,
705+ paths : {
706+ '/api/test' : {
707+ post : { 'x-payment-info' : { amount : '100' } , responses : { '402' : { } } } ,
708+ } ,
709+ } ,
710+ } ) ,
711+ )
712+ return
713+ }
714+ res . writeHead ( 402 , { [ Constants . Headers . wwwAuthenticate ] : header } )
715+ res . end ( )
716+ } )
717+ const { output } = await serve ( [ 'validate' , server . url , '--outputJson' , '--yes' ] )
718+ const jsonStart = output . indexOf ( '{' )
719+ const jsonEnd = output . lastIndexOf ( '}' )
720+ const result = JSON . parse ( output . slice ( jsonStart , jsonEnd + 1 ) )
721+ const paymentLabels = result . endpoints [ 0 ] . payment . map ( ( r : { label : string } ) => r . label )
722+ for ( const method of methods ) {
723+ expect ( paymentLabels . some ( ( l : string ) => l . includes ( `[${ method } ]` ) ) ) . toBe ( true )
724+ }
725+ } ,
726+ )
727+ } )
728+
729+ describe ( 'validate: JSON mode' , ( ) => {
730+ function mainnetChallenge ( ) {
731+ return makeChallenge ( {
732+ request : {
733+ amount : '10000' ,
734+ currency : '0x20c0000000000000000000000000000000000000' ,
735+ recipient : '0x1234567890123456789012345678901234567890' ,
736+ methodDetails : { chainId : 4217 } ,
737+ } ,
738+ } as Partial < Challenge . Challenge > )
739+ }
740+
741+ function parseJson ( output : string ) {
742+ const jsonStart = output . indexOf ( '{' )
743+ const jsonEnd = output . lastIndexOf ( '}' )
744+ return JSON . parse ( output . slice ( jsonStart , jsonEnd + 1 ) )
745+ }
746+
747+ test ( 'does not prompt (non-interactive)' , { timeout : 15_000 } , async ( ) => {
748+ const server = await mppServer ( mainnetChallenge ( ) )
749+ const { output } = await serve ( [ 'validate' , server . url , '--outputJson' ] )
750+ const result = parseJson ( output )
751+ const allPayment = result . endpoints . flatMap ( ( ep : { payment : unknown [ ] } ) => ep . payment )
752+ expect ( allPayment . length ) . toBeGreaterThan ( 0 )
753+ expect ( allPayment . every ( ( r : { severity : string } ) => r . severity === 'skip' ) ) . toBe ( true )
754+ } )
755+
756+ test ( 'no console leaks before JSON' , { timeout : 15_000 } , async ( ) => {
757+ const server = await mppServer ( mainnetChallenge ( ) )
758+ const { output } = await serve ( [ 'validate' , server . url , '--outputJson' , '--yes' ] )
759+ const jsonStart = output . indexOf ( '{' )
760+ expect ( jsonStart ) . toBeGreaterThanOrEqual ( 0 )
761+ const beforeJson = output . slice ( 0 , jsonStart )
762+ expect ( beforeJson ) . not . toContain ( 'Using wallet' )
763+ expect ( beforeJson ) . not . toContain ( 'Auto-approved' )
764+ expect ( beforeJson ) . not . toContain ( 'Attempting' )
765+ } )
766+
767+ test ( 'includes suggestions' , { timeout : 15_000 } , async ( ) => {
768+ const server = await mppServer ( mainnetChallenge ( ) )
769+ const { output } = await serve ( [ 'validate' , server . url , '--outputJson' , '--yes' ] )
770+ const result = parseJson ( output )
771+ expect ( Array . isArray ( result . suggestions ) ) . toBe ( true )
772+ } )
773+ } )
0 commit comments