74 lines
2.4 KiB
Dart
74 lines
2.4 KiB
Dart
// 功能描述:账单金额严格解析、筛选请求和过期会话保护;版本:1.0.0。
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
import 'package:http/http.dart' as http;
|
||
import 'package:http/testing.dart';
|
||
import 'package:user_app/data/repositories/client_repository.dart';
|
||
import 'package:user_app/data/services/api_client.dart';
|
||
import 'package:user_app/domain/models/wallet_bill.dart';
|
||
|
||
void main() {
|
||
test('钱包缺失或小数金额不能显示为零余额', () async {
|
||
for (final data in [
|
||
'{}',
|
||
'{"balance":1.5,"withdrawal_balance":0}',
|
||
'{"balance":0,"withdrawal_balance":1}',
|
||
]) {
|
||
final repo = ClientRepository(
|
||
ApiClient(
|
||
() => 't',
|
||
client: MockClient((_) async => http.Response('{"code":0,"details":$data}', 200)),
|
||
),
|
||
);
|
||
await expectLater(repo.wallet(), throwsA(isA<ApiException>()));
|
||
}
|
||
});
|
||
final valid = <String, Object?>{
|
||
'identity': 'r1',
|
||
'direction': 'expense',
|
||
'amount': 100,
|
||
'fee': 0,
|
||
'balance_after': 500,
|
||
'created_at': '2026-09-08T08:00:00Z',
|
||
};
|
||
test('金额和收支不推测、不截断为整数', () {
|
||
expect(WalletBill.fromJson(valid).signedAmount, '-¥1.00');
|
||
for (final patch in [
|
||
{'amount': 1.5},
|
||
{'amount': -1},
|
||
{'fee': '0'},
|
||
{'direction': 'unknown'},
|
||
{'created_at': ''},
|
||
]) {
|
||
expect(() => WalletBill.fromJson({...valid, ...patch}), throwsFormatException);
|
||
}
|
||
});
|
||
test('账单筛选和游标传递,不将错误响应当空列表', () async {
|
||
final repo = ClientRepository(
|
||
ApiClient(
|
||
() => 't',
|
||
client: MockClient((r) async {
|
||
expect(r.url.queryParameters, {'direction': 'income', 'cursor': '50'});
|
||
return http.Response('{"code":0,"details":{}}', 200);
|
||
}),
|
||
),
|
||
);
|
||
await expectLater(
|
||
repo.walletBills(direction: 'income', cursor: '50'),
|
||
throwsA(isA<ApiException>()),
|
||
);
|
||
});
|
||
test('切换账户后迟到的账单不可显示', () async {
|
||
var token = 'alice';
|
||
final repo = ClientRepository(
|
||
ApiClient(
|
||
() => token,
|
||
client: MockClient((r) async {
|
||
token = 'bob';
|
||
return http.Response('{"code":0,"details":{"items":[],"next_cursor":""}}', 200);
|
||
}),
|
||
),
|
||
);
|
||
await expectLater(repo.walletBills(), throwsA(isA<SessionExpiredException>()));
|
||
});
|
||
}
|