Files
tatlock-ui/test/routing/room_registry_test.dart
T
Jeroen SchweitzerandClaude Opus 4.5 d6fd9aea60 test: add test harness and widget tests for DataGrid pages
Add comprehensive testing infrastructure:
- Test harness with mock auth, API client, and fixtures
- Mock Dio interceptor for canned API responses
- Fixtures for containers, domains, users, groups

Add widget tests for all DataGrid pages:
- ContainersListPage (21 tests)
- ProxyHostsPage (16 tests)
- UsersListPage (21 tests)
- GroupsListPage (18 tests)

Add unit tests:
- RoomRegistry (28 tests)
- DataGrid components (35 tests)

Test count: 282 -> 357 (+75 tests)
Coverage: 5.7% -> 19.1% (+504 lines)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-05 21:18:34 +01:00

205 lines
6.2 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:go_router/go_router.dart';
import 'package:tatlock_ui/routing/room_registry.dart';
import '../harness/test_harness.dart';
void main() {
final harness = TestHarness();
setUp(() => harness.setUp());
tearDown(() => harness.tearDown());
group('RoomDefinition', () {
test('creates room with all required fields', () {
final room = RoomDefinition(
id: 'test-room',
label: 'Test Room',
icon: Icons.home_outlined,
selectedIcon: Icons.home,
defaultRoute: '/test-room',
routes: () => [],
);
expect(room.id, 'test-room');
expect(room.label, 'Test Room');
expect(room.icon, Icons.home_outlined);
expect(room.selectedIcon, Icons.home);
expect(room.defaultRoute, '/test-room');
expect(room.requiredPermissions, isEmpty);
});
test('creates room with permissions', () {
final room = RoomDefinition(
id: 'admin-room',
label: 'Admin Room',
icon: Icons.admin_panel_settings_outlined,
selectedIcon: Icons.admin_panel_settings,
defaultRoute: '/admin',
routes: () => [],
requiredPermissions: ['admin:access', 'admin:read'],
);
expect(room.requiredPermissions.length, 2);
expect(room.requiredPermissions, contains('admin:access'));
});
test('routes function returns RouteBase list', () {
final room = RoomDefinition(
id: 'test-room',
label: 'Test Room',
icon: Icons.home_outlined,
selectedIcon: Icons.home,
defaultRoute: '/test-room',
routes: () => [
GoRoute(
path: '/test-room',
builder: (context, state) => const SizedBox(),
),
],
);
final routes = room.routes();
expect(routes.length, 1);
expect(routes.first, isA<GoRoute>());
});
});
group('RoomRegistry', () {
test('all returns registered rooms', () {
// Rooms are registered by harness.setUp()
final rooms = roomRegistry.all;
expect(rooms, isNotEmpty);
});
test('byId returns room for valid ID', () {
final room = roomRegistry.byId('front-hall');
expect(room, isNotNull);
expect(room!.label, 'Front Hall');
});
test('byId returns null for invalid ID', () {
final room = roomRegistry.byId('non-existent-room');
expect(room, isNull);
});
test('indexOfId returns correct index', () {
final index = roomRegistry.indexOfId('front-hall');
expect(index, 0);
final controlRoomIndex = roomRegistry.indexOfId('control-room');
expect(controlRoomIndex, 1);
});
test('indexOfId returns -1 for invalid ID', () {
final index = roomRegistry.indexOfId('non-existent');
expect(index, -1);
});
test('indexOfRoute matches exact route', () {
final index = roomRegistry.indexOfRoute('/front-hall');
expect(index, 0);
});
test('indexOfRoute matches sub-routes', () {
final index = roomRegistry.indexOfRoute('/control-room/containers');
expect(index, 1);
final securityIndex = roomRegistry.indexOfRoute('/security/users');
expect(securityIndex, 2);
});
test('indexOfRoute returns 0 for unknown route', () {
final index = roomRegistry.indexOfRoute('/unknown-route');
expect(index, 0); // Defaults to first room
});
test('allRoutes returns routes from all rooms', () {
final routes = roomRegistry.allRoutes();
expect(routes, isNotEmpty);
// Should have routes from all registered rooms
});
test('accessibleTo filters by permissions', () {
// All current rooms have no required permissions
final accessible = roomRegistry.accessibleTo({});
expect(accessible.length, roomRegistry.all.length);
});
test('accessibleTo returns all rooms for empty permissions when no rooms require permissions', () {
final accessible = roomRegistry.accessibleTo({'some:permission'});
// All rooms should be accessible since none require permissions
expect(accessible.length, roomRegistry.all.length);
});
});
group('Room Registration Order', () {
test('front-hall is first', () {
expect(roomRegistry.all[0].id, 'front-hall');
});
test('control-room is second', () {
expect(roomRegistry.all[1].id, 'control-room');
});
test('security is third', () {
expect(roomRegistry.all[2].id, 'security');
});
test('parlor is fourth', () {
expect(roomRegistry.all[3].id, 'parlor');
});
test('media-room is fifth', () {
expect(roomRegistry.all[4].id, 'media-room');
});
});
group('Room Default Routes', () {
test('front-hall default route is /front-hall', () {
final room = roomRegistry.byId('front-hall');
expect(room?.defaultRoute, '/front-hall');
});
test('control-room default route is /control-room/containers', () {
final room = roomRegistry.byId('control-room');
expect(room?.defaultRoute, '/control-room/containers');
});
test('security default route is /security/users', () {
final room = roomRegistry.byId('security');
expect(room?.defaultRoute, '/security/users');
});
test('parlor default route is /parlor', () {
final room = roomRegistry.byId('parlor');
expect(room?.defaultRoute, '/parlor');
});
test('media-room default route is /media-room', () {
final room = roomRegistry.byId('media-room');
expect(room?.defaultRoute, '/media-room');
});
});
group('Room Icons', () {
test('each room has distinct icons', () {
final rooms = roomRegistry.all;
final icons = rooms.map((r) => r.icon).toSet();
final selectedIcons = rooms.map((r) => r.selectedIcon).toSet();
// All icons should be unique
expect(icons.length, rooms.length);
expect(selectedIcons.length, rooms.length);
});
test('icon and selectedIcon are different for each room', () {
for (final room in roomRegistry.all) {
expect(room.icon, isNot(equals(room.selectedIcon)),
reason: '${room.label} should have different icon and selectedIcon');
}
});
});
}