···11+CREATE TABLE IF NOT EXISTS account_deletion_requests (
22+ token TEXT PRIMARY KEY,
33+ did TEXT NOT NULL REFERENCES users(did) ON DELETE CASCADE,
44+ expires_at TIMESTAMPTZ NOT NULL,
55+ created_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
66+);
···442442 assert_eq!(claims["iss"], did);
443443 assert_eq!(claims["aud"], "did:web:api.bsky.app");
444444 assert_eq!(claims["lxm"], "com.atproto.repo.uploadBlob");
445445-}445445+}
446446+447447+#[tokio::test]
448448+async fn test_request_account_delete() {
449449+ let client = client();
450450+ let (did, jwt) = setup_new_user("request-delete-test").await;
451451+452452+ let res = client
453453+ .post(format!(
454454+ "{}/xrpc/com.atproto.server.requestAccountDelete",
455455+ base_url().await
456456+ ))
457457+ .bearer_auth(&jwt)
458458+ .send()
459459+ .await
460460+ .expect("Failed to request account deletion");
461461+462462+ assert_eq!(res.status(), StatusCode::OK);
463463+464464+ let db_url = get_db_connection_string().await;
465465+ let pool = sqlx::PgPool::connect(&db_url).await.expect("Failed to connect to test DB");
466466+467467+ let row = sqlx::query!("SELECT token, expires_at FROM account_deletion_requests WHERE did = $1", did)
468468+ .fetch_optional(&pool)
469469+ .await
470470+ .expect("Failed to query DB");
471471+472472+ assert!(row.is_some(), "Deletion token should exist in DB");
473473+ let row = row.unwrap();
474474+ assert!(!row.token.is_empty(), "Token should not be empty");
475475+ assert!(row.expires_at > Utc::now(), "Token should not be expired");
476476+}