// 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/watch_api.dart'; import 'package:fruitshorts/core/data/repositories/watch_history_repository.dart'; import '../support/fake_http_adapter.dart'; void main() { test('should_request_recent_with_page_and_parse_display_fields', () async { final adapter = FakeHttpAdapter( (_) async => FakeHttpResponse( jsonEncode({ 'code': 0, 'message': 'ok', 'data': { 'total': '18', 'list': [ { 'dramaId': '12', 'episodeId': '88', 'dramaTitle': '剧名', 'dramaCover': '/files/12.png', 'episodeNumber': 6, 'totalEpisodes': 68, 'positionMs': '80000', 'durationMs': '120000', }, ], }, }), ), ); final api = WatchApi( ApiClient(baseUrl: 'http://127.0.0.1:8081', adapter: adapter), ); final page = await api.recent(pageIndex: 2, pageSize: 10); final request = adapter.requests.single; expect(request.uri.path, '/app/watch/recent'); expect(request.queryParameters['pageIndex'], '2'); expect(request.queryParameters['pageSize'], '10'); expect(request.queryParameters.containsKey('limit'), isFalse); expect(page.total, 18); expect(page.list.single.dramaTitle, '剧名'); expect(page.list.single.dramaCover, '/files/12.png'); expect(page.list.single.episodeNumber, 6); expect(page.list.single.totalEpisodes, 68); }); test('should_return_empty_page_when_recent_list_is_empty', () async { final adapter = FakeHttpAdapter( (_) async => FakeHttpResponse( jsonEncode({ 'code': 0, 'message': 'ok', 'data': {'total': '0', 'list': []}, }), ), ); final api = WatchApi( ApiClient(baseUrl: 'http://127.0.0.1:8081', adapter: adapter), ); final page = await api.recent(); expect(page.total, 0); expect(page.list, isEmpty); }); test('should_throw_api_exception_when_recent_response_is_error', () async { final adapter = FakeHttpAdapter( (_) async => FakeHttpResponse( jsonEncode({'code': 401, 'message': 'unauthorized', 'data': null}), ), ); final api = WatchApi( ApiClient( baseUrl: 'http://127.0.0.1:8081', adapter: adapter, tokenRefresher: null, ), ); await expectLater( () => api.recent(), throwsA( isA() .having((e) => e.code, 'code', 401) .having((e) => e.message, 'message', 'unauthorized'), ), ); }); test('should_allow_guest_watch_read_save_and_clear', () async { final adapter = FakeHttpAdapter((options) async { if (options.method == 'GET' && options.uri.path.endsWith('/progress')) { return FakeHttpResponse( jsonEncode({ 'code': 0, 'message': 'ok', 'data': { 'dramaId': '12', 'episodeId': '88', 'positionMs': '8000', 'durationMs': '60000', }, }), ); } if (options.method == 'GET') { return FakeHttpResponse( jsonEncode({ 'code': 0, 'message': 'ok', 'data': {'total': '0', 'list': []}, }), ); } return FakeHttpResponse( jsonEncode({'code': 0, 'message': 'ok', 'data': null}), ); }); final repository = HttpWatchHistoryRepository( WatchApi(ApiClient(baseUrl: 'http://127.0.0.1:8081', adapter: adapter)), ); expect((await repository.progressFor('12'))?.episodeId, '88'); expect((await repository.recent()).list, isEmpty); await repository.save( episodeId: '88', position: const Duration(seconds: 8), ); await repository.remove('12'); await repository.clear(); expect( adapter.requests.map( (request) => '${request.method} ${request.uri.path}', ), [ 'GET /app/watch/progress', 'GET /app/watch/recent', 'POST /app/watch/progress', 'DELETE /app/watch/progress/12', 'DELETE /app/watch/progress', ], ); }); }