JJ_MKVMaker/integration_test/windows_magnet_shot_test.dart

93 lines
4.5 KiB
Dart

import 'dart:io';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import 'package:jj_mkvmaker/app/download_manager.dart';
import 'package:jj_mkvmaker/app/i18n_controller.dart';
import 'package:jj_mkvmaker/app/settings.dart';
import 'package:jj_mkvmaker/core/download_detect.dart';
import 'package:jj_mkvmaker/l10n/tr.dart';
import 'package:jj_mkvmaker/services/downloader.dart';
import 'package:jj_mkvmaker/ui/downloads_page.dart';
import 'package:jj_mkvmaker/ui/theme.dart';
import 'package:path/path.dart' as p;
/// 이름을 바꾸지 않는 가짜 백엔드 (아무것도 받지 않음 - 줄의 상태는 시험이 정한다)
class _Quiet implements DownloadBackend {
@override
final DownloadKind kind;
_Quiet(this.kind);
@override
Future<(String, List<PlaylistEntry>)?> expandPlaylist(String url) async => null;
@override
Future<void> start(DownloadTask t, void Function() changed) async {
t
..state = DownloadState.downloading
..progress = null;
changed();
}
@override
Future<void> pause(DownloadTask t) async => t.state = DownloadState.paused;
@override
Future<void> cancel(DownloadTask t) async => t.state = DownloadState.cancelled;
@override
Future<void> shutdown() async {}
}
/// 관리자 지시 (10/20, 28 확인): 마그넷 줄 - 메타데이터 전에도 dn 이름 · 멈춘 줄의 막대는 움직이지 않고 주황 "멈춤".
/// 크기 412 · 960, 언어 ko · en · ja 로 찍는다 (가짜 백엔드 - 아무것도 받지 않음).
/// 실행: flutter test integration_test\windows_magnet_shot_test.dart -d windows (JJ_SHOT_DIR 에 PNG)
void main() {
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
final out = Platform.environment['JJ_SHOT_DIR'] ?? p.join(Directory.systemTemp.path, 'jj_shots_magnet');
const h = 'magnet:?xt=urn:btih:0123456789abcdef0123456789abcdef0123456';
for (final lang in ['ko', 'en', 'ja']) {
for (final (w, hh) in [(412, 900), (960, 600)]) {
testWidgets('마그넷 줄 $lang ${w}x$hh', (t) async {
t.view.physicalSize = Size(w.toDouble(), hh.toDouble());
t.view.devicePixelRatio = 1;
addTearDown(t.view.reset);
await t.runAsync(() => i18n.apply(lang, save: false));
addTearDown(() => i18n.apply('ko', save: false));
final d = DownloadManager(
backends: [_Quiet(DownloadKind.video), _Quiet(DownloadKind.torrent)],
settings: () => AppSettings()..downloadRoot = r'D:\dl',
readClipboard: () async => null,
);
// ① 메타데이터를 받는 중 (dn 이름 · 움직이는 "준비 중…") ② 멈춤 (이유 후보 · [다시 시도]) ③ 이름이 없는 마그넷
d.add('${h}1&dn=${Uri.encodeQueryComponent('[시험] 아주 긴 이름의 토렌트 묶음 - Big Buck Bunny 1080p (2008) 한글 자막 포함')}&tr=udp%3A%2F%2Ft.example%3A80');
d.add('${h}2&dn=Ubuntu+24.04.1+Desktop+amd64&tr=udp%3A%2F%2Ft.example%3A80');
d.add('${h}3');
final stalled = d.tasks.firstWhere((x) => x.title.startsWith('Ubuntu'));
stalled.extra
..['stalled'] = true
..['stallSince'] = DateTime.now().millisecondsSinceEpoch - 75000
..['stallReasons'] = ['dns', 'firewall'];
d.useSystemDns = () async {};
final shotKey = GlobalKey();
await t.pumpWidget(RepaintBoundary(
key: shotKey,
child: MaterialApp(theme: buildTheme(), debugShowCheckedModeBanner: false, home: DownloadsPage(d: d)),
));
for (var i = 0; i < 6; i++) {
await t.runAsync(() => Future<void>.delayed(const Duration(milliseconds: 60)));
await t.pump(const Duration(milliseconds: 60));
}
expect(t.takeException(), isNull, reason: '넘침');
expect(find.textContaining('[시험] 아주 긴 이름'), findsOneWidget);
expect(find.textContaining('Ubuntu 24.04.1 Desktop amd64'), findsOneWidget);
expect(find.text(tr('멈춤')), findsOneWidget);
final b = shotKey.currentContext!.findRenderObject()! as RenderRepaintBoundary;
final img = await t.runAsync(() => b.toImage());
final bytes = await t.runAsync(() => img!.toByteData(format: ui.ImageByteFormat.png));
Directory(out).createSync(recursive: true);
File(p.join(out, 'magnet_${lang}_$w.png')).writeAsBytesSync(bytes!.buffer.asUint8List());
});
}
}
}