JJ_MKVMaker/test/browser_modules_contract_te...

117 lines
5.1 KiB
Dart

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 = <String>[];
@override
Future<void> load(String url) async => calls.add('load $url');
@override
Future<void> back() async => calls.add('back');
@override
Future<void> forward() async => calls.add('forward');
@override
Future<void> reload() async => calls.add('reload');
@override
Future<void> stop() async => calls.add('stop');
@override
Future<void> exportCookies() async => calls.add('cookies');
@override
Future<void> pauseMedia() async => calls.add('pause');
@override
Future<void> runScript(String js) async => calls.add('run $js');
@override
Future<void> clearData() async => calls.add('clear');
@override
Future<Object?> evaluate(String js) async {
calls.add('eval $js');
return 7;
}
@override
Future<void> 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 = <Object>[];
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<void>.delayed(Duration.zero);
expect(nav.calls, isEmpty, reason: '화면이 가려졌거나 웹 주소가 아님');
can = true;
t.now();
await Future<void>.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]);
});
}