import 'package:block_seasons/data/save_repository.dart'; import 'package:block_seasons/state/providers.dart'; import 'package:block_seasons/state/tutorial_notifier.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; void main() { late ProviderContainer container; late SaveRepository repo; setUp(() async { SharedPreferences.setMockInitialValues({}); repo = SaveRepository(await SharedPreferences.getInstance()); container = ProviderContainer( overrides: [saveRepositoryProvider.overrideWithValue(repo)], ); }); tearDown(() => container.dispose()); test('inactive by default', () { expect(container.read(tutorialProvider), isNull); }); test('happy path: drag -> clear -> hud -> done, persists flag', () async { final n = container.read(tutorialProvider.notifier); n.start(); expect(container.read(tutorialProvider), TutorialStep.dragPiece); n.onPlaced(); expect(container.read(tutorialProvider), TutorialStep.clearLine); n.onLineCleared(); expect(container.read(tutorialProvider), TutorialStep.explainHud); await n.dismissHud(); expect(container.read(tutorialProvider), isNull); expect(repo.tutorialDone, isTrue); }); test('out-of-order events are ignored', () { final n = container.read(tutorialProvider.notifier); n.start(); n.onLineCleared(); // not in clearLine step yet expect(container.read(tutorialProvider), TutorialStep.dragPiece); }); test('skip finishes from any step and persists', () async { final n = container.read(tutorialProvider.notifier); n.start(); await n.skip(); expect(container.read(tutorialProvider), isNull); expect(repo.tutorialDone, isTrue); }); test('start is a no-op when tutorial already done', () async { await repo.markTutorialDone(); final n = container.read(tutorialProvider.notifier); n.start(); expect(container.read(tutorialProvider), isNull); }); }