atagen

macltok

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

Blame: tests/state.rs

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