@@ -628,3 +628,87 @@ fn empty() -> BoxBody<Bytes, hyper::Error> {
628628fn full < T : Into < Bytes > > ( chunk : T ) -> BoxBody < Bytes , hyper:: Error > {
629629 Full :: new ( chunk. into ( ) ) . map_err ( |never| match never { } ) . boxed ( )
630630}
631+
632+ #[ cfg( test) ]
633+ mod tests {
634+ use std:: time:: Duration ;
635+
636+ use http_body_util:: BodyExt ;
637+ use hyper:: body:: Bytes ;
638+ use hyper:: { Method , Request , StatusCode } ;
639+ use ohttp_relay:: SentinelTag ;
640+ use payjoin:: directory:: ShortId ;
641+
642+ use super :: * ;
643+
644+ async fn test_service ( enable_v1 : bool ) -> Service < FilesDb > {
645+ let dir = tempfile:: tempdir ( ) . expect ( "tempdir" ) ;
646+ let db = FilesDb :: init ( Duration :: from_millis ( 100 ) , dir. keep ( ) ) . await . expect ( "db init" ) ;
647+ let ohttp: ohttp:: Server =
648+ key_config:: gen_ohttp_server_config ( ) . expect ( "ohttp config" ) . into ( ) ;
649+ Service :: new ( db, ohttp, SentinelTag :: new ( [ 0u8 ; 32 ] ) , enable_v1)
650+ }
651+
652+ /// A valid ShortId encoded as bech32 for use in URL paths.
653+ fn valid_short_id_path ( ) -> String {
654+ let id = ShortId ( [ 0u8 ; 8 ] ) ;
655+ id. to_string ( )
656+ }
657+
658+ async fn collect_body ( res : Response < BoxBody < Bytes , hyper:: Error > > ) -> ( StatusCode , String ) {
659+ let ( parts, body) = res. into_parts ( ) ;
660+ let bytes = body. collect ( ) . await . unwrap ( ) . to_bytes ( ) ;
661+ ( parts. status , String :: from_utf8 ( bytes. to_vec ( ) ) . unwrap ( ) )
662+ }
663+
664+ #[ tokio:: test]
665+ async fn post_v1_when_disabled_returns_version_unsupported ( ) {
666+ let mut svc = test_service ( false ) . await ;
667+ let id = valid_short_id_path ( ) ;
668+ let req = Request :: builder ( )
669+ . method ( Method :: POST )
670+ . uri ( format ! ( "http://localhost/{id}" ) )
671+ . body ( Full :: new ( Bytes :: from ( "base64-psbt" ) ) )
672+ . unwrap ( ) ;
673+
674+ let res = tower:: Service :: call ( & mut svc, req) . await . unwrap ( ) ;
675+ let ( status, body) = collect_body ( res) . await ;
676+
677+ assert_eq ! ( status, StatusCode :: BAD_REQUEST ) ;
678+ assert_eq ! ( body, V1_VERSION_UNSUPPORTED_RES_JSON ) ;
679+ }
680+
681+ #[ tokio:: test]
682+ async fn post_v1_with_invalid_body_returns_reject ( ) {
683+ let mut svc = test_service ( true ) . await ;
684+ let id = valid_short_id_path ( ) ;
685+ let req = Request :: builder ( )
686+ . method ( Method :: POST )
687+ . uri ( format ! ( "http://localhost/{id}" ) )
688+ . body ( Full :: new ( Bytes :: from ( vec ! [ 0xFF , 0xFE ] ) ) )
689+ . unwrap ( ) ;
690+
691+ let res = tower:: Service :: call ( & mut svc, req) . await . unwrap ( ) ;
692+ let ( status, body) = collect_body ( res) . await ;
693+
694+ assert_eq ! ( status, StatusCode :: BAD_REQUEST ) ;
695+ assert_eq ! ( body, V1_REJECT_RES_JSON ) ;
696+ }
697+
698+ #[ tokio:: test]
699+ async fn post_v1_with_no_receiver_returns_unavailable ( ) {
700+ let mut svc = test_service ( true ) . await ;
701+ let id = valid_short_id_path ( ) ;
702+ let req = Request :: builder ( )
703+ . method ( Method :: POST )
704+ . uri ( format ! ( "http://localhost/{id}" ) )
705+ . body ( Full :: new ( Bytes :: from ( "base64-psbt" ) ) )
706+ . unwrap ( ) ;
707+
708+ let res = tower:: Service :: call ( & mut svc, req) . await . unwrap ( ) ;
709+ let ( status, body) = collect_body ( res) . await ;
710+
711+ assert_eq ! ( status, StatusCode :: SERVICE_UNAVAILABLE ) ;
712+ assert_eq ! ( body, V1_UNAVAILABLE_RES_JSON ) ;
713+ }
714+ }
0 commit comments