115 lines
3.7 KiB
Dart
115 lines
3.7 KiB
Dart
// 功能描述:验证作业前检查页面失败重试不会向 setState 返回异步任务。
|
||
// 版本:1.0.0
|
||
import 'package:flutter/material.dart';
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
import 'package:service_app/app/dependencies.dart';
|
||
import 'package:service_app/data/repositories/service_repository.dart';
|
||
import 'package:service_app/data/services/api_client.dart';
|
||
import 'package:service_app/data/services/location_service.dart';
|
||
import 'package:service_app/data/services/secure_session_store.dart';
|
||
import 'package:service_app/domain/models/service_models.dart';
|
||
import 'package:service_app/ui/features/preflight/preflight_page.dart';
|
||
|
||
/// 提供无需平台插件的空会话存储。
|
||
class _EmptySessionStore implements SessionStore {
|
||
@override
|
||
Future<void> delete(String key) async {}
|
||
|
||
@override
|
||
Future<String?> read(String key) async => null;
|
||
|
||
@override
|
||
Future<void> write(String key, String value) async {}
|
||
}
|
||
|
||
/// 提供不会在重试测试中访问系统定位的占位实现。
|
||
class _UnusedLocationService implements LocationService {
|
||
@override
|
||
Future<LocationPoint> current() => throw UnimplementedError();
|
||
}
|
||
|
||
/// 首次加载失败、第二次成功,用于验证真实重试路径。
|
||
class _FailOnceRepository extends ServiceRepository {
|
||
_FailOnceRepository()
|
||
: super(
|
||
ApiClient(() => '', baseUrl: 'https://api.example.com'),
|
||
_UnusedLocationService(),
|
||
);
|
||
|
||
int calls = 0;
|
||
|
||
@override
|
||
Future<PreflightResult> preflight() async {
|
||
calls += 1;
|
||
if (calls == 1) throw StateError('temporary failure');
|
||
return const PreflightResult(
|
||
roleCode: 'delivery',
|
||
workStatus: 'off_duty',
|
||
canWork: false,
|
||
checks: {},
|
||
);
|
||
}
|
||
}
|
||
|
||
/// 返回包含一个真实阻断项和一个暂不检查项的固定预检结果。
|
||
class _BlockedRepository extends ServiceRepository {
|
||
_BlockedRepository()
|
||
: super(
|
||
ApiClient(() => '', baseUrl: 'https://api.example.com'),
|
||
_UnusedLocationService(),
|
||
);
|
||
|
||
@override
|
||
Future<PreflightResult> preflight() async => const PreflightResult(
|
||
roleCode: 'delivery',
|
||
workStatus: 'on_duty',
|
||
canWork: false,
|
||
checks: {
|
||
'credential': {'status': 'blocked', 'reason': 'missing'},
|
||
'daily_training': {'status': 'not_configured'},
|
||
},
|
||
);
|
||
}
|
||
|
||
/// 点击重新加载后应成功刷新,且测试过程不得出现 Flutter 断言。
|
||
void main() {
|
||
testWidgets('作业检查失败后可重新加载', (tester) async {
|
||
final repository = _FailOnceRepository();
|
||
final session = StaffSession(_EmptySessionStore());
|
||
await tester.pumpWidget(
|
||
MaterialApp(
|
||
home: PreflightPage(session: session, repository: repository),
|
||
),
|
||
);
|
||
await tester.pumpAndSettle();
|
||
|
||
expect(find.text('作业检查加载失败'), findsOneWidget);
|
||
expect(repository.calls, 1);
|
||
|
||
await tester.tap(find.text('重新加载'));
|
||
await tester.pumpAndSettle();
|
||
|
||
expect(find.text('作业检查加载失败'), findsNothing);
|
||
expect(find.text('仍有前置条件未完成'), findsOneWidget);
|
||
expect(repository.calls, 2);
|
||
expect(tester.takeException(), isNull);
|
||
});
|
||
|
||
testWidgets('仅统计阻断项并显示资质处理指引', (tester) async {
|
||
await tester.pumpWidget(
|
||
MaterialApp(
|
||
home: PreflightPage(
|
||
session: StaffSession(_EmptySessionStore()),
|
||
repository: _BlockedRepository(),
|
||
),
|
||
),
|
||
);
|
||
await tester.pumpAndSettle();
|
||
|
||
expect(find.text('完成 1 项阻断后可进入'), findsOneWidget);
|
||
expect(find.text('暂不检查'), findsOneWidget);
|
||
expect(find.text('尚未配置有效资质,请联系所属组织管理员补充或审核'), findsOneWidget);
|
||
expect(find.text('下班打卡'), findsOneWidget);
|
||
});
|
||
}
|