Files
web-cad/frontend/tests/GroupTool.test.ts
T
Leopoldadmin 1bcfaffdd4 fix: replace hardcoded localhost:3001 with relative API URL + add canvas mock and integration test
- Fix frontend Network error: API_BASE now defaults to empty string (same-origin)
- Fix 3 files: api.ts, AuthContext.tsx, Dashboard.tsx
- Add Canvas 2D context mock in tests/setup.ts for jsdom
- Fix -0 vs +0 in ZoomPanController.getViewport()
- Add IntegrationWorkflow.test.ts (35 tests, full CAD workflow)
2026-06-26 17:48:24 +02:00

191 lines
6.2 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/**
* GroupTool Tests GroupManager: create, ungroup, nest, query
*/
import { describe, it, expect, beforeEach } from 'vitest';
import { GroupManager } from '../src/tools/modification/GroupTool';
import type { ElementGroup } from '../src/tools/modification/GroupTool';
describe('GroupManager', () => {
let gm: GroupManager;
beforeEach(() => {
gm = new GroupManager();
});
describe('createGroup', () => {
it('should create a group with element IDs', () => {
const group = gm.createGroup(['el-1', 'el-2', 'el-3']);
expect(group.id).toBeDefined();
expect(group.elementIds).toEqual(['el-1', 'el-2', 'el-3']);
expect(group.parentGroupId).toBeNull();
});
it('should create a group with a custom name', () => {
const group = gm.createGroup(['el-1'], 'My Group');
expect(group.name).toBe('My Group');
});
it('should create a group with default name when no name provided', () => {
const group = gm.createGroup(['el-1']);
expect(group.name).toContain('Group');
});
it('should create multiple groups with unique IDs', () => {
const g1 = gm.createGroup(['el-1']);
const g2 = gm.createGroup(['el-2']);
expect(g1.id).not.toBe(g2.id);
});
});
describe('ungroup', () => {
it('should remove a group and return its element IDs', () => {
const group = gm.createGroup(['el-1', 'el-2']);
const ids = gm.ungroup(group.id);
expect(ids).toEqual(['el-1', 'el-2']);
expect(gm.getGroup(group.id)).toBeUndefined();
});
it('should return empty array for non-existent group', () => {
const ids = gm.ungroup('non-existent');
expect(ids).toEqual([]);
});
});
describe('getGroup', () => {
it('should retrieve a group by ID', () => {
const group = gm.createGroup(['el-1']);
const retrieved = gm.getGroup(group.id);
expect(retrieved).toBeDefined();
expect(retrieved!.id).toBe(group.id);
});
it('should return undefined for non-existent group', () => {
expect(gm.getGroup('non-existent')).toBeUndefined();
});
});
describe('getGroups', () => {
it('should return all groups', () => {
gm.createGroup(['el-1']);
gm.createGroup(['el-2']);
expect(gm.getGroups().length).toBe(2);
});
it('should return empty array when no groups', () => {
expect(gm.getGroups()).toEqual([]);
});
});
describe('getGroupedElements', () => {
it('should return set of all element IDs in all groups', () => {
gm.createGroup(['el-1', 'el-2']);
gm.createGroup(['el-3']);
const ids = gm.getGroupedElements();
expect(ids.size).toBe(3);
expect(ids.has('el-1')).toBe(true);
expect(ids.has('el-2')).toBe(true);
expect(ids.has('el-3')).toBe(true);
});
it('should return empty set when no groups', () => {
expect(gm.getGroupedElements().size).toBe(0);
});
});
describe('getGroupForElement', () => {
it('should return group ID for an element in a group', () => {
const group = gm.createGroup(['el-1', 'el-2']);
expect(gm.getGroupForElement('el-1')).toBe(group.id);
expect(gm.getGroupForElement('el-2')).toBe(group.id);
});
it('should return null for element not in any group', () => {
expect(gm.getGroupForElement('el-lonely')).toBeNull();
});
});
describe('moveGroup', () => {
it('should return element IDs that need to be moved', () => {
const group = gm.createGroup(['el-1', 'el-2']);
const ids = gm.moveGroup(group.id, 10, 20);
expect(ids).toEqual(['el-1', 'el-2']);
});
it('should return empty array for non-existent group', () => {
const ids = gm.moveGroup('non-existent', 10, 20);
expect(ids).toEqual([]);
});
});
describe('setParent (nested groups)', () => {
it('should set parent group for nesting', () => {
const parent = gm.createGroup(['el-1']);
const child = gm.createGroup(['el-2']);
gm.setParent(child.id, parent.id);
expect(gm.getGroup(child.id)!.parentGroupId).toBe(parent.id);
});
it('should prevent circular references', () => {
const g1 = gm.createGroup(['el-1']);
const g2 = gm.createGroup(['el-2']);
gm.setParent(g1.id, g2.id);
// Trying to set g2's parent to g1 would create a cycle: g1 -> g2 -> g1
gm.setParent(g2.id, g1.id);
expect(gm.getGroup(g2.id)!.parentGroupId).toBeNull();
});
it('should allow setting parent to null', () => {
const parent = gm.createGroup(['el-1']);
const child = gm.createGroup(['el-2']);
gm.setParent(child.id, parent.id);
gm.setParent(child.id, null);
expect(gm.getGroup(child.id)!.parentGroupId).toBeNull();
});
it('should do nothing for non-existent group', () => {
gm.setParent('non-existent', null);
expect(gm.getGroup('non-existent')).toBeUndefined();
});
});
describe('clear', () => {
it('should clear all groups', () => {
gm.createGroup(['el-1']);
gm.createGroup(['el-2']);
gm.clear();
expect(gm.getGroups().length).toBe(0);
});
});
describe('toJSON & fromJSON', () => {
it('should serialize groups to JSON', () => {
gm.createGroup(['el-1', 'el-2'], 'Group A');
gm.createGroup(['el-3'], 'Group B');
const json = gm.toJSON();
expect(json.length).toBe(2);
expect(json[0].name).toBe('Group A');
expect(json[1].name).toBe('Group B');
});
it('should restore groups from JSON', () => {
const groups: ElementGroup[] = [
{ id: 'grp-1', name: 'Restored A', elementIds: ['el-1'], parentGroupId: null },
{ id: 'grp-2', name: 'Restored B', elementIds: ['el-2', 'el-3'], parentGroupId: 'grp-1' },
];
gm.fromJSON(groups);
expect(gm.getGroups().length).toBe(2);
expect(gm.getGroup('grp-1')!.name).toBe('Restored A');
expect(gm.getGroup('grp-2')!.parentGroupId).toBe('grp-1');
});
it('should clear existing groups when restoring from JSON', () => {
gm.createGroup(['el-old']);
gm.fromJSON([
{ id: 'grp-new', name: 'New', elementIds: ['el-new'], parentGroupId: null },
]);
expect(gm.getGroups().length).toBe(1);
expect(gm.getGroup('grp-new')).toBeDefined();
});
});
});