mirror of
https://github.com/FoggedLens/deflock-app.git
synced 2026-02-12 16:52:51 +00:00
Route calculation to alprwatch API fails with HTTP 400 because built-in profiles include empty tag values (e.g. camera:mount: '') that get serialized into the request body and rejected by the API. Add routing_service_test.dart with 5 tests: - Empty tags filtered from request (reproduces the bug) - Successful route parsing - HTTP error handling - Network error wrapping - API-level error surfacing Add node_profile_test.dart with 4 tests: - toJson/fromJson round-trip - getDefaults returns expected profiles - Empty tag values exist in defaults (documents bug origin) - Equality based on id Tests require RoutingService to accept an injectable http.Client, which will be added in the next commit along with the fix. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
77 lines
2.5 KiB
Dart
77 lines
2.5 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:deflockapp/models/node_profile.dart';
|
|
|
|
void main() {
|
|
group('NodeProfile', () {
|
|
test('toJson/fromJson round-trip preserves all fields', () {
|
|
final profile = NodeProfile(
|
|
id: 'test-id',
|
|
name: 'Test Profile',
|
|
tags: const {'man_made': 'surveillance', 'camera:type': 'fixed'},
|
|
builtin: true,
|
|
requiresDirection: false,
|
|
submittable: true,
|
|
editable: false,
|
|
fov: 90.0,
|
|
);
|
|
|
|
final json = profile.toJson();
|
|
final restored = NodeProfile.fromJson(json);
|
|
|
|
expect(restored.id, equals(profile.id));
|
|
expect(restored.name, equals(profile.name));
|
|
expect(restored.tags, equals(profile.tags));
|
|
expect(restored.builtin, equals(profile.builtin));
|
|
expect(restored.requiresDirection, equals(profile.requiresDirection));
|
|
expect(restored.submittable, equals(profile.submittable));
|
|
expect(restored.editable, equals(profile.editable));
|
|
expect(restored.fov, equals(profile.fov));
|
|
});
|
|
|
|
test('getDefaults returns expected profiles', () {
|
|
final defaults = NodeProfile.getDefaults();
|
|
|
|
expect(defaults.length, greaterThanOrEqualTo(10));
|
|
|
|
final ids = defaults.map((p) => p.id).toSet();
|
|
expect(ids, contains('builtin-flock'));
|
|
expect(ids, contains('builtin-generic-alpr'));
|
|
expect(ids, contains('builtin-motorola'));
|
|
expect(ids, contains('builtin-shotspotter'));
|
|
});
|
|
|
|
test('empty tag values exist in default profiles', () {
|
|
// Documents that profiles like builtin-flock ship with camera:mount: ''
|
|
// This is the root cause of the HTTP 400 bug — the routing service must
|
|
// filter these out before sending to the API.
|
|
final defaults = NodeProfile.getDefaults();
|
|
final flock = defaults.firstWhere((p) => p.id == 'builtin-flock');
|
|
|
|
expect(flock.tags.containsKey('camera:mount'), isTrue);
|
|
expect(flock.tags['camera:mount'], equals(''));
|
|
});
|
|
|
|
test('equality is based on id', () {
|
|
final a = NodeProfile(
|
|
id: 'same-id',
|
|
name: 'Profile A',
|
|
tags: const {'tag': 'a'},
|
|
);
|
|
final b = NodeProfile(
|
|
id: 'same-id',
|
|
name: 'Profile B',
|
|
tags: const {'tag': 'b'},
|
|
);
|
|
final c = NodeProfile(
|
|
id: 'different-id',
|
|
name: 'Profile A',
|
|
tags: const {'tag': 'a'},
|
|
);
|
|
|
|
expect(a, equals(b));
|
|
expect(a.hashCode, equals(b.hashCode));
|
|
expect(a, isNot(equals(c)));
|
|
});
|
|
});
|
|
}
|