From 2dd16e8512eb7ba7b0df9da673370f70faa74191 Mon Sep 17 00:00:00 2001 From: Libby Date: Fri, 13 Nov 2026 12:51:20 +0000 Subject: [PATCH] cultcache-rs: pin catalog versions that differ from .v1 and first-lister resolution (tests only) Co-Authored-By: Claude Sonnet 5.5 --- packages/cultcache-rs/tests/schema_catalog.rs | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/packages/cultcache-rs/tests/schema_catalog.rs b/packages/cultcache-rs/tests/schema_catalog.rs index 9b6e32e7..36ec3bed 100644 --- a/packages/cultcache-rs/tests/schema_catalog.rs +++ b/packages/cultcache-rs/tests/schema_catalog.rs @@ -123,3 +123,43 @@ fn a_store_the_csharp_reference_wrote_gives_its_versions() { let catalog = store.pull_schema_catalog().unwrap(); assert_eq!(catalog[0].content_hash, "sha256:02f0c8b7ea07c11705c1365fc29136ada08c8076209cacfb8d5526229461ce7a"); } + +type Entry = (&'static str, &'static str, &'static str, &'static str, &'static str, Vec<&'static str>, Vec<()>); + +// A hand-built v3 store whose versions are not the `.v1` the writers above publish, so a version read from anywhere but the +// version slot cannot pass. `shared` is listed by two entries (the first lister wins); `id.c` is owned by one entry and listed by +// an earlier one (the owner wins). +#[test] +fn distinct_versions_come_through_with_the_decoders_resolution() { + let catalog: Vec = vec![ + ("id.a", "N.a", "9.9.9", "hash-a", "{}", vec!["id.a", "shared"], vec![]), + ("id.b", "N.b", "7.0", "hash-b", "{}", vec!["id.b", "shared", "id.c"], vec![]), + ("id.c", "N.c", "3", "hash-c", "{}", vec!["id.c"], vec![]), + ]; + let record = |key: &str, id: &str| (key.to_string(), id.to_string(), "2026-11-13T00:00:00Z".to_string(), b"x".to_vec()); + let records = vec![record("r1", "shared"), record("r2", "id.c"), record("r3", "id.b"), record("r4", "id.a")]; + let dir = tempfile::tempdir().unwrap(); + let path = dir.path().join("store.cc"); + std::fs::write(&path, rmp_serde::to_vec(&("cultcache.store.v3", catalog, records)).unwrap()).unwrap(); + + let store = SingleFileMessagePackBackingStore::new(&path); + let listed = store.pull_schema_catalog().unwrap(); + assert_eq!(listed.iter().map(|e| e.schema_version.as_str()).collect::>(), vec!["9.9.9", "7.0", "3"]); + assert_eq!(listed[1].content_hash, "hash-b"); + assert_eq!(listed[1].compatible_schema_ids, vec!["id.b", "shared", "id.c"]); + let got: Vec<(String, String, String)> = { + let mut rows: Vec<_> = store + .pull_all() + .unwrap() + .iter() + .map(|e| { + let entry = resolve_schema_entry(&listed, e.schema_id.as_deref().unwrap()).unwrap(); + (e.key.clone(), entry.schema_name.clone(), entry.schema_version.clone()) + }) + .collect(); + rows.sort(); + rows + }; + let row = |k: &str, n: &str, v: &str| (k.to_string(), n.to_string(), v.to_string()); + assert_eq!(got, vec![row("r1", "N.a", "9.9.9"), row("r2", "N.c", "3"), row("r3", "N.b", "7.0"), row("r4", "N.a", "9.9.9")]); +}