use super::*;
use std::sync::{Arc, RwLock};
use tempfile::TempDir;
#[test]
fn disabled_relays_do_not_start_public_graph_refresh() {
let temp = TempDir::new().unwrap();
let owner = Keys::generate();
let device = Keys::generate();
let mut core = AppCore::new(
flume::unbounded().0,
flume::unbounded().0,
temp.path().to_string_lossy().to_string(),
Arc::new(RwLock::new(AppState::empty())),
);
core.logged_in = Some(LoggedInState {
owner_pubkey: owner.public_key(),
owner_keys: Some(owner),
device_keys: device.clone(),
client: Client::new(device),
relay_urls: Vec::new(),
authorization_state: LocalAuthorizationState::Authorized,
});
core.request_user_discovery_refresh(true);
assert!(!core.user_discovery_runtime.in_flight);
assert!(!core.user_discovery_runtime.refresh_pending);
assert!(core.user_discovery_runtime.last_started_at.is_none());
}
#[test]
fn completed_fetch_starts_one_pending_refresh_despite_reconnect_floor() {
let temp = TempDir::new().unwrap();
let owner = Keys::generate();
let device = Keys::generate();
let mut core = AppCore::new(
flume::unbounded().0,
flume::unbounded().0,
temp.path().to_string_lossy().to_string(),
Arc::new(RwLock::new(AppState::empty())),
);
core.logged_in = Some(LoggedInState {
owner_pubkey: owner.public_key(),
owner_keys: Some(owner),
device_keys: device.clone(),
client: Client::new(device),
relay_urls: relay_urls_from_strings(&["wss://example.invalid".to_string()]),
authorization_state: LocalAuthorizationState::Authorized,
});
core.user_discovery_runtime.token = 7;
core.user_discovery_runtime.in_flight = true;
core.user_discovery_runtime.refresh_pending = false;
core.user_discovery_runtime.last_started_at = Some(Instant::now());
core.user_discovery_syncing = true;
core.request_user_discovery_refresh(false);
assert!(core.user_discovery_runtime.refresh_pending);
let result = UserDiscoveryFetchResult {
cache: UserDiscoveryCache::default(),
metadata_events: Vec::new(),
detail: "test".to_string(),
};
core.handle_user_discovery_fetch_finished(7, result);
assert_eq!(core.user_discovery_runtime.token, 8);
assert!(core.user_discovery_runtime.in_flight);
assert!(!core.user_discovery_runtime.refresh_pending);
core.handle_user_discovery_fetch_finished(
7,
UserDiscoveryFetchResult {
cache: UserDiscoveryCache::default(),
metadata_events: Vec::new(),
detail: "stale".to_string(),
},
);
assert_eq!(core.user_discovery_runtime.token, 8);
core.profile_search_runtime.token = 12;
core.profile_search_runtime.query = "alice".to_string();
core.profile_search_runtime.in_flight = true;
core.reset_user_discovery_runtime();
assert_eq!(core.user_discovery_runtime.token, 9);
assert!(!core.user_discovery_runtime.in_flight);
assert_eq!(core.profile_search_runtime.token, 13);
assert!(core.profile_search_runtime.query.is_empty());
assert!(!core.profile_search_runtime.in_flight);
assert!(!core.user_discovery_syncing);
}
#[test]
fn restore_adopts_legacy_unowned_cache_without_social_rank() {
let temp = TempDir::new().unwrap();
let owner = Keys::generate();
let friend = Keys::generate().public_key().to_hex();
let mut core = AppCore::new(
flume::unbounded().0,
flume::unbounded().0,
temp.path().to_string_lossy().to_string(),
Arc::new(RwLock::new(AppState::empty())),
);
core.app_store
.replace_user_discovery(&UserDiscoveryCache {
follow_event_json: None,
owner_pubkey_hex: None,
follow_event_id: Some("legacy-head".to_string()),
follow_created_at_secs: 1,
users: BTreeMap::from([(
friend.clone(),
DiscoveredUserRecord {
owner_pubkey_hex: friend,
follow_position: 0,
petname: None,
},
)]),
social_rank_ready: true,
social_friend_support: BTreeMap::from([("stale".to_string(), 1)]),
social_graph: Some(vec![1, 2, 3]),
social_opinion_events: Vec::new(),
})
.unwrap();
core.restore_user_discovery_cache(owner.public_key());
assert_eq!(
core.user_discovery.owner_pubkey_hex,
Some(owner.public_key().to_hex())
);
assert_eq!(core.user_discovery.users.len(), 1);
assert!(!core.user_discovery.social_rank_ready);
assert!(core.user_discovery.social_friend_support.is_empty());
assert_eq!(
core.app_store.load_user_discovery().unwrap(),
core.user_discovery
);
}
#[test]
fn restoring_another_account_clears_personalized_ranking() {
let temp = TempDir::new().unwrap();
let owner = Keys::generate();
let other_owner = Keys::generate();
let target = Keys::generate().public_key().to_hex();
let mut core = AppCore::new(
flume::unbounded().0,
flume::unbounded().0,
temp.path().to_string_lossy().to_string(),
Arc::new(RwLock::new(AppState::empty())),
);
core.app_store
.replace_user_discovery(&UserDiscoveryCache {
follow_event_json: None,
owner_pubkey_hex: Some(owner.public_key().to_hex()),
follow_event_id: Some("head".to_string()),
follow_created_at_secs: 1,
users: BTreeMap::new(),
social_rank_ready: true,
social_friend_support: BTreeMap::from([(target, 1)]),
social_graph: Some(vec![1, 2, 3]),
social_opinion_events: Vec::new(),
})
.unwrap();
core.restore_user_discovery_cache(other_owner.public_key());
assert_eq!(core.user_discovery, UserDiscoveryCache::default());
assert_eq!(
core.app_store.load_user_discovery().unwrap(),
UserDiscoveryCache::default()
);
}