test(session): pin offline-queue session_id stamping (#487 follow-up)
The #487 fix relies on `save_offline_queue_state` correctly stamping the session id so the load path's mismatch check has something to compare against. The existing `test_offline_queue_round_trip_and_clear` covers serialization + clear but doesn't pin the session_id stamping behavior. Adds `test_offline_queue_stamps_session_id_on_save` which exercises three cases: * `save(state, Some("session-A"))` → loaded session_id is `Some("session-A")`. The stamp made it to disk. * `save(state, Some("session-B"))` → re-saving replaces the stamp; loaded session_id is `Some("session-B")`. No stale ID lingers. * `save(state, None)` → loaded session_id is `None`. The UI's load path treats this as legacy-unscoped and refuses to restore (fail-closed), which is what protects users from pre-#487 queues leaking into new chats. Pure additive coverage. The 2 existing offline-queue tests pass unchanged.
This commit is contained in:
@@ -967,6 +967,60 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_offline_queue_stamps_session_id_on_save() {
|
||||
// #487: save_offline_queue_state must stamp the supplied
|
||||
// session id so the load path's mismatch check has something
|
||||
// to compare against. A queue persisted without a session id
|
||||
// is the legacy unscoped form which the load path treats as
|
||||
// stale-risky and refuses to restore.
|
||||
let tmp = tempdir().expect("tempdir");
|
||||
let manager = SessionManager::new(tmp.path().join("sessions")).expect("new");
|
||||
|
||||
let state = OfflineQueueState {
|
||||
messages: vec![QueuedSessionMessage {
|
||||
display: "first parked".to_string(),
|
||||
skill_instruction: None,
|
||||
}],
|
||||
..OfflineQueueState::default()
|
||||
};
|
||||
|
||||
manager
|
||||
.save_offline_queue_state(&state, Some("session-A"))
|
||||
.expect("save with session id");
|
||||
let loaded = manager
|
||||
.load_offline_queue_state()
|
||||
.expect("ok")
|
||||
.expect("present");
|
||||
assert_eq!(loaded.session_id.as_deref(), Some("session-A"));
|
||||
|
||||
// Re-saving with a different session id replaces the stamp.
|
||||
manager
|
||||
.save_offline_queue_state(&state, Some("session-B"))
|
||||
.expect("re-save");
|
||||
let reloaded = manager
|
||||
.load_offline_queue_state()
|
||||
.expect("ok")
|
||||
.expect("present");
|
||||
assert_eq!(reloaded.session_id.as_deref(), Some("session-B"));
|
||||
|
||||
// Saving without a session id explicitly (None) clears the
|
||||
// stamp — UI's load path treats that as legacy-unscoped and
|
||||
// fails closed.
|
||||
manager
|
||||
.save_offline_queue_state(&state, None)
|
||||
.expect("save without session id");
|
||||
let unscoped = manager
|
||||
.load_offline_queue_state()
|
||||
.expect("ok")
|
||||
.expect("present");
|
||||
assert!(
|
||||
unscoped.session_id.is_none(),
|
||||
"save with None must persist a missing session_id, got {:?}",
|
||||
unscoped.session_id
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_session_context_references_round_trip() {
|
||||
let tmp = tempdir().expect("tempdir");
|
||||
|
||||
Reference in New Issue
Block a user