import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:patbond_flutter/core/theme/app_theme.dart'; import 'package:patbond_flutter/core/widgets/like_button.dart'; import 'package:patbond_flutter/core/widgets/post_card.dart'; import 'package:patbond_flutter/core/widgets/post_media_grid.dart'; import 'package:patbond_flutter/features/community/community_models.dart'; import 'package:patbond_flutter/widgets/common.dart'; import '../../helpers/community_test_helpers.dart'; FeedCard cardFrom(Map overrides) => FeedCard.fromJson({...sampleFeedCardJson(), ...overrides}); Widget wrap(Widget child) => MaterialApp( theme: buildAppTheme(), home: Scaffold(body: SingleChildScrollView(child: child)), ); void main() { testWidgets('单图形态:通栏 4:3 出血,不走九宫格,预览 2 行', (tester) async { final card = cardFrom({'mediaCount': 1}); await tester.pumpWidget(wrap(PostCard(card: card))); expect(find.byType(AspectRatio), findsOneWidget); expect(find.byType(PostMediaGrid), findsNothing); final preview = tester.widget(find.text('晒了一下午太阳。')); expect(preview.maxLines, 2); }); testWidgets('多图形态:九宫格折叠封面 + 「+N」角标(契约只带封面与计数)', (tester) async { final card = cardFrom({'mediaCount': 5}); await tester.pumpWidget(wrap(PostCard(card: card))); expect(find.byType(PostMediaGrid), findsOneWidget); expect(find.text('+4'), findsOneWidget); }); testWidgets('纯文字形态:无媒体区,正文放宽 6 行、15/1.6', (tester) async { final card = cardFrom({'coverImage': null, 'mediaCount': 0}); await tester.pumpWidget(wrap(PostCard(card: card))); expect(find.byType(PostMediaGrid), findsNothing); expect(find.byType(AspectRatio), findsNothing); final preview = tester.widget(find.text('晒了一下午太阳。')); expect(preview.maxLines, 6); expect(preview.style?.fontSize, 15); }); testWidgets('头部行:作者名 + 相对时间;求助帖追加 accent 标', (tester) async { final card = cardFrom({ 'category': 'help', 'publishedAt': DateTime.now() .subtract(const Duration(hours: 2)) .toUtc() .toIso8601String(), }); await tester.pumpWidget(wrap(PostCard(card: card))); expect(find.text('毛毛的铲屎官'), findsOneWidget); expect(find.text('2 小时前'), findsOneWidget); expect(find.widgetWithText(TagPill, '求助'), findsOneWidget); }); testWidgets('降级作者:占位头像 + 「宠友」默认名', (tester) async { final card = cardFrom({ 'author': sampleAuthorJson(nickname: null, avatarUrl: null), }); await tester.pumpWidget(wrap(PostCard(card: card))); expect(find.text('宠友'), findsOneWidget); expect(find.text('毛毛的铲屎官'), findsNothing); }); testWidgets('操作行:计数与激活态展示;T3-14 纯展示点按无副作用', (tester) async { final card = cardFrom({ 'likedByMe': true, 'likeCount': 6, 'bookmarkedByMe': false, 'bookmarkCount': 2, 'commentCount': 3, }); await tester.pumpWidget(wrap(PostCard(card: card))); expect(find.text('6'), findsOneWidget); expect(find.text('2'), findsOneWidget); expect(find.text('3'), findsOneWidget); // 点赞激活:实心 favorite + error 色(Colors.red 修订 D6)。 final likeIcon = tester.widget(find.byIcon(Icons.favorite)); expect(likeIcon.color, AppColors.error); // 收藏未激活:描边 + inkSoft。 final bookmarkIcon = tester.widget( find.byIcon(Icons.bookmark_border), ); expect(bookmarkIcon.color, AppColors.inkSoft); // 回调未接(null):点按不抛错、无状态变化。 await tester.tap(find.byType(LikeButton).first, warnIfMissed: false); await tester.pump(); expect(find.byIcon(Icons.favorite), findsOneWidget); }); }