fix(layout): auto-réparer l'onglet actif
stale
Le backend renvoie l'id actif autoritaire et le
frontend l'adopte pour éviter de rejouer un layout
disparu après overwrite externe.
Co-Authored-By: Claude Opus 4.8
<noreply@anthropic.com>
This commit is contained in:
@ -338,21 +338,24 @@ async fn load_tolerates_corrupt_json_with_default() {
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn load_unknown_layout_id_is_not_found() {
|
||||
async fn load_unknown_layout_id_self_heals_to_active() {
|
||||
let store = FakeStore::default();
|
||||
let fs = FakeFs::default();
|
||||
let id = register_project(&store, pid(5)).await;
|
||||
seed_layouts(&fs, lid(1), &single_leaf(nid(1)));
|
||||
|
||||
// A stale requested id (e.g. left over after git overwrote layouts.json)
|
||||
// must NOT hard-error and freeze the workspace; it degrades silently to the
|
||||
// valid active layout (invariant I3), whose id is authoritative (I4).
|
||||
let load = LoadLayout::new(Arc::new(store), Arc::new(fs));
|
||||
let err = load
|
||||
let out = load
|
||||
.execute(LoadLayoutInput {
|
||||
project_id: id,
|
||||
layout_id: Some(lid(999)),
|
||||
})
|
||||
.await
|
||||
.expect_err("unknown layout id rejected");
|
||||
assert_eq!(err.code(), "NOT_FOUND", "got {err:?}");
|
||||
.expect("stale layout id must self-heal, not error");
|
||||
assert_eq!(out.layout_id, lid(1));
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
@ -937,13 +940,15 @@ async fn set_active_layout_switches_and_load_follows() {
|
||||
.unwrap();
|
||||
|
||||
// Switch back to the Default layout.
|
||||
SetActiveLayout::new(Arc::new(store.clone()), Arc::new(fs.clone()), Arc::new(bus))
|
||||
let set = SetActiveLayout::new(Arc::new(store.clone()), Arc::new(fs.clone()), Arc::new(bus))
|
||||
.execute(SetActiveLayoutInput {
|
||||
project_id: pid(35),
|
||||
layout_id: lid(1),
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
// Output echoes the actually-activated id (I4).
|
||||
assert_eq!(set.active_id, lid(1));
|
||||
|
||||
let loaded = LoadLayout::new(Arc::new(store), Arc::new(fs))
|
||||
.execute(LoadLayoutInput {
|
||||
@ -955,3 +960,31 @@ async fn set_active_layout_switches_and_load_follows() {
|
||||
assert_eq!(loaded.layout_id, lid(1));
|
||||
assert_ne!(loaded.layout_id, created.layout_id);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn set_active_layout_stale_id_self_heals_to_current_active() {
|
||||
// Seeded env: a single "Default" layout, active = lid(1).
|
||||
let (store, fs, bus) = mgmt_env(pid(36)).await;
|
||||
|
||||
// Targeting a stale id (e.g. an activeId left over after git overwrote
|
||||
// layouts.json) must NOT error and must NOT freeze the workspace (I3):
|
||||
// it degrades to the current active id and returns it (I4).
|
||||
let out = SetActiveLayout::new(Arc::new(store.clone()), Arc::new(fs.clone()), Arc::new(bus))
|
||||
.execute(SetActiveLayoutInput {
|
||||
project_id: pid(36),
|
||||
layout_id: lid(999),
|
||||
})
|
||||
.await
|
||||
.expect("stale set_active must self-heal, not error");
|
||||
assert_eq!(out.active_id, lid(1));
|
||||
|
||||
// And a subsequent load of the current view resolves to that valid id.
|
||||
let loaded = LoadLayout::new(Arc::new(store), Arc::new(fs))
|
||||
.execute(LoadLayoutInput {
|
||||
project_id: pid(36),
|
||||
layout_id: None,
|
||||
})
|
||||
.await
|
||||
.unwrap();
|
||||
assert_eq!(loaded.layout_id, lid(1));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user