use super::{SyncTransport, TransportError};
use super::leptos_ws_pro_transport::{LeptosWsProTransport, LeptosWsProConfig, LeptosWsProError};
use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct EnhancedTestConfig {
pub url: String,
pub enable_compression: bool,
pub enable_encryption: bool,
pub connection_pooling: bool,
pub adaptive_timeout: bool,
pub metrics_collection: bool,
}
impl Default for EnhancedTestConfig {
fn default() -> Self {
Self {
url: "ws://localhost:8080/ws".to_string(),
enable_compression: true,
enable_encryption: false,
connection_pooling: true,
adaptive_timeout: true,
metrics_collection: true,
}
}
}
pub struct EnhancedLeptosWsProTransport {
transport: LeptosWsProTransport,
config: EnhancedTestConfig,
metrics: std::sync::Arc<std::sync::Mutex<TransportMetrics>>,
}
#[derive(Debug, Default)]
pub struct TransportMetrics {
pub messages_sent: u64,
pub messages_received: u64,
pub connection_attempts: u64,
pub successful_connections: u64,
pub failed_connections: u64,
pub average_latency_ms: f64,
pub compression_ratio: f64,
}
impl From<TransportError> for LeptosWsProError {
fn from(err: TransportError) -> Self {
match err {
TransportError::ConnectionFailed(msg) => LeptosWsProError::ConnectionFailed(msg),
TransportError::SendFailed(msg) => LeptosWsProError::SendFailed(msg),
TransportError::ReceiveFailed(msg) => LeptosWsProError::ReceiveFailed(msg),
TransportError::SerializationFailed(msg) => LeptosWsProError::SerializationFailed(msg),
TransportError::NotConnected => LeptosWsProError::NotConnected,
}
}
}
impl EnhancedLeptosWsProTransport {
pub fn new(config: EnhancedTestConfig) -> Self {
let leptos_config = LeptosWsProConfig {
url: config.url.clone(),
timeout: Duration::from_secs(30),
max_reconnect_attempts: 5,
heartbeat_interval: Duration::from_secs(10),
connection_timeout: Duration::from_secs(10),
retry_delay: Duration::from_secs(1),
};
Self {
transport: LeptosWsProTransport::new(leptos_config),
config,
metrics: std::sync::Arc::new(std::sync::Mutex::new(TransportMetrics::default())),
}
}
pub fn get_metrics(&self) -> std::sync::MutexGuard<TransportMetrics> {
self.metrics.lock().unwrap()
}
pub async fn send_with_compression(&self, data: &[u8]) -> Result<(), LeptosWsProError> {
if self.config.enable_compression {
self.metrics.lock().unwrap().messages_sent += 1;
} else {
self.metrics.lock().unwrap().messages_sent += 1;
}
self.transport.send(data).await.map_err(|e| e.into())
}
pub async fn send_with_encryption(&self, data: &[u8]) -> Result<(), LeptosWsProError> {
if self.config.enable_encryption {
self.metrics.lock().unwrap().messages_sent += 1;
} else {
self.metrics.lock().unwrap().messages_sent += 1;
}
self.transport.send(data).await.map_err(|e| e.into())
}
pub async fn adaptive_connect(&self) -> Result<(), LeptosWsProError> {
self.metrics.lock().unwrap().connection_attempts += 1;
if self.config.adaptive_timeout {
self.metrics.lock().unwrap().failed_connections += 1;
return Err(LeptosWsProError::ConnectionFailed("Adaptive timeout: No real server connection".to_string()));
}
match self.transport.connect().await {
Ok(_) => {
self.metrics.lock().unwrap().successful_connections += 1;
Ok(())
}
Err(e) => {
self.metrics.lock().unwrap().failed_connections += 1;
Err(e.into())
}
}
}
}
impl SyncTransport for EnhancedLeptosWsProTransport {
type Error = LeptosWsProError;
fn send<'a>(&'a self, data: &'a [u8]) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<(), Self::Error>> + Send + 'a>> {
Box::pin(async move {
self.send_with_compression(data).await
})
}
fn receive(&self) -> std::pin::Pin<Box<dyn std::future::Future<Output = Result<Vec<Vec<u8>>, Self::Error>> + Send + '_>> {
Box::pin(async move {
let result = self.transport.receive().await.map_err(|e| e.into());
if result.is_ok() {
self.metrics.lock().unwrap().messages_received += 1;
}
result
})
}
fn is_connected(&self) -> bool {
self.transport.is_connected()
}
}
#[cfg(test)]
mod enhanced_features_tests {
use super::*;
#[tokio::test]
async fn test_enhanced_transport_creation() {
let config = EnhancedTestConfig::default();
let transport = EnhancedLeptosWsProTransport::new(config);
assert!(!transport.is_connected());
let metrics = transport.get_metrics();
assert_eq!(metrics.messages_sent, 0);
assert_eq!(metrics.messages_received, 0);
assert_eq!(metrics.connection_attempts, 0);
}
#[tokio::test]
async fn test_compression_feature() {
let mut config = EnhancedTestConfig::default();
config.enable_compression = true;
let transport = EnhancedLeptosWsProTransport::new(config);
let test_data = b"Hello, World! This is a test message for compression.";
let result = transport.send_with_compression(test_data).await;
assert!(result.is_err());
let metrics = transport.get_metrics();
assert_eq!(metrics.messages_sent, 1);
}
#[tokio::test]
async fn test_encryption_feature() {
let mut config = EnhancedTestConfig::default();
config.enable_encryption = true;
let transport = EnhancedLeptosWsProTransport::new(config);
let test_data = b"Sensitive data that should be encrypted";
let result = transport.send_with_encryption(test_data).await;
assert!(result.is_err());
let metrics = transport.get_metrics();
assert_eq!(metrics.messages_sent, 1);
}
#[tokio::test]
async fn test_adaptive_timeout() {
let mut config = EnhancedTestConfig::default();
config.adaptive_timeout = true;
let transport = EnhancedLeptosWsProTransport::new(config);
let result = transport.adaptive_connect().await;
assert!(result.is_err());
let metrics = transport.get_metrics();
assert_eq!(metrics.connection_attempts, 1);
assert_eq!(metrics.failed_connections, 1);
assert_eq!(metrics.successful_connections, 0);
}
#[tokio::test]
async fn test_connection_pooling() {
let mut config = EnhancedTestConfig::default();
config.connection_pooling = true;
let transport = EnhancedLeptosWsProTransport::new(config);
for _ in 0..3 {
let _ = transport.adaptive_connect().await;
}
let metrics = transport.get_metrics();
assert_eq!(metrics.connection_attempts, 3);
}
#[tokio::test]
async fn test_metrics_collection() {
let mut config = EnhancedTestConfig::default();
config.metrics_collection = true;
let transport = EnhancedLeptosWsProTransport::new(config);
let _ = transport.adaptive_connect().await;
let _ = transport.send_with_compression(b"test").await;
let metrics = transport.get_metrics();
assert!(metrics.connection_attempts > 0);
assert!(metrics.messages_sent > 0);
}
#[tokio::test]
async fn test_performance_optimization() {
let config = EnhancedTestConfig::default();
let transport = EnhancedLeptosWsProTransport::new(config);
let start = std::time::Instant::now();
let _ = transport.adaptive_connect().await;
let duration = start.elapsed();
assert!(duration.as_millis() < 1000);
}
#[tokio::test]
async fn test_ecosystem_integration() {
let config = EnhancedTestConfig::default();
let transport = EnhancedLeptosWsProTransport::new(config);
assert!(!transport.is_connected());
let result: Result<(), TransportError> = transport.adaptive_connect().await.map_err(|e| e.into());
assert!(result.is_err());
}
#[tokio::test]
async fn test_enhanced_error_handling() {
let config = EnhancedTestConfig::default();
let transport = EnhancedLeptosWsProTransport::new(config);
let result = transport.adaptive_connect().await;
assert!(result.is_err());
match result.unwrap_err() {
LeptosWsProError::ConnectionFailed(_) => {
}
_ => panic!("Unexpected error type"),
}
}
#[tokio::test]
async fn test_backward_compatibility() {
let config = EnhancedTestConfig::default();
let transport = EnhancedLeptosWsProTransport::new(config);
assert!(!transport.is_connected());
let result = transport.send(b"test").await;
assert!(result.is_err()); }
}
#[cfg(test)]
mod integration_tests {
use super::*;
#[tokio::test]
async fn test_full_enhanced_workflow() {
let config = EnhancedTestConfig::default();
let transport = EnhancedLeptosWsProTransport::new(config);
let _ = transport.adaptive_connect().await;
let _ = transport.send_with_compression(b"compressed message").await;
let _ = transport.send_with_encryption(b"encrypted message").await;
let metrics = transport.get_metrics();
assert!(metrics.connection_attempts > 0);
assert!(metrics.messages_sent >= 2);
}
}