From 1b66b5f573c8de883947d712057ff85f5513e8ae Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 21 May 2026 23:50:26 +0300 Subject: Implement offline progress queue with sqflite and connectivity_plus (3b) Introduces ProgressQueue backed by SQLite for offline-capable progress tracking, with ProgressQueueBase (LSP+DIP), databaseFactory injection (DIP), and ProgressSyncClient narrow interface (ISP). Co-Authored-By: Claude Sonnet 4.6 --- .../test/screens/audio_player_screen_test.dart | 26 +++++++++++++++++++ .../test/screens/video_player_screen_test.dart | 30 ++++++++++++++++++++++ 2 files changed, 56 insertions(+) (limited to 'player-android/test/screens') diff --git a/player-android/test/screens/audio_player_screen_test.dart b/player-android/test/screens/audio_player_screen_test.dart index a7af1fb..0c10177 100644 --- a/player-android/test/screens/audio_player_screen_test.dart +++ b/player-android/test/screens/audio_player_screen_test.dart @@ -39,8 +39,10 @@ import 'package:player_android/api/dio_client.dart'; import 'package:player_android/api/player_api_client.dart'; import 'package:player_android/providers/api_client_provider.dart'; import 'package:player_android/providers/audio_handler_provider.dart'; +import 'package:player_android/providers/progress_queue_provider.dart'; import 'package:player_android/screens/audio_player_screen.dart'; import 'package:player_android/services/audio_handler.dart'; +import 'package:player_android/services/progress_queue.dart'; // --------------------------------------------------------------------------- // Fakes @@ -99,6 +101,27 @@ class _FakeApiClient extends PlayerApiClient { 'http://localhost:8080/api/v1/media/$mediaId/stream'; } +/// No-op [ProgressQueueBase] stub for widget tests. +/// +/// Implements [ProgressQueueBase] directly rather than extending [ProgressQueue] +/// so no real SQLite database is opened and no connectivity subscription is +/// created in the test harness (Liskov Substitution — any [ProgressQueueBase] +/// can be injected wherever the interface is required). +class _FakeProgressQueue implements ProgressQueueBase { + @override + Future init() async {} // no-op — no DB needed in widget tests + + @override + Future enqueue( + int mediaId, + double positionSeconds, { + bool finished = false, + }) async {} // no-op — prevent SQLite calls in widget tests + + @override + Future dispose() async {} // no-op +} + /// A [PlayerAudioHandler] subclass that wraps a real [AudioPlayer] but /// overrides [setMediaItem] and playback methods to be no-ops so that no /// platform channels are invoked during widget tests. @@ -185,6 +208,9 @@ Future _pumpScreen( // Override audioHandlerProvider so no real AudioService or AudioPlayer // platform channels are invoked during widget tests. audioHandlerProvider.overrideWithValue(handler), + // Override progressQueueProvider so no real SQLite DB is opened and + // no connectivity subscription is created during widget tests. + progressQueueProvider.overrideWithValue(_FakeProgressQueue()), ], child: MaterialApp.router(routerConfig: router), ), diff --git a/player-android/test/screens/video_player_screen_test.dart b/player-android/test/screens/video_player_screen_test.dart index 8f24817..e2b34c0 100644 --- a/player-android/test/screens/video_player_screen_test.dart +++ b/player-android/test/screens/video_player_screen_test.dart @@ -31,7 +31,9 @@ import 'package:go_router/go_router.dart'; import 'package:player_android/api/dio_client.dart'; import 'package:player_android/api/player_api_client.dart'; import 'package:player_android/providers/api_client_provider.dart'; +import 'package:player_android/providers/progress_queue_provider.dart'; import 'package:player_android/screens/video_player_screen.dart'; +import 'package:player_android/services/progress_queue.dart'; // --------------------------------------------------------------------------- // Fakes @@ -101,6 +103,31 @@ class _FakeApiClient extends PlayerApiClient { 'http://localhost:8080/api/v1/media/$mediaId/stream'; } +// --------------------------------------------------------------------------- +// Fakes +// --------------------------------------------------------------------------- + +/// No-op [ProgressQueueBase] stub for widget tests. +/// +/// Implements [ProgressQueueBase] directly rather than extending [ProgressQueue] +/// so no real SQLite database is opened and no connectivity subscription is +/// created in the test harness (Liskov Substitution — any [ProgressQueueBase] +/// can be injected wherever the interface is required). +class _FakeProgressQueue implements ProgressQueueBase { + @override + Future init() async {} + + @override + Future enqueue( + int mediaId, + double positionSeconds, { + bool finished = false, + }) async {} + + @override + Future dispose() async {} +} + // --------------------------------------------------------------------------- // Helpers // --------------------------------------------------------------------------- @@ -137,6 +164,9 @@ Future _pumpScreen( overrides: [ tokenStorageProvider.overrideWithValue(const _FakeTokenStorage()), apiClientProvider.overrideWithValue(fakeClient), + // Override progressQueueProvider so no real SQLite DB is opened and + // no connectivity subscription is created during widget tests. + progressQueueProvider.overrideWithValue(_FakeProgressQueue()), ], child: MaterialApp.router(routerConfig: router), ), -- cgit v1.2.3