/** * Task H1 – simple/pro Mode. * * uiModeService: persistierter UI-Modus ('simple' | 'pro', Default 'pro'), * localStorage-Persistenz, Subscribe für Live-Updates. * RibbonBar filtert im simple-Modus auf tools mit tags 'basic'. * CommandLine ist pro-only (im simple-Modus versteckt). */ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'; import { render, screen, fireEvent, cleanup } from '@testing-library/react'; import { getUIMode, setUIMode, subscribeUIMode, UIMode, } from '../src/services/uiModeService'; afterEach(cleanup); // ─── uiModeService ──────────────────────────────────────── describe('H1: uiModeService', () => { beforeEach(() => { localStorage.clear(); }); it('Default ist pro (Vollständige Werkzeugpalette)', () => { expect(getUIMode()).toBe('pro'); }); it('setUIMode simple persistiert in localStorage', () => { setUIMode('simple'); expect(getUIMode()).toBe('simple'); expect(localStorage.getItem('webcad.uiMode')).toBe('simple'); }); it('Persistiert über Reload hinweg (localStorage gesetzt vor erstem get)', () => { localStorage.setItem('webcad.uiMode', 'simple'); expect(getUIMode()).toBe('simple'); }); it('subscribeUIMode feuert bei Wechsel und unsubscribed korrekt', () => { const cb = vi.fn(); const off = subscribeUIMode(cb); setUIMode('simple'); expect(cb).toHaveBeenCalledWith('simple'); setUIMode('pro'); expect(cb).toHaveBeenCalledWith('pro'); off(); cb.mockClear(); setUIMode('simple'); expect(cb).not.toHaveBeenCalled(); // Aufräumen für weitere Tests setUIMode('pro'); }); it('ungültiger localStorage-Wert fällt auf pro zurück', () => { localStorage.setItem('webcad.uiMode', 'gibts-nicht'); expect(getUIMode()).toBe('pro'); }); }); // ─── RibbonBar simple-Filter ───────────────────────────── describe('H1: RibbonBar simple-Filter', () => { beforeEach(() => { localStorage.clear(); setUIMode('pro'); }); it('pro-Modus: alle V2-Tools sichtbar (basic + pro-Tags)', async () => { const { registerBuiltinPlugins, pluginRegistry } = await import('../src/plugins'); registerBuiltinPlugins(); pluginRegistry.initDefaults(); const RibbonBar = (await import('../src/components/RibbonBar')).default; render( {}} onAction={() => {}} />); const all = screen.getAllByRole('button').length; expect(all).toBeGreaterThan(10); cleanup(); setUIMode('simple'); render( {}} onAction={() => {}} />); const simpleCount = screen.getAllByRole('button').length; expect(simpleCount).toBeLessThan(all); expect(simpleCount).toBeGreaterThan(0); }); it('simple-Modus: pro-Tools (rotate/scale/mirror) fehlen, basic (line) bleibt', async () => { localStorage.clear(); setUIMode('simple'); const { registerBuiltinPlugins, pluginRegistry } = await import('../src/plugins'); registerBuiltinPlugins(); pluginRegistry.initDefaults(); const RibbonBar = (await import('../src/components/RibbonBar')).default; render( {}} onAction={() => {}} />); const html = document.body.innerHTML; expect(html).toContain('data-v2tool="line"'); expect(html).not.toContain('data-v2tool="rotate"'); expect(html).not.toContain('data-v2tool="mirror"'); }); it('CommandLine-Komponente: pro-only rendering via useUIMode', async () => { const { useUIMode } = await import('../src/services/uiModeService'); const CommandLine = (await import('../src/components/CommandLine')).default; setUIMode('pro'); const { container: proContainer } = render( {}} />); expect(proContainer.querySelector('.cmdline')).toBeTruthy(); cleanup(); setUIMode('simple'); const { container: simpleContainer } = render( {}} />); expect(simpleContainer.querySelector('.cmdline')).toBeFalsy(); }); it('Topbar-Toggle wechselt Mode', async () => { const Topbar = (await import('../src/components/Topbar')).default; setUIMode('pro'); render( {}} onRedo={() => {}} onThemeToggle={() => {}} theme="dark" />); const btn = screen.getByTitle(/Modus.*wechseln|Einfach.*Modus|Profi-Modus/i); fireEvent.click(btn); expect(getUIMode()).toBe('simple'); }); });