forked from
tranquil.farm/tranquil-pds
Our Personal Data Server from scratch!
3.2 kB
100 lines
1mod common;
2use common::*;
3use reqwest::{Client, StatusCode};
4use serde_json::{Value, json};
5use tranquil_pds::api::error::ApiError;
6use tranquil_pds::api::invite::{InviteRegistration, check_registration_invite};
7use tranquil_types::InviteCode;
8
9async fn create_invite_code(client: &Client, admin_jwt: &str, use_count: u32) -> InviteCode {
10 let res = client
11 .post(format!(
12 "{}/xrpc/com.atproto.server.createInviteCode",
13 base_url().await
14 ))
15 .bearer_auth(admin_jwt)
16 .json(&json!({ "useCount": use_count }))
17 .send()
18 .await
19 .expect("failed to create invite code");
20 assert_eq!(res.status(), StatusCode::OK);
21 let body: Value = res.json().await.expect("invite code response not json");
22 InviteCode::from(body["code"].as_str().expect("missing code").to_string())
23}
24
25#[tokio::test]
26async fn check_registration_invite_validates_without_consuming() {
27 let state = get_test_app_state().await;
28
29 let client = client();
30 let (admin_jwt, _did) = create_admin_account_and_login(&client).await;
31 let code = create_invite_code(&client, &admin_jwt, 1).await;
32
33 assert_eq!(
34 check_registration_invite(state, Some(code.as_str()))
35 .await
36 .unwrap(),
37 InviteRegistration::Standard(Some(code.clone()))
38 );
39 assert_eq!(
40 state
41 .repos
42 .infra
43 .get_invite_code_available_uses(&code)
44 .await
45 .unwrap(),
46 Some(1),
47 "validation must not consume the invite"
48 );
49
50 assert_eq!(
51 check_registration_invite(state, Some(&format!(" {code} ")))
52 .await
53 .unwrap(),
54 InviteRegistration::Standard(Some(code.clone())),
55 "surrounding whitespace must be trimmed into the validated code"
56 );
57
58 assert!(matches!(
59 check_registration_invite(state, Some("whelk")).await,
60 Err(ApiError::InvalidInviteCode)
61 ));
62}
63
64#[tokio::test]
65async fn create_account_consumes_invite_code_exactly_once() {
66 let client = client();
67 let (admin_jwt, _did) = create_admin_account_and_login(&client).await;
68 let code = create_invite_code(&client, &admin_jwt, 2).await;
69
70 let handle = format!("u{}", &uuid::Uuid::new_v4().simple().to_string()[..12]);
71 let res = client
72 .post(format!(
73 "{}/xrpc/com.atproto.server.createAccount",
74 base_url().await
75 ))
76 .json(&json!({
77 "handle": handle,
78 "email": format!("{handle}@nel.pet"),
79 "password": "Testpass123!",
80 "inviteCode": code,
81 }))
82 .send()
83 .await
84 .expect("createAccount request failed");
85 let status = res.status();
86 let text = res.text().await.unwrap_or_default();
87 assert_eq!(status, StatusCode::OK, "createAccount failed: {text}");
88
89 let state = get_test_app_state().await;
90 assert_eq!(
91 state
92 .repos
93 .infra
94 .get_invite_code_available_uses(&code)
95 .await
96 .unwrap(),
97 Some(1),
98 "a single registration must consume exactly one invite use"
99 );
100}