aro-web 1.0.0

HTTP/ADR layer for the Aro web framework
Documentation
//! Integration tests for `ETag` / conditional response helpers.

use aro_web::cache::{IfNoneMatch, conditional, with_etag};
use axum::Router;
use axum::body::Body;
use axum::http::{Request, StatusCode, header};
use axum::routing::get;
use tower::ServiceExt;

const ETAG: &str = "\"v1\"";

async fn etag_handler(inm: IfNoneMatch) -> axum::response::Response {
    if let Some(not_modified) = conditional(ETAG, &inm) {
        return not_modified;
    }
    with_etag("hello", ETAG)
}

fn app() -> Router {
    Router::new().route("/resource", get(etag_handler))
}

#[tokio::test]
async fn matching_if_none_match_returns_304() {
    let req = Request::builder()
        .uri("/resource")
        .header(header::IF_NONE_MATCH, ETAG)
        .body(Body::empty())
        .unwrap();

    let resp = app().oneshot(req).await.unwrap();

    assert_eq!(resp.status(), StatusCode::NOT_MODIFIED);
    assert_eq!(
        resp.headers().get(header::ETAG).unwrap().to_str().unwrap(),
        ETAG
    );
    let body = axum::body::to_bytes(resp.into_body(), usize::MAX)
        .await
        .unwrap();
    assert!(body.is_empty(), "304 response should have no body");
}

#[tokio::test]
async fn non_matching_if_none_match_returns_200_with_etag() {
    let req = Request::builder()
        .uri("/resource")
        .header(header::IF_NONE_MATCH, "\"stale\"")
        .body(Body::empty())
        .unwrap();

    let resp = app().oneshot(req).await.unwrap();

    assert_eq!(resp.status(), StatusCode::OK);
    assert_eq!(
        resp.headers().get(header::ETAG).unwrap().to_str().unwrap(),
        ETAG
    );
}

#[tokio::test]
async fn no_if_none_match_returns_200_with_etag() {
    let req = Request::builder()
        .uri("/resource")
        .body(Body::empty())
        .unwrap();

    let resp = app().oneshot(req).await.unwrap();

    assert_eq!(resp.status(), StatusCode::OK);
    assert_eq!(
        resp.headers().get(header::ETAG).unwrap().to_str().unwrap(),
        ETAG
    );
}