// Author: fruit.com.cn import 'dart:async'; import 'package:fruitshorts/core/data/models/comment.dart'; import 'package:fruitshorts/core/data/models/interaction.dart'; import 'package:fruitshorts/core/data/repositories/comment_repository.dart'; import 'package:fruitshorts/core/data/repositories/interaction_repository.dart'; class CommentPageCall { const CommentPageCall({ required this.dramaId, required this.episodeId, required this.rootId, required this.cursor, required this.size, }); final String dramaId; final String? episodeId; final String? rootId; final String? cursor; final int size; } class PublishCall { const PublishCall({ required this.dramaId, required this.episodeId, required this.content, required this.parentId, }); final String dramaId; final String? episodeId; final String content; final String? parentId; } class FakeCommentRepository implements CommentRepository { FakeCommentRepository({ List? pages, this.publishResult, this.publishError, this.deleteError, this.pageError, this.countResult, this.countError, }) : pages = pages ?? const []; final List pages; final DramaComment? publishResult; final Object? publishError; final Object? deleteError; final Object? pageError; final int? countResult; final Object? countError; final List pageCalls = []; final List publishCalls = []; final List deleteCalls = []; final List countCalls = []; final List countEpisodeCalls = []; int _pageIndex = 0; @override Future page({ required String dramaId, String? episodeId, String? rootId, String? cursor, int size = commentPageSize, }) async { pageCalls.add( CommentPageCall( dramaId: dramaId, episodeId: episodeId, rootId: rootId, cursor: cursor, size: size, ), ); final error = pageError; if (error != null) throw error; if (_pageIndex >= pages.length) return const CommentPage(); return pages[_pageIndex++]; } @override Future count(String dramaId, {String? episodeId}) async { countCalls.add(dramaId); if (episodeId != null && episodeId.isNotEmpty) { countEpisodeCalls.add(episodeId); } final error = countError; if (error != null) throw error; final result = countResult; if (result == null) throw StateError('comment count unavailable'); return result; } @override Future publish({ required String dramaId, String? episodeId, required String content, String? parentId, }) async { publishCalls.add( PublishCall( dramaId: dramaId, episodeId: episodeId, content: content, parentId: parentId, ), ); final error = publishError; if (error != null) throw error; return publishResult ?? commentFixture( id: 'new-comment', dramaId: dramaId, content: content, mine: true, ); } @override Future delete(String commentId) async { deleteCalls.add(commentId); final error = deleteError; if (error != null) throw error; } } class FakeInteractionRepository implements InteractionRepository { FakeInteractionRepository({ this.nextLikeResult = const LikeToggleResult(liked: true, count: 1), }); LikeToggleResult nextLikeResult; Object? likeError; Object? reportError; Completer? likeGate; String reportId = 'report-1'; final List likeTargets = []; final List reports = []; @override Future toggleLike({ required InteractionTargetType targetType, required String targetId, }) async { likeTargets.add('${targetType.apiValue}:$targetId'); final gate = likeGate; if (gate != null) await gate.future; final error = likeError; if (error != null) throw error; return nextLikeResult; } @override Future report(ReportRequest request) async { reports.add(request); final error = reportError; if (error != null) throw error; return reportId; } } DramaComment commentFixture({ String id = '1001', String dramaId = '5', String? parentId, String? rootId, String content = 'A comment', String status = 'published', int likeCount = 0, int replyCount = 0, bool liked = false, bool mine = false, }) => DramaComment( id: id, dramaId: dramaId, episodeId: '0', parentId: parentId ?? '0', rootId: rootId ?? '0', userId: mine ? '9' : '8', uid: mine ? 'me' : 'viewer', nickname: mine ? 'Me' : 'Viewer', avatarUrl: '', content: content, status: status, auditReason: '', likeCount: likeCount, replyCount: replyCount, reportCount: 0, createdAt: DateTime(2026, 10, 17, 12), mine: mine, liked: liked, );