atagen

macltok

public
Star0
Watch0
9d584825009ddce6ae71cf151793e63b4902ed25
3
ssh://brewery@pls.lobotomise.me:33/atagen/macltok.git
tests/mentions_decryption.rsRust128 lines4.5 KB
1
use std::time::Duration;
2
3
use futures_util::StreamExt;
4
use matrix_sdk::{
5
    deserialized_responses::TimelineEventKind, event_cache::RedecryptorReport,
6
    test_utils::mocks::MatrixMockServer,
7
};
8
use matrix_sdk_test::{JoinedRoomBuilder, event_factory::EventFactory};
9
use ruma::{RoomVersionId, device_id, event_id, room_id, user_id};
10
use serde_json::json;
11
12
#[tokio::test]
13
async fn late_key_exposes_a_mention_without_a_ui_timeline() {
14
    let server = MatrixMockServer::new().await;
15
    server.mock_crypto_endpoints_preset().await;
16
    let alice_id = user_id!("@alice:localhost");
17
    let bob_id = user_id!("@bob:localhost");
18
    let room_id = room_id!("!mentions-encrypted:localhost");
19
    let event_id = event_id!("$late-mention");
20
    let alice = server
21
        .client_builder_for_crypto_end_to_end(alice_id, device_id!("ALICEDEVICE"))
22
        .build()
23
        .await;
24
    let bob = server
25
        .client_builder_for_crypto_end_to_end(bob_id, device_id!("BOBDEVICE"))
26
        .build()
27
        .await;
28
    bob.event_cache().subscribe().unwrap();
29
    server.exchange_e2ee_identities(&alice, &bob).await;
30
31
    let factory = EventFactory::new().room(room_id).sender(alice_id);
32
    let joined = JoinedRoomBuilder::new(room_id)
33
        .add_state_event(factory.create(alice_id, RoomVersionId::V1))
34
        .add_state_event(factory.room_encryption())
35
        .add_state_event(factory.member(alice_id))
36
        .add_state_event(factory.member(bob_id));
37
    server.sync_room(&alice, joined.clone()).await;
38
    server.sync_room(&bob, joined).await;
39
40
    let room = alice.get_room(room_id).unwrap();
41
    let (encrypted_event, send) = server.mock_room_send().ok_with_capture(event_id, alice_id);
42
    let _send = send.mock_once().mount_as_scoped().await;
43
    let (_keys, room_key) = server.mock_capture_put_to_device(alice_id).await;
44
    server
45
        .mock_get_members()
46
        .ok(vec![
47
            factory.member(alice_id).into_raw(),
48
            factory.member(bob_id).into_raw(),
49
        ])
50
        .mock_once()
51
        .mount()
52
        .await;
53
    room.send_raw(
54
        "m.room.message",
55
        json!({
56
            "msgtype": "m.text",
57
            "body": "a private mention",
58
            "m.mentions": { "user_ids": [bob_id] }
59
        }),
60
    )
61
    .await
62
    .unwrap();
63
    let encrypted_event = encrypted_event.await.unwrap();
64
    let room_key = room_key.await;
65
66
    let mut sync_updates = bob.subscribe_to_all_room_updates();
67
    let mut cache_updates = bob.event_cache().subscribe_to_room_generic_updates();
68
    let mut reports = bob.event_cache().subscribe_to_decryption_reports();
69
    server
70
        .sync_room(
71
            &bob,
72
            JoinedRoomBuilder::new(room_id).add_timeline_event(encrypted_event),
73
        )
74
        .await;
75
    let update = sync_updates.recv().await.unwrap();
76
    let event = &update.joined[room_id].timeline.events[0];
77
    assert!(matches!(
78
        event.kind,
79
        TimelineEventKind::UnableToDecrypt { .. }
80
    ));
81
    tokio::time::timeout(Duration::from_secs(5), async {
82
        while cache_updates.recv().await.unwrap().room_id != room_id {}
83
    })
84
    .await
85
    .unwrap();
86
87
    server
88
        .mock_sync()
89
        .ok_and_run(&bob, |sync| {
90
            sync.add_to_device_event(room_key.deserialize_as().unwrap());
91
        })
92
        .await;
93
    tokio::time::timeout(Duration::from_secs(5), async {
94
        while let Some(report) = reports.next().await {
95
            if let Ok(RedecryptorReport::ResolvedUtds {
96
                room_id: resolved,
97
                events,
98
            }) = report
99
            {
100
                if resolved == room_id && events.contains(event_id) {
101
                    return;
102
                }
103
            }
104
        }
105
        panic!("decryption reports ended before the mention was decrypted");
106
    })
107
    .await
108
    .unwrap();
109
110
    let room = bob.get_room(room_id).unwrap();
111
    let (cache, _cache_handles) = room.event_cache().await.unwrap();
112
    let decrypted = cache.find_event(event_id).await.unwrap().unwrap();
113
    assert!(matches!(decrypted.kind, TimelineEventKind::Decrypted(_)));
114
    let content = decrypted
115
        .raw()
116
        .get_field::<serde_json::Value>("content")
117
        .unwrap()
118
        .unwrap();
119
    assert_eq!(content["body"], "a private mention");
120
    assert_eq!(content["m.mentions"]["user_ids"], json!([bob_id]));
121
    let push_actions = room
122
        .event_push_actions(decrypted.raw())
123
        .await
124
        .unwrap()
125
        .unwrap();
126
    assert!(push_actions.iter().any(|action| action.should_notify()));
127
    assert_eq!(cache.events().await.unwrap().len(), 1);
128
}