diff --git a/src/static/tests/VoiceGlowSpec.js b/src/static/tests/VoiceGlowSpec.js index 336642d..c9ece7b 100644 --- a/src/static/tests/VoiceGlowSpec.js +++ b/src/static/tests/VoiceGlowSpec.js @@ -143,6 +143,23 @@ describe("VoiceGlow", () => { expect(hasMuted(burger)).toBe(false); }); + it("auto-disconnect (muted→not-in-call) stops the priRd/.fa-ban path + returns to the available nudge", () => { + // The 3-min mute timeout leaves voice → the mesh notifies + // {inCall:false, muted:false}; the glow must drop the muted colour + // (priRd/.fa-ban) + fall back to the channel-available nudge, live — + // no refresh (user-spec 2026-05-30). + vg = bindVoiceGlow(); + burger.classList.add("active"); // fan open → cues land on the voice btn + vg.setVoiceState({ inCall: true, peerCount: 0, muted: true }); + expect(hasMuted(voice)).toBe(true); + vg.setVoiceState({ inCall: false, peerCount: 0, muted: false }); + expect(hasMuted(voice)).toBe(false); // priRd/.fa-ban path stopped + expect(hasMuted(burger)).toBe(false); + expect(hasGlow(voice)).toBe(true); // back to the available nudge + expect(hasPulse(voice)).toBe(false); // not "live" anymore + expect(hasEq(voice)).toBe(false); + }); + it("hands the pulse to whichever surface is showing (fan toggles)", () => { vg = bindVoiceGlow(); vg.setVoiceState({ inCall: true, peerCount: 0 }); diff --git a/src/static_src/tests/VoiceGlowSpec.js b/src/static_src/tests/VoiceGlowSpec.js index 336642d..c9ece7b 100644 --- a/src/static_src/tests/VoiceGlowSpec.js +++ b/src/static_src/tests/VoiceGlowSpec.js @@ -143,6 +143,23 @@ describe("VoiceGlow", () => { expect(hasMuted(burger)).toBe(false); }); + it("auto-disconnect (muted→not-in-call) stops the priRd/.fa-ban path + returns to the available nudge", () => { + // The 3-min mute timeout leaves voice → the mesh notifies + // {inCall:false, muted:false}; the glow must drop the muted colour + // (priRd/.fa-ban) + fall back to the channel-available nudge, live — + // no refresh (user-spec 2026-05-30). + vg = bindVoiceGlow(); + burger.classList.add("active"); // fan open → cues land on the voice btn + vg.setVoiceState({ inCall: true, peerCount: 0, muted: true }); + expect(hasMuted(voice)).toBe(true); + vg.setVoiceState({ inCall: false, peerCount: 0, muted: false }); + expect(hasMuted(voice)).toBe(false); // priRd/.fa-ban path stopped + expect(hasMuted(burger)).toBe(false); + expect(hasGlow(voice)).toBe(true); // back to the available nudge + expect(hasPulse(voice)).toBe(false); // not "live" anymore + expect(hasEq(voice)).toBe(false); + }); + it("hands the pulse to whichever surface is showing (fan toggles)", () => { vg = bindVoiceGlow(); vg.setVoiceState({ inCall: true, peerCount: 0 });