From 3698048b26c940ebf2538e12ffb757d736c4ea5e Mon Sep 17 00:00:00 2001 From: Bernd Steckmeister Date: Mon, 6 Jul 2026 17:54:06 +0200 Subject: [PATCH] test: VoicePrefs-Fassade abgesichert - historische Keys, null/leer-Loeschen, Fallback 1.0 (3 neue Tests, gesamt 32) Nagelt den dokumentierten Vertrag der M2-Fassade (d22f9c2) fest, damit bestehende Nutzer-Einstellungen (Utas Geraet) bei weiteren Umbauten der Call-Schicht nachweislich erhalten bleiben. Co-Authored-By: Claude Fable 5 --- CHANGES.md | 1 + test/settings_prefs_test.dart | 49 +++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 21ac8ed..bd99a22 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1430,3 +1430,4 @@ 2026-07-06 17:51 [Edit] C:\Users\nordm\pyramid - Kopie\docs\M2_STATE_MANAGEMENT.md 2026-07-06 17:51 [Edit] C:\Users\nordm\pyramid - Kopie\docs\M2_STATE_MANAGEMENT.md 2026-07-06 17:51 [Edit] C:\Users\nordm\pyramid - Kopie\ROADMAP.md +2026-07-06 17:53 [Edit] C:\Users\nordm\pyramid - Kopie\test\settings_prefs_test.dart diff --git a/test/settings_prefs_test.dart b/test/settings_prefs_test.dart index 1981b92..af1f393 100644 --- a/test/settings_prefs_test.dart +++ b/test/settings_prefs_test.dart @@ -113,6 +113,55 @@ void main() { }); }); + group('VoicePrefs', () { + // Die Fassade (M2, 2026-07-06) hat drei dokumentierte Garantien: + // historische voice_*-Keys unverändert, null/leer = Pref löschen, + // Fallback-Lautstärke 1.0. Dieser Vertrag muss bei jedem weiteren + // Umbau der Call-Schicht stehen bleiben. + test('leerer Store: Geräte null (= System-Standard), Lautstärke 1.0', + () async { + final d = await VoicePrefs.loadDevices(); + expect((d.mic, d.speaker, d.camera), (null, null, null)); + expect(await VoicePrefs.loadOutputVolume(), 1.0); + }); + + test('liest die historischen voice_*-Keys – Bestands-Einstellungen ' + '(Utas Gerät!) bleiben nach dem Fassaden-Umbau erhalten', () async { + SharedPreferences.setMockInitialValues({ + 'voice_mic_device': 'mic-1', + 'voice_speaker_device': 'spk-1', + 'voice_camera_device': 'cam-1', + 'voice_output_volume': 0.4, + }); + final d = await VoicePrefs.loadDevices(); + expect((d.mic, d.speaker, d.camera), ('mic-1', 'spk-1', 'cam-1')); + expect(await VoicePrefs.loadOutputVolume(), 0.4); + }); + + test('Roundtrip unter denselben Keys; null/leer LÖSCHT das Pref', () async { + await VoicePrefs.saveMic('mic-2'); + await VoicePrefs.saveSpeaker('spk-2'); + await VoicePrefs.saveCamera('cam-2'); + await VoicePrefs.saveOutputVolume(0.75); + final p = await SharedPreferences.getInstance(); + // Key-Vertrag: exakt die historischen Keys, keine neuen Namen. + expect(p.getString('voice_mic_device'), 'mic-2'); + expect(p.getString('voice_speaker_device'), 'spk-2'); + expect(p.getString('voice_camera_device'), 'cam-2'); + expect(p.getDouble('voice_output_volume'), 0.75); + + await VoicePrefs.saveMic(null); + await VoicePrefs.saveSpeaker(''); + final d = await VoicePrefs.loadDevices(); + expect((d.mic, d.speaker, d.camera), (null, null, 'cam-2')); + expect(p.containsKey('voice_mic_device'), false, + reason: 'null muss das Pref löschen (System-Standard), ' + 'nicht einen leeren String speichern'); + expect(p.containsKey('voice_speaker_device'), false, + reason: 'leerer String zählt wie null'); + }); + }); + group('Server-Banner', () { test('Roundtrip + Entfernen per null/leerem mxcUri', () async { await saveServerBanner('https://hs1', 'mxc://hs1/abc');