import 'package:flutter_test/flutter_test.dart'; import 'package:fruitshorts/core/data/remote/api_client.dart'; import 'package:fruitshorts/core/data/remote/catalog_api.dart'; import 'package:fruitshorts/core/data/remote/playback_api.dart'; /// 联调测试:直连本机客户端接口服务(8081)。 /// 服务没启动时自动跳过,不影响日常 `flutter test`。 void main() { final client = ApiClient(baseUrl: 'http://127.0.0.1:8081'); final api = CatalogApi(client); final playback = PlaybackApi(client); tearDownAll(client.close); Future serverUp() async { try { await api.homeFeed(); return true; } catch (_) { return false; } } test('should_parse_banner_and_sections_when_home_feed_is_fetched', () async { if (!await serverUp()) { markTestSkipped('客户端接口服务未启动,已跳过联调测试'); return; } final feed = await api.homeFeed(); expect(feed.sections, isNotEmpty); expect(feed.dramas, isNotEmpty); final card = feed.dramas.first; expect(card.id, isNotEmpty); expect(card.title, isNotEmpty); expect(card.posterUrl, startsWith('/files/')); }); test('should_order_episodes_by_number_and_attach_url_when_detail_is_fetched', () async { if (!await serverUp()) { markTestSkipped('客户端接口服务未启动,已跳过联调测试'); return; } final feed = await api.homeFeed(); final card = feed.dramas.first; final detail = await api.dramaDetail(card.id); expect(detail.id, card.id); expect(detail.episodes, isNotEmpty); final numbers = detail.episodes.map((episode) => episode.number).toList(); expect(numbers, orderedEquals([...numbers]..sort())); for (final episode in detail.episodes) { if (episode.locked) { expect(episode.videoUrl, isEmpty); } else { expect(episode.videoUrl, startsWith('/files/')); } } }); test('should_return_play_url_when_episode_is_playable', () async { if (!await serverUp()) { markTestSkipped('客户端接口服务未启动,已跳过联调测试'); return; } final feed = await api.homeFeed(); final detail = await api.dramaDetail(feed.dramas.first.id); final playable = detail.episodes .where((episode) => episode.videoUrl.isNotEmpty) .toList(); if (playable.isEmpty) { return; } final ticket = await playback.ticket(playable.first.id); expect(ticket.accessible, isTrue); expect(ticket.playUrl, startsWith('/files/')); }); }