@@ -24,6 +24,7 @@ use crate::tests::{
2424 CategoryListResponse , CategoryResponse , CrateList , CrateResponse , GoodCrate , OwnerResp ,
2525 OwnersResponse , VersionResponse ,
2626} ;
27+ use std:: future:: Future ;
2728
2829use http:: { Method , Request } ;
2930
@@ -33,6 +34,7 @@ use axum::body::{Body, Bytes};
3334use axum:: extract:: connect_info:: MockConnectInfo ;
3435use chrono:: NaiveDateTime ;
3536use cookie:: Cookie ;
37+ use futures_util:: FutureExt ;
3638use http:: header;
3739use secrecy:: ExposeSecret ;
3840use serde_json:: json;
@@ -91,23 +93,28 @@ pub trait RequestHelper {
9193 fn app ( & self ) -> & TestApp ;
9294
9395 /// Run a request that is expected to succeed
94- async fn run < T > ( & self , request : Request < impl Into < Body > > ) -> Response < T > {
96+ fn run < T > ( & self , request : Request < impl Into < Body > > ) -> impl Future < Output = Response < T > > {
9597 let app = self . app ( ) ;
96- let router = app . router ( ) . clone ( ) ;
98+ let request = request . map ( Into :: into ) ;
9799
98- // Add a mock `SocketAddr` to the requests so that the `ConnectInfo`
99- // extractor has something to extract.
100- let mocket_addr = SocketAddr :: from ( ( [ 127 , 0 , 0 , 1 ] , 52381 ) ) ;
101- let router = router . layer ( MockConnectInfo ( mocket_addr ) ) ;
100+ // This inner function is used to avoid long compile times
101+ // due to monomorphization of the `run()` fn itself
102+ async fn inner ( app : & TestApp , request : Request < Body > ) -> axum :: response :: Response < Bytes > {
103+ let router = app . router ( ) . clone ( ) ;
102104
103- let request = request. map ( Into :: into) ;
104- let axum_response = router. oneshot ( request) . await . unwrap ( ) ;
105+ // Add a mock `SocketAddr` to the requests so that the `ConnectInfo`
106+ // extractor has something to extract.
107+ let mocket_addr = SocketAddr :: from ( ( [ 127 , 0 , 0 , 1 ] , 52381 ) ) ;
108+ let router = router. layer ( MockConnectInfo ( mocket_addr) ) ;
109+
110+ let axum_response = router. oneshot ( request) . await . unwrap ( ) ;
105111
106- let ( parts, body) = axum_response. into_parts ( ) ;
107- let bytes = axum:: body:: to_bytes ( body, usize:: MAX ) . await . unwrap ( ) ;
108- let bytes_response = axum:: response:: Response :: from_parts ( parts, bytes) ;
112+ let ( parts, body) = axum_response. into_parts ( ) ;
113+ let bytes = axum:: body:: to_bytes ( body, usize:: MAX ) . await . unwrap ( ) ;
114+ axum:: response:: Response :: from_parts ( parts, bytes)
115+ }
109116
110- Response :: new ( bytes_response )
117+ inner ( app , request ) . map ( Response :: new)
111118 }
112119
113120 /// Create a get request
@@ -134,26 +141,18 @@ pub trait RequestHelper {
134141
135142 /// Issue a PUT request
136143 async fn put < T > ( & self , path : & str , body : impl Into < Bytes > ) -> Response < T > {
137- let body = body. into ( ) ;
138-
139- let mut request = self . request_builder ( Method :: PUT , path) ;
140- * request. body_mut ( ) = body;
141- if is_json_body ( request. body ( ) ) {
142- request. header ( header:: CONTENT_TYPE , "application/json" ) ;
143- }
144+ let request = self
145+ . request_builder ( Method :: PUT , path)
146+ . with_body ( body. into ( ) ) ;
144147
145148 self . run ( request) . await
146149 }
147150
148151 /// Issue a PATCH request
149152 async fn patch < T > ( & self , path : & str , body : impl Into < Bytes > ) -> Response < T > {
150- let body = body. into ( ) ;
151-
152- let mut request = self . request_builder ( Method :: PATCH , path) ;
153- * request. body_mut ( ) = body;
154- if is_json_body ( request. body ( ) ) {
155- request. header ( header:: CONTENT_TYPE , "application/json" ) ;
156- }
153+ let request = self
154+ . request_builder ( Method :: PATCH , path)
155+ . with_body ( body. into ( ) ) ;
157156
158157 self . run ( request) . await
159158 }
@@ -166,13 +165,9 @@ pub trait RequestHelper {
166165
167166 /// Issue a DELETE request with a body... yes we do it, for crate owner removal
168167 async fn delete_with_body < T > ( & self , path : & str , body : impl Into < Bytes > ) -> Response < T > {
169- let body = body. into ( ) ;
170-
171- let mut request = self . request_builder ( Method :: DELETE , path) ;
172- * request. body_mut ( ) = body;
173- if is_json_body ( request. body ( ) ) {
174- request. header ( header:: CONTENT_TYPE , "application/json" ) ;
175- }
168+ let request = self
169+ . request_builder ( Method :: DELETE , path)
170+ . with_body ( body. into ( ) ) ;
176171
177172 self . run ( request) . await
178173 }
@@ -256,11 +251,6 @@ fn req(method: Method, path: &str) -> MockRequest {
256251 . unwrap ( )
257252}
258253
259- fn is_json_body ( body : & Bytes ) -> bool {
260- ( body. starts_with ( b"{" ) && body. ends_with ( b"}" ) )
261- || ( body. starts_with ( b"[" ) && body. ends_with ( b"]" ) )
262- }
263-
264254/// A type that can generate unauthenticated requests
265255pub struct MockAnonymousUser {
266256 app : TestApp ,
0 commit comments