atagen

macltok

public
Star0
Watch0
fa9114fcf75f7bdf1a7cec3b3367d604cf7de472
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]
fa9114fcf75fatagen2026-09-24 12:51 UTC86
async fn soft_logout_says_so_and_stops_the_engine() {
fa9114fcf75fatagen2026-09-24 12:51 UTC87
    let server = MatrixMockServer::new().await;
fa9114fcf75fatagen2026-09-24 12:51 UTC88
    server
fa9114fcf75fatagen2026-09-24 12:51 UTC89
        .mock_sliding_sync()
fa9114fcf75fatagen2026-09-24 12:51 UTC90
        .error_unknown_token(true)
fa9114fcf75fatagen2026-09-24 12:51 UTC91
        .mount()
fa9114fcf75fatagen2026-09-24 12:51 UTC92
        .await;
fa9114fcf75fatagen2026-09-24 12:51 UTC93
    let client = server.client_builder().build().await;
fa9114fcf75fatagen2026-09-24 12:51 UTC94
    let (engine, _handle, mut events) = Engine::from_client(
fa9114fcf75fatagen2026-09-24 12:51 UTC95
        client,
fa9114fcf75fatagen2026-09-24 12:51 UTC96
        EngineConfig::default().with_initial_history_limit(0),
fa9114fcf75fatagen2026-09-24 12:51 UTC97
    )
fa9114fcf75fatagen2026-09-24 12:51 UTC98
    .await
fa9114fcf75fatagen2026-09-24 12:51 UTC99
    .unwrap();
fa9114fcf75fatagen2026-09-24 12:51 UTC100
    let running = tokio::spawn(engine.run());
fa9114fcf75fatagen2026-09-24 12:51 UTC101
    receive_until(&mut events, |event| {
fa9114fcf75fatagen2026-09-24 12:51 UTC102
        matches!(event, Event::SessionAccessRejected { soft_logout: true })
fa9114fcf75fatagen2026-09-24 12:51 UTC103
    })
fa9114fcf75fatagen2026-09-24 12:51 UTC104
    .await;
fa9114fcf75fatagen2026-09-24 12:51 UTC105
    receive_until(&mut events, |event| matches!(event, Event::Stopped)).await;
fa9114fcf75fatagen2026-09-24 12:51 UTC106
    running.await.unwrap().unwrap();
fa9114fcf75fatagen2026-09-24 12:51 UTC107
}
fa9114fcf75fatagen2026-09-24 12:51 UTC108
fa9114fcf75fatagen2026-09-24 12:51 UTC109
#[tokio::test]
96fdf90aacd6atagen2026-09-08 08:24 UTC110
async fn closing_the_event_stream_stops_an_idle_engine() {
96fdf90aacd6atagen2026-09-08 08:24 UTC111
    let server = MatrixMockServer::new().await;
96fdf90aacd6atagen2026-09-08 08:24 UTC112
    server
96fdf90aacd6atagen2026-09-08 08:24 UTC113
        .mock_sliding_sync()
96fdf90aacd6atagen2026-09-08 08:24 UTC114
        .ok(v5::Response::new("1".to_owned()))
96fdf90aacd6atagen2026-09-08 08:24 UTC115
        .mount()
96fdf90aacd6atagen2026-09-08 08:24 UTC116
        .await;
96fdf90aacd6atagen2026-09-08 08:24 UTC117
    let client = server.client_builder().build().await;
96fdf90aacd6atagen2026-09-08 08:24 UTC118
    let (engine, handle, mut events) = Engine::from_client(
96fdf90aacd6atagen2026-09-08 08:24 UTC119
        client,
96fdf90aacd6atagen2026-09-08 08:24 UTC120
        EngineConfig::default().with_initial_history_limit(0),
96fdf90aacd6atagen2026-09-08 08:24 UTC121
    )
96fdf90aacd6atagen2026-09-08 08:24 UTC122
    .await
96fdf90aacd6atagen2026-09-08 08:24 UTC123
    .unwrap();
96fdf90aacd6atagen2026-09-08 08:24 UTC124
    let running = tokio::spawn(engine.run());
96fdf90aacd6atagen2026-09-08 08:24 UTC125
    receive_until(&mut events, |event| {
96fdf90aacd6atagen2026-09-08 08:24 UTC126
        matches!(event, Event::ConnectionChanged(ConnectionState::Online))
96fdf90aacd6atagen2026-09-08 08:24 UTC127
    })
96fdf90aacd6atagen2026-09-08 08:24 UTC128
    .await;
96fdf90aacd6atagen2026-09-08 08:24 UTC129
    drop(events);
96fdf90aacd6atagen2026-09-08 08:24 UTC130
    let result = tokio::time::timeout(Duration::from_secs(2), running)
96fdf90aacd6atagen2026-09-08 08:24 UTC131
        .await
96fdf90aacd6atagen2026-09-08 08:24 UTC132
        .expect("engine did not stop after its event receiver closed")
96fdf90aacd6atagen2026-09-08 08:24 UTC133
        .unwrap();
96fdf90aacd6atagen2026-09-08 08:24 UTC134
    assert!(matches!(result, Err(EngineError::EventReceiverClosed)));
96fdf90aacd6atagen2026-09-08 08:24 UTC135
    drop(handle);
96fdf90aacd6atagen2026-09-08 08:24 UTC136
}
96fdf90aacd6atagen2026-09-08 08:24 UTC137
96fdf90aacd6atagen2026-09-08 08:24 UTC138
async fn wait_for_connection(
96fdf90aacd6atagen2026-09-08 08:24 UTC139
    connection: &mut watch::Receiver<ConnectionState>,
96fdf90aacd6atagen2026-09-08 08:24 UTC140
    expected: ConnectionState,
96fdf90aacd6atagen2026-09-08 08:24 UTC141
) {
96fdf90aacd6atagen2026-09-08 08:24 UTC142
    tokio::time::timeout(Duration::from_secs(2), async {
96fdf90aacd6atagen2026-09-08 08:24 UTC143
        loop {
96fdf90aacd6atagen2026-09-08 08:24 UTC144
            if *connection.borrow_and_update() == expected {
96fdf90aacd6atagen2026-09-08 08:24 UTC145
                return;
96fdf90aacd6atagen2026-09-08 08:24 UTC146
            }
96fdf90aacd6atagen2026-09-08 08:24 UTC147
            connection
96fdf90aacd6atagen2026-09-08 08:24 UTC148
                .changed()
96fdf90aacd6atagen2026-09-08 08:24 UTC149
                .await
96fdf90aacd6atagen2026-09-08 08:24 UTC150
                .expect("connection watch closed before the expected state");
96fdf90aacd6atagen2026-09-08 08:24 UTC151
        }
96fdf90aacd6atagen2026-09-08 08:24 UTC152
    })
96fdf90aacd6atagen2026-09-08 08:24 UTC153
    .await
96fdf90aacd6atagen2026-09-08 08:24 UTC154
    .expect("expected connection state did not arrive");
96fdf90aacd6atagen2026-09-08 08:24 UTC155
}
96fdf90aacd6atagen2026-09-08 08:24 UTC156
96fdf90aacd6atagen2026-09-08 08:24 UTC157
async fn receive_until(
96fdf90aacd6atagen2026-09-08 08:24 UTC158
    events: &mut macltok::EventStream,
96fdf90aacd6atagen2026-09-08 08:24 UTC159
    predicate: impl Fn(&Event) -> bool,
96fdf90aacd6atagen2026-09-08 08:24 UTC160
) -> Event {
96fdf90aacd6atagen2026-09-08 08:24 UTC161
    tokio::time::timeout(Duration::from_secs(2), async {
96fdf90aacd6atagen2026-09-08 08:24 UTC162
        while let Some(event) = events.recv().await {
96fdf90aacd6atagen2026-09-08 08:24 UTC163
            if predicate(&event) {
96fdf90aacd6atagen2026-09-08 08:24 UTC164
                return event;
96fdf90aacd6atagen2026-09-08 08:24 UTC165
            }
96fdf90aacd6atagen2026-09-08 08:24 UTC166
        }
96fdf90aacd6atagen2026-09-08 08:24 UTC167
        panic!("event stream closed before the expected event");
96fdf90aacd6atagen2026-09-08 08:24 UTC168
    })
96fdf90aacd6atagen2026-09-08 08:24 UTC169
    .await
96fdf90aacd6atagen2026-09-08 08:24 UTC170
    .expect("expected event did not arrive")
96fdf90aacd6atagen2026-09-08 08:24 UTC171
}