import 'dart:typed_data'; import 'package:dio/dio.dart'; import 'package:fixnum/fixnum.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:jinzhi_flutter_app/features/ads/data/ads_api_client.dart'; import 'package:jinzhi_flutter_app/models/pb/jinzhi/v1/ads.pb.dart' as pb; void main() { test( 'Retrofit client decodes generated ad protobuf and encodes events', () async { final adapter = _AdsAdapter(); final backend = AdsBackendApiClient( Dio(BaseOptions(responseType: ResponseType.bytes)) ..httpClientAdapter = adapter, ); final client = AdsApiClient(backend); final result = await client.getAdResult(splashAdPlacement); expect(result.enabled, isTrue); expect(result.ad?.title, '商城'); expect(result.ad?.endAtMs, 4102444800000); await client.report(result.ad!, 'impression'); final report = pb.ReportAdEventRequest.fromBuffer(adapter.lastBody!); expect(report.eventName, 'impression'); expect(report.adId, 'ad-1'); }, ); } class _AdsAdapter implements HttpClientAdapter { List? lastBody; @override Future fetch( RequestOptions options, Stream? requestStream, Future? cancelFuture, ) async { if (options.path == '/api/v1/ads') { return ResponseBody.fromBytes( pb.GetAdReply( enabled: true, dailyCap: 1, ad: pb.AdCreative( adId: 'ad-1', placement: splashAdPlacement, title: '商城', imageUrl: 'https://cdn.example.com/ad.png', h5Url: 'https://example.com', trackedUrl: 'https://example.com', mediaType: pb.MediaType.MEDIA_TYPE_IMAGE, openMode: pb.AdOpenMode.AD_OPEN_MODE_EXTERNAL, endAtMs: Int64(4102444800000), ), ).writeToBuffer(), 200, ); } lastBody = (options.data as List).toList(); return ResponseBody.fromBytes(pb.ReportAdEventReply().writeToBuffer(), 200); } @override void close({bool force = false}) {} }