Signed by hannaSSH key fingerprint: SHA256:4g9cWhkAAw8gwqhJUcVbSnGEvdGwklW+1Aa/fMUu59k
crates/web/src/tests.rs +56 −0
| @@ -331,6 +331,62 @@ async fn explore_users_lists_the_directory() { | |||
| 331 | assert!(html.contains("/avatar/ada"), "user avatar shown"); | 331 | assert!(html.contains("/avatar/ada"), "user avatar shown"); |
| 332 | } | 332 | } |
| 333 | 333 | ||
| 334 | /// Sign in as `ada` and return the `Cookie` header value carrying the session. | ||
| 335 | async fn login(app: &Router) -> String { | ||
| 336 | let form = app.clone().oneshot(get("/login")).await.unwrap(); | ||
| 337 | let csrf = form | ||
| 338 | .headers() | ||
| 339 | .get(header::SET_COOKIE) | ||
| 340 | .unwrap() | ||
| 341 | .to_str() | ||
| 342 | .unwrap() | ||
| 343 | .to_string(); | ||
| 344 | let token = csrf | ||
| 345 | .split("fabrica_csrf=") | ||
| 346 | .nth(1) | ||
| 347 | .and_then(|s| s.split(';').next()) | ||
| 348 | .unwrap() | ||
| 349 | .to_string(); | ||
| 350 | let req = Request::builder() | ||
| 351 | .method("POST") | ||
| 352 | .uri("/login") | ||
| 353 | .header(header::CONTENT_TYPE, "application/x-www-form-urlencoded") | ||
| 354 | .header(header::COOKIE, format!("fabrica_csrf={token}")) | ||
| 355 | .body(Body::from(format!( | ||
| 356 | "username=ada&password=secret12&_csrf={token}" | ||
| 357 | ))) | ||
| 358 | .unwrap(); | ||
| 359 | let res = app.clone().oneshot(req).await.unwrap(); | ||
| 360 | let session = res | ||
| 361 | .headers() | ||
| 362 | .get(header::SET_COOKIE) | ||
| 363 | .unwrap() | ||
| 364 | .to_str() | ||
| 365 | .unwrap(); | ||
| 366 | let session = session.split(';').next().unwrap(); | ||
| 367 | format!("fabrica_csrf={token}; {session}") | ||
| 368 | } | ||
| 369 | |||
| 370 | #[tokio::test] | ||
| 371 | async fn dashboard_shows_activity_and_repos_when_signed_in() { | ||
| 372 | let (_state, app) = app().await; | ||
| 373 | let cookie = login(&app).await; | ||
| 374 | let req = Request::builder() | ||
| 375 | .uri("/") | ||
| 376 | .header(header::COOKIE, cookie) | ||
| 377 | .body(Body::empty()) | ||
| 378 | .unwrap(); | ||
| 379 | let res = app.oneshot(req).await.unwrap(); | ||
| 380 | assert_eq!(res.status(), StatusCode::OK); | ||
| 381 | let html = body_string(res).await; | ||
| 382 | assert!( | ||
| 383 | html.contains("contributions in the last year"), | ||
| 384 | "activity heatmap caption present" | ||
| 385 | ); | ||
| 386 | assert!(html.contains("Recent activity"), "activity feed present"); | ||
| 387 | assert!(html.contains("class=\"heatmap\""), "heatmap svg present"); | ||
| 388 | } | ||
| 389 | |||
| 334 | #[tokio::test] | 390 | #[tokio::test] |
| 335 | async fn settings_requires_authentication() { | 391 | async fn settings_requires_authentication() { |
| 336 | let (_state, app) = app().await; | 392 | let (_state, app) = app().await; |