import 'package:flutter_test/flutter_test.dart'; import 'package:dmc_app/domain/telemetry/system_message.dart'; import 'package:dmc_app/transport/flight_controller_link.dart'; TelemetryFrame _frame({ int batteryPercent = 80, int navMode = 0, bool hasFix = true, int numSat = 10, }) { return TelemetryFrame( lat: 52.5, lon: 13.4, hasFix: hasFix, numSat: numSat, altitudeM: 100, gpsAltitudeM: 100, speedMs: 15, headingDeg: 0, armed: true, batteryPercent: batteryPercent, batteryVoltage: 22.0, currentA: 10.0, linkQuality: 90, snrDb: 5, hdop: 1.0, navMode: navMode, flightMode: 'Idle', sensorStatusBits: 0, temperaturesC: const [null, null, null], verticalSpeedMs: 0, ); } void main() { final now = DateTime(2026, 1, 1, 12, 0, 0); group('detectSystemMessages - battery', () { test('kein Ereignis ohne vorherigen Frame', () { final events = detectSystemMessages( previous: null, current: _frame(batteryPercent: 15), now: now, ); expect(events, isEmpty); }); test('kein Ereignis, solange keine Schwelle unterschritten wird', () { final events = detectSystemMessages( previous: _frame(batteryPercent: 80), current: _frame(batteryPercent: 75), now: now, ); expect(events, isEmpty); }); test('"Battery low" beim Unterschreiten von 30%', () { final events = detectSystemMessages( previous: _frame(batteryPercent: 32), current: _frame(batteryPercent: 28), now: now, ); expect(events, hasLength(1)); expect(events.single.severity, SystemMessageSeverity.warning); expect(events.single.message, contains('Battery low')); }); test('"Battery critical" beim Unterschreiten von 20%', () { final events = detectSystemMessages( previous: _frame(batteryPercent: 22), current: _frame(batteryPercent: 18), now: now, ); expect(events, hasLength(1)); expect(events.single.severity, SystemMessageSeverity.critical); expect(events.single.message, contains('Battery critical')); }); test('nur "Battery critical", wenn beide Schwellen im selben Schritt fallen', () { final events = detectSystemMessages( previous: _frame(batteryPercent: 35), current: _frame(batteryPercent: 15), now: now, ); expect(events, hasLength(1)); expect(events.single.message, contains('Battery critical')); }); test('kein erneutes Ereignis, solange der Ladestand unter der Schwelle bleibt', () { final events = detectSystemMessages( previous: _frame(batteryPercent: 25), current: _frame(batteryPercent: 22), now: now, ); expect(events, isEmpty); }); }); group('detectSystemMessages - failsafe', () { test('"Failsafe mode activated" beim Wechsel in Emergency (navMode 15)', () { final events = detectSystemMessages( previous: _frame(navMode: 3), current: _frame(navMode: 15), now: now, ); expect(events, hasLength(1)); expect(events.single.severity, SystemMessageSeverity.critical); expect(events.single.message, 'Failsafe mode activated'); }); test('kein erneutes Ereignis, solange Emergency anhaelt', () { final events = detectSystemMessages( previous: _frame(navMode: 15), current: _frame(navMode: 15), now: now, ); expect(events, isEmpty); }); }); group('detectSystemMessages - GPS fix', () { test('kein Ereignis ohne vorherigen Frame, auch wenn hasFix true ist', () { final events = detectSystemMessages( previous: null, current: _frame(hasFix: true, numSat: 9), now: now, ); expect(events, isEmpty); }); test('"GPS fix acquired" beim Uebergang von keinem zu einem Fix', () { final events = detectSystemMessages( previous: _frame(hasFix: false, numSat: 2), current: _frame(hasFix: true, numSat: 9), now: now, ); expect(events, hasLength(1)); expect(events.single.severity, SystemMessageSeverity.info); expect(events.single.message, 'GPS fix acquired (9 satellites)'); }); test('kein Ereignis, solange der Fix bereits vorher bestand', () { final events = detectSystemMessages( previous: _frame(hasFix: true, numSat: 8), current: _frame(hasFix: true, numSat: 11), now: now, ); expect(events, isEmpty); }); test('kein Ereignis beim Verlust des Fixes', () { final events = detectSystemMessages( previous: _frame(hasFix: true, numSat: 8), current: _frame(hasFix: false, numSat: 3), now: now, ); expect(events, isEmpty); }); }); }