File size: 2,950 Bytes
94193b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
import { describe, it, expect, beforeEach, vi } from 'vitest';

const mockLocalStorage: Record<string, string> = {};
vi.stubGlobal('localStorage', {
  getItem: (key: string) => mockLocalStorage[key] ?? null,
  setItem: (key: string, value: string) => { mockLocalStorage[key] = value; },
  removeItem: (key: string) => { delete mockLocalStorage[key]; },
});

import { createStore } from 'zustand/vanilla';
import { createLayoutSlice, LayoutSlice } from '../slices/layout';

function createLayoutStore() {
  return createStore<LayoutSlice>()((...a) => ({
    ...createLayoutSlice(...a),
  }));
}

describe('layout slice', () => {
  let store: ReturnType<typeof createLayoutStore>;

  beforeEach(() => {
    for (const key of Object.keys(mockLocalStorage)) delete mockLocalStorage[key];
    store = createLayoutStore();
  });

  it('starts with default panel visibility', () => {
    const s = store.getState();
    expect(s.showChat).toBe(true);
    expect(s.showFiles).toBe(true);
    expect(s.showEditor).toBe(false);
    expect(s.showPreview).toBe(true);
  });

  it('togglePanel flips visibility', () => {
    store.getState().togglePanel('editor');
    expect(store.getState().showEditor).toBe(true);
    store.getState().togglePanel('editor');
    expect(store.getState().showEditor).toBe(false);
  });

  it('setPanelOrder updates order', () => {
    const newOrder = ['preview', 'chat', 'files', 'editor', 'console', 'checkpoints', 'debug', 'skills'];
    store.getState().setPanelOrder(newOrder);
    expect(store.getState().panelOrder).toEqual(newOrder);
  });

  it('setActiveMobilePanel sets panel and closes overflow', () => {
    store.setState({ mobileOverflowOpen: true });
    store.getState().setActiveMobilePanel('editor');
    expect(store.getState().activeMobilePanel).toBe('editor');
    expect(store.getState().mobileOverflowOpen).toBe(false);
  });

  it('startDrag / endDrag manage drag state', () => {
    store.getState().startDrag('chat');
    expect(store.getState().draggingPanel).toBe('chat');
    store.getState().endDrag();
    expect(store.getState().draggingPanel).toBeNull();
    expect(store.getState().dropTarget).toBeNull();
  });

  it('resetLayout clears transient state but keeps panel visibility', () => {
    store.getState().togglePanel('editor');
    store.setState({ draggingPanel: 'chat', mobileOverflowOpen: true });
    store.getState().resetLayout();
    expect(store.getState().draggingPanel).toBeNull();
    expect(store.getState().mobileOverflowOpen).toBe(false);
    expect(store.getState().showEditor).toBe(true); // preserved
  });

  it('initLayout reloads panel order from localStorage', () => {
    const customOrder = ['preview', 'chat', 'files', 'editor', 'skills', 'console', 'checkpoints', 'debug'];
    mockLocalStorage['osw-workspace-panel-order'] = JSON.stringify(customOrder);
    store.getState().initLayout();
    expect(store.getState().panelOrder).toEqual(customOrder);
  });
});