06e8ee96a5
- Add TokenClaims message for JWT payload structure with user id, issuer, timestamps, and scopes - Implement IssueTokenRequest/Response for creating access and refresh tokens with TTL support - Create RefreshTokenRequest/Response for token rotation functionality - Define RevokeTokenRequest/Response with support for single token or user-wide revocation - Add VerifyTokenRequest/Response for validating JWT tokens with detailed claims information - Implement signing key distribution system with GetSigningKeysRequest/Response - Create TokenService gRPC service with IssueToken, RefreshToken, RevokeToken, VerifyToken, and GetSigningKeys methods - Add build.rs configuration to compile proto files using tonic_prost_build - Include channel, channel_settings, member, and permission protocol definitions for IM services - Generate Rust code bindings through pb/core.rs and pb/im.rs modules
130 lines
3.7 KiB
Rust
130 lines
3.7 KiB
Rust
use imks::engine::session::{generate_sid, SessionState, SessionStore, TransportType};
|
|
|
|
#[test]
|
|
fn test_session_store_create_and_get() {
|
|
let store = SessionStore::new();
|
|
let sid = generate_sid();
|
|
|
|
let _rx = store.create(sid.clone(), TransportType::Polling);
|
|
|
|
assert!(store.exists(&sid));
|
|
assert!(store.get(&sid).is_some());
|
|
assert_eq!(store.len(), 1);
|
|
}
|
|
|
|
#[test]
|
|
fn test_session_store_remove() {
|
|
let store = SessionStore::new();
|
|
let sid = generate_sid();
|
|
|
|
let _rx = store.create(sid.clone(), TransportType::Polling);
|
|
assert!(store.exists(&sid));
|
|
|
|
store.remove(&sid);
|
|
assert!(!store.exists(&sid));
|
|
assert!(store.get(&sid).is_none());
|
|
}
|
|
|
|
#[test]
|
|
fn test_session_store_multiple_sessions() {
|
|
let store = SessionStore::new();
|
|
|
|
let sid1 = generate_sid();
|
|
let sid2 = generate_sid();
|
|
let sid3 = generate_sid();
|
|
|
|
let _rx1 = store.create(sid1.clone(), TransportType::Polling);
|
|
let _rx2 = store.create(sid2.clone(), TransportType::WebSocket);
|
|
let _rx3 = store.create(sid3.clone(), TransportType::WebTransport);
|
|
|
|
assert_eq!(store.len(), 3);
|
|
assert!(store.exists(&sid1));
|
|
assert!(store.exists(&sid2));
|
|
assert!(store.exists(&sid3));
|
|
}
|
|
|
|
#[test]
|
|
fn test_generate_sid_uniqueness() {
|
|
let sids: Vec<String> = (0..100).map(|_| generate_sid()).collect();
|
|
|
|
let unique_sids: std::collections::HashSet<String> = sids.into_iter().collect();
|
|
assert_eq!(unique_sids.len(), 100);
|
|
}
|
|
|
|
#[test]
|
|
fn test_generate_sid_format() {
|
|
let sid = generate_sid();
|
|
|
|
assert_eq!(sid.len(), 20);
|
|
assert!(sid.chars().all(|c| c.is_ascii_alphanumeric() || c == '_' || c == '-'));
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_session_state_transitions() {
|
|
let store = SessionStore::new();
|
|
let sid = generate_sid();
|
|
|
|
let _rx = store.create(sid.clone(), TransportType::Polling);
|
|
|
|
if let Some(session) = store.get(&sid) {
|
|
let mut session = session.write().await;
|
|
assert_eq!(session.state, SessionState::Connecting);
|
|
|
|
session.set_state(SessionState::Open);
|
|
assert_eq!(session.state, SessionState::Open);
|
|
|
|
session.set_state(SessionState::Upgrading);
|
|
assert_eq!(session.state, SessionState::Upgrading);
|
|
|
|
session.set_state(SessionState::Open);
|
|
assert_eq!(session.state, SessionState::Open);
|
|
|
|
session.set_state(SessionState::Closing);
|
|
assert_eq!(session.state, SessionState::Closing);
|
|
|
|
session.set_state(SessionState::Closed);
|
|
assert_eq!(session.state, SessionState::Closed);
|
|
}
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_session_transport_change() {
|
|
let store = SessionStore::new();
|
|
let sid = generate_sid();
|
|
|
|
let _rx = store.create(sid.clone(), TransportType::Polling);
|
|
|
|
if let Some(session) = store.get(&sid) {
|
|
let mut session = session.write().await;
|
|
assert_eq!(session.transport, TransportType::Polling);
|
|
|
|
session.set_transport(TransportType::WebSocket);
|
|
assert_eq!(session.transport, TransportType::WebSocket);
|
|
}
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_session_ping_update() {
|
|
let store = SessionStore::new();
|
|
let sid = generate_sid();
|
|
|
|
let _rx = store.create(sid.clone(), TransportType::Polling);
|
|
|
|
if let Some(session) = store.get(&sid) {
|
|
let mut session = session.write().await;
|
|
let initial_ping = session.last_ping;
|
|
|
|
std::thread::sleep(std::time::Duration::from_millis(10));
|
|
session.update_ping();
|
|
|
|
assert!(session.last_ping > initial_ping);
|
|
}
|
|
}
|
|
|
|
#[test]
|
|
fn test_transport_type_as_str() {
|
|
assert_eq!(TransportType::Polling.as_str(), "polling");
|
|
assert_eq!(TransportType::WebSocket.as_str(), "websocket");
|
|
assert_eq!(TransportType::WebTransport.as_str(), "webtransport");
|
|
}
|