@@ -19,6 +19,7 @@ mod tests {
1919 use reqwest:: { header, StatusCode } ;
2020 use sqlx:: PgPool ;
2121 use tap_core:: { manager:: Manager , receipt:: checks:: CheckList } ;
22+ use tokio:: time:: sleep;
2223 use tower:: { Service , ServiceBuilder , ServiceExt } ;
2324 use tower_http:: auth:: AsyncRequireAuthorizationLayer ;
2425
@@ -27,80 +28,111 @@ mod tests {
2728 use test_assets:: { create_signed_receipt, TAP_EIP712_DOMAIN } ;
2829
2930 const ALLOCATION_ID : Address = address ! ( "deadbeefcafebabedeadbeefcafebabedeadbeef" ) ;
31+ const BEARER_TOKEN : & str = "test" ;
3032
31- async fn handle ( _: Request < Body > ) -> anyhow:: Result < Response < Body > > {
32- Ok ( Response :: new ( Body :: default ( ) ) )
33- }
34-
35- #[ sqlx:: test( migrations = "../../migrations" ) ]
36- async fn test_middleware_composition ( pgpool : PgPool ) {
37- let token = "test" . to_string ( ) ;
33+ async fn service (
34+ pgpool : PgPool ,
35+ ) -> impl Service < Request < Body > , Response = Response < Body > , Error = impl std:: fmt:: Debug > {
3836 let context = IndexerTapContext :: new ( pgpool. clone ( ) , TAP_EIP712_DOMAIN . clone ( ) ) . await ;
3937 let tap_manager = Box :: leak ( Box :: new ( Manager :: new (
4038 TAP_EIP712_DOMAIN . clone ( ) ,
4139 context,
4240 CheckList :: empty ( ) ,
4341 ) ) ) ;
42+
43+ let registry = prometheus:: Registry :: new ( ) ;
4444 let metric = Box :: leak ( Box :: new (
45- prometheus:: register_counter_vec !(
45+ prometheus:: register_counter_vec_with_registry !(
4646 "merge_checks_test" ,
4747 "Failed queries to handler" ,
48- & [ "deployment" ]
48+ & [ "deployment" ] ,
49+ registry,
4950 )
5051 . unwrap ( ) ,
5152 ) ) ;
52- let free_query = Bearer :: new ( & token ) ;
53+ let free_query = Bearer :: new ( BEARER_TOKEN ) ;
5354 let tap_auth = auth:: tap_receipt_authorize ( tap_manager, metric) ;
5455 let authorize_requests = free_query. or ( tap_auth) ;
5556
5657 let authorization_middleware = AsyncRequireAuthorizationLayer :: new ( authorize_requests) ;
5758
5859 let mut service = ServiceBuilder :: new ( )
5960 . layer ( authorization_middleware)
60- . service_fn ( handle) ;
61+ . service_fn ( |_: Request < Body > | async {
62+ Ok :: < _ , anyhow:: Error > ( Response :: new ( Body :: default ( ) ) )
63+ } ) ;
6164
62- let handle = service. ready ( ) . await . unwrap ( ) ;
65+ service. ready ( ) . await . unwrap ( ) ;
66+ service
67+ }
6368
69+ #[ sqlx:: test( migrations = "../../migrations" ) ]
70+ async fn test_composition_header_valid ( pgpool : PgPool ) {
71+ let mut service = service ( pgpool. clone ( ) ) . await ;
6472 // should allow queries that contains the free token
6573 // if the token does not match, return payment required
6674 let mut req = Request :: new ( Default :: default ( ) ) ;
6775 req. headers_mut ( ) . insert (
6876 header:: AUTHORIZATION ,
69- format ! ( "Bearer {token}" ) . parse ( ) . unwrap ( ) ,
77+ format ! ( "Bearer {}" , BEARER_TOKEN ) . parse ( ) . unwrap ( ) ,
7078 ) ;
71- let res = handle . call ( req) . await . unwrap ( ) ;
79+ let res = service . call ( req) . await . unwrap ( ) ;
7280 assert_eq ! ( res. status( ) , StatusCode :: OK ) ;
81+ }
82+
83+ #[ sqlx:: test( migrations = "../../migrations" ) ]
84+ async fn test_composition_header_invalid ( pgpool : PgPool ) {
85+ let mut service = service ( pgpool. clone ( ) ) . await ;
7386
7487 // if the token exists but is wrong, try the receipt
7588 let mut req = Request :: new ( Default :: default ( ) ) ;
7689 req. headers_mut ( )
7790 . insert ( header:: AUTHORIZATION , "Bearer wrongtoken" . parse ( ) . unwrap ( ) ) ;
78- let res = handle . call ( req) . await . unwrap ( ) ;
91+ let res = service . call ( req) . await . unwrap ( ) ;
7992 // we return the error from tap
8093 assert_eq ! ( res. status( ) , StatusCode :: PAYMENT_REQUIRED ) ;
94+ }
95+
96+ #[ sqlx:: test( migrations = "../../migrations" ) ]
97+ async fn test_composition_with_receipt ( pgpool : PgPool ) {
98+ let mut service = service ( pgpool. clone ( ) ) . await ;
8199
82100 let receipt = create_signed_receipt ( ALLOCATION_ID , 1 , 1 , 1 ) . await ;
83101
84102 // check with receipt
85103 let mut req = Request :: new ( Default :: default ( ) ) ;
86104 req. extensions_mut ( ) . insert ( receipt) ;
87- let res = handle . call ( req) . await . unwrap ( ) ;
105+ let res = service . call ( req) . await . unwrap ( ) ;
88106 assert_eq ! ( res. status( ) , StatusCode :: OK ) ;
89107
90- // todo make this sleep better
91- tokio:: time:: sleep ( Duration :: from_millis ( 100 ) ) . await ;
92-
93108 // verify receipts
94- let result = sqlx:: query!( "SELECT * FROM scalar_tap_receipts" )
95- . fetch_all ( & pgpool)
96- . await
97- . unwrap ( ) ;
98- assert_eq ! ( result. len( ) , 1 ) ;
99-
100- // if it has neither, should return unauthorized
101- // check no headers
109+ if tokio:: time:: timeout ( Duration :: from_secs ( 1 ) , async {
110+ loop {
111+ let result = sqlx:: query!( "SELECT * FROM scalar_tap_receipts" )
112+ . fetch_all ( & pgpool)
113+ . await
114+ . unwrap ( ) ;
115+
116+ if result. is_empty ( ) {
117+ sleep ( Duration :: from_millis ( 50 ) ) . await ;
118+ } else {
119+ break ;
120+ }
121+ }
122+ } )
123+ . await
124+ . is_err ( )
125+ {
126+ panic ! ( "Timeout assertion" ) ;
127+ }
128+ }
129+
130+ #[ sqlx:: test( migrations = "../../migrations" ) ]
131+ async fn test_composition_without_header_or_receipt ( pgpool : PgPool ) {
132+ let mut service = service ( pgpool. clone ( ) ) . await ;
133+ // if it has neither, should return payment required
102134 let req = Request :: new ( Default :: default ( ) ) ;
103- let res = handle . call ( req) . await . unwrap ( ) ;
135+ let res = service . call ( req) . await . unwrap ( ) ;
104136 assert_eq ! ( res. status( ) , StatusCode :: PAYMENT_REQUIRED ) ;
105137 }
106138}
0 commit comments