修复用户端订单列表生命周期与刷新
This commit is contained in:
97
apps/user_app/test/ui/orders_page_test.dart
Normal file
97
apps/user_app/test/ui/orders_page_test.dart
Normal file
@@ -0,0 +1,97 @@
|
||||
// 功能描述:验证订单退款成功后的跨标签刷新行为。
|
||||
// 版本:1.0.0
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.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/client_models.dart';
|
||||
import 'package:user_app/ui/features/orders/orders_page.dart';
|
||||
|
||||
/// 提供无需网络的订单数据并记录各列表刷新次数。
|
||||
class _FakeRepository extends ClientRepository {
|
||||
_FakeRepository() : super(ApiClient(() => '', baseUrl: 'https://api.example.com'));
|
||||
|
||||
int shopCalls = 0;
|
||||
int gasCalls = 0;
|
||||
int refundCalls = 0;
|
||||
int ticketCalls = 0;
|
||||
int createRefundCalls = 0;
|
||||
|
||||
@override
|
||||
Future<List<ClientRecord>> shopOrders() async {
|
||||
shopCalls += 1;
|
||||
return const [
|
||||
ClientRecord(
|
||||
identity: 'shop-1',
|
||||
title: '商城订单一',
|
||||
subtitle: '',
|
||||
status: 18,
|
||||
raw: {
|
||||
'items': [
|
||||
{'identity': 'item-1', 'quantity': 1},
|
||||
],
|
||||
},
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ClientRecord>> gasOrders() async {
|
||||
gasCalls += 1;
|
||||
return const [];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ClientRecord>> refunds() async {
|
||||
refundCalls += 1;
|
||||
return const [];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<List<ClientRecord>> tickets() async {
|
||||
ticketCalls += 1;
|
||||
return const [];
|
||||
}
|
||||
|
||||
@override
|
||||
Future<void> createRefund({
|
||||
required String business,
|
||||
required String identity,
|
||||
required String requestNo,
|
||||
required String reason,
|
||||
required List<Map<String, Object?>> items,
|
||||
}) async {
|
||||
createRefundCalls += 1;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
testWidgets('退款成功后刷新商城订单和退款记录', (tester) async {
|
||||
final repository = _FakeRepository();
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(home: OrdersPage(repository: repository)),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
await tester.tap(find.text('退款'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(repository.refundCalls, 1);
|
||||
|
||||
await tester.tap(find.text('商城'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(repository.shopCalls, 1);
|
||||
|
||||
await tester.tap(find.text('商城订单一'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.tap(find.text('申请退款'));
|
||||
await tester.pumpAndSettle();
|
||||
await tester.enterText(find.byType(TextField), '商品问题');
|
||||
await tester.tap(find.text('提交'));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(repository.createRefundCalls, 1);
|
||||
expect(repository.shopCalls, 2);
|
||||
expect(repository.refundCalls, 2);
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
}
|
||||
45
apps/user_app/test/ui/record_list_page_test.dart
Normal file
45
apps/user_app/test/ui/record_list_page_test.dart
Normal file
@@ -0,0 +1,45 @@
|
||||
// 功能描述:验证记录列表在父组件重建和刷新标记变化时的生命周期。
|
||||
// 版本:1.0.0
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:user_app/domain/models/client_models.dart';
|
||||
import 'package:user_app/ui/features/shared/record_list_page.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('普通重建不重复请求,刷新标记变化才重新加载', (tester) async {
|
||||
var calls = 0;
|
||||
var refreshToken = 0;
|
||||
late StateSetter rebuild;
|
||||
Future<List<ClientRecord>> loader() async {
|
||||
calls += 1;
|
||||
return const [];
|
||||
}
|
||||
|
||||
await tester.pumpWidget(
|
||||
MaterialApp(
|
||||
home: StatefulBuilder(
|
||||
builder: (context, setState) {
|
||||
rebuild = setState;
|
||||
return RecordListPage(
|
||||
title: '测试列表',
|
||||
eyebrow: '测试',
|
||||
sourceKey: 'records',
|
||||
loader: loader,
|
||||
refreshToken: refreshToken,
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
await tester.pumpAndSettle();
|
||||
expect(calls, 1);
|
||||
|
||||
rebuild(() {});
|
||||
await tester.pumpAndSettle();
|
||||
expect(calls, 1);
|
||||
|
||||
rebuild(() => refreshToken += 1);
|
||||
await tester.pumpAndSettle();
|
||||
expect(calls, 2);
|
||||
});
|
||||
}
|
||||
52
apps/user_app/test/ui/record_list_view_model_test.dart
Normal file
52
apps/user_app/test/ui/record_list_view_model_test.dart
Normal file
@@ -0,0 +1,52 @@
|
||||
// 功能描述:验证记录列表异步请求的代次与销毁保护。
|
||||
// 版本:1.0.0
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:user_app/domain/models/client_models.dart';
|
||||
import 'package:user_app/ui/features/shared/record_list_view_model.dart';
|
||||
|
||||
ClientRecord _record(String identity) => ClientRecord(
|
||||
identity: identity,
|
||||
title: identity,
|
||||
subtitle: '',
|
||||
raw: const {},
|
||||
);
|
||||
|
||||
void main() {
|
||||
test('后发请求优先,旧结果不会覆盖新数据', () async {
|
||||
final first = Completer<List<ClientRecord>>();
|
||||
final second = Completer<List<ClientRecord>>();
|
||||
var calls = 0;
|
||||
final viewModel = RecordListViewModel(() {
|
||||
calls += 1;
|
||||
return calls == 1 ? first.future : second.future;
|
||||
});
|
||||
|
||||
final firstLoad = viewModel.load();
|
||||
final secondLoad = viewModel.load();
|
||||
second.complete([_record('new')]);
|
||||
await secondLoad;
|
||||
first.complete([_record('old')]);
|
||||
await firstLoad;
|
||||
|
||||
expect(viewModel.records.single.identity, 'new');
|
||||
expect(viewModel.loading, isFalse);
|
||||
viewModel.dispose();
|
||||
});
|
||||
|
||||
test('销毁后异步结果不会继续通知监听器', () async {
|
||||
final pending = Completer<List<ClientRecord>>();
|
||||
final viewModel = RecordListViewModel(() => pending.future);
|
||||
var notifications = 0;
|
||||
viewModel.addListener(() => notifications += 1);
|
||||
|
||||
final load = viewModel.load();
|
||||
expect(notifications, 1);
|
||||
viewModel.dispose();
|
||||
pending.complete([_record('late')]);
|
||||
await load;
|
||||
|
||||
expect(notifications, 1);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user