/*! Unit tests. Note that these require https://gitlab.torproject.org/vecna/lox/-/tree/main/crates/lox-distributor to be running. That fork adds an endpoint which allows for artificially increasing the number of days that have passed, which allows us to test trust migration and level up functions. */ // TODO: // - unit test file save/read functions // - unit test migration when possible // Note: We can't run multiple time-changing tests simultaneously because // they will invalidate invites that haven't been redeemed yet. use super::client_lib::*; use super::client_net::HyperNet; use lox_library::bridge_table::BridgeLine; use lox_library::proto::level_up::{LEVEL_INTERVAL, LEVEL_INVITATIONS}; use lox_library::proto::trust_promotion::UNTRUSTED_INTERVAL; use lox_library::scalar_u32; use std::cmp::min; use tokio::spawn; // These are all combined into the same test because otherwise we run into // issues with server state due to asynchronicity. #[tokio::test] async fn test_credential_operations() { let net = HyperNet { hostname: "http://localhost:8001".to_string(), }; let net_test = HyperNet { hostname: "http://localhost:8005".to_string(), }; let la_pubkeys = get_lox_auth_keys(&net).await; // Get new Lox credential let open_inv = get_open_invitation(&net).await; let (mut cred, bridgeline) = get_lox_credential(&net, &open_inv, get_lox_pub(&la_pubkeys)).await; let bucket = get_bucket(&net, &cred).await; assert_eq!(bucket[0], bridgeline); assert_eq!(bucket[1], BridgeLine::default()); assert_eq!(bucket[2], BridgeLine::default()); // Level up Lox Credential assert_eq!(scalar_u32(&cred.trust_level).unwrap(), 0); // Advance server time and trust migrate advance_days(&net_test, u16::try_from(UNTRUSTED_INTERVAL).unwrap()).await; assert!(eligible_for_trust_promotion(&net, &cred).await); let migration_cred = trust_promotion(&net, &cred, get_lox_pub(&la_pubkeys)).await; cred = trust_migration( &net, &cred, &migration_cred, get_lox_pub(&la_pubkeys), get_migration_pub(&la_pubkeys), ) .await; assert_eq!(scalar_u32(&cred.trust_level).unwrap(), 1); // Advance server time and level up for i in 1..LEVEL_INTERVAL.len() { assert_eq!( scalar_u32(&cred.trust_level).unwrap(), u32::try_from(i).unwrap() ); advance_days(&net_test, u16::try_from(LEVEL_INTERVAL[i]).unwrap()).await; assert!(eligible_for_level_up(&net, &cred).await); let encbuckets = get_reachability_credential(&net).await; cred = level_up( &net, &cred, &encbuckets, get_lox_pub(&la_pubkeys), get_reachability_pub(&la_pubkeys), ) .await .0; // Assert that we increased level by 1 or stayed at 4 assert_eq!( scalar_u32(&cred.trust_level).unwrap(), u32::try_from(min(i + 1, LEVEL_INTERVAL.len() - 1)).unwrap() ); assert_eq!( scalar_u32(&cred.invites_remaining).unwrap(), LEVEL_INVITATIONS[i] ); // Invite as many friends as possible for j in 0..LEVEL_INVITATIONS[i] { let encbuckets = get_reachability_credential(&net).await; let (new_cred, invite) = issue_invite( &net, &cred, &encbuckets, get_lox_pub(&la_pubkeys), get_reachability_pub(&la_pubkeys), get_invitation_pub(&la_pubkeys), ) .await; let (friend_cred, friend_bucket) = redeem_invite( &net, &invite, get_lox_pub(&la_pubkeys), get_invitation_pub(&la_pubkeys), ) .await; cred = new_cred; assert_eq!( scalar_u32(&cred.invites_remaining).unwrap(), LEVEL_INVITATIONS[i] - j - 1 ); assert_eq!(scalar_u32(&friend_cred.trust_level).unwrap(), 1); assert_eq!(&cred.bucket, &friend_cred.bucket); } } }