test(pds-server): listRepos-Test unabhängig von der Tabellengröße machen
sync_list_repos_includes_recent_user paginierte von vorn durch listRepos und gab nach 50 Seiten à 50 Zeilen auf. Die repos-Tabelle der Dev-Instanz ist inzwischen auf ~3800 Zeilen gewachsen, der frisch angelegte DID sortierte dahinter — der Test war rot, obwohl der Endpoint korrekt antwortet (manuell mit passendem Cursor verifiziert). Der Cursor startet jetzt unmittelbar *vor* dem Ziel-DID. did_cursor_lt() taugte dafür nicht: es dekrementiert das erste Byte und landet damit vor jedem did:..., also wieder am Tabellenanfang. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013HC9HLrUU1LNwkzp8nkDLX
This commit is contained in:
co-authored by
Claude Opus 5
parent
465a88e4e5
commit
bce4c7862f
@@ -758,8 +758,14 @@ async fn sync_list_repos_includes_recent_user() {
|
||||
return;
|
||||
}
|
||||
let (c, did, _jwt, _cids) = fresh_user_with_records().await;
|
||||
// Page through listRepos with a small limit until we see our DID.
|
||||
let mut cursor: Option<String> = None;
|
||||
// Page through listRepos until we see our DID. Start the cursor
|
||||
// immediately *below* the target rather than at the beginning of
|
||||
// the table: `repos` grows without bound on a long-lived dev
|
||||
// instance (a few thousand rows already), and scanning from the
|
||||
// top made this test fail purely because the DID sorted past the
|
||||
// iteration cap. Anchoring at the DID keeps the cursor round trip
|
||||
// under test while staying independent of table size.
|
||||
let mut cursor: Option<String> = Some(did_cursor_just_before(&did));
|
||||
let mut found = false;
|
||||
for _ in 0..50 {
|
||||
let url = match &cursor {
|
||||
@@ -1022,6 +1028,23 @@ fn urlencode(s: &str) -> String {
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// The immediate keyset predecessor of `did`: the same string with
|
||||
/// its last byte decremented. `listRepos` filters with `did > cursor`,
|
||||
/// so paging from here puts `did` on the first page regardless of how
|
||||
/// many repos precede it in the table. Unlike [`did_cursor_lt`] — which
|
||||
/// decrements the *first* byte and therefore lands before every
|
||||
/// `did:...` — this stays adjacent to the target.
|
||||
///
|
||||
/// DIDs are ASCII (`did:plc:` + base32), so byte surgery is safe here.
|
||||
fn did_cursor_just_before(did: &str) -> String {
|
||||
let mut bytes = did.as_bytes().to_vec();
|
||||
match bytes.last_mut() {
|
||||
Some(b) if *b > 0 => *b -= 1,
|
||||
_ => return did.to_string(),
|
||||
}
|
||||
String::from_utf8(bytes).unwrap_or_else(|_| did.to_string())
|
||||
}
|
||||
|
||||
fn did_cursor_lt(did: &str) -> String {
|
||||
let bytes = did.as_bytes();
|
||||
let mut prefix = Vec::with_capacity(bytes.len());
|
||||
|
||||
Reference in New Issue
Block a user