// Author: fruit.com.cn import 'dart:convert'; import 'package:flutter_test/flutter_test.dart'; import 'package:fruitshorts/core/data/remote/api_client.dart'; import 'package:fruitshorts/core/data/remote/comment_api.dart'; import '../support/fake_http_adapter.dart'; void main() { String envelope(Object? data) => jsonEncode({'code': 0, 'message': 'ok', 'data': data}); Map commentJson({ String id = '2111012753262120962', String content = 'Great episode', String status = 'published', bool mine = false, bool liked = true, String parentId = '0', String rootId = '0', }) => { 'id': id, 'dramaId': '5', 'episodeId': '7', 'parentId': parentId, 'rootId': rootId, 'userId': '2111012753262120001', 'uid': 'viewer-1', 'nickname': 'Viewer', 'avatarUrl': '', 'content': content, 'status': status, 'auditReason': '', 'likeCount': '12', 'replyCount': 2, 'reportCount': '0', 'createdAt': '2026-10-17T12:30:00', 'mine': mine, 'liked': liked, }; test('should_parse_cursor_page_and_string_ids_when_comment_list_is_loaded', () async { final adapter = FakeHttpAdapter((options) async { return FakeHttpResponse( envelope({ 'list': [commentJson()], 'nextCursor': '2111012753262120962', 'hasMore': true, }), ); }); final api = CommentApi( ApiClient(baseUrl: 'http://127.0.0.1:8081', adapter: adapter), ); final page = await api.page( dramaId: '5', episodeId: '7', cursor: '99', size: 20, ); expect(adapter.requests.single.method, 'GET'); expect(adapter.requests.single.uri.path, '/app/comments'); expect(adapter.requests.single.queryParameters, { 'dramaId': '5', 'episodeId': '7', 'cursor': '99', 'size': '20', }); expect(page.comments.single.id, '2111012753262120962'); expect(page.comments.single.dramaId, '5'); expect(page.comments.single.episodeId, '7'); expect(page.comments.single.likeCount, 12); expect(page.nextCursor, '2111012753262120962'); expect(page.hasMore, isTrue); }); test('should_send_parent_id_only_for_reply_and_parse_replaced_content_when_published', () async { final adapter = FakeHttpAdapter((options) async { return FakeHttpResponse( envelope( commentJson( id: '2111012753262120999', content: 'great ***', status: 'pending', mine: true, parentId: '2111012753262120962', rootId: '2111012753262120962', ), ), ); }); final api = CommentApi( ApiClient(baseUrl: 'http://127.0.0.1:8081', adapter: adapter), ); final reply = await api.publish( dramaId: '5', episodeId: '7', content: 'great badword', parentId: '2111012753262120962', ); expect(adapter.requests.single.method, 'POST'); expect(adapter.requests.single.uri.path, '/app/comments'); expect(adapter.requests.single.data, { 'dramaId': '5', 'episodeId': '7', 'content': 'great badword', 'parentId': '2111012753262120962', }); expect(reply.content, 'great ***'); expect(reply.status, 'pending'); expect(reply.parentId, '2111012753262120962'); expect(reply.rootId, '2111012753262120962'); }); test('should_delete_comment_by_string_id_when_requested', () async { final adapter = FakeHttpAdapter( (_) async => FakeHttpResponse(envelope(null)), ); final api = CommentApi( ApiClient(baseUrl: 'http://127.0.0.1:8081', adapter: adapter), ); await api.delete('2111012753262120962'); expect(adapter.requests.single.method, 'DELETE'); expect( adapter.requests.single.uri.path, '/app/comments/2111012753262120962', ); }); test('should_parse_numeric_comment_count', () async { final adapter = FakeHttpAdapter( (_) async => FakeHttpResponse(envelope(17)), ); final api = CommentApi( ApiClient(baseUrl: 'http://127.0.0.1:8081', adapter: adapter), ); final count = await api.count('5', episodeId: '7'); expect(count, 17); expect(adapter.requests.single.method, 'GET'); expect(adapter.requests.single.uri.path, '/app/comments/count'); expect(adapter.requests.single.queryParameters, { 'dramaId': '5', 'episodeId': '7', }); }); test('should_parse_string_comment_count', () async { final adapter = FakeHttpAdapter( (_) async => FakeHttpResponse(envelope('2111012753262120962')), ); final api = CommentApi( ApiClient(baseUrl: 'http://127.0.0.1:8081', adapter: adapter), ); expect(await api.count('5'), 2111012753262120962); }); }