Files
platforms/apps/user_app/test/domain/recharge_flow_test.dart

122 lines
3.8 KiB
Dart
Raw Normal View History

// 功能描述充值先存后发和未确认订单保留版本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<PendingRecharge?> read(String owner) async => value;
@override
Future<void> write(String owner, PendingRecharge draft) async {
if (fail) throw StateError('存储失败');
value = draft;
}
@override
Future<void> 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<String> rechargeDraftOwner() async => owner;
@override
Future<Map<String, Object?>> createRecharge({
required String request,
required int amount,
required String channel,
required String payType,
}) async {
expect(store.value?.request, request);
calls++;
throw StateError('响应丢失');
}
@override
Future<RechargeRecord> 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<ApiException>().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);
});
}