Skip to main content

max / makenotwork

2.8 KB · 95 lines History Blame Raw
1 //! Site access gate (`ACCESS_GATE=fan_plus_or_creator`): the testnot-style
2 //! gate that restricts the whole site to creators and Fan+ members.
3
4 use crate::harness::seed_user;
5 use crate::harness::{BuildOptions, TestHarness};
6 use makenotwork::config::AccessGate;
7
8 fn location(resp: &crate::harness::client::TestResponse) -> String {
9 resp.headers
10 .get("location")
11 .and_then(|v| v.to_str().ok())
12 .unwrap_or("")
13 .to_string()
14 }
15
16 #[tokio::test]
17 async fn access_gate_restricts_to_fan_plus_or_creator() {
18 let mut h = TestHarness::build(BuildOptions {
19 access_gate: AccessGate::FanPlusOrCreator,
20 ..Default::default()
21 })
22 .await;
23 // Seeded directly rather than via `signup`: the HTTP signup flow is itself
24 // behind this gate, so the test seeds the rows and authenticates through the
25 // exempt `/login`.
26 let creator = seed_user(&h.db, "gatecreator").await;
27 h.grant_creator(creator).await;
28 seed_user(&h.db, "plainfan").await;
29
30 // Anonymous visitor → bounced to login with the gate notice.
31 let r = h.client.get("/").await;
32 assert!(
33 r.status.is_redirection(),
34 "anon should be redirected, got {}",
35 r.status
36 );
37 assert!(
38 location(&r).starts_with("/login"),
39 "anon should land on login, got {}",
40 location(&r)
41 );
42
43 // Exempt paths stay reachable while the gate is on, or login is impossible.
44 assert_eq!(
45 h.client.get("/login").await.status.as_u16(),
46 200,
47 "login page must be reachable"
48 );
49 assert_eq!(
50 h.client.get("/health").await.status.as_u16(),
51 200,
52 "health must be reachable"
53 );
54
55 // A logged-in plain fan (no creator, no Fan+) is still blocked, the gate
56 // is stricter than ordinary auth.
57 h.login("plainfan", "password123").await;
58 let r = h.client.get("/library").await;
59 assert!(
60 r.status.is_redirection(),
61 "plain fan should be gated, got {}",
62 r.status
63 );
64 assert!(
65 location(&r).starts_with("/login"),
66 "plain fan should land on login"
67 );
68
69 // A creator passes the gate (library renders 200 for the logged-in owner).
70 h.client.post_form("/logout", "").await;
71 h.login("gatecreator", "password123").await;
72 let r = h.client.get("/library").await;
73 assert_eq!(
74 r.status.as_u16(),
75 200,
76 "creator should pass the gate: {} {}",
77 r.status,
78 r.text
79 );
80 }
81
82 #[tokio::test]
83 async fn access_gate_open_serves_public_site() {
84 // Default (Open), the public landing renders for an anonymous visitor,
85 // proving the gate is off unless explicitly enabled.
86 let mut h = TestHarness::new().await;
87 let r = h.client.get("/").await;
88 assert_eq!(
89 r.status.as_u16(),
90 200,
91 "open site should serve landing to anon: {}",
92 r.status
93 );
94 }
95