Something went wrong. Try again.
relay filter/appview bootstrap
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412mod common;
use std::str::FromStr;
use chrono::Utc;use jacquard_common::types::{aturi::AtUri, cid::Cid as AtpCid, did::Did};use prism::records::{ CHANNEL_COLLECTION, INVITE_COLLECTION, LATTICE_COLLECTION, MEMBERSHIP_COLLECTION, Record, RecordRefs, SHARD_COLLECTION, new_cursor,};use reqwest::StatusCode;use serde_json::{Value, json};
async fn insert_test_channel(pool: &sqlx::SqlitePool, cid: &str, creator_did: &str, name: &str) { let uri = format!( "at://{}/systems.gmstn.development.channel/{}", creator_did, cid ); prism::db::insert_record( pool, &Record { uri: AtUri::new_owned(&uri).unwrap(), cid: AtpCid::from_str(cid).unwrap(), collection: CHANNEL_COLLECTION.clone(), creator_did: Did::new_owned(creator_did).unwrap(), created_at: Utc::now(), cursor: new_cursor(), data: json!({"name": name, "topic": "test topic"}), target_did: None, refs: RecordRefs::default(), }, ) .await .unwrap();}
async fn insert_test_invite( pool: &sqlx::SqlitePool, cid: &str, creator_did: &str, channel_cid: &str, recipient_did: &str,) { let uri = format!( "at://{}/systems.gmstn.development.channel.invite/{}", creator_did, cid ); prism::db::insert_record( pool, &Record { uri: AtUri::new_owned(&uri).unwrap(), cid: AtpCid::from_str(cid).unwrap(), collection: INVITE_COLLECTION.clone(), creator_did: Did::new_owned(creator_did).unwrap(), created_at: Utc::now(), cursor: new_cursor(), data: json!({"recipient": recipient_did}), target_did: Some(Did::new_owned(recipient_did).unwrap()), refs: RecordRefs { channel: Some(AtpCid::from_str(channel_cid).unwrap()), invite: None, }, }, ) .await .unwrap();}
async fn insert_test_membership( pool: &sqlx::SqlitePool, cid: &str, recipient_did: &str, channel_cid: &str, invite_cid: &str,) { let uri = format!( "at://{}/systems.gmstn.development.channel.membership/{}", recipient_did, cid ); prism::db::insert_record( pool, &Record { uri: AtUri::new_owned(&uri).unwrap(), cid: AtpCid::from_str(cid).unwrap(), collection: MEMBERSHIP_COLLECTION.clone(), creator_did: Did::new_owned(recipient_did).unwrap(), created_at: Utc::now(), cursor: new_cursor(), data: json!({"state": "accepted"}), target_did: Some(Did::new_owned(recipient_did).unwrap()), refs: RecordRefs { channel: Some(AtpCid::from_str(channel_cid).unwrap()), invite: Some(AtpCid::from_str(invite_cid).unwrap()), }, }, ) .await .unwrap();}
async fn insert_test_lattice(pool: &sqlx::SqlitePool, cid: &str, creator_did: &str) { let uri = format!( "at://{}/systems.gmstn.development.lattice/{}", creator_did, cid ); prism::db::insert_record( pool, &Record { uri: AtUri::new_owned(&uri).unwrap(), cid: AtpCid::from_str(cid).unwrap(), collection: LATTICE_COLLECTION.clone(), creator_did: Did::new_owned(creator_did).unwrap(), created_at: Utc::now(), cursor: new_cursor(), data: json!({"description": "test lattice"}), target_did: None, refs: RecordRefs::default(), }, ) .await .unwrap();}
async fn insert_test_shard(pool: &sqlx::SqlitePool, cid: &str, creator_did: &str) { let uri = format!( "at://{}/systems.gmstn.development.shard/{}", creator_did, cid ); prism::db::insert_record( pool, &Record { uri: AtUri::new_owned(&uri).unwrap(), cid: AtpCid::from_str(cid).unwrap(), collection: SHARD_COLLECTION.clone(), creator_did: Did::new_owned(creator_did).unwrap(), created_at: Utc::now(), cursor: new_cursor(), data: json!({"description": "test shard"}), target_did: None, refs: RecordRefs::default(), }, ) .await .unwrap();}
#[tokio::test]async fn test_list_channels_returns_correct_structure() { let base_url = common::base_url().await; let pool = common::get_db_pool().await; let client = common::client();
let test_did = "did:plc:testchannelsstructure"; insert_test_channel(&pool, "bafychannel001", test_did, "Test Channel").await;
let res = client .get(format!( "{}/xrpc/systems.gmstn.development.channel.listChannels?author={}", base_url, test_did )) .send() .await .unwrap();
assert_eq!(res.status(), StatusCode::OK);
let body: Value = res.json().await.unwrap(); assert!(body["channels"].is_array());
let channels = body["channels"].as_array().unwrap(); assert!(!channels.is_empty());
let channel = &channels[0]; assert!(channel["uri"].is_string()); assert!(channel["cid"].is_string()); assert!(channel["displayName"].is_string()); assert!(channel["createdAt"].is_string()); assert!(channel["indexedAt"].is_string());}
#[tokio::test]async fn test_list_channels_empty_author() { let base_url = common::base_url().await; let client = common::client();
let res = client .get(format!( "{}/xrpc/systems.gmstn.development.channel.listChannels?author=did:plc:nonexistent", base_url )) .send() .await .unwrap();
assert_eq!(res.status(), StatusCode::OK);
let body: Value = res.json().await.unwrap(); assert!(body["channels"].is_array()); assert!(body["channels"].as_array().unwrap().is_empty()); assert!(body["cursor"].is_null());}
#[tokio::test]async fn test_list_channels_limit_bounds() { let base_url = common::base_url().await; let pool = common::get_db_pool().await; let client = common::client();
let test_did = "did:plc:testlimitbounds";
futures::future::join_all((0..5).map(|i| { let pool = pool.clone(); let did = test_did.to_string(); async move { insert_test_channel( &pool, &format!("bafylimitchan{}", i), &did, &format!("Channel {}", i), ) .await; } })) .await;
let res = client .get(format!( "{}/xrpc/systems.gmstn.development.channel.listChannels?author={}&limit=2", base_url, test_did )) .send() .await .unwrap();
assert_eq!(res.status(), StatusCode::OK);
let body: Value = res.json().await.unwrap(); let channels = body["channels"].as_array().unwrap(); assert_eq!(channels.len(), 2); assert!(body["cursor"].is_string());
let res_over_limit = client .get(format!( "{}/xrpc/systems.gmstn.development.channel.listChannels?author={}&limit=150", base_url, test_did )) .send() .await .unwrap();
assert_eq!(res_over_limit.status(), StatusCode::OK);
let body_over: Value = res_over_limit.json().await.unwrap(); let channels_over = body_over["channels"].as_array().unwrap(); assert!(channels_over.len() <= 100);}
#[tokio::test]async fn test_list_invites_by_recipient() { let base_url = common::base_url().await; let pool = common::get_db_pool().await; let client = common::client();
let creator_did = "did:plc:invitecreator"; let recipient_did = "did:plc:inviterecipient";
insert_test_invite( &pool, "bafyinvite001", creator_did, "bafyinvitechan001", recipient_did, ) .await;
let res = client .get(format!( "{}/xrpc/systems.gmstn.development.channel.listInvites?recipient={}", base_url, recipient_did )) .send() .await .unwrap();
assert_eq!(res.status(), StatusCode::OK);
let body: Value = res.json().await.unwrap(); assert!(body["invites"].is_array());
let invites = body["invites"].as_array().unwrap(); assert!(!invites.is_empty());
let invite = &invites[0]; assert!(invite["uri"].is_string()); assert!(invite["cid"].is_string()); assert!(invite["channel"].is_string()); assert!(invite["recipient"].is_string()); assert!(invite["createdAt"].is_string());}
#[tokio::test]async fn test_list_memberships_by_recipient() { let base_url = common::base_url().await; let pool = common::get_db_pool().await; let client = common::client();
let recipient_did = "did:plc:membershiprecipient";
insert_test_membership( &pool, "bafymem001", recipient_did, "bafymemchan001", "bafymeminvite001", ) .await;
let res = client .get(format!( "{}/xrpc/systems.gmstn.development.channel.listMemberships?recipient={}", base_url, recipient_did )) .send() .await .unwrap();
assert_eq!(res.status(), StatusCode::OK);
let body: Value = res.json().await.unwrap(); assert!(body["memberships"].is_array());
let memberships = body["memberships"].as_array().unwrap(); assert!(!memberships.is_empty());
let membership = &memberships[0]; assert!(membership["uri"].is_string()); assert!(membership["cid"].is_string()); assert!(membership["channel"].is_string()); assert!(membership["invite"].is_string()); assert!(membership["recipient"].is_string()); assert!(membership["state"].is_string()); assert!(membership["createdAt"].is_string());}
#[tokio::test]async fn test_list_lattices_by_author() { let base_url = common::base_url().await; let pool = common::get_db_pool().await; let client = common::client();
let test_did = "did:plc:latticeauthor"; insert_test_lattice(&pool, "bafylattice001", test_did).await;
let res = client .get(format!( "{}/xrpc/systems.gmstn.development.lattice.listLattices?author={}", base_url, test_did )) .send() .await .unwrap();
assert_eq!(res.status(), StatusCode::OK);
let body: Value = res.json().await.unwrap(); assert!(body["lattices"].is_array());
let lattices = body["lattices"].as_array().unwrap(); assert!(!lattices.is_empty());
let lattice = &lattices[0]; assert!(lattice["uri"].is_string()); assert!(lattice["cid"].is_string()); assert!(lattice["author"].is_string()); assert!(lattice["createdAt"].is_string()); assert!(lattice["indexedAt"].is_string());}
#[tokio::test]async fn test_list_shards_by_author() { let base_url = common::base_url().await; let pool = common::get_db_pool().await; let client = common::client();
let test_did = "did:plc:shardauthor"; insert_test_shard(&pool, "bafyshard001", test_did).await;
let res = client .get(format!( "{}/xrpc/systems.gmstn.development.shard.listShards?author={}", base_url, test_did )) .send() .await .unwrap();
assert_eq!(res.status(), StatusCode::OK);
let body: Value = res.json().await.unwrap(); assert!(body["shards"].is_array());
let shards = body["shards"].as_array().unwrap(); assert!(!shards.is_empty());
let shard = &shards[0]; assert!(shard["uri"].is_string()); assert!(shard["cid"].is_string()); assert!(shard["author"].is_string()); assert!(shard["createdAt"].is_string()); assert!(shard["indexedAt"].is_string());}