201 lines
10 KiB
Dart
201 lines
10 KiB
Dart
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/components.dart';
|
|
import 'package:jj_mkvmaker/app/net_guard.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/app_actions.dart';
|
|
import 'package:jj_mkvmaker/ui/component_settings.dart';
|
|
import 'package:jj_mkvmaker/ui/home_page.dart';
|
|
import 'package:jj_mkvmaker/ui/theme.dart';
|
|
|
|
AppController _plain() =>
|
|
AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
|
|
|
void main() {
|
|
test('컴포넌트: 설치한 화면만 순서대로 · 홈 화면은 제거되면 첫 화면 · 설정 저장', () {
|
|
final s = AppSettings();
|
|
expect(s.display.components, containsAll(['mkv', 'browser', 'explorer', 'rsync', 'downloads', 'viewer']));
|
|
expect(s.display.components, isNot(contains('docs'))); // 변환기를 받아야 하는 것은 처음엔 꺼짐
|
|
expect([for (final p in AppComponent.pages(s.display.components, s.display.navOrder)) p.id],
|
|
['mkv', 'browser', 'explorer', 'rsync', 'downloads', 'aiimage']);
|
|
s
|
|
..display.navOrder = ['explorer', 'mkv']
|
|
..display.components = ['mkv', 'explorer', 'downloads'];
|
|
expect([for (final p in AppComponent.pages(s.display.components, s.display.navOrder)) p.id], ['explorer', 'mkv', 'downloads']);
|
|
s.display.startScreen = 'browser'; // 제거한 화면 → 설치된 첫 화면
|
|
expect(AppNavButtons.homeId(s), 'explorer');
|
|
final back = AppSettings.fromJson(s.toJson());
|
|
expect(back.display.components, ['mkv', 'explorer', 'downloads']);
|
|
expect(back.display.navOrder, ['explorer', 'mkv']);
|
|
// 예전 설정 (컴포넌트 없음) 은 기본
|
|
expect(AppSettings.fromJson({}).display.components, AppComponent.defaultInstalled);
|
|
});
|
|
|
|
test('225: 이 판이 모르는 구성 요소 · 화면 id 는 지우지 않는다 (예전 판을 거쳐 다시 올려도 켠 것이 남게)', () {
|
|
final j = {'aiImageV1': true, 'components': ['mkv', 'browser', 'future_screen'], 'navOrder': ['browser', 'future_screen', 'mkv']};
|
|
final s = AppSettings.fromJson(j);
|
|
expect(s.display.components, ['mkv', 'browser', 'future_screen']);
|
|
expect(s.display.navOrder, ['browser', 'future_screen', 'mkv']);
|
|
// 화면 · 버튼에는 아는 것만
|
|
expect([for (final p in AppComponent.pages(s.display.components, s.display.navOrder)) p.id], ['browser', 'mkv']);
|
|
// 저장했다 다시 읽어도 그대로
|
|
final back = AppSettings.fromJson(s.toJson());
|
|
expect(back.display.components, contains('future_screen'));
|
|
expect(back.display.navOrder, contains('future_screen'));
|
|
// 순서 바꾸기 (explorer 를 맨 앞으로): future_screen 은 둘째 자리 그대로
|
|
expect(AppComponent.reorder(s.display.navOrder, ['explorer', 'mkv', 'browser']), ['explorer', 'future_screen', 'mkv', 'browser']);
|
|
// 예전 순서에 없던 아는 화면은 뒤에
|
|
expect(AppComponent.reorder(['future_screen', 'mkv'], ['mkv', 'explorer']), ['future_screen', 'mkv', 'explorer']);
|
|
});
|
|
|
|
testWidgets('249: DNS 서버에 닿지 않는 동안 MKV 화면의 작업 기록 위에 상태 줄 (기록을 숨겨도)', (tester) async {
|
|
tester.view.physicalSize = const Size(1500, 900);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
final g = NetGuard.instance;
|
|
addTearDown(() => g.failure.value = null);
|
|
final c = _plain();
|
|
await tester.pumpWidget(MaterialApp(
|
|
builder: (context, child) => AppScope(controller: c, child: child!),
|
|
home: HomePage(c: c),
|
|
));
|
|
expect(find.textContaining('에 닿지 않음'), findsNothing);
|
|
g.failure.value = DnsFailure('192.0.2.1', 'x', DateTime(2026, 10, 12, 1, 35));
|
|
await tester.pump();
|
|
expect(find.text('DNS 서버 (192.0.2.1) 에 닿지 않음 (01:35부터)'), findsOneWidget);
|
|
await c.updateSettings((s) => s.display.showLog = !s.display.showLog);
|
|
await tester.pump();
|
|
expect(find.text('DNS 서버 (192.0.2.1) 에 닿지 않음 (01:35부터)'), findsOneWidget);
|
|
await tester.tap(find.text('시스템 DNS 로 바꾸기'));
|
|
await tester.pump();
|
|
expect(c.settings.network.mode, 'system');
|
|
});
|
|
|
|
testWidgets('위쪽 이동 버튼: 설치한 화면만 · 설정을 바꾸면 바로 · 하나뿐이면 그것만', (tester) async {
|
|
tester.view.physicalSize = const Size(1500, 900);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
final c = _plain();
|
|
await tester.pumpWidget(MaterialApp(
|
|
builder: (context, child) => AppScope(controller: c, child: child!),
|
|
home: HomePage(c: c),
|
|
));
|
|
expect(find.byTooltip('MKV 화면 (지금 여기)'), findsOneWidget);
|
|
expect(find.byTooltip('파일 탐색기'), findsOneWidget);
|
|
expect(find.byTooltip('Rsync'), findsOneWidget);
|
|
await c.updateSettings((s) => s.display.components = ['mkv', 'explorer']);
|
|
await tester.pump();
|
|
expect(find.byTooltip('Rsync'), findsNothing);
|
|
expect(find.byTooltip('파일 탐색기'), findsOneWidget);
|
|
await c.updateSettings((s) => s.display.components = ['mkv']);
|
|
await tester.pump();
|
|
expect(find.byTooltip('파일 탐색기'), findsNothing);
|
|
expect(find.byTooltip('MKV 화면 (지금 여기)'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('화면 순서: ▲ ▼ 로 바꾸고 위쪽 버튼 줄도 그 순서', (tester) async {
|
|
tester.view.physicalSize = const Size(1200, 2400);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
final c = _plain();
|
|
await tester.pumpWidget(MaterialApp(
|
|
builder: (context, child) => AppScope(controller: c, child: child!),
|
|
home: Scaffold(body: SingleChildScrollView(child: ListenableBuilder(
|
|
listenable: c, builder: (_, _) => ComponentSettings(c: c)))),
|
|
));
|
|
// 2번째 (웹 브라우저) 를 위로 → 맨 앞
|
|
await tester.tap(find.byTooltip('위로').at(1));
|
|
await tester.pump();
|
|
expect(c.settings.display.navOrder.take(2), ['browser', 'mkv']);
|
|
// 맨 앞 (웹 브라우저) 를 아래로 → 다시 2번째
|
|
await tester.tap(find.byTooltip('아래로').first);
|
|
await tester.pump();
|
|
expect(c.settings.display.navOrder.take(2), ['mkv', 'browser']);
|
|
// 마지막 (AI 그림) 을 위로 → 5번째
|
|
await tester.tap(find.byTooltip('위로').last);
|
|
await tester.pump();
|
|
expect(c.settings.display.navOrder, ['mkv', 'browser', 'explorer', 'rsync', 'aiimage', 'downloads']);
|
|
});
|
|
|
|
testWidgets('화면 가운데를 좌우로 밀면 순서대로 다음 · 이전 화면 (끝 다음은 처음)', (tester) async {
|
|
tester.view.physicalSize = const Size(1500, 900);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
final c = _plain();
|
|
c.settings
|
|
..display.components = ['mkv', 'explorer', 'rsync']
|
|
..display.navOrder = ['mkv', 'explorer', 'rsync'];
|
|
await tester.pumpWidget(MaterialApp(
|
|
builder: (context, child) => AppScope(controller: c, child: child!),
|
|
home: HomePage(c: c),
|
|
));
|
|
Future<void> swipe(double dx) async {
|
|
await tester.flingFrom(const Offset(750, 450), Offset(dx, 0), 2000);
|
|
await tester.pump();
|
|
await tester.pump(const Duration(milliseconds: 500));
|
|
}
|
|
|
|
// 66-2: 민 쪽으로 미끄러져 들어온다 (오른쪽에서) · 지금 화면 아이콘은 파랗게
|
|
await tester.flingFrom(const Offset(750, 450), const Offset(-600, 0), 2000);
|
|
await tester.pump();
|
|
await tester.pump(const Duration(milliseconds: 80));
|
|
expect(find.byType(SlideTransition), findsWidgets);
|
|
await tester.pump(const Duration(milliseconds: 500));
|
|
expect(find.byTooltip('파일 탐색기 (지금 여기)'), findsOneWidget);
|
|
final here = tester.widget<IconButton>(find.ancestor(of: find.byTooltip('파일 탐색기 (지금 여기)'), matching: find.byType(IconButton)).first);
|
|
expect(here.style?.foregroundColor?.resolve({}), JjColors.accent);
|
|
await swipe(-600);
|
|
expect(find.byTooltip('Rsync (지금 여기)'), findsOneWidget);
|
|
await swipe(-600); // 마지막 다음은 처음
|
|
expect(find.byTooltip('MKV 화면 (지금 여기)'), findsOneWidget);
|
|
// 66-2: 끝에서 처음으로 넘어가면 알린다
|
|
expect(find.textContaining('처음으로: MKV 만들기'), findsOneWidget);
|
|
await swipe(600); // 오른쪽으로 → 이전 (끝으로)
|
|
expect(find.byTooltip('Rsync (지금 여기)'), findsOneWidget);
|
|
// 102: 끝에서 처음으로 돌기를 끄면 끝에서 멈춘다
|
|
await c.updateSettings((s) => s.display.swipeWrap = false);
|
|
await tester.pump();
|
|
await swipe(-600);
|
|
expect(find.byTooltip('Rsync (지금 여기)'), findsOneWidget);
|
|
expect(find.textContaining('마지막 화면입니다'), findsOneWidget, reason: '끝에서 멈출 때도 왜 안 넘어가는지 알림');
|
|
await swipe(600);
|
|
expect(find.byTooltip('파일 탐색기 (지금 여기)'), findsOneWidget);
|
|
await swipe(-600);
|
|
expect(find.byTooltip('Rsync (지금 여기)'), findsOneWidget);
|
|
await c.updateSettings((s) => s.display.swipeWrap = true);
|
|
// 끄면 밀어도 그대로
|
|
await c.updateSettings((s) => s.display.swipeNav = false);
|
|
await tester.pump();
|
|
await swipe(600);
|
|
expect(find.byTooltip('Rsync (지금 여기)'), findsOneWidget);
|
|
});
|
|
|
|
test('66-2: 웹 브라우저 화면 옮기기 안내는 한 번만 (설정에 남음)', () {
|
|
expect(AppSettings().browser.swipeHinted, isFalse);
|
|
expect(AppSettings.fromJson((AppSettings()..browser.swipeHinted = true).toJson()).browser.swipeHinted, isTrue);
|
|
});
|
|
|
|
testWidgets('174: MKV 화면이 맨 처음 화면이 아니어도 (홈 화면 = 탐색기 등) MKV 아이콘이 "지금 여기"', (tester) async {
|
|
tester.view.physicalSize = const Size(1500, 900);
|
|
tester.view.devicePixelRatio = 1;
|
|
addTearDown(tester.view.reset);
|
|
final c = _plain();
|
|
c.settings
|
|
..display.components = ['mkv', 'explorer']
|
|
..display.navOrder = ['mkv', 'explorer'];
|
|
final navKey = GlobalKey<NavigatorState>();
|
|
await tester.pumpWidget(MaterialApp(
|
|
navigatorKey: navKey,
|
|
builder: (context, child) => AppScope(controller: c, child: child!),
|
|
home: const Scaffold(body: Text('맨 처음 화면')),
|
|
));
|
|
navKey.currentState!.push(MaterialPageRoute<void>(builder: (_) => HomePage(c: c)));
|
|
await tester.pumpAndSettle();
|
|
expect(find.byTooltip('MKV 화면 (지금 여기)'), findsOneWidget);
|
|
});
|
|
}
|