diff --git a/flutter_client/test/library/widgets_smoke_test.dart b/flutter_client/test/library/widgets_smoke_test.dart index 599dba58..56e39a8b 100644 --- a/flutter_client/test/library/widgets_smoke_test.dart +++ b/flutter_client/test/library/widgets_smoke_test.dart @@ -1,7 +1,10 @@ +import 'package:drift/native.dart' show NativeDatabase; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:minstrel/cache/audio_cache_manager.dart' show appDbProvider; +import 'package:minstrel/cache/db.dart'; import 'package:minstrel/library/widgets/album_card.dart'; import 'package:minstrel/library/widgets/track_row.dart'; import 'package:minstrel/models/album.dart'; @@ -29,9 +32,20 @@ void main() { }); testWidgets('TrackRow shows mm:ss duration', (tester) async { - // TrackRow now contains CachedIndicator (ConsumerWidget) so a - // ProviderScope is required at the root. + // TrackRow contains CachedIndicator (ConsumerWidget) which reaches + // audioCacheManagerProvider → appDbProvider. Override appDbProvider + // with an explicit NativeDatabase.memory() executor — drift_flutter's + // default `driftDatabase()` schedules a deferred-init Timer that + // outlives the test widget tree and trips + // _verifyInvariants("A Timer is still pending after dispose"). await tester.pumpWidget(ProviderScope( + overrides: [ + appDbProvider.overrideWith((ref) { + final db = AppDb(NativeDatabase.memory()); + ref.onDispose(db.close); + return db; + }), + ], child: MaterialApp( theme: buildThemeData(), home: Scaffold( diff --git a/flutter_client/test/likes/like_button_test.dart b/flutter_client/test/likes/like_button_test.dart index 55e4a4ed..8976904d 100644 --- a/flutter_client/test/likes/like_button_test.dart +++ b/flutter_client/test/likes/like_button_test.dart @@ -9,6 +9,7 @@ import 'package:minstrel/models/album.dart'; import 'package:minstrel/models/artist.dart'; import 'package:minstrel/models/page.dart'; import 'package:minstrel/models/track.dart'; +import 'package:minstrel/shared/widgets/lucide_heart.dart'; import 'package:minstrel/theme/theme_data.dart'; class _ThrowingLikesApi implements LikesApi { @@ -62,10 +63,16 @@ void main() { )); await tester.pumpAndSettle(); - // First tap = like; succeeds → icon flips to favorite. + // Helper: read the current heart-fill state straight off the widget. + // LikeButton renders LucideHeart(filled: ), so the assertion + // is "the LucideHeart in the tree is filled" not "find an Icon." + bool heartFilled() => + tester.widget(find.byType(LucideHeart)).filled; + + // First tap = like; succeeds → heart flips to filled. await tester.tap(find.byType(IconButton)); await tester.pump(); - expect(find.byIcon(Icons.favorite), findsOneWidget); + expect(heartFilled(), isTrue); // Force the next mutation to fail; rollback restores prior state. api.throwOnNext = true; @@ -74,6 +81,6 @@ void main() { await controller.toggle(LikeKind.album, 'al-1'); } catch (_) {/* expected */} await tester.pump(); - expect(find.byIcon(Icons.favorite), findsOneWidget); // rolled back + expect(heartFilled(), isTrue); // rolled back to liked }); }