atagen

macltok

public
Star0
Watch0
cff1b0a4eb30290a6fe32fea825c816b696fe4f4
3
ssh://brewery@pls.lobotomise.me:33/atagen/macltok.git
src/search/feed_tests.rsRust187 lines5.4 KB
1
use serde_json::json;
2
3
use super::*;
4
use crate::search::index::KeywordIndex;
5
6
const ROOM: &str = "!room:x";
7
8
fn message(id: &str, sender: &str, ts: u64, body: &str) -> Value {
9
    json!({
10
        "type": "m.room.message",
11
        "event_id": id,
12
        "sender": sender,
13
        "origin_server_ts": ts,
14
        "content": { "msgtype": "m.text", "body": body },
15
    })
16
}
17
18
fn edit(id: &str, sender: &str, ts: u64, target: &str, body: &str) -> Value {
19
    json!({
20
        "type": "m.room.message",
21
        "event_id": id,
22
        "sender": sender,
23
        "origin_server_ts": ts,
24
        "content": {
25
            "msgtype": "m.text",
26
            "body": format!("* {body}"),
27
            "m.new_content": { "msgtype": "m.text", "body": body },
28
            "m.relates_to": { "rel_type": "m.replace", "event_id": target },
29
        },
30
    })
31
}
32
33
fn redaction(id: &str, target: &str) -> Value {
34
    json!({
35
        "type": "m.room.redaction",
36
        "event_id": id,
37
        "sender": "@a:x",
38
        "origin_server_ts": 99,
39
        "redacts": target,
40
        "content": {},
41
    })
42
}
43
44
fn feed(index: &mut KeywordIndex, redactions: &mut Redactions, value: Value) -> Effect {
45
    apply(index, redactions, ROOM, observe(&value))
46
}
47
48
fn keys(index: &mut KeywordIndex, query: &str) -> Vec<String> {
49
    let (hits, _) = index.search(query, None, None, 10).unwrap();
50
    hits.into_iter().map(|hit| hit.key).collect()
51
}
52
53
/// backfill walks newest first, so an edit routinely lands before what it edits
54
#[test]
55
fn an_edit_before_its_original_keeps_the_edit_and_takes_the_original_timestamp() {
56
    let mut index = KeywordIndex::new(false);
57
    let mut redactions = Redactions::default();
58
    feed(
59
        &mut index,
60
        &mut redactions,
61
        edit("$e", "@a:x", 20, "$o", "fixed words"),
62
    );
63
    let provisional = index.get("$o").unwrap();
64
    assert!(provisional.provisional);
65
    assert_eq!(provisional.ts, 20);
66
    feed(
67
        &mut index,
68
        &mut redactions,
69
        message("$o", "@a:x", 10, "typo wrds"),
70
    );
71
    let doc = index.get("$o").unwrap();
72
    assert!(!doc.provisional);
73
    assert_eq!((doc.ts, doc.content.as_str()), (10, "$e"));
74
    assert_eq!(keys(&mut index, "fixed"), vec!["$o"]);
75
    assert!(keys(&mut index, "wrds").is_empty());
76
}
77
78
#[test]
79
fn edits_from_someone_else_and_older_edits_lose() {
80
    let mut index = KeywordIndex::new(false);
81
    let mut redactions = Redactions::default();
82
    feed(
83
        &mut index,
84
        &mut redactions,
85
        message("$o", "@a:x", 10, "original"),
86
    );
87
    feed(
88
        &mut index,
89
        &mut redactions,
90
        edit("$e2", "@a:x", 30, "$o", "newest"),
91
    );
92
    assert_eq!(
93
        feed(
94
            &mut index,
95
            &mut redactions,
96
            edit("$e1", "@a:x", 20, "$o", "older")
97
        ),
98
        Effect::Nothing
99
    );
100
    assert_eq!(
101
        feed(
102
            &mut index,
103
            &mut redactions,
104
            edit("$h", "@b:x", 40, "$o", "hijack")
105
        ),
106
        Effect::Nothing
107
    );
108
    assert_eq!(keys(&mut index, "newest"), vec!["$o"]);
109
    assert!(keys(&mut index, "hijack").is_empty());
110
    assert!(keys(&mut index, "original").is_empty());
111
}
112
113
#[test]
114
fn a_provisional_edit_from_someone_else_gives_way_to_the_original() {
115
    let mut index = KeywordIndex::new(false);
116
    let mut redactions = Redactions::default();
117
    feed(
118
        &mut index,
119
        &mut redactions,
120
        edit("$h", "@b:x", 20, "$o", "hijack"),
121
    );
122
    feed(
123
        &mut index,
124
        &mut redactions,
125
        message("$o", "@a:x", 10, "genuine"),
126
    );
127
    assert_eq!(keys(&mut index, "genuine"), vec!["$o"]);
128
    assert!(keys(&mut index, "hijack").is_empty());
129
}
130
131
#[test]
132
fn a_redaction_removes_the_message_and_a_stale_copy_cannot_bring_it_back() {
133
    let mut index = KeywordIndex::new(false);
134
    let mut redactions = Redactions::default();
135
    feed(
136
        &mut index,
137
        &mut redactions,
138
        message("$o", "@a:x", 10, "secret"),
139
    );
140
    assert_eq!(
141
        feed(&mut index, &mut redactions, redaction("$r", "$o")),
142
        Effect::Removed
143
    );
144
    feed(
145
        &mut index,
146
        &mut redactions,
147
        message("$o", "@a:x", 10, "secret"),
148
    );
149
    assert!(keys(&mut index, "secret").is_empty());
150
}
151
152
#[test]
153
fn redacting_the_latest_edit_asks_for_the_original_again() {
154
    let mut index = KeywordIndex::new(false);
155
    let mut redactions = Redactions::default();
156
    feed(
157
        &mut index,
158
        &mut redactions,
159
        message("$o", "@a:x", 10, "first"),
160
    );
161
    feed(
162
        &mut index,
163
        &mut redactions,
164
        edit("$e", "@a:x", 20, "$o", "second"),
165
    );
166
    assert_eq!(
167
        feed(&mut index, &mut redactions, redaction("$r", "$e")),
168
        Effect::Refetch("$o".to_owned())
169
    );
170
    let mut original = message("$o", "@a:x", 10, "first");
171
    original["unsigned"] =
172
        json!({ "m.relations": { "m.replace": edit("$e", "@a:x", 20, "$o", "second") } });
173
    feed(&mut index, &mut redactions, original);
174
    assert_eq!(keys(&mut index, "first"), vec!["$o"]);
175
    assert!(keys(&mut index, "second").is_empty());
176
}
177
178
#[test]
179
fn reply_fallbacks_are_not_indexed() {
180
    let mut index = KeywordIndex::new(false);
181
    let mut redactions = Redactions::default();
182
    let mut reply = message("$r", "@a:x", 10, "> <@b:x> quoted stuff\n\nactual answer");
183
    reply["content"]["m.relates_to"] = json!({ "m.in_reply_to": { "event_id": "$q" } });
184
    feed(&mut index, &mut redactions, reply);
185
    assert_eq!(keys(&mut index, "answer"), vec!["$r"]);
186
    assert!(keys(&mut index, "quoted").is_empty());
187
}