import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:life_helper/domain/catalog/catalog_item.dart'; import 'package:life_helper/domain/catalog/display_category.dart'; import 'package:life_helper/state/catalog_providers.dart'; import 'package:life_helper/ui/screens/protocol_preview_screen.dart'; ProtocolCatalogItem _sampleProtocol({List refIds = const []}) => ProtocolCatalogItem( id: 'morning_sunlight', title: '아침 햇빛', titleEn: 'Morning Sunlight', summary: '기상 후 햇빛', displayCategory: DisplayCategory.lightCircadian, evidenceStrength: 'strong_rct', referenceIds: refIds, what: '기상 후 햇빛 노출.', whenText: '기상 후 30~60분.', dose: '5~10분.', why: 'ipRGC 자극으로 일주기 리셋.', how: const ['밖으로 나간다', '하늘을 쳐다본다'], checkText: '60분 이내 외출', caution: '직사 응시 금지', defaultAnchor: const {'when': '기상 후', 'after_what': '세수'}, minDoseForStart: '2분', sourceDoc: 'huberman-protocols.md', ); void main() { Widget buildHarness(CatalogItem item, {List refs = const []}) { return ProviderScope( overrides: [ referencesByIdsProvider.overrideWith((ref, ids) async => []), ], child: MaterialApp(home: ProtocolPreviewScreen(item: item)), ); } testWidgets('Protocol: 모든 핵심 필드 표시', (tester) async { final item = _sampleProtocol(); await tester.pumpWidget(buildHarness(item)); await tester.pump(); // Header + 상단 가시 필드. expect(find.text('아침 햇빛'), findsAtLeastNWidgets(1)); expect(find.text('Morning Sunlight'), findsOneWidget); expect(find.text('빛/일주기'), findsOneWidget); // ListView lazy-builds — 하위 필드는 명시적 스크롤로 가져온다. final scrollable = find.byType(Scrollable).first; for (final t in [ 'ipRGC 자극으로 일주기 리셋.', '1. 밖으로 나간다', '2. 하늘을 쳐다본다', '60분 이내 외출', '직사 응시 금지', '2분', 'huberman-protocols.md', ]) { await tester.scrollUntilVisible(find.text(t), 100, scrollable: scrollable); expect(find.text(t), findsOneWidget, reason: 'missing: $t'); } }); testWidgets('"내 습관으로" 버튼 disabled + tooltip', (tester) async { await tester.pumpWidget(buildHarness(_sampleProtocol())); await tester.pump(); final button = tester.widget(find.byType(FilledButton)); expect(button.onPressed, isNull); expect(find.byType(Tooltip), findsAtLeastNWidgets(1)); }); testWidgets('reference 없으면 References 섹션 숨김', (tester) async { await tester.pumpWidget(buildHarness(_sampleProtocol(refIds: const []))); await tester.pump(); expect(find.textContaining('참고 ('), findsNothing); }); }