atagen

macltok

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

Blame: src/search/feed_tests.rs

c9effeac326aatagen2026-10-25 10:32 UTC1
use serde_json::json;
c9effeac326aatagen2026-10-25 10:32 UTC2
c9effeac326aatagen2026-10-25 10:32 UTC3
use super::*;
c9effeac326aatagen2026-10-25 10:32 UTC4
use crate::search::index::KeywordIndex;
c9effeac326aatagen2026-10-25 10:32 UTC5
c9effeac326aatagen2026-10-25 10:32 UTC6
const ROOM: &str = "!room:x";
c9effeac326aatagen2026-10-25 10:32 UTC7
c9effeac326aatagen2026-10-25 10:32 UTC8
fn message(id: &str, sender: &str, ts: u64, body: &str) -> Value {
c9effeac326aatagen2026-10-25 10:32 UTC9
    json!({
c9effeac326aatagen2026-10-25 10:32 UTC10
        "type": "m.room.message",
c9effeac326aatagen2026-10-25 10:32 UTC11
        "event_id": id,
c9effeac326aatagen2026-10-25 10:32 UTC12
        "sender": sender,
c9effeac326aatagen2026-10-25 10:32 UTC13
        "origin_server_ts": ts,
c9effeac326aatagen2026-10-25 10:32 UTC14
        "content": { "msgtype": "m.text", "body": body },
c9effeac326aatagen2026-10-25 10:32 UTC15
    })
c9effeac326aatagen2026-10-25 10:32 UTC16
}
c9effeac326aatagen2026-10-25 10:32 UTC17
c9effeac326aatagen2026-10-25 10:32 UTC18
fn edit(id: &str, sender: &str, ts: u64, target: &str, body: &str) -> Value {
c9effeac326aatagen2026-10-25 10:32 UTC19
    json!({
c9effeac326aatagen2026-10-25 10:32 UTC20
        "type": "m.room.message",
c9effeac326aatagen2026-10-25 10:32 UTC21
        "event_id": id,
c9effeac326aatagen2026-10-25 10:32 UTC22
        "sender": sender,
c9effeac326aatagen2026-10-25 10:32 UTC23
        "origin_server_ts": ts,
c9effeac326aatagen2026-10-25 10:32 UTC24
        "content": {
c9effeac326aatagen2026-10-25 10:32 UTC25
            "msgtype": "m.text",
c9effeac326aatagen2026-10-25 10:32 UTC26
            "body": format!("* {body}"),
c9effeac326aatagen2026-10-25 10:32 UTC27
            "m.new_content": { "msgtype": "m.text", "body": body },
c9effeac326aatagen2026-10-25 10:32 UTC28
            "m.relates_to": { "rel_type": "m.replace", "event_id": target },
c9effeac326aatagen2026-10-25 10:32 UTC29
        },
c9effeac326aatagen2026-10-25 10:32 UTC30
    })
c9effeac326aatagen2026-10-25 10:32 UTC31
}
c9effeac326aatagen2026-10-25 10:32 UTC32
c9effeac326aatagen2026-10-25 10:32 UTC33
fn redaction(id: &str, target: &str) -> Value {
c9effeac326aatagen2026-10-25 10:32 UTC34
    json!({
c9effeac326aatagen2026-10-25 10:32 UTC35
        "type": "m.room.redaction",
c9effeac326aatagen2026-10-25 10:32 UTC36
        "event_id": id,
c9effeac326aatagen2026-10-25 10:32 UTC37
        "sender": "@a:x",
c9effeac326aatagen2026-10-25 10:32 UTC38
        "origin_server_ts": 99,
c9effeac326aatagen2026-10-25 10:32 UTC39
        "redacts": target,
c9effeac326aatagen2026-10-25 10:32 UTC40
        "content": {},
c9effeac326aatagen2026-10-25 10:32 UTC41
    })
c9effeac326aatagen2026-10-25 10:32 UTC42
}
c9effeac326aatagen2026-10-25 10:32 UTC43
c9effeac326aatagen2026-10-25 10:32 UTC44
fn feed(index: &mut KeywordIndex, redactions: &mut Redactions, value: Value) -> Effect {
c9effeac326aatagen2026-10-25 10:32 UTC45
    apply(index, redactions, ROOM, observe(&value))
c9effeac326aatagen2026-10-25 10:32 UTC46
}
c9effeac326aatagen2026-10-25 10:32 UTC47
c9effeac326aatagen2026-10-25 10:32 UTC48
fn keys(index: &mut KeywordIndex, query: &str) -> Vec<String> {
c9effeac326aatagen2026-10-25 10:32 UTC49
    let (hits, _) = index.search(query, None, None, 10).unwrap();
c9effeac326aatagen2026-10-25 10:32 UTC50
    hits.into_iter().map(|hit| hit.key).collect()
c9effeac326aatagen2026-10-25 10:32 UTC51
}
c9effeac326aatagen2026-10-25 10:32 UTC52
c9effeac326aatagen2026-10-25 10:32 UTC53
/// backfill walks newest first, so an edit routinely lands before what it edits
c9effeac326aatagen2026-10-25 10:32 UTC54
#[test]
c9effeac326aatagen2026-10-25 10:32 UTC55
fn an_edit_before_its_original_keeps_the_edit_and_takes_the_original_timestamp() {
c9effeac326aatagen2026-10-25 10:32 UTC56
    let mut index = KeywordIndex::new(false);
c9effeac326aatagen2026-10-25 10:32 UTC57
    let mut redactions = Redactions::default();
c9effeac326aatagen2026-10-25 10:32 UTC58
    feed(
c9effeac326aatagen2026-10-25 10:32 UTC59
        &mut index,
c9effeac326aatagen2026-10-25 10:32 UTC60
        &mut redactions,
c9effeac326aatagen2026-10-25 10:32 UTC61
        edit("$e", "@a:x", 20, "$o", "fixed words"),
c9effeac326aatagen2026-10-25 10:32 UTC62
    );
c9effeac326aatagen2026-10-25 10:32 UTC63
    let provisional = index.get("$o").unwrap();
c9effeac326aatagen2026-10-25 10:32 UTC64
    assert!(provisional.provisional);
c9effeac326aatagen2026-10-25 10:32 UTC65
    assert_eq!(provisional.ts, 20);
c9effeac326aatagen2026-10-25 10:32 UTC66
    feed(
c9effeac326aatagen2026-10-25 10:32 UTC67
        &mut index,
c9effeac326aatagen2026-10-25 10:32 UTC68
        &mut redactions,
c9effeac326aatagen2026-10-25 10:32 UTC69
        message("$o", "@a:x", 10, "typo wrds"),
c9effeac326aatagen2026-10-25 10:32 UTC70
    );
c9effeac326aatagen2026-10-25 10:32 UTC71
    let doc = index.get("$o").unwrap();
c9effeac326aatagen2026-10-25 10:32 UTC72
    assert!(!doc.provisional);
c9effeac326aatagen2026-10-25 10:32 UTC73
    assert_eq!((doc.ts, doc.content.as_str()), (10, "$e"));
c9effeac326aatagen2026-10-25 10:32 UTC74
    assert_eq!(keys(&mut index, "fixed"), vec!["$o"]);
c9effeac326aatagen2026-10-25 10:32 UTC75
    assert!(keys(&mut index, "wrds").is_empty());
c9effeac326aatagen2026-10-25 10:32 UTC76
}
c9effeac326aatagen2026-10-25 10:32 UTC77
c9effeac326aatagen2026-10-25 10:32 UTC78
#[test]
c9effeac326aatagen2026-10-25 10:32 UTC79
fn edits_from_someone_else_and_older_edits_lose() {
c9effeac326aatagen2026-10-25 10:32 UTC80
    let mut index = KeywordIndex::new(false);
c9effeac326aatagen2026-10-25 10:32 UTC81
    let mut redactions = Redactions::default();
c9effeac326aatagen2026-10-25 10:32 UTC82
    feed(
c9effeac326aatagen2026-10-25 10:32 UTC83
        &mut index,
c9effeac326aatagen2026-10-25 10:32 UTC84
        &mut redactions,
c9effeac326aatagen2026-10-25 10:32 UTC85
        message("$o", "@a:x", 10, "original"),
c9effeac326aatagen2026-10-25 10:32 UTC86
    );
c9effeac326aatagen2026-10-25 10:32 UTC87
    feed(
c9effeac326aatagen2026-10-25 10:32 UTC88
        &mut index,
c9effeac326aatagen2026-10-25 10:32 UTC89
        &mut redactions,
c9effeac326aatagen2026-10-25 10:32 UTC90
        edit("$e2", "@a:x", 30, "$o", "newest"),
c9effeac326aatagen2026-10-25 10:32 UTC91
    );
c9effeac326aatagen2026-10-25 10:32 UTC92
    assert_eq!(
c9effeac326aatagen2026-10-25 10:32 UTC93
        feed(
c9effeac326aatagen2026-10-25 10:32 UTC94
            &mut index,
c9effeac326aatagen2026-10-25 10:32 UTC95
            &mut redactions,
c9effeac326aatagen2026-10-25 10:32 UTC96
            edit("$e1", "@a:x", 20, "$o", "older")
c9effeac326aatagen2026-10-25 10:32 UTC97
        ),
c9effeac326aatagen2026-10-25 10:32 UTC98
        Effect::Nothing
c9effeac326aatagen2026-10-25 10:32 UTC99
    );
c9effeac326aatagen2026-10-25 10:32 UTC100
    assert_eq!(
c9effeac326aatagen2026-10-25 10:32 UTC101
        feed(
c9effeac326aatagen2026-10-25 10:32 UTC102
            &mut index,
c9effeac326aatagen2026-10-25 10:32 UTC103
            &mut redactions,
c9effeac326aatagen2026-10-25 10:32 UTC104
            edit("$h", "@b:x", 40, "$o", "hijack")
c9effeac326aatagen2026-10-25 10:32 UTC105
        ),
c9effeac326aatagen2026-10-25 10:32 UTC106
        Effect::Nothing
c9effeac326aatagen2026-10-25 10:32 UTC107
    );
c9effeac326aatagen2026-10-25 10:32 UTC108
    assert_eq!(keys(&mut index, "newest"), vec!["$o"]);
c9effeac326aatagen2026-10-25 10:32 UTC109
    assert!(keys(&mut index, "hijack").is_empty());
c9effeac326aatagen2026-10-25 10:32 UTC110
    assert!(keys(&mut index, "original").is_empty());
c9effeac326aatagen2026-10-25 10:32 UTC111
}
c9effeac326aatagen2026-10-25 10:32 UTC112
c9effeac326aatagen2026-10-25 10:32 UTC113
#[test]
c9effeac326aatagen2026-10-25 10:32 UTC114
fn a_provisional_edit_from_someone_else_gives_way_to_the_original() {
c9effeac326aatagen2026-10-25 10:32 UTC115
    let mut index = KeywordIndex::new(false);
c9effeac326aatagen2026-10-25 10:32 UTC116
    let mut redactions = Redactions::default();
c9effeac326aatagen2026-10-25 10:32 UTC117
    feed(
c9effeac326aatagen2026-10-25 10:32 UTC118
        &mut index,
c9effeac326aatagen2026-10-25 10:32 UTC119
        &mut redactions,
c9effeac326aatagen2026-10-25 10:32 UTC120
        edit("$h", "@b:x", 20, "$o", "hijack"),
c9effeac326aatagen2026-10-25 10:32 UTC121
    );
c9effeac326aatagen2026-10-25 10:32 UTC122
    feed(
c9effeac326aatagen2026-10-25 10:32 UTC123
        &mut index,
c9effeac326aatagen2026-10-25 10:32 UTC124
        &mut redactions,
c9effeac326aatagen2026-10-25 10:32 UTC125
        message("$o", "@a:x", 10, "genuine"),
c9effeac326aatagen2026-10-25 10:32 UTC126
    );
c9effeac326aatagen2026-10-25 10:32 UTC127
    assert_eq!(keys(&mut index, "genuine"), vec!["$o"]);
c9effeac326aatagen2026-10-25 10:32 UTC128
    assert!(keys(&mut index, "hijack").is_empty());
c9effeac326aatagen2026-10-25 10:32 UTC129
}
c9effeac326aatagen2026-10-25 10:32 UTC130
c9effeac326aatagen2026-10-25 10:32 UTC131
#[test]
c9effeac326aatagen2026-10-25 10:32 UTC132
fn a_redaction_removes_the_message_and_a_stale_copy_cannot_bring_it_back() {
c9effeac326aatagen2026-10-25 10:32 UTC133
    let mut index = KeywordIndex::new(false);
c9effeac326aatagen2026-10-25 10:32 UTC134
    let mut redactions = Redactions::default();
c9effeac326aatagen2026-10-25 10:32 UTC135
    feed(
c9effeac326aatagen2026-10-25 10:32 UTC136
        &mut index,
c9effeac326aatagen2026-10-25 10:32 UTC137
        &mut redactions,
c9effeac326aatagen2026-10-25 10:32 UTC138
        message("$o", "@a:x", 10, "secret"),
c9effeac326aatagen2026-10-25 10:32 UTC139
    );
c9effeac326aatagen2026-10-25 10:32 UTC140
    assert_eq!(
c9effeac326aatagen2026-10-25 10:32 UTC141
        feed(&mut index, &mut redactions, redaction("$r", "$o")),
c9effeac326aatagen2026-10-25 10:32 UTC142
        Effect::Removed
c9effeac326aatagen2026-10-25 10:32 UTC143
    );
c9effeac326aatagen2026-10-25 10:32 UTC144
    feed(
c9effeac326aatagen2026-10-25 10:32 UTC145
        &mut index,
c9effeac326aatagen2026-10-25 10:32 UTC146
        &mut redactions,
c9effeac326aatagen2026-10-25 10:32 UTC147
        message("$o", "@a:x", 10, "secret"),
c9effeac326aatagen2026-10-25 10:32 UTC148
    );
c9effeac326aatagen2026-10-25 10:32 UTC149
    assert!(keys(&mut index, "secret").is_empty());
c9effeac326aatagen2026-10-25 10:32 UTC150
}
c9effeac326aatagen2026-10-25 10:32 UTC151
c9effeac326aatagen2026-10-25 10:32 UTC152
#[test]
c9effeac326aatagen2026-10-25 10:32 UTC153
fn redacting_the_latest_edit_asks_for_the_original_again() {
c9effeac326aatagen2026-10-25 10:32 UTC154
    let mut index = KeywordIndex::new(false);
c9effeac326aatagen2026-10-25 10:32 UTC155
    let mut redactions = Redactions::default();
c9effeac326aatagen2026-10-25 10:32 UTC156
    feed(
c9effeac326aatagen2026-10-25 10:32 UTC157
        &mut index,
c9effeac326aatagen2026-10-25 10:32 UTC158
        &mut redactions,
c9effeac326aatagen2026-10-25 10:32 UTC159
        message("$o", "@a:x", 10, "first"),
c9effeac326aatagen2026-10-25 10:32 UTC160
    );
c9effeac326aatagen2026-10-25 10:32 UTC161
    feed(
c9effeac326aatagen2026-10-25 10:32 UTC162
        &mut index,
c9effeac326aatagen2026-10-25 10:32 UTC163
        &mut redactions,
c9effeac326aatagen2026-10-25 10:32 UTC164
        edit("$e", "@a:x", 20, "$o", "second"),
c9effeac326aatagen2026-10-25 10:32 UTC165
    );
c9effeac326aatagen2026-10-25 10:32 UTC166
    assert_eq!(
c9effeac326aatagen2026-10-25 10:32 UTC167
        feed(&mut index, &mut redactions, redaction("$r", "$e")),
c9effeac326aatagen2026-10-25 10:32 UTC168
        Effect::Refetch("$o".to_owned())
c9effeac326aatagen2026-10-25 10:32 UTC169
    );
c9effeac326aatagen2026-10-25 10:32 UTC170
    let mut original = message("$o", "@a:x", 10, "first");
c9effeac326aatagen2026-10-25 10:32 UTC171
    original["unsigned"] =
c9effeac326aatagen2026-10-25 10:32 UTC172
        json!({ "m.relations": { "m.replace": edit("$e", "@a:x", 20, "$o", "second") } });
c9effeac326aatagen2026-10-25 10:32 UTC173
    feed(&mut index, &mut redactions, original);
c9effeac326aatagen2026-10-25 10:32 UTC174
    assert_eq!(keys(&mut index, "first"), vec!["$o"]);
c9effeac326aatagen2026-10-25 10:32 UTC175
    assert!(keys(&mut index, "second").is_empty());
c9effeac326aatagen2026-10-25 10:32 UTC176
}
c9effeac326aatagen2026-10-25 10:32 UTC177
c9effeac326aatagen2026-10-25 10:32 UTC178
#[test]
c9effeac326aatagen2026-10-25 10:32 UTC179
fn reply_fallbacks_are_not_indexed() {
c9effeac326aatagen2026-10-25 10:32 UTC180
    let mut index = KeywordIndex::new(false);
c9effeac326aatagen2026-10-25 10:32 UTC181
    let mut redactions = Redactions::default();
c9effeac326aatagen2026-10-25 10:32 UTC182
    let mut reply = message("$r", "@a:x", 10, "> <@b:x> quoted stuff\n\nactual answer");
c9effeac326aatagen2026-10-25 10:32 UTC183
    reply["content"]["m.relates_to"] = json!({ "m.in_reply_to": { "event_id": "$q" } });
c9effeac326aatagen2026-10-25 10:32 UTC184
    feed(&mut index, &mut redactions, reply);
c9effeac326aatagen2026-10-25 10:32 UTC185
    assert_eq!(keys(&mut index, "answer"), vec!["$r"]);
c9effeac326aatagen2026-10-25 10:32 UTC186
    assert!(keys(&mut index, "quoted").is_empty());
c9effeac326aatagen2026-10-25 10:32 UTC187
}