task(H1): simple/pro mode - uiModeService with localStorage persistence, ribbon basic-tag filter, commandline pro-only, topbar toggle
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
/**
|
||||
* 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(<RibbonBar activeTab="canvas" onTabChange={() => {}} onAction={() => {}} />);
|
||||
const all = screen.getAllByRole('button').length;
|
||||
expect(all).toBeGreaterThan(10);
|
||||
cleanup();
|
||||
setUIMode('simple');
|
||||
render(<RibbonBar activeTab="canvas" onTabChange={() => {}} 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(<RibbonBar activeTab="canvas" onTabChange={() => {}} 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(<CommandLine history={[]} onCommand={() => {}} />);
|
||||
expect(proContainer.querySelector('.cmdline')).toBeTruthy();
|
||||
cleanup();
|
||||
setUIMode('simple');
|
||||
const { container: simpleContainer } = render(<CommandLine history={[]} onCommand={() => {}} />);
|
||||
expect(simpleContainer.querySelector('.cmdline')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('Topbar-Toggle wechselt Mode', async () => {
|
||||
const Topbar = (await import('../src/components/Topbar')).default;
|
||||
setUIMode('pro');
|
||||
render(<Topbar projectName="Testprojekt" savedStatus="Gespeichert" onUndo={() => {}} onRedo={() => {}} onThemeToggle={() => {}} theme="dark" />);
|
||||
const btn = screen.getByTitle(/Modus.*wechseln|Einfach.*Modus|Profi-Modus/i);
|
||||
fireEvent.click(btn);
|
||||
expect(getUIMode()).toBe('simple');
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user