From 61347de7d0242bfcf2d6c026df95c050832b2b6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lukas=20W=C3=B6lfer?= Date: Fri, 10 Apr 2026 23:09:33 +0200 Subject: [PATCH] test: initialize e2e tests --- tests/e2e.rs | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 107 insertions(+) create mode 100644 tests/e2e.rs diff --git a/tests/e2e.rs b/tests/e2e.rs new file mode 100644 index 0000000..8128905 --- /dev/null +++ b/tests/e2e.rs @@ -0,0 +1,107 @@ +use axum::{body::Body, http::{header, Request, StatusCode}}; +use oauth2::{basic::BasicClient, AuthUrl, ClientId, ClientSecret, TokenUrl}; +use sqlx::SqlitePool; +use tower::ServiceExt; +use weight_tracker::{create_app, AppState}; + +async fn make_app() -> axum::Router { + let pool = SqlitePool::connect("sqlite::memory:").await.unwrap(); + sqlx::query(include_str!("../migrations/20260408203423_create_weights_table.sql")) + .execute(&pool) + .await + .unwrap(); + + let oidc_client = BasicClient::new( + ClientId::new("test-client".into()), + Some(ClientSecret::new("test-secret".into())), + AuthUrl::new("http://localhost/auth".into()).unwrap(), + Some(TokenUrl::new("http://localhost/token".into()).unwrap()), + ); + + let state = AppState { pool, oidc_client }; + create_app(state, b"01234567890123456789012345678901".to_vec()) +} + +#[tokio::test] +async fn index_returns_ok() { + let app = make_app().await; + + let response = app + .oneshot(Request::builder().uri("/").body(Body::empty()).unwrap()) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::OK); +} + +#[tokio::test] +async fn auth_login_redirects_and_sets_cookie() { + let app = make_app().await; + + let response = app + .oneshot(Request::builder().uri("/auth/login").body(Body::empty()).unwrap()) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::FOUND); + assert!(response.headers().get(header::LOCATION).is_some()); + assert!(response.headers().get(header::SET_COOKIE).is_some()); +} + +#[tokio::test] +async fn input_post_requires_authentication() { + let app = make_app().await; + + let response = app + .oneshot( + Request::builder() + .method("POST") + .uri("/input") + .header(header::CONTENT_TYPE, "application/x-www-form-urlencoded") + .body(Body::from("date=2026-04-10&weight=80")) + .unwrap(), + ) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::FOUND); + assert_eq!(response.headers().get(header::LOCATION).unwrap(), "/auth/login"); +} + +#[tokio::test] +async fn authenticated_input_post_stores_weight() { + let app = make_app().await; + let app_clone = app.clone(); + + let auth_response = app_clone + .oneshot(Request::builder().uri("/test/login").body(Body::empty()).unwrap()) + .await + .unwrap(); + + assert_eq!(auth_response.status(), StatusCode::FOUND); + let cookie = auth_response + .headers() + .get(header::SET_COOKIE) + .unwrap() + .to_str() + .unwrap(); + + let response = app + .oneshot( + Request::builder() + .method("POST") + .uri("/input") + .header(header::CONTENT_TYPE, "application/x-www-form-urlencoded") + .header(header::COOKIE, cookie) + .body(Body::from("date=2026-04-10&weight=80")) + .unwrap(), + ) + .await + .unwrap(); + + assert_eq!(response.status(), StatusCode::OK); + let body_bytes = hyper::body::to_bytes(response.into_body()).await.unwrap(); + let body_text = std::str::from_utf8(&body_bytes).unwrap(); + assert!(body_text.contains("80 kg")); + assert!(body_text.contains("test-user")); +}