import { beforeEach, describe, expect, it } from 'vitest'; import { createEmptyMap } from '@/services/mapFactory'; import { useEditorStore } from '@/stores/editorStore'; function store() { return useEditorStore.getState(); } function rootId(): string { return store().map?.nodes[0]?.id as string; } function nodeById(id: string) { return store().map?.nodes.find((node) => node.id === id); } function makeChildren(count: number): string[] { const ids: string[] = []; for (let index = 0; index < count; index += 1) { ids.push(store().addChild(rootId()) as string); } store().setEditingNode(null); return ids; } beforeEach(() => { useEditorStore.getState().loadMap(createEmptyMap('Styles')); }); describe('application de style a plusieurs noeuds', () => { it('applique une couleur a toute la selection en une entree d historique', () => { const ids = makeChildren(3); store().setSelection(ids); const before = store().past.length; store().updateNodesStyle(ids, { backgroundColor: '#112233' }); expect(store().past.length).toBe(before + 1); for (const id of ids) { expect(nodeById(id)?.style?.backgroundColor).toBe('#112233'); } }); it('applique un padding a toute la selection', () => { const ids = makeChildren(2); store().updateNodesLayout(ids, { paddingX: 28, paddingY: 18 }); for (const id of ids) { expect(nodeById(id)?.layout?.paddingX).toBe(28); expect(nodeById(id)?.layout?.paddingY).toBe(18); } }); it('ne laisse pas d objet de style vide dans le document', () => { const [id] = makeChildren(1); store().updateNodesStyle([id as string], { bold: true }); store().updateNodesStyle([id as string], { bold: undefined }); expect(nodeById(id as string)?.style).toBeUndefined(); }); }); describe('copier / coller le style', () => { it('copie uniquement les proprietes visuelles', () => { const [source, target] = makeChildren(2) as [string, string]; store().updateNodeText(source, 'Source'); store().updateNode(source, { note: 'Note privee', url: 'https://exemple.fr/' }); store().updateNodesStyle([source], { backgroundColor: '#abcdef', textAlign: 'center' }); store().updateNodesLayout([source], { paddingX: 24 }); store().setNodesIcon([source], 'server', 'builtin'); store().updateNodeText(target, 'Cible'); store().setSelection([source]); expect(store().copyStyle()).toBe(true); store().setSelection([target]); expect(store().pasteStyle()).toBe(1); const pasted = nodeById(target); expect(pasted?.style?.backgroundColor).toBe('#abcdef'); expect(pasted?.style?.textAlign).toBe('center'); expect(pasted?.layout?.paddingX).toBe(24); expect(pasted?.icon).toBe('server'); expect(pasted?.iconStyle?.kind).toBe('builtin'); // Le contenu de la cible n'est pas touche. expect(pasted?.text).toBe('Cible'); expect(pasted?.note).toBeUndefined(); expect(pasted?.url).toBeUndefined(); expect(pasted?.parentId).toBe(rootId()); }); it('colle le style sur plusieurs noeuds en une entree d historique', () => { const ids = makeChildren(4) as string[]; const source = ids[0] as string; store().updateNodesStyle([source], { borderColor: '#ff0000' }); store().setSelection([source]); store().copyStyle(); store().setSelection(ids.slice(1)); const before = store().past.length; expect(store().pasteStyle()).toBe(3); expect(store().past.length).toBe(before + 1); for (const id of ids.slice(1)) { expect(nodeById(id)?.style?.borderColor).toBe('#ff0000'); } }); it('ne colle rien sans style copie', () => { const ids = makeChildren(1); store().setSelection(ids); expect(store().pasteStyle()).toBe(0); }); }); describe('reinitialisation du style', () => { it('remet le theme sans toucher au contenu ni a la hierarchie', () => { const [id] = makeChildren(1) as [string]; store().updateNodeText(id, 'Firewall'); store().updateNode(id, { note: 'A verifier', url: 'https://exemple.fr/' }); store().updateNodesStyle([id], { backgroundColor: '#000000', shape: 'circle' }); store().updateNodesLayout([id], { paddingX: 30 }); store().updateNodesBranch([id], { color: '#00ff00' }); store().resetNodesStyle([id]); const node = nodeById(id); expect(node?.style).toBeUndefined(); expect(node?.layout).toBeUndefined(); expect(node?.branch).toBeUndefined(); expect(node?.text).toBe('Firewall'); expect(node?.note).toBe('A verifier'); expect(node?.url).toBe('https://exemple.fr/'); expect(node?.parentId).toBe(rootId()); }); });