import 'package:drift/drift.dart' show Value; import 'package:drift/native.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:mews/application/controllers/reader_settings_controller.dart'; import 'package:mews/database/database.dart'; import 'package:mews/mews/document.dart'; void main() { late MewsDatabase db; setUp(() { db = MewsDatabase.test(NativeDatabase.memory()); }); tearDown(() async { await db.close(); }); test('settings round-trip through the database', () async { final settings = ReaderSettingsController(db); await settings.setFont('Atkinson Hyperlegible'); await settings.increaseSize(); await settings.setThemeMode('dark'); await settings.setVariant('warm'); final reloaded = ReaderSettingsController(db); await reloaded.load(); expect(reloaded.font.value, 'Atkinson Hyperlegible'); expect(reloaded.fontScale.value, 1.125); expect(reloaded.themeMode.value, 'dark'); expect(reloaded.variant.value, 'warm'); }); test('text size stays within its limits', () async { final settings = ReaderSettingsController(db); for (var i = 0; i < 30; i++) { await settings.increaseSize(); } expect(settings.fontScale.value, ReaderSettingsController.maxScale); for (var i = 0; i < 40; i++) { await settings.decreaseSize(); } expect(settings.fontScale.value, ReaderSettingsController.minScale); }); test('bookmarks toggle and persist', () async { final library = LibraryController(db); await library.load(); await library.toggleBookmark('https://example.com/', 'Example'); expect(library.isBookmarked('https://example.com/'), isTrue); final reloaded = LibraryController(db); await reloaded.load(); expect(reloaded.isBookmarked('https://example.com/'), isTrue); await reloaded.toggleBookmark('https://example.com/', 'Example'); expect(reloaded.isBookmarked('https://example.com/'), isFalse); }); test('subscription refresh reports only unseen entries', () async { final library = LibraryController(db); await library.load(); final firstPost = MewsEntry( url: 'https://example.com/a.html', date: DateTime(2026, 9, 21), title: 'First post'); await library.toggleSubscription( 'https://example.com/', 'Example', [firstPost]); expect(library.isSubscribed('https://example.com/'), isTrue); // Nothing new yet. await library.refreshSubscription(_page('https://example.com/', [firstPost])); expect(library.newEntries.value['https://example.com/'], isNull); // A new post appears. final newPost = MewsEntry( url: 'https://example.com/b.html', date: DateTime(2026, 10, 8), title: 'Second post'); await library.refreshSubscription(_page('https://example.com/', [newPost, firstPost])); final fresh = library.newEntries.value['https://example.com/']!; expect(fresh, hasLength(1)); expect(fresh.single.url, 'https://example.com/b.html'); // The refresh stored it; a repeat refresh reports nothing. await library.refreshSubscription(_page('https://example.com/', [newPost, firstPost])); expect(library.newEntries.value['https://example.com/'], isNull); }); test('caches pages for offline reopening', () async { await db.saveCachedPage(CachedPagesCompanion.insert( url: 'https://example.com/page.html', source: 'html', title: const Value('Page'), etag: const Value('"v1"'), )); final cached = await db.cachedPage('https://example.com/page.html'); expect(cached!.source, 'html'); expect(cached.etag, '"v1"'); expect(cached.title, 'Page'); }); test('records history and returns the last visited page', () async { await db.recordVisit('https://a.example/', 'A'); await db.recordVisit('https://b.example/', 'B'); expect(await db.lastVisitedUrl(), 'https://b.example/'); }); } MewsPage _page(String url, List entries) => MewsPage( url: url, body: const [], lang: 'en', direction: TextDirection.ltr, variant: MewsVariant.plain, entries: entries, specVersion: '0.1', );