import 'package:flutter_test/flutter_test.dart'; import 'package:nontonki/core/data/remote/api_client.dart'; import 'package:nontonki/core/data/remote/catalog_api.dart'; /// 联调测试:直连本机客户端接口服务(8081)。 /// 服务没启动时自动跳过,不影响日常 `flutter test`。 void main() { final client = ApiClient(baseUrl: 'http://127.0.0.1:8081'); final api = CatalogApi(client); tearDownAll(client.close); Future serverUp() async { try { await api.homeFeed(); return true; } catch (_) { return false; } } test('首页聚合:能解析出轮播与分区', () 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('详情:剧集按下发顺序排列,可播放集带地址', () 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('播放票据:可播放时返回地址', () 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 api.playTicket(playable.first.id); expect(ticket.accessible, isTrue); expect(ticket.playUrl, startsWith('/files/')); }); }