//! Page route tests: public pages, user/project/item detail, RSS feeds, discover. //! //! These test that page routes render successfully and contain expected content. //! Complements the API workflow tests which focus on JSON endpoints. use crate::harness::TestHarness; use serde_json::Value; #[tokio::test] async fn public_pages_render() { let mut h = TestHarness::new().await; // Landing page let resp = h.client.get("/").await; assert_eq!(resp.status, 200, "Landing page should return 200"); // Login page let resp = h.client.get("/login").await; assert_eq!(resp.status, 200, "Login page should return 200"); // Join page let resp = h.client.get("/join").await; assert_eq!(resp.status, 200, "Join page should return 200"); // Pricing page let resp = h.client.get("/pricing").await; assert_eq!(resp.status, 200, "Pricing page should return 200"); // Discover page let resp = h.client.get("/discover").await; assert_eq!(resp.status, 200, "Discover page should return 200"); // Discover with filters let resp = h.client.get("/discover?mode=projects").await; assert_eq!(resp.status, 200, "Discover projects mode should return 200"); // Tag tree browser let resp = h.client.get("/discover/tags").await; assert_eq!(resp.status, 200, "Tag tree should return 200"); } #[tokio::test] async fn user_and_project_pages() { let mut h = TestHarness::new().await; // Setup: creator with public project and item let user_id = h.signup("pagetest", "pagetest@example.com", "password123").await; h.grant_creator(user_id).await; h.client.post_form("/logout", "").await; h.login("pagetest", "password123").await; let resp = h .client .post_form("/api/projects", "slug=test-proj&title=Test+Project") .await; let project: Value = resp.json(); let project_id = project["id"].as_str().unwrap(); // Make project public h.client .put_json( &format!("/api/projects/{}", project_id), r#"{"is_public": true}"#, ) .await; // Create a text item and make it public let resp = h .client .post_form( &format!("/api/projects/{}/items", project_id), "title=Test+Article&item_type=text&is_public=true&price_cents=0", ) .await; assert!(resp.status.is_success(), "Create item failed: {}", resp.text); let item: Value = resp.json(); let item_id = item["id"].as_str().unwrap(); // Add text content. The store page renders an excerpt from the first // paragraph (full body lives on /l/{id}), so keep the asserted phrase // in paragraph one. h.client .put_json( &format!("/api/items/{}/text", item_id), "{\"body\": \"Test content for page rendering.\\n\\n# Hello\\n\\nMore body below.\"}", ) .await; // Log out to test as anonymous user h.client.post_form("/logout", "").await; // ── User profile page ── let resp = h.client.get("/u/pagetest").await; assert_eq!(resp.status, 200, "User page should return 200"); assert!( resp.text.contains("Test Project"), "User page should show project title" ); // ── Project page ── let resp = h.client.get("/p/test-proj").await; assert_eq!(resp.status, 200, "Project page should return 200"); assert!( resp.text.contains("Test Article"), "Project page should show item title" ); // ── Item page (text reader) ── let resp = h.client.get(&format!("/i/{}", item_id)).await; assert_eq!(resp.status, 200, "Item page should return 200"); assert!( resp.text.contains("Test content"), "Item page should render text content" ); // ── 404 for nonexistent user/project ── let resp = h.client.get("/u/nonexistent-user-xyz").await; assert_eq!(resp.status, 404, "Nonexistent user should return 404"); let resp = h.client.get("/p/nonexistent-project-xyz").await; assert_eq!(resp.status, 404, "Nonexistent project should return 404"); } #[tokio::test] async fn rss_feeds() { let mut h = TestHarness::new().await; // Setup: creator with public project and item let user_id = h.signup("rsstest", "rsstest@example.com", "password123").await; h.grant_creator(user_id).await; h.client.post_form("/logout", "").await; h.login("rsstest", "password123").await; let resp = h .client .post_form("/api/projects", "slug=rss-proj&title=RSS+Project") .await; let project: Value = resp.json(); let project_id = project["id"].as_str().unwrap(); // Make project public h.client .put_json( &format!("/api/projects/{}", project_id), r#"{"is_public": true}"#, ) .await; // Create a public item let resp = h .client .post_form( &format!("/api/projects/{}/items", project_id), "title=RSS+Item&item_type=text&is_public=true&price_cents=0", ) .await; assert!(resp.status.is_success(), "Create item failed: {}", resp.text); h.client.post_form("/logout", "").await; // ── Creator RSS feed ── let resp = h.client.get("/u/rsstest/rss").await; assert_eq!(resp.status, 200, "Creator RSS feed should return 200"); assert!( resp.text.contains("