/** * LayoutService behavior: the cross-plugin panel-action face. Geometry * lives in the entry store (layout-store.spec.ts) — here we assert the * delegation seam: attachPanels wiring, the three actions forwarding, the * unwired fail-loud, and re-attach overwriting a stale action set. */ import { describe, expect, it, vi } from 'vitest' import { LayoutService } from '@deepseek-ai/dsh-client-ui-layout/src/client/service.ts' import type { PanelActions } from '@deepseek-ai/dsh-client-ui-layout/src/client/service.ts' function fakePanels(): PanelActions { return { setSidebar: vi.fn(), setDetails: vi.fn(), toggleSidebar: vi.fn(), openDetails: vi.fn(), closeDetails: vi.fn(), } } describe('LayoutService', () => { it('forwards the three panel actions to the attached set', () => { const service = new LayoutService() const panels = fakePanels() service.attachPanels(panels) service.toggleSidebar() service.openDetails() service.closeDetails() expect(panels.toggleSidebar).toHaveBeenCalledTimes(1) expect(panels.openDetails).toHaveBeenCalledTimes(1) expect(panels.closeDetails).toHaveBeenCalledTimes(1) expect(panels.setSidebar).not.toHaveBeenCalled() expect(panels.setDetails).not.toHaveBeenCalled() }) it('fails loud before the root entry wired its actions', () => { const service = new LayoutService() expect(() => { service.toggleSidebar() }).toThrow(/panel actions not wired/) expect(() => { service.openDetails() }).toThrow(/panel actions not wired/) expect(() => { service.closeDetails() }).toThrow(/panel actions not wired/) }) it('re-attach overwrites the stale action set (entry re-register)', () => { const service = new LayoutService() const stale = fakePanels() const fresh = fakePanels() service.attachPanels(stale) service.attachPanels(fresh) service.toggleSidebar() expect(stale.toggleSidebar).not.toHaveBeenCalled() expect(fresh.toggleSidebar).toHaveBeenCalledTimes(1) }) })