JJ_MKVMaker/integration_test/windows_reset_shot_test.dart

95 lines
4.4 KiB
Dart

import 'dart:async';
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/app_controller.dart';
import 'package:jj_mkvmaker/app/i18n_controller.dart';
import 'package:jj_mkvmaker/app/master_lock.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/services/secret_store.dart';
import 'package:jj_mkvmaker/ui/master_prompt.dart';
import 'package:jj_mkvmaker/ui/theme.dart';
import 'package:path/path.dart' as p;
/// 145 (관리자 지시 10/19): 124 초기화 창 (최상 비밀번호 - 초기화 · 정말 초기화할까요? · 마스터를 잊었을 때) 을
/// 크기 412 · 960, 언어 ko · en · ja 로 찍는다. 아무것도 지우지 않는다 (가짜 저장소, [초기화] 는 누르지 않음).
/// 실행: flutter test integration_test\windows_reset_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_reset');
for (final lang in ['ko', 'en', 'ja']) {
for (final (w, h) in [(412, 900), (960, 600)]) {
testWidgets('초기화 창 $lang ${w}x$h', (t) async {
t.view.physicalSize = Size(w.toDouble(), h.toDouble());
t.view.devicePixelRatio = 1;
addTearDown(t.view.reset);
await t.runAsync(() => i18n.apply(lang, save: false));
addTearDown(() => i18n.apply('ko', save: false));
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
final lock = MasterLock(MemorySecretStore());
await t.runAsync(() async {
await lock.load();
await lock.setMaster('시험-마스터');
});
final navKey = GlobalKey<NavigatorState>();
final shotKey = GlobalKey();
await t.pumpWidget(RepaintBoundary(
key: shotKey,
child: MaterialApp(
theme: buildTheme(), debugShowCheckedModeBanner: false, navigatorKey: navKey, home: const Scaffold(body: SizedBox.expand())),
));
Future<void> settle([int n = 8]) async {
for (var i = 0; i < n; i++) {
await t.runAsync(() => Future<void>.delayed(const Duration(milliseconds: 60)));
await t.pump();
}
}
Future<void> shot(String name) async {
await settle(3);
expect(t.takeException(), isNull, reason: '$name 넘침');
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, 'reset_${name}_${lang}_$w.png')).writeAsBytesSync(bytes!.buffer.asUint8List());
}
Future<void> closeAll() async {
navKey.currentState!.popUntil((r) => r.isFirst);
await settle();
}
// ① 최상 비밀번호 - 초기화 (무엇을 초기화할지) - 셋 다 체크해 긴 설명까지 보이게
unawaited(showSuperReset(navKey.currentContext!, c, lock));
await settle();
await shot('1_super');
for (final cb in find.byType(CheckboxListTile).evaluate().toList()) {
final tile = cb.widget as CheckboxListTile;
if (tile.value != true && tile.onChanged != null) tile.onChanged!(true);
}
await settle();
await shot('2_super_all');
// ② 정말 초기화할까요? (한 번 더 확인) - 여기서는 [취소]
await t.tap(find.byType(FilledButton).last);
await settle();
await shot('3_sure');
await closeAll();
// ③ 마스터를 잊었을 때 (저장된 비밀번호를 지우고 마스터 초기화) - 확인 창만
unawaited(forgotMaster(navKey.currentContext!, c, lock));
await settle();
await shot('4_forgot');
await closeAll();
expect(lock.hasMaster, isTrue, reason: '찍기만 하고 지우지 않음');
});
}
}
}