Repository: actix/actix-web
File: src/middleware/normalize.rs (Rust)

Code before:
                    web::resource("/v2/something/")
                        .guard(fn_guard(|req| req.uri.query() == Some("query=test")))
                        .to(HttpResponse::Ok),
                ),
        )
        .await;

        let test_uris = vec![
            "/",
            "///",
            "/v1/something",
            "/v1/something/",
            "/v1/something////",
            "//v1//something",
            "//v1//something//",
            "/v2/something?query=test",
            "/v2/something/?query=test",
            "/v2/something////?query=test",
            "//v2//something?query=test",
            "//v2//something//?query=test",
        ];

        for uri in test_uris {
            let req = TestRequest::with_uri(uri).to_request();
            let res = call_service(&app, req).await;
            assert!(res.status().is_success());
        }
    }

    #[actix_rt::test]
    async fn ensure_root_trailing_slash_with_query() {
        let app = init_service(
            App::new()
                .wrap(NormalizePath(TrailingSlash::Always))
                .service(
                    web::resource("/")
                        .guard(fn_guard(|req| req.uri.query() == Some("query=test")))
                        .to(HttpResponse::Ok),
                ),
        )
        .await;

        let test_uris = vec!["/?query=test", "//?query=test", "///?query=test"];

        for uri in test_uris {
            let req = TestRequest::with_uri(uri).to_request();
            let res = call_service(&app, req).await;
            assert!(res.status().is_success());
        }
    }


Review comment (bug):
On those asserts, it'd be nice to provide a more informative error when the assert fails so it provides some more information as it'll act on a loop. 

Code after:
                    web::resource("/v2/something/")
                        .guard(fn_guard(|req| req.uri.query() == Some("query=test")))
                        .to(HttpResponse::Ok),
                ),
        )
        .await;

        let test_uris = vec![
            "/",
            "///",
            "/v1/something",
            "/v1/something/",
            "/v1/something////",
            "//v1//something",
            "//v1//something//",
            "/v2/something?query=test",
            "/v2/something/?query=test",
            "/v2/something////?query=test",
            "//v2//something?query=test",
            "//v2//something//?query=test",
        ];

        for uri in test_uris {
            let req = TestRequest::with_uri(uri).to_request();
            let res = call_service(&app, req).await;
            assert!(res.status().is_success(), "Failed uri: {}", uri);
        }
    }

    #[actix_rt::test]
    async fn ensure_root_trailing_slash_with_query() {
        let app = init_service(
            App::new()
                .wrap(NormalizePath(TrailingSlash::Always))
                .service(
                    web::resource("/")
                        .guard(fn_guard(|req| req.uri.query() == Some("query=test")))
                        .to(HttpResponse::Ok),
                ),
        )
        .await;

        let test_uris = vec!["/?query=test", "//?query=test", "///?query=test"];

        for uri in test_uris {
            let req = TestRequest::with_uri(uri).to_request();
            let res = call_service(&app, req).await;
            assert!(res.status().is_success(), "Failed uri: {}", uri);
        }
    }