607278928b
Pure advanceStreak (1-day grace none, milestone flags at 3/7/14/30), persisted in the save blob; StreakNotifier advances on every finished attempt; home screen flame chip and milestone snackbar. Fix flutter create's camelCased iOS bundle id and underscored Android application id to the agreed lowercase form before any store registration. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
39 lines
1.5 KiB
Dart
39 lines
1.5 KiB
Dart
import 'package:block_seasons/data/save_repository.dart';
|
|
import 'package:block_seasons/state/providers.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
test('onStagePlayed advances, persists, and surfaces milestones', () async {
|
|
SharedPreferences.setMockInitialValues({});
|
|
final prefs = await SharedPreferences.getInstance();
|
|
final repo = SaveRepository(prefs);
|
|
final container = ProviderContainer(
|
|
overrides: [saveRepositoryProvider.overrideWithValue(repo)],
|
|
);
|
|
addTearDown(container.dispose);
|
|
|
|
final notifier = container.read(streakProvider.notifier);
|
|
expect(container.read(streakProvider).current, 0);
|
|
|
|
await notifier.onStagePlayed(DateTime(2026, 6, 11));
|
|
await notifier.onStagePlayed(DateTime(2026, 6, 12));
|
|
await notifier.onStagePlayed(DateTime(2026, 6, 13));
|
|
|
|
final state = container.read(streakProvider);
|
|
expect(state.current, 3);
|
|
expect(state.hitMilestone, 3);
|
|
|
|
// Persisted: a fresh repository over the same prefs sees the streak.
|
|
expect(SaveRepository(prefs).streak.current, 3);
|
|
|
|
// Same-day replays neither grow nor re-flag.
|
|
await notifier.onStagePlayed(DateTime(2026, 6, 13, 22));
|
|
expect(container.read(streakProvider).current, 3);
|
|
expect(container.read(streakProvider).hitMilestone, isNull);
|
|
});
|
|
}
|