import 'package:flutter_test/flutter_test.dart'; import 'package:nontonki/core/data/models/drama.dart'; import 'package:nontonki/core/data/repositories/watch_history_repository.dart'; import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart'; import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart'; void main() { test('resume position clamps invalid and completed values', () { const duration = Duration(seconds: 8); expect( clampResumePosition(const Duration(seconds: -1), duration), Duration.zero, ); expect( clampResumePosition(const Duration(seconds: 3), duration), const Duration(seconds: 3), ); expect( clampResumePosition(const Duration(seconds: 9), duration), Duration.zero, ); expect( clampResumePosition(const Duration(milliseconds: 7700), duration), Duration.zero, ); }); test('watch history is scoped by profile, drama and episode', () async { SharedPreferencesAsyncPlatform.instance = InMemorySharedPreferencesAsync.empty(); final history = SharedPreferencesWatchHistoryRepository(); await history.save( 'profile-a', 'drama-a', 'episode-1', const Duration(seconds: 3), ); await history.save( 'profile-a', 'drama-a', 'episode-2', const Duration(seconds: 5), ); expect( await history.positionFor('profile-a', 'drama-a', 'episode-1'), const Duration(seconds: 3), ); expect( await history.positionFor('profile-b', 'drama-a', 'episode-1'), isNull, ); expect(await history.lastEpisodeId('profile-a', 'drama-a'), 'episode-2'); expect(await history.lastEpisodeId('profile-a', 'drama-b'), isNull); }); test('resume prefers the first loaded episode', () async { SharedPreferencesAsyncPlatform.instance = InMemorySharedPreferencesAsync.empty(); final history = SharedPreferencesWatchHistoryRepository(); await history.save( 'profile-a', 'drama-a', 'episode-1', const Duration(seconds: 3), ); await history.save( 'profile-a', 'drama-a', 'episode-2', const Duration(seconds: 5), ); final drama = Drama( id: 'drama-a', title: 'title', synopsis: 'synopsis', posterUrl: '', episodes: const [ Episode(id: 'episode-1', number: 1, title: 'E1', isFree: true), Episode(id: 'episode-2', number: 2, title: 'E2', isFree: true), ], ); expect( await history.resumePositionFor('profile-a', drama), const Duration(seconds: 3), ); }); test('resume falls back to the last watched episode for a list card', () async { SharedPreferencesAsyncPlatform.instance = InMemorySharedPreferencesAsync.empty(); final history = SharedPreferencesWatchHistoryRepository(); await history.save( 'profile-a', 'drama-a', 'episode-2', const Duration(seconds: 5), ); const card = Drama( id: 'drama-a', title: 'title', synopsis: 'synopsis', posterUrl: '', totalEpisodes: 12, ); expect( await history.resumePositionFor('profile-a', card), const Duration(seconds: 5), ); }); test('a list card with no history has no resume position', () async { SharedPreferencesAsyncPlatform.instance = InMemorySharedPreferencesAsync.empty(); final history = SharedPreferencesWatchHistoryRepository(); const card = Drama( id: 'drama-b', title: 'title', synopsis: 'synopsis', posterUrl: '', totalEpisodes: 12, ); expect(await history.resumePositionFor('profile-a', card), isNull); }); }