JJ_MKVMaker/test/monitor_modules_test.dart

107 lines
5.3 KiB
Dart

// 모니터링 모듈 (lib/ui/monitor/) 의 약속 시험. 실제 AppController (settingsStore 없음 - 사용자 설정 저장소를 쓰지 않음) ·
// 실제 시험 폴더 · 실제 위젯으로 확인한다.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:jj_mkvmaker/app/app_controller.dart';
import 'package:jj_mkvmaker/app/copy_center.dart';
import 'package:jj_mkvmaker/app/settings.dart';
import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart';
import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
import 'package:jj_mkvmaker/services/platform_services.dart';
import 'package:jj_mkvmaker/ui/monitor/copy_task_card.dart';
import 'package:jj_mkvmaker/ui/monitor/live_pair_card.dart';
import 'package:jj_mkvmaker/ui/monitor/live_sync_flow.dart';
import 'package:jj_mkvmaker/ui/monitor/transfer_widgets.dart';
import 'package:path/path.dart' as p;
AppController _controller() =>
AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
void main() {
late Directory tmp;
setUp(() => tmp = Directory.systemTemp.createTempSync('jj_monmod_'));
tearDown(() => tmp.deleteSync(recursive: true));
test('transfer_widgets: formatRunStamp 는 날짜면 "M/D HH:MM", 아니면 빈 글', () {
expect(formatRunStamp('2026-10-22T09:05:00'), '10/22 09:05');
expect(formatRunStamp('x'), '');
expect(formatRunStamp(''), '');
});
testWidgets('transfer_widgets: PruneChoice 는 고른 값을 돌려주고, allowNone 일 때만 "그대로" 칩', (tester) async {
String? got;
await tester.pumpWidget(MaterialApp(home: Scaffold(body: PruneChoice(value: 'keep', onChanged: (v) => got = v))));
expect(find.byType(ChoiceChip), findsNWidgets(2));
await tester.tap(find.text(pruneLabel('all')));
expect(got, 'all');
await tester.pumpWidget(MaterialApp(home: Scaffold(body: PruneChoice(value: '', allowNone: true, onChanged: (v) => got = v))));
expect(find.byType(ChoiceChip), findsNWidgets(3));
await tester.tap(find.text(pruneLabel('')));
expect(got, '');
});
testWidgets('transfer_widgets: DiskSpaceInfo 는 없는 경로면 있는 위 폴더의 디스크를 잰다', (tester) async {
await tester.pumpWidget(MaterialApp(home: Scaffold(body: DiskSpaceInfo(path: p.join(tmp.path, 'none', 'deeper')))));
await tester.runAsync(() => Future<void>.delayed(const Duration(seconds: 2)));
await tester.pump();
expect(find.textContaining('대상 디스크: 남은'), findsOneWidget);
});
test('live_sync_flow: replaceLiveSyncPair 는 같은 쌍만 바꾸고 순서는 그대로', () async {
final c = _controller();
final a = LiveSyncPair(p.join(tmp.path, 'a'), p.join(tmp.path, 'A'));
final b = LiveSyncPair(p.join(tmp.path, 'b'), p.join(tmp.path, 'B'));
final d = LiveSyncPair(p.join(tmp.path, 'd'), p.join(tmp.path, 'D'));
c.settings.liveSyncPairs = [a, b, d];
await replaceLiveSyncPair(c, b, b.copyWith(enabled: false));
expect(c.settings.liveSyncPairs.map((x) => x.source), [a.source, b.source, d.source]);
expect(c.settings.liveSyncPairs.map((x) => x.enabled), [true, false, true]);
});
testWidgets('copy_task_card: 작업이 없으면 안내, 있으면 작업마다 카드', (tester) async {
final c = _controller();
tester.view.physicalSize = const Size(1500, 1000);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset);
await tester.pumpWidget(MaterialApp(home: Scaffold(body: CopyTaskList(c: c))));
expect(find.textContaining('실행한 rsync 가 없습니다'), findsOneWidget);
await CopyCenter.of(c).remember([tmp.path], p.join(tmp.path, '..'), method: 'builtin');
await tester.pump();
expect(find.byType(CopyTaskCard), findsOneWidget);
expect(find.text('lsync 로 이동'), findsOneWidget);
});
testWidgets('live_pair_card: 화면 일은 부르는 쪽 콜백으로 (최종 정리 · 복사 목록으로)', (tester) async {
final c = _controller();
final x = LiveSyncPair(tmp.path, p.join(tmp.path, 'x'), method: 'builtin');
c.settings.liveSyncPairs = [x];
tester.view.physicalSize = const Size(1500, 1000);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset);
var finalize = 0, shown = 0;
await tester.pumpWidget(MaterialApp(
home: Scaffold(
body: ListView(children: [
LivePairCard(c: c, live: null, pair: x, onFinalize: () => finalize++, onShowCopyList: () => shown++),
]),
),
));
// live 가 없으면 세기 · 맞추기는 꺼짐
expect(tester.widget<FilledButton>(find.ancestor(of: find.text('지금 맞추기'), matching: find.byWidgetPredicate((w) => w is FilledButton))).onPressed, isNull);
await tester.tap(find.text('최종 정리'));
expect(finalize, 1);
// 스위치는 replaceLiveSyncPair 로 저장
await tester.tap(find.byType(Switch));
await tester.pump();
expect(c.settings.liveSyncPairs.single.enabled, isFalse);
// 복사 목록으로 옮기면 lsync 쌍은 빠지고 복사 작업이 생긴 뒤 부르는 쪽 콜백
await tester.tap(find.text('복사 · rsync 로 이동'));
await tester.pumpAndSettle();
expect(shown, 1);
expect(c.settings.liveSyncPairs, isEmpty);
expect(c.settings.copyTasks.single.dest, x.target);
});
}