flowsdk 0.5.3

Safety-first, realistic, behavior-predictable messaging SDK for MQTT and more.
Documentation
// SPDX-License-Identifier: MPL-2.0

//! Integration tests for transport abstraction layer

use flowsdk::mqtt_client::transport::{TcpTransport, Transport};

#[tokio::test]
#[ignore] // Requires network access
async fn test_transport_abstraction_with_echo_server() {
    // This test demonstrates the transport abstraction works correctly
    // It would connect to an echo server and verify read/write operations

    // For now, we just verify the type can be used through the trait
    let result = TcpTransport::connect("broker.emqx.io:1883").await;
    assert!(result.is_ok(), "Should connect through Transport trait");

    if let Ok(transport) = result {
        // Verify we can use it as a trait object
        let boxed: Box<dyn Transport> = Box::new(transport);

        // Verify peer_addr works through trait
        let peer = boxed.peer_addr();
        assert!(peer.is_ok(), "Should get peer address through trait");
    }
}

#[tokio::test]
async fn test_transport_trait_object() {
    // This test verifies the trait can be used as a trait object
    // which is essential for the client to be transport-agnostic

    async fn use_any_transport(
        addr: &str,
    ) -> Result<Box<dyn Transport>, Box<dyn std::error::Error>> {
        // This function shows how the client will use the transport abstraction
        let transport = TcpTransport::connect(addr).await?;
        Ok(Box::new(transport))
    }

    // Test with an invalid address to verify error handling
    let result = use_any_transport("invalid:9999").await;
    assert!(result.is_err(), "Should fail with invalid address");
}

#[tokio::test]
async fn test_transport_as_async_io() {
    // Test that Transport trait includes AsyncRead/AsyncWrite bounds
    // This is critical for the MQTT client integration

    // This function signature proves our Transport trait is usable with async I/O
    // because it requires AsyncRead + AsyncWrite bounds
    fn _check_transport_bounds<T: Transport>(_t: T) {
        // The fact this compiles proves Transport: AsyncRead + AsyncWrite
    }

    // Additional check: verify we can use Transport in generic contexts
    async fn _use_transport<T: Transport>(
        _transport: T,
    ) -> Result<String, Box<dyn std::error::Error>> {
        // Would use transport.peer_addr() here
        Ok("test".to_string())
    }
}