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/bookmarks_controller.dart'; import 'package:jj_mkvmaker/app/settings.dart'; import 'package:jj_mkvmaker/platform/windows/cef_runtime.dart'; import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart'; import 'package:jj_mkvmaker/platform/windows/elevation.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/browser_page.dart'; import 'package:path/path.dart' as p; /// 207: 내장 Chrome 엔진 (CEF) 은 관리자 권한이면 스스로 끝난다 (종료 코드 38). 관리자 판단: 처음 값은 시작하지 않고 이유와 고를 것을 보인다. /// 사용자가 "그래도 쓰기" 를 고르면 설정이 켜진다. 시작하지 못하면 빙글이만 돌게 두지 않는다 void main() { late Directory dir; late AppController c; late BookmarksController bm; setUp(() { dir = Directory.systemTemp.createTempSync('jj_cef_elev_'); c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService())); c.settings ..browserEngine = 'chrome' ..webViewDataDir = p.join(dir.path, 'webview'); bm = BookmarksController(p.join(dir.path, 'bookmarks.json')); CefRuntime.readyThisRun = true; }); tearDown(() { Elevation.debugElevated = null; CefRuntime.readyThisRun = false; dir.deleteSync(recursive: true); }); Future open(WidgetTester t) async { t.view.physicalSize = const Size(1400, 900); t.view.devicePixelRatio = 1; addTearDown(t.view.reset); await t.pumpWidget(MaterialApp( builder: (context, child) => AppScope(controller: c, bookmarks: bm, child: child!), home: BrowserPage(c: c, bookmarks: bm, initialUrl: 'https://example.com/'), )); await t.pump(); } testWidgets('관리자 권한: Chrome 엔진을 시작하지 않고 이유 · [Edge 엔진으로 바꾸기]', (t) async { Elevation.debugElevated = true; await open(t); expect(find.text('관리자 권한으로 실행 중이라 Chrome 엔진을 쓸 수 없습니다 (보안)'), findsOneWidget); await t.tap(find.text('Edge 엔진으로 바꾸기')); await t.pump(); expect(c.settings.browserEngine, 'edge'); await t.pumpWidget(const SizedBox()); }); testWidgets('관리자 권한: [그래도 Chrome 엔진 쓰기…] 는 경고를 보이고, 취소하면 그대로 · 고르면 설정이 켜짐', (t) async { Elevation.debugElevated = true; await open(t); await t.tap(find.text('그래도 Chrome 엔진 쓰기…')); await t.pumpAndSettle(); expect(find.textContaining('샌드박스 (웹 페이지를 가두는 보호) 가 꺼져'), findsOneWidget); await t.tap(find.text('취소')); await t.pumpAndSettle(); expect(c.settings.cefWhenElevated, isFalse); await t.tap(find.text('그래도 Chrome 엔진 쓰기…')); await t.pumpAndSettle(); await t.tap(find.text('그래도 쓰기')); await t.pumpAndSettle(); expect(c.settings.cefWhenElevated, isTrue); expect(find.text('관리자 권한으로 실행 중이라 Chrome 엔진을 쓸 수 없습니다 (보안)'), findsNothing); await t.pumpWidget(const SizedBox()); }); testWidgets('시작하지 못하면 빙글이만 돌지 않고 "Chrome 엔진을 시작하지 못했습니다" · [Edge 엔진으로 바꾸기] · [다시 시도]', (t) async { Elevation.debugElevated = false; BrowserPage.cefStartTimeout = const Duration(seconds: 2); addTearDown(() => BrowserPage.cefStartTimeout = const Duration(seconds: 20)); await open(t); // 시험에는 Chrome 엔진 (플러그인) 이 없어 끝나지 않거나 실패한다 - 정한 시간 (여기선 2초) 이 지나면 안내 expect(find.text('Chrome 엔진을 시작하지 못했습니다'), findsNothing); await t.pump(const Duration(seconds: 3)); expect(find.text('Chrome 엔진을 시작하지 못했습니다'), findsOneWidget); expect(find.text('다시 시도'), findsOneWidget); await t.tap(find.text('Edge 엔진으로 바꾸기')); await t.pump(); expect(c.settings.browserEngine, 'edge'); await t.pumpWidget(const SizedBox()); }); test('설정: 관리자 권한일 때 Chrome 엔진 쓰기는 처음 꺼짐 · 저장 · 틀린 값은 꺼짐', () { expect(AppSettings().cefWhenElevated, isFalse); expect(AppSettings.fromJson((AppSettings()..cefWhenElevated = true).toJson()).cefWhenElevated, isTrue); expect(AppSettings.fromJson({'cefWhenElevated': 'yes'}).cefWhenElevated, isFalse); }); }