glam/frontend/tests/unit/use-graph-data.test.ts
kempersc 2761857b0d Add scripts for converting OWL/Turtle ontology to Mermaid and PlantUML diagrams
- Implemented `owl_to_mermaid.py` to convert OWL/Turtle files into Mermaid class diagrams.
- Implemented `owl_to_plantuml.py` to convert OWL/Turtle files into PlantUML class diagrams.
- Added two new PlantUML files for custodian multi-aspect diagrams.
2025-11-22 23:01:13 +01:00

271 lines
7.9 KiB
TypeScript

/**
* Tests for useGraphData Hook
*/
import { describe, it, expect } from 'vitest';
import { renderHook, act } from '@testing-library/react';
import { useGraphData } from '@/hooks/useGraphData';
import type { GraphData } from '@/types/rdf';
describe('useGraphData', () => {
const sampleGraphData: GraphData = {
nodes: [
{ id: 'node1', type: 'uri', label: 'Node 1' },
{ id: 'node2', type: 'literal', label: 'Node 2' },
{ id: 'node3', type: 'Agent', label: 'Node 3' },
],
links: [
{ source: 'node1', target: 'node2', predicate: 'http://example.org/pred1', label: 'predicate 1' },
{ source: 'node2', target: 'node3', predicate: 'http://example.org/pred2', label: 'predicate 2' },
],
};
it('should initialize with empty state', () => {
const { result } = renderHook(() => useGraphData());
expect(result.current.nodes).toEqual([]);
expect(result.current.links).toEqual([]);
expect(result.current.filteredNodes).toEqual([]);
expect(result.current.filteredLinks).toEqual([]);
expect(result.current.nodeTypes).toEqual([]);
expect(result.current.predicates).toEqual([]);
expect(result.current.selectedNode).toBe(null);
expect(result.current.stats.totalNodes).toBe(0);
expect(result.current.stats.totalLinks).toBe(0);
});
it('should load graph data', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
});
expect(result.current.nodes).toEqual(sampleGraphData.nodes);
expect(result.current.links).toEqual(sampleGraphData.links);
expect(result.current.stats.totalNodes).toBe(3);
expect(result.current.stats.totalLinks).toBe(2);
});
it('should extract node types', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
});
expect(result.current.nodeTypes).toContain('uri');
expect(result.current.nodeTypes).toContain('literal');
expect(result.current.nodeTypes).toContain('Agent');
expect(result.current.nodeTypes.length).toBe(3);
});
it('should extract predicates', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
});
expect(result.current.predicates).toContain('http://example.org/pred1');
expect(result.current.predicates).toContain('http://example.org/pred2');
expect(result.current.predicates.length).toBe(2);
});
it('should filter nodes by type', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
});
act(() => {
result.current.setFilters({ nodeTypes: new Set(['uri']) });
});
expect(result.current.filteredNodes.length).toBe(1);
expect(result.current.filteredNodes[0].type).toBe('uri');
});
it('should filter nodes by search term', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
});
act(() => {
result.current.setFilters({ searchTerm: 'Node 1' });
});
expect(result.current.filteredNodes.length).toBe(1);
expect(result.current.filteredNodes[0].label).toBe('Node 1');
});
it('should filter links based on filtered nodes', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
});
// Filter to only node1
act(() => {
result.current.setFilters({ nodeTypes: new Set(['uri']) });
});
// Links should be empty because both endpoints aren't in filtered nodes
expect(result.current.filteredLinks.length).toBe(0);
});
it('should filter links by predicate', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
});
act(() => {
result.current.setFilters({ predicates: new Set(['http://example.org/pred1']) });
});
expect(result.current.filteredLinks.length).toBe(1);
expect(result.current.filteredLinks[0].predicate).toBe('http://example.org/pred1');
});
it('should handle node selection', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
});
act(() => {
result.current.setSelectedNode(sampleGraphData.nodes[0]);
});
expect(result.current.selectedNode).toEqual(sampleGraphData.nodes[0]);
});
it('should clear node selection', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
result.current.setSelectedNode(sampleGraphData.nodes[0]);
});
expect(result.current.selectedNode).not.toBe(null);
act(() => {
result.current.setSelectedNode(null);
});
expect(result.current.selectedNode).toBe(null);
});
it('should reset filters', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
result.current.setFilters({
nodeTypes: new Set(['uri']),
searchTerm: 'test',
});
});
expect(result.current.filters.nodeTypes.size).toBe(1);
expect(result.current.filters.searchTerm).toBe('test');
act(() => {
result.current.resetFilters();
});
expect(result.current.filters.nodeTypes.size).toBe(0);
expect(result.current.filters.searchTerm).toBe('');
});
it('should clear graph data', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
});
expect(result.current.nodes.length).toBe(3);
act(() => {
result.current.clearGraphData();
});
expect(result.current.nodes.length).toBe(0);
expect(result.current.links.length).toBe(0);
expect(result.current.selectedNode).toBe(null);
});
it('should calculate stats correctly', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
});
expect(result.current.stats.totalNodes).toBe(3);
expect(result.current.stats.totalLinks).toBe(2);
expect(result.current.stats.filteredNodeCount).toBe(3);
expect(result.current.stats.filteredLinkCount).toBe(2);
// Apply filter
act(() => {
result.current.setFilters({ nodeTypes: new Set(['uri']) });
});
expect(result.current.stats.totalNodes).toBe(3); // Total unchanged
expect(result.current.stats.filteredNodeCount).toBe(1); // Filtered count changed
});
it('should handle link counts', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
});
expect(result.current.linkCounts).toHaveProperty('http://example.org/pred1');
expect(result.current.linkCounts['http://example.org/pred1']).toBe(1);
expect(result.current.linkCounts['http://example.org/pred2']).toBe(1);
});
it('should handle node counts', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
});
expect(result.current.nodeCounts).toHaveProperty('uri');
expect(result.current.nodeCounts['uri']).toBe(1);
expect(result.current.nodeCounts['literal']).toBe(1);
expect(result.current.nodeCounts['Agent']).toBe(1);
});
it('should combine multiple filters', () => {
const { result } = renderHook(() => useGraphData());
act(() => {
result.current.loadGraphData(sampleGraphData);
});
act(() => {
result.current.setFilters({
nodeTypes: new Set(['uri', 'literal']),
searchTerm: 'Node 1',
});
});
// Only Node 1 should match (uri type AND "Node 1" in label)
expect(result.current.filteredNodes.length).toBe(1);
expect(result.current.filteredNodes[0].id).toBe('node1');
});
});