7dfdbf1159
8 Tests mit dem offiziellen SharedPreferences-In-Memory-Mock: BoolPref, StringSetPref, Theme-Prefs (Roundtrip/Teil-Save), Server-Banner inkl. korruptes-JSON-Fehlerpfad. Sichert die Schnittstelle ab, die beim M2-Storage-Umbau zur Pflicht-Fassade wird. Alle 22 Tests grün auf dem Pi. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
104 lines
3.7 KiB
Dart
104 lines
3.7 KiB
Dart
import 'package:flutter_test/flutter_test.dart';
|
||
import 'package:pyramid/core/settings_prefs.dart';
|
||
import 'package:shared_preferences/shared_preferences.dart';
|
||
|
||
/// Tests für die Storage-Fassade, die laut M2-Modulschnitt zur Pflicht-
|
||
/// Schnittstelle für alle Einstellungs-Zugriffe ausgebaut werden soll –
|
||
/// dieses Vertragsnetz muss bei dem Umbau stehen bleiben.
|
||
void main() {
|
||
TestWidgetsFlutterBinding.ensureInitialized();
|
||
|
||
setUp(() {
|
||
// Frischer In-Memory-Store pro Test (setzt auch die gecachte
|
||
// SharedPreferences-Instanz zurück).
|
||
SharedPreferences.setMockInitialValues({});
|
||
});
|
||
|
||
group('BoolPref', () {
|
||
test('lädt persistierten Wert und überstimmt damit den Default', () async {
|
||
SharedPreferences.setMockInitialValues({'notif_sound': false});
|
||
final pref = BoolPref('notif_sound', true);
|
||
expect(pref.state, true, reason: 'Default gilt, bis geladen ist');
|
||
await pumpEventQueue();
|
||
expect(pref.state, false, reason: 'persistierter Wert muss gewinnen');
|
||
});
|
||
|
||
test('set/toggle ändern Zustand und persistieren', () async {
|
||
final pref = BoolPref('notif_desktop', true);
|
||
await pumpEventQueue();
|
||
pref.toggle();
|
||
await pumpEventQueue();
|
||
expect(pref.state, false);
|
||
final p = await SharedPreferences.getInstance();
|
||
expect(p.getBool('notif_desktop'), false);
|
||
});
|
||
});
|
||
|
||
group('StringSetPref', () {
|
||
test('lädt persistierte Liste als Set, add/remove persistieren', () async {
|
||
SharedPreferences.setMockInitialValues({
|
||
'muted_rooms': ['!a:hs', '!b:hs'],
|
||
});
|
||
final pref = StringSetPref('muted_rooms');
|
||
await pumpEventQueue();
|
||
expect(pref.state, {'!a:hs', '!b:hs'});
|
||
|
||
await pref.add('!c:hs');
|
||
await pref.remove('!a:hs');
|
||
final p = await SharedPreferences.getInstance();
|
||
expect(p.getStringList('muted_rooms')!.toSet(), {'!b:hs', '!c:hs'});
|
||
});
|
||
|
||
test('doppeltes add und remove von Fehlendem sind No-Ops', () async {
|
||
final pref = StringSetPref('muted_rooms');
|
||
await pumpEventQueue();
|
||
await pref.add('!a:hs');
|
||
await pref.add('!a:hs');
|
||
await pref.remove('!gibtsnicht:hs');
|
||
expect(pref.state, {'!a:hs'});
|
||
});
|
||
});
|
||
|
||
group('Theme-Prefs', () {
|
||
test('leerer Store liefert die dokumentierten Defaults', () async {
|
||
final t = await loadThemePrefs();
|
||
expect(t.isDark, true);
|
||
expect(t.accentIdx, 0);
|
||
expect(t.radius, 12.0);
|
||
expect(t.motion, 1.0);
|
||
});
|
||
|
||
test('Roundtrip: gespeicherte Werte kommen zurück, Teil-Save lässt '
|
||
'den Rest unangetastet', () async {
|
||
await saveThemePrefs(isDark: false, accentIdx: 3, radius: 8, motion: 0.5);
|
||
var t = await loadThemePrefs();
|
||
expect((t.isDark, t.accentIdx, t.radius, t.motion), (false, 3, 8.0, 0.5));
|
||
|
||
// Nur ein Feld ändern – die anderen dürfen nicht zurückfallen.
|
||
await saveThemePrefs(accentIdx: 1);
|
||
t = await loadThemePrefs();
|
||
expect((t.isDark, t.accentIdx, t.radius, t.motion), (false, 1, 8.0, 0.5));
|
||
});
|
||
});
|
||
|
||
group('Server-Banner', () {
|
||
test('Roundtrip + Entfernen per null/leerem mxcUri', () async {
|
||
await saveServerBanner('https://hs1', 'mxc://hs1/abc');
|
||
await saveServerBanner('https://hs2', 'mxc://hs2/def');
|
||
expect(await loadAllServerBanners(),
|
||
{'https://hs1': 'mxc://hs1/abc', 'https://hs2': 'mxc://hs2/def'});
|
||
|
||
await saveServerBanner('https://hs1', null);
|
||
await saveServerBanner('https://hs2', '');
|
||
expect(await loadAllServerBanners(), isEmpty);
|
||
});
|
||
|
||
test('korruptes JSON im Store crasht nicht, sondern liefert leere Map',
|
||
() async {
|
||
SharedPreferences.setMockInitialValues(
|
||
{'server_banners': '{kein json'});
|
||
expect(await loadAllServerBanners(), isEmpty);
|
||
});
|
||
});
|
||
}
|