import 'dart:io'; import 'package:flutter_test/flutter_test.dart'; import 'package:jj_mkvmaker/app/net_guard.dart'; import 'package:jj_mkvmaker/core/download_detect.dart' show CookieExport, CookieRecord; import 'package:jj_mkvmaker/core/web_translate.dart' show webTranslateRestoreScript; import 'package:jj_mkvmaker/ui/browser/dns_block.dart'; import 'package:jj_mkvmaker/ui/browser/page_translation.dart'; import 'package:jj_mkvmaker/ui/browser/web_nav.dart'; import 'package:path/path.dart' as p; /// 받은 조작을 적어 두는 WebNav (NavWatch 가 무엇을 그대로 넘기는지 보려고) class _Log implements WebNav { final calls = []; @override Future load(String url) async => calls.add('load $url'); @override Future back() async => calls.add('back'); @override Future forward() async => calls.add('forward'); @override Future reload() async => calls.add('reload'); @override Future stop() async => calls.add('stop'); @override Future exportCookies() async => calls.add('cookies'); @override Future pauseMedia() async => calls.add('pause'); @override Future runScript(String js) async => calls.add('run $js'); @override Future clearData() async => calls.add('clear'); @override Future evaluate(String js) async { calls.add('eval $js'); return 7; } @override Future setJavaScript(bool on) async => calls.add('js $on'); } void main() { test('약속 NavWatch: 사용자가 옮길 때 (주소 · 뒤로 · 앞으로 · 새로고침) 만 알리고, 모든 조작은 그대로 넘긴다', () async { final inner = _Log(); var moved = 0; final w = NavWatch(inner, () => moved++); await w.load('https://a.example/'); await w.back(); await w.forward(); await w.reload(); expect(moved, 4); await w.stop(); await w.exportCookies(); await w.pauseMedia(); await w.runScript('x'); await w.clearData(); expect(await w.evaluate('y'), 7); await w.setJavaScript(false); expect(moved, 4, reason: '멈춤 · 쿠키 · 스크립트 등은 페이지를 옮기지 않는다'); expect(inner.calls, ['load https://a.example/', 'back', 'forward', 'reload', 'stop', 'cookies', 'pause', 'run x', 'clear', 'eval y', 'js false']); }); test('약속 writeLoginCookies · deleteExportedCookies: cookies.txt 를 한 번에 바꿔 넣고, 지우면 임시 파일까지 없앤다', () async { final dir = await Directory.systemTemp.createTemp('jj_cookie_'); addTearDown(() => dir.delete(recursive: true)); final file = File(p.join(dir.path, CookieExport.fileName)); await writeLoginCookies(dir.path, const []); expect(file.existsSync(), isFalse, reason: '쿠키가 없으면 쓰지 않는다'); await writeLoginCookies('', [const CookieRecord(name: 'a', value: 'b', domain: '.youtube.com')]); await writeLoginCookies(dir.path, [const CookieRecord(name: 'SID', value: 'v1', domain: '.youtube.com', expires: 0)]); expect(file.readAsStringSync(), contains('SID\tv1')); expect(File('${file.path}.tmp').existsSync(), isFalse, reason: '임시 파일은 바꿔 넣은 뒤 남지 않는다'); File('${file.path}.tmp').writeAsStringSync('half'); await deleteExportedCookies(dir.path); expect([file.existsSync(), File('${file.path}.tmp').existsSync()], [false, false]); await deleteExportedCookies(''); // 데이터 폴더가 없으면 아무것도 안 함 }); test('약속 PageTranslation: 꺼져 있거나 할 수 없을 때는 페이지를 건드리지 않고, 끄면 원문으로 되돌린다', () async { final nav = _Log(); var can = false; final gaveUp = []; final t = PageTranslation(on: false, nav: () => nav, canRun: () => can, onGiveUp: gaveUp.add); addTearDown(t.dispose); t.now(); expect(nav.calls, isEmpty, reason: '꺼져 있음'); t.setOn(true, force: true); expect([t.on, t.force], [true, true]); await Future.delayed(Duration.zero); expect(nav.calls, isEmpty, reason: '화면이 가려졌거나 웹 주소가 아님'); can = true; t.now(); await Future.delayed(Duration.zero); expect(nav.calls.where((c) => c.startsWith('eval ')).length, 1, reason: '모을 글자를 한 번 묻는다 (받은 값이 글자 묶음이 아니면 멈춤)'); nav.calls.clear(); t.setOn(false, force: true); expect([t.on, t.force], [false, false]); expect(nav.calls, ['eval $webTranslateRestoreScript']); expect(gaveUp, isEmpty); }); test('약속 DnsBlockWatch: 실패 기록이 없으면 막지 않고, 덮개가 있는 동안만 아래 알림을 막는다', () { final w = DnsBlockWatch(); final g = NetGuard.instance.noticeBlockers; final before = g.value; expect(w.find(host: ''), isNull); expect(w.find(host: 'never-failed.example'), isNull); w.set(('a.example', '8.8.8.8')); w.set(('b.example', '8.8.8.8')); expect([w.blocked, g.value], [('b.example', '8.8.8.8'), before + 1], reason: '덮개를 바꿔도 한 번만 막는다'); w.set(null); expect([w.blocked, g.value], [null, before]); }); }