@@ -180,8 +180,9 @@ macro_rules! pub_response_impl {
180180 self . _into_msgpack( ) $( . $suffix) ?
181181 }
182182
183- /// Checks if a route was routed by a specific route type. This only returns true if the route
184- /// actually generated a response, and a catcher was not run.
183+ /// Checks if a response was generted by a specific route type. This only returns true if the route
184+ /// actually generated the response, and a catcher was _not_ run. See [`was_attempted_by`] to
185+ /// check if a route was attempted, but may not have generated the response
185186 ///
186187 /// # Example
187188 ///
@@ -202,13 +203,69 @@ macro_rules! pub_response_impl {
202203 /// return a static file can be checked against it. Libraries which provide custom Routes should
203204 /// implement `RouteType`, see [`RouteType`](crate::route::RouteType) for more information.
204205 pub fn was_routed_by<T : crate :: route:: RouteType >( & self ) -> bool {
205- if let Some ( route_type) = self . _request( ) . route( ) . map( |r| r. route_type) . flatten( ) {
206+ // If this request was caught, the route in `.route()` did NOT generate this response.
207+ if self . _request( ) . catcher( ) . is_some( ) {
208+ false
209+ } else if let Some ( route_type) = self . _request( ) . route( ) . map( |r| r. route_type) . flatten( ) {
206210 route_type == std:: any:: TypeId :: of:: <T >( )
207211 } else {
208212 false
209213 }
210214 }
211215
216+ /// Checks if a request was routed to a specific route type. This will return true for routes
217+ /// that were attempted, _but not actually called_. This enables a test to verify that a route
218+ /// was attempted, even if another route actually generated the response, e.g. an
219+ /// authenticated route will typically defer to an error catcher if the request does not have
220+ /// the proper authentication. This makes it possible to verify that a request was routed to
221+ /// the authentication route, even if the response was eventaully generated by another route or
222+ /// a catcher.
223+ ///
224+ /// # Example
225+ ///
226+ // WARNING: this doc-test is NOT run, because cargo test --doc does not run doc-tests for items
227+ // only available during tests.
228+ /// ```rust
229+ /// # use rocket::{get, routes, async_trait, request::{Request, Outcome, FromRequest}};
230+ /// # struct WillFail {}
231+ /// # #[async_trait]
232+ /// # impl<'r> FromRequest<'r> for WillFail {
233+ /// # type Error = ();
234+ /// # async fn from_request(request: &'r Request<'_>) -> Outcome<Self, Self::Error> {
235+ /// # Outcome::Forward(())
236+ /// # }
237+ /// # }
238+ /// #[get("/", rank = 2)]
239+ /// fn index1(guard: WillFail) -> &'static str { "Hello World" }
240+ /// #[get("/")]
241+ /// fn index2() -> &'static str { "Hello World" }
242+ #[ doc = $doc_prelude]
243+ /// # Client::_test_with(|r| r.mount("/", routes![index1, index2]), |_, _, response| {
244+ /// let response: LocalResponse = response;
245+ /// assert!(response.was_attempted_by::<index1>());
246+ /// assert!(response.was_attempted_by::<index2>());
247+ /// assert!(response.was_routed_by::<index2>());
248+ /// # });
249+ /// ```
250+ ///
251+ /// # Other Route types
252+ ///
253+ /// [`FileServer`](crate::fs::FileServer) implementes `RouteType`, so a route that should
254+ /// return a static file can be checked against it. Libraries which provide custom Routes should
255+ /// implement `RouteType`, see [`RouteType`](crate::route::RouteType) for more information.
256+ ///
257+ /// # Note
258+ ///
259+ /// This method is marked as `cfg(test)`, and is therefore only available in unit and
260+ /// integration tests. This is because the list of routes attempted is only collected in these
261+ /// testing environments, to minimize performance impacts during normal operation.
262+ #[ cfg( test) ]
263+ pub fn was_attempted_by<T : crate :: route:: RouteType >( & self ) -> bool {
264+ self . _request( ) . route_path( |path| path. iter( ) . any( |r|
265+ r. route_type == Some ( std:: any:: TypeId :: of:: <T >( ) )
266+ ) )
267+ }
268+
212269 /// Checks if a route was caught by a specific route type
213270 ///
214271 /// # Example
0 commit comments