import 'package:block_seasons/data/save_repository.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; void main() { TestWidgetsFlutterBinding.ensureInitialized(); Future freshRepo() async { SharedPreferences.setMockInitialValues({}); return SaveRepository(await SharedPreferences.getInstance()); } test('starts empty: no progress, zero stars, first stage unlocked', () async { final repo = await freshRepo(); expect(repo.progressFor('season_001', 's1'), isNull); expect(repo.totalStars('season_001'), 0); expect(repo.highestUnlockedIndex('season_001', ['s1', 's2', 's3']), 0); }); test('records results and keeps the best', () async { final repo = await freshRepo(); await repo.recordResult( seasonId: 'season_001', stageId: 's1', stars: 2, score: 500); await repo.recordResult( seasonId: 'season_001', stageId: 's1', stars: 1, score: 900); final progress = repo.progressFor('season_001', 's1')!; expect(progress.stars, 2, reason: 'stars never downgrade'); expect(progress.bestScore, 900, reason: 'best score upgrades'); }); test('unlock walks forward through starred stages', () async { final repo = await freshRepo(); final ids = ['s1', 's2', 's3', 's4']; await repo.recordResult( seasonId: 'season_001', stageId: 's1', stars: 1, score: 100); await repo.recordResult( seasonId: 'season_001', stageId: 's2', stars: 3, score: 300); expect(repo.highestUnlockedIndex('season_001', ids), 2); // Completing the last stage caps the index at the end of the list. await repo.recordResult( seasonId: 'season_001', stageId: 's3', stars: 1, score: 1); await repo.recordResult( seasonId: 'season_001', stageId: 's4', stars: 1, score: 1); expect(repo.highestUnlockedIndex('season_001', ids), 3); }); test('totals stars per season independently', () async { final repo = await freshRepo(); await repo.recordResult( seasonId: 'season_001', stageId: 's1', stars: 2, score: 1); await repo.recordResult( seasonId: 'season_001', stageId: 's2', stars: 3, score: 1); await repo.recordResult( seasonId: 'season_002', stageId: 's1', stars: 1, score: 1); expect(repo.totalStars('season_001'), 5); expect(repo.totalStars('season_002'), 1); }); test('persists across repository instances', () async { SharedPreferences.setMockInitialValues({}); final prefs = await SharedPreferences.getInstance(); final first = SaveRepository(prefs); await first.recordResult( seasonId: 'season_001', stageId: 's1', stars: 3, score: 777); final second = SaveRepository(prefs); expect(second.progressFor('season_001', 's1')!.stars, 3); expect(second.progressFor('season_001', 's1')!.bestScore, 777); }); group('tutorial flag and endless best', () { test('defaults: tutorial not done, endless best 0', () async { SharedPreferences.setMockInitialValues({}); final repo = SaveRepository(await SharedPreferences.getInstance()); expect(repo.tutorialDone, isFalse); expect(repo.endlessBest, 0); }); test('markTutorialDone persists across reload', () async { SharedPreferences.setMockInitialValues({}); final prefs = await SharedPreferences.getInstance(); await SaveRepository(prefs).markTutorialDone(); expect(SaveRepository(prefs).tutorialDone, isTrue); }); test('recordEndlessScore keeps the max', () async { SharedPreferences.setMockInitialValues({}); final prefs = await SharedPreferences.getInstance(); final repo = SaveRepository(prefs); await repo.recordEndlessScore(500); await repo.recordEndlessScore(300); expect(repo.endlessBest, 500); expect(SaveRepository(prefs).endlessBest, 500); }); test('legacy blob without new keys still loads', () async { SharedPreferences.setMockInitialValues({ 'save_v1': '{"saveVersion":1,"progress":{},"streak":{"current":0,"best":0,"lastYmd":null}}', }); final repo = SaveRepository(await SharedPreferences.getInstance()); expect(repo.tutorialDone, isFalse); expect(repo.endlessBest, 0); }); }); }