atagen

macltok

public
Star0
Watch0
96fdf90aacd6dc2b8bd3d63773234245b389d28c
3
ssh://brewery@pls.lobotomise.me:33/atagen/macltok.git

Blame: tests/state.rs

96fdf90aacd6atagen2026-09-08 08:24 UTC1
use std::time::Duration;
96fdf90aacd6atagen2026-09-08 08:24 UTC2
96fdf90aacd6atagen2026-09-08 08:24 UTC3
use macltok::{
96fdf90aacd6atagen2026-09-08 08:24 UTC4
    Command, ConnectionState, Engine, EngineConfig, EngineError, Event, LifecycleCommand,
96fdf90aacd6atagen2026-09-08 08:24 UTC5
    RoomMembership,
96fdf90aacd6atagen2026-09-08 08:24 UTC6
};
96fdf90aacd6atagen2026-09-08 08:24 UTC7
use matrix_sdk::{
96fdf90aacd6atagen2026-09-08 08:24 UTC8
    ruma::{api::client::sync::sync_events::v5, room_id},
96fdf90aacd6atagen2026-09-08 08:24 UTC9
    test_utils::mocks::MatrixMockServer,
96fdf90aacd6atagen2026-09-08 08:24 UTC10
};
96fdf90aacd6atagen2026-09-08 08:24 UTC11
use tokio::sync::watch;
96fdf90aacd6atagen2026-09-08 08:24 UTC12
96fdf90aacd6atagen2026-09-08 08:24 UTC13
#[tokio::test]
96fdf90aacd6atagen2026-09-08 08:24 UTC14
async fn rooms_changed_invalidates_room_summaries() {
96fdf90aacd6atagen2026-09-08 08:24 UTC15
    let server = MatrixMockServer::new().await;
96fdf90aacd6atagen2026-09-08 08:24 UTC16
    server
96fdf90aacd6atagen2026-09-08 08:24 UTC17
        .mock_sliding_sync()
96fdf90aacd6atagen2026-09-08 08:24 UTC18
        .ok(v5::Response::new("1".to_owned()))
96fdf90aacd6atagen2026-09-08 08:24 UTC19
        .mount()
96fdf90aacd6atagen2026-09-08 08:24 UTC20
        .await;
96fdf90aacd6atagen2026-09-08 08:24 UTC21
    let client = server.client_builder().build().await;
96fdf90aacd6atagen2026-09-08 08:24 UTC22
    let room_id = room_id!("!state:localhost");
96fdf90aacd6atagen2026-09-08 08:24 UTC23
    server.mock_room_state_encryption().plain().mount().await;
96fdf90aacd6atagen2026-09-08 08:24 UTC24
    server.sync_joined_room(&client, room_id).await;
96fdf90aacd6atagen2026-09-08 08:24 UTC25
    let config = EngineConfig::default().with_initial_history_limit(0);
96fdf90aacd6atagen2026-09-08 08:24 UTC26
    let (engine, handle, mut events) = Engine::from_client(client, config).await.unwrap();
96fdf90aacd6atagen2026-09-08 08:24 UTC27
    let running = tokio::spawn(engine.run());
96fdf90aacd6atagen2026-09-08 08:24 UTC28
96fdf90aacd6atagen2026-09-08 08:24 UTC29
    receive_until(&mut events, |event| matches!(event, Event::RoomsChanged)).await;
96fdf90aacd6atagen2026-09-08 08:24 UTC30
    let rooms = handle.rooms().await;
96fdf90aacd6atagen2026-09-08 08:24 UTC31
    let summary = rooms
96fdf90aacd6atagen2026-09-08 08:24 UTC32
        .iter()
96fdf90aacd6atagen2026-09-08 08:24 UTC33
        .find(|summary| summary.room_id == room_id)
96fdf90aacd6atagen2026-09-08 08:24 UTC34
        .expect("synced room was absent from the room summaries");
96fdf90aacd6atagen2026-09-08 08:24 UTC35
    assert_eq!(summary.membership, RoomMembership::Joined);
96fdf90aacd6atagen2026-09-08 08:24 UTC36
    assert!(!summary.name.is_empty());
96fdf90aacd6atagen2026-09-08 08:24 UTC37
96fdf90aacd6atagen2026-09-08 08:24 UTC38
    handle
96fdf90aacd6atagen2026-09-08 08:24 UTC39
        .send(Command::Lifecycle(LifecycleCommand::Shutdown))
96fdf90aacd6atagen2026-09-08 08:24 UTC40
        .await
96fdf90aacd6atagen2026-09-08 08:24 UTC41
        .unwrap();
96fdf90aacd6atagen2026-09-08 08:24 UTC42
    receive_until(&mut events, |event| matches!(event, Event::Stopped)).await;
96fdf90aacd6atagen2026-09-08 08:24 UTC43
    running.await.unwrap().unwrap();
96fdf90aacd6atagen2026-09-08 08:24 UTC44
}
96fdf90aacd6atagen2026-09-08 08:24 UTC45
96fdf90aacd6atagen2026-09-08 08:24 UTC46
#[tokio::test]
96fdf90aacd6atagen2026-09-08 08:24 UTC47
async fn connection_watch_tracks_the_engine_lifecycle() {
96fdf90aacd6atagen2026-09-08 08:24 UTC48
    let server = MatrixMockServer::new().await;
96fdf90aacd6atagen2026-09-08 08:24 UTC49
    server
96fdf90aacd6atagen2026-09-08 08:24 UTC50
        .mock_sliding_sync()
96fdf90aacd6atagen2026-09-08 08:24 UTC51
        .ok(v5::Response::new("1".to_owned()))
96fdf90aacd6atagen2026-09-08 08:24 UTC52
        .mount()
96fdf90aacd6atagen2026-09-08 08:24 UTC53
        .await;
96fdf90aacd6atagen2026-09-08 08:24 UTC54
    let client = server.client_builder().build().await;
96fdf90aacd6atagen2026-09-08 08:24 UTC55
    let config = EngineConfig::default().with_initial_history_limit(0);
96fdf90aacd6atagen2026-09-08 08:24 UTC56
    let (engine, handle, mut events) = Engine::from_client(client, config).await.unwrap();
96fdf90aacd6atagen2026-09-08 08:24 UTC57
    let mut connection = handle.connection_state();
96fdf90aacd6atagen2026-09-08 08:24 UTC58
    let connection_peer = connection.clone();
96fdf90aacd6atagen2026-09-08 08:24 UTC59
    assert_eq!(*connection.borrow(), ConnectionState::Idle);
96fdf90aacd6atagen2026-09-08 08:24 UTC60
    assert_eq!(*connection_peer.borrow(), ConnectionState::Idle);
96fdf90aacd6atagen2026-09-08 08:24 UTC61
96fdf90aacd6atagen2026-09-08 08:24 UTC62
    let running = tokio::spawn(engine.run());
96fdf90aacd6atagen2026-09-08 08:24 UTC63
    receive_until(&mut events, |event| {
96fdf90aacd6atagen2026-09-08 08:24 UTC64
        matches!(event, Event::ConnectionChanged(ConnectionState::Connecting))
96fdf90aacd6atagen2026-09-08 08:24 UTC65
    })
96fdf90aacd6atagen2026-09-08 08:24 UTC66
    .await;
96fdf90aacd6atagen2026-09-08 08:24 UTC67
    assert_ne!(*connection.borrow(), ConnectionState::Idle);
96fdf90aacd6atagen2026-09-08 08:24 UTC68
    receive_until(&mut events, |event| {
96fdf90aacd6atagen2026-09-08 08:24 UTC69
        matches!(event, Event::ConnectionChanged(ConnectionState::Online))
96fdf90aacd6atagen2026-09-08 08:24 UTC70
    })
96fdf90aacd6atagen2026-09-08 08:24 UTC71
    .await;
96fdf90aacd6atagen2026-09-08 08:24 UTC72
    wait_for_connection(&mut connection, ConnectionState::Online).await;
96fdf90aacd6atagen2026-09-08 08:24 UTC73
    assert_eq!(*connection_peer.borrow(), ConnectionState::Online);
96fdf90aacd6atagen2026-09-08 08:24 UTC74
96fdf90aacd6atagen2026-09-08 08:24 UTC75
    handle
96fdf90aacd6atagen2026-09-08 08:24 UTC76
        .send(Command::Lifecycle(LifecycleCommand::Shutdown))
96fdf90aacd6atagen2026-09-08 08:24 UTC77
        .await
96fdf90aacd6atagen2026-09-08 08:24 UTC78
        .unwrap();
96fdf90aacd6atagen2026-09-08 08:24 UTC79
    receive_until(&mut events, |event| matches!(event, Event::Stopped)).await;
96fdf90aacd6atagen2026-09-08 08:24 UTC80
    running.await.unwrap().unwrap();
96fdf90aacd6atagen2026-09-08 08:24 UTC81
    wait_for_connection(&mut connection, ConnectionState::Stopped).await;
96fdf90aacd6atagen2026-09-08 08:24 UTC82
    assert_eq!(*connection_peer.borrow(), ConnectionState::Stopped);
96fdf90aacd6atagen2026-09-08 08:24 UTC83
}
96fdf90aacd6atagen2026-09-08 08:24 UTC84
96fdf90aacd6atagen2026-09-08 08:24 UTC85
#[tokio::test]
96fdf90aacd6atagen2026-09-08 08:24 UTC86
async fn closing_the_event_stream_stops_an_idle_engine() {
96fdf90aacd6atagen2026-09-08 08:24 UTC87
    let server = MatrixMockServer::new().await;
96fdf90aacd6atagen2026-09-08 08:24 UTC88
    server
96fdf90aacd6atagen2026-09-08 08:24 UTC89
        .mock_sliding_sync()
96fdf90aacd6atagen2026-09-08 08:24 UTC90
        .ok(v5::Response::new("1".to_owned()))
96fdf90aacd6atagen2026-09-08 08:24 UTC91
        .mount()
96fdf90aacd6atagen2026-09-08 08:24 UTC92
        .await;
96fdf90aacd6atagen2026-09-08 08:24 UTC93
    let client = server.client_builder().build().await;
96fdf90aacd6atagen2026-09-08 08:24 UTC94
    let (engine, handle, mut events) = Engine::from_client(
96fdf90aacd6atagen2026-09-08 08:24 UTC95
        client,
96fdf90aacd6atagen2026-09-08 08:24 UTC96
        EngineConfig::default().with_initial_history_limit(0),
96fdf90aacd6atagen2026-09-08 08:24 UTC97
    )
96fdf90aacd6atagen2026-09-08 08:24 UTC98
    .await
96fdf90aacd6atagen2026-09-08 08:24 UTC99
    .unwrap();
96fdf90aacd6atagen2026-09-08 08:24 UTC100
    let running = tokio::spawn(engine.run());
96fdf90aacd6atagen2026-09-08 08:24 UTC101
    receive_until(&mut events, |event| {
96fdf90aacd6atagen2026-09-08 08:24 UTC102
        matches!(event, Event::ConnectionChanged(ConnectionState::Online))
96fdf90aacd6atagen2026-09-08 08:24 UTC103
    })
96fdf90aacd6atagen2026-09-08 08:24 UTC104
    .await;
96fdf90aacd6atagen2026-09-08 08:24 UTC105
    drop(events);
96fdf90aacd6atagen2026-09-08 08:24 UTC106
    let result = tokio::time::timeout(Duration::from_secs(2), running)
96fdf90aacd6atagen2026-09-08 08:24 UTC107
        .await
96fdf90aacd6atagen2026-09-08 08:24 UTC108
        .expect("engine did not stop after its event receiver closed")
96fdf90aacd6atagen2026-09-08 08:24 UTC109
        .unwrap();
96fdf90aacd6atagen2026-09-08 08:24 UTC110
    assert!(matches!(result, Err(EngineError::EventReceiverClosed)));
96fdf90aacd6atagen2026-09-08 08:24 UTC111
    drop(handle);
96fdf90aacd6atagen2026-09-08 08:24 UTC112
}
96fdf90aacd6atagen2026-09-08 08:24 UTC113
96fdf90aacd6atagen2026-09-08 08:24 UTC114
async fn wait_for_connection(
96fdf90aacd6atagen2026-09-08 08:24 UTC115
    connection: &mut watch::Receiver<ConnectionState>,
96fdf90aacd6atagen2026-09-08 08:24 UTC116
    expected: ConnectionState,
96fdf90aacd6atagen2026-09-08 08:24 UTC117
) {
96fdf90aacd6atagen2026-09-08 08:24 UTC118
    tokio::time::timeout(Duration::from_secs(2), async {
96fdf90aacd6atagen2026-09-08 08:24 UTC119
        loop {
96fdf90aacd6atagen2026-09-08 08:24 UTC120
            if *connection.borrow_and_update() == expected {
96fdf90aacd6atagen2026-09-08 08:24 UTC121
                return;
96fdf90aacd6atagen2026-09-08 08:24 UTC122
            }
96fdf90aacd6atagen2026-09-08 08:24 UTC123
            connection
96fdf90aacd6atagen2026-09-08 08:24 UTC124
                .changed()
96fdf90aacd6atagen2026-09-08 08:24 UTC125
                .await
96fdf90aacd6atagen2026-09-08 08:24 UTC126
                .expect("connection watch closed before the expected state");
96fdf90aacd6atagen2026-09-08 08:24 UTC127
        }
96fdf90aacd6atagen2026-09-08 08:24 UTC128
    })
96fdf90aacd6atagen2026-09-08 08:24 UTC129
    .await
96fdf90aacd6atagen2026-09-08 08:24 UTC130
    .expect("expected connection state did not arrive");
96fdf90aacd6atagen2026-09-08 08:24 UTC131
}
96fdf90aacd6atagen2026-09-08 08:24 UTC132
96fdf90aacd6atagen2026-09-08 08:24 UTC133
async fn receive_until(
96fdf90aacd6atagen2026-09-08 08:24 UTC134
    events: &mut macltok::EventStream,
96fdf90aacd6atagen2026-09-08 08:24 UTC135
    predicate: impl Fn(&Event) -> bool,
96fdf90aacd6atagen2026-09-08 08:24 UTC136
) -> Event {
96fdf90aacd6atagen2026-09-08 08:24 UTC137
    tokio::time::timeout(Duration::from_secs(2), async {
96fdf90aacd6atagen2026-09-08 08:24 UTC138
        while let Some(event) = events.recv().await {
96fdf90aacd6atagen2026-09-08 08:24 UTC139
            if predicate(&event) {
96fdf90aacd6atagen2026-09-08 08:24 UTC140
                return event;
96fdf90aacd6atagen2026-09-08 08:24 UTC141
            }
96fdf90aacd6atagen2026-09-08 08:24 UTC142
        }
96fdf90aacd6atagen2026-09-08 08:24 UTC143
        panic!("event stream closed before the expected event");
96fdf90aacd6atagen2026-09-08 08:24 UTC144
    })
96fdf90aacd6atagen2026-09-08 08:24 UTC145
    .await
96fdf90aacd6atagen2026-09-08 08:24 UTC146
    .expect("expected event did not arrive")
96fdf90aacd6atagen2026-09-08 08:24 UTC147
}