Automerge backed Markdown editor for the Atmosphere
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135// src/layout/hooks/__tests__/useWorkspaceViews.test.tsximport { describe, it, expect } from 'vitest'import { renderHook, act } from '@testing-library/react'import { Workspace } from '../../../plugin/workspace'import { ItemView } from '../../../plugin/views/item-view'import { useWorkspaceViews } from '../useWorkspaceViews'import { ReamsEvents } from '../../../plugin/reams/events'import type { App } from '../../../plugin/app'
class TestView extends ItemView { getViewType() { return 'test-view' } getDisplayText() { return 'Test' }}
class TestViewB extends ItemView { getViewType() { return 'test-view-b' } getDisplayText() { return 'Test B' }}
/** * Create a minimal App mock for testing hooks that need app.reamsEvents */function createAppMock(ws: Workspace): App { const reamsEvents = new ReamsEvents() const app = { workspace: ws, reamsEvents, } as unknown as App ws.app = app return app}
// Core views (#406) registered by Workspace constructor for content-type routing.const CORE_VIEW_TYPES = ['markdown', 'reams-unsupported']
describe('useWorkspaceViews', () => { it('returns empty leaves and only core view registrations initially', () => { const ws = new Workspace(document.createElement('div')) const app = createAppMock(ws) const { result } = renderHook(() => useWorkspaceViews(app)) expect(result.current.leftLeaves).toEqual([]) expect(result.current.rightLeaves).toEqual([]) expect([...result.current.registeredTypes].sort()).toEqual([...CORE_VIEW_TYPES].sort()) })
it('updates when a view is registered', () => { const ws = new Workspace(document.createElement('div')) const app = createAppMock(ws) const { result } = renderHook(() => useWorkspaceViews(app))
act(() => { ws.registerViewType('test-view', (leaf) => new TestView(leaf)) })
expect(result.current.registeredTypes).toContain('test-view') })
it('updates when a view is unregistered', () => { const ws = new Workspace(document.createElement('div')) const app = createAppMock(ws) ws.registerViewType('test-view', (leaf) => new TestView(leaf)) const { result } = renderHook(() => useWorkspaceViews(app))
expect(result.current.registeredTypes).toContain('test-view')
act(() => { ws.unregisterViewType('test-view') })
expect(result.current.registeredTypes).not.toContain('test-view') })
it('updates leftLeaves when layout changes', () => { const ws = new Workspace(document.createElement('div')) const app = createAppMock(ws) const { result } = renderHook(() => useWorkspaceViews(app))
act(() => { ws.getLeftLeaf(true) })
expect(result.current.leftLeaves).toHaveLength(1) })
it('updates rightLeaves when layout changes', () => { const ws = new Workspace(document.createElement('div')) const app = createAppMock(ws) const { result } = renderHook(() => useWorkspaceViews(app))
act(() => { ws.getRightLeaf(true) })
expect(result.current.rightLeaves).toHaveLength(1) })
it('detects view swap on existing leaf (same leaf, different view)', async () => { const ws = new Workspace(document.createElement('div')) const app = createAppMock(ws) ws.registerViewType('test-view', (leaf) => new TestView(leaf)) ws.registerViewType('test-view-b', (leaf) => new TestViewB(leaf))
// Create a right leaf with test-view const leaf = ws.getRightLeaf(true) await leaf.openView('test-view')
const { result } = renderHook(() => useWorkspaceViews(app))
// Verify initial state expect(result.current.rightLeaves).toHaveLength(1) expect(result.current.rightLeaves[0].view?.getViewType()).toBe('test-view')
// Swap the view on the SAME leaf — openView triggers layout-change await act(async () => { await leaf.openView('test-view-b') })
// Hook should have re-rendered and picked up the new view expect(result.current.rightLeaves).toHaveLength(1) expect(result.current.rightLeaves[0]).toBe(leaf) // same leaf object expect(result.current.rightLeaves[0].view?.getViewType()).toBe('test-view-b') })
it('cleans up event listeners on unmount', () => { const ws = new Workspace(document.createElement('div')) const app = createAppMock(ws) const { unmount } = renderHook(() => useWorkspaceViews(app))
unmount()
// After unmount, registering a view should not cause errors expect(() => ws.registerViewType('test-view', (leaf) => new TestView(leaf))).not.toThrow() })})