// 功能描述:充值先存后发和未确认订单保留;版本:1.0.0。 import 'package:flutter_test/flutter_test.dart'; import 'package:user_app/data/services/recharge_draft_store.dart'; import 'package:user_app/data/services/recharge_flow.dart'; import 'package:user_app/data/services/api_client.dart'; import 'package:user_app/domain/models/recharge.dart'; import '../support/a1_fixture.dart'; class _Store implements RechargeDraftStore { PendingRecharge? value; bool fail = false; @override Future read(String owner) async => value; @override Future write(String owner, PendingRecharge draft) async { if (fail) throw StateError('存储失败'); value = draft; } @override Future delete(String owner) async { value = null; } } class _Repo extends A1FixtureRepository { _Repo(this.store); final _Store store; int calls = 0, status = 10; int? queryError; String owner = 'api#alice'; bool changeOwnerOnQuery = false; @override Future rechargeDraftOwner() async => owner; @override Future> createRecharge({ required String request, required int amount, required String channel, required String payType, }) async { expect(store.value?.request, request); calls++; throw StateError('响应丢失'); } @override Future rechargeResult(String request) async { if (changeOwnerOnQuery) owner = 'api#bob'; if (queryError != null) throw ApiException(queryError!, '查询失败'); return RechargeRecord( identity: 'order', number: request, amount: 100, status: status, channel: 'alipay', createdAt: DateTime(2026), ); } } void main() { test('明确不存在可原号重发,网络错误和账号切换不能发单', () async { const draft = PendingRecharge( request: 'request-1', amount: 100, channel: 'alipay', payType: 'wap', ); for (final code in [1112, 500]) { final store = _Store()..value = draft; final repo = _Repo(store)..queryError = code; final flow = RechargeFlow(repo, store); await expectLater( flow.create(draft), code == 1112 ? throwsStateError : throwsA(isA().having((e) => e.code, '错误码', 500)), ); expect(repo.calls, code == 1112 ? 1 : 0); expect(store.value?.request, draft.request); } final store = _Store()..value = draft; final repo = _Repo(store)..changeOwnerOnQuery = true; await expectLater(RechargeFlow(repo, store).create(draft), throwsStateError); expect(repo.calls, 0); expect(store.value, isNotNull); }); test('存储失败不发单,响应丢失保留原请求,到账后才清除', () async { final store = _Store()..fail = true; final repo = _Repo(store); final flow = RechargeFlow(repo, store); const draft = PendingRecharge( request: 'request-1', amount: 100, channel: 'alipay', payType: 'wap', ); await expectLater(flow.create(draft), throwsStateError); expect(repo.calls, 0); store.fail = false; await expectLater(flow.create(draft), throwsStateError); expect(repo.calls, 1); expect(store.value?.request, 'request-1'); await expectLater( flow.create( const PendingRecharge(request: 'request-2', amount: 100, channel: 'alipay', payType: 'wap'), ), throwsStateError, ); expect(repo.calls, 1); expect((await flow.recover())?.credited, isFalse); expect(store.value, isNotNull); repo.status = 23; expect(await flow.create(draft), {'recharge_status': 23}); expect(repo.calls, 1); expect(store.value, isNotNull); expect((await flow.recover())?.credited, isTrue); expect(store.value, isNull); }); }