148 lines
5.8 KiB
Dart
148 lines
5.8 KiB
Dart
// 功能描述:验证一级页面保留入口、游客数据边界、筛选及刷新错误恢复。
|
||
// 版本:1.0.0
|
||
import 'package:flutter/material.dart';
|
||
import 'dart:async';
|
||
import 'package:flutter_test/flutter_test.dart';
|
||
import 'package:go_router/go_router.dart';
|
||
import 'package:user_app/domain/models/client_models.dart';
|
||
import 'package:user_app/domain/models/order_summary.dart';
|
||
import 'package:user_app/ui/features/home/home_page.dart';
|
||
import 'package:user_app/ui/features/shop/shop_page.dart';
|
||
import 'package:user_app/ui/core/async_content.dart';
|
||
import 'package:user_app/ui/core/text_entry_dialog.dart';
|
||
import '../support/a1_fixture.dart';
|
||
|
||
void main() {
|
||
testWidgets('刷新失败保留上次数据,较迟的旧请求不覆盖新数据', (tester) async {
|
||
final key = GlobalKey<AsyncContentState<String>>();
|
||
final pending = <Completer<String>>[];
|
||
await tester.pumpWidget(
|
||
MaterialApp(
|
||
home: Scaffold(
|
||
body: AsyncContent<String>(
|
||
key: key,
|
||
load: () {
|
||
final c = Completer<String>();
|
||
pending.add(c);
|
||
return c.future;
|
||
},
|
||
builder: (_, value) => ListView(children: [Text(value)]),
|
||
),
|
||
),
|
||
),
|
||
);
|
||
pending[0].complete('初始数据');
|
||
await tester.pumpAndSettle();
|
||
final first = key.currentState!.refresh();
|
||
final second = key.currentState!.refresh();
|
||
pending[2].complete('最新数据');
|
||
await second;
|
||
await tester.pump();
|
||
pending[1].complete('旧请求结果');
|
||
await first;
|
||
await tester.pump();
|
||
expect(find.text('最新数据'), findsOneWidget);
|
||
expect(find.text('旧请求结果'), findsNothing);
|
||
final failure = key.currentState!.refresh();
|
||
pending[3].completeError(Exception('offline'));
|
||
await failure;
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('最新数据'), findsOneWidget);
|
||
expect(find.textContaining('刷新失败,当前显示上次数据'), findsOneWidget);
|
||
});
|
||
testWidgets('输入弹窗关闭动画期间控制器有效,空值阻止提交', (tester) async {
|
||
String? result;
|
||
await tester.pumpWidget(
|
||
MaterialApp(
|
||
home: Builder(
|
||
builder: (context) => Scaffold(
|
||
body: TextButton(
|
||
onPressed: () async {
|
||
result = await showDialog<String>(
|
||
context: context,
|
||
builder: (_) => const TextEntryDialog(title: '新增地址', label: '详细地址', action: '保存'),
|
||
);
|
||
},
|
||
child: const Text('打开'),
|
||
),
|
||
),
|
||
),
|
||
),
|
||
);
|
||
await tester.tap(find.text('打开'));
|
||
await tester.pumpAndSettle();
|
||
await tester.tap(find.text('保存'));
|
||
await tester.pump();
|
||
expect(find.text('请填写详细地址'), findsOneWidget);
|
||
await tester.enterText(find.byType(TextField), '测试地址');
|
||
await tester.tap(find.text('保存'));
|
||
await tester.pump();
|
||
await tester.pumpAndSettle();
|
||
expect(result, '测试地址');
|
||
expect(tester.takeException(), isNull);
|
||
});
|
||
testWidgets('游客首页不读取个人归属并保留设备入口', (tester) async {
|
||
final source = A1FixtureRepository();
|
||
await tester.pumpWidget(MaterialApp(home: HomePage(repository: source, authenticated: false)));
|
||
await tester.pumpAndSettle();
|
||
expect(source.relationCalls, 0);
|
||
await tester.ensureVisible(find.text('扫码添加'));
|
||
await tester.tap(find.text('扫码添加'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.textContaining('该功能暂未开放'), findsOneWidget);
|
||
expect(find.text('85%'), findsNothing);
|
||
});
|
||
testWidgets('首页真实入口可进入设备页且未接入入口明确提示', (tester) async {
|
||
final source = A1FixtureRepository();
|
||
final router = GoRouter(
|
||
initialLocation: '/home',
|
||
routes: [
|
||
GoRoute(
|
||
path: '/home',
|
||
builder: (_, _) => HomePage(repository: source),
|
||
),
|
||
GoRoute(
|
||
path: '/devices',
|
||
builder: (_, _) => const Scaffold(body: Text('设备页已打开')),
|
||
),
|
||
],
|
||
);
|
||
addTearDown(router.dispose);
|
||
await tester.pumpWidget(MaterialApp.router(routerConfig: router));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('查看设备状态与告警记录'), findsOneWidget);
|
||
expect(find.text('查看气瓶使用与检测信息'), findsOneWidget);
|
||
await tester.tap(find.text('查看详情'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('设备页已打开'), findsOneWidget);
|
||
});
|
||
testWidgets('首次加载失败可重试恢复真实内容', (tester) async {
|
||
final source = A1FixtureRepository()..fail = true;
|
||
await tester.pumpWidget(MaterialApp(home: HomePage(repository: source)));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('加载失败'), findsOneWidget);
|
||
source.fail = false;
|
||
await tester.tap(find.text('重新加载'));
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('当前服务归属'), findsOneWidget);
|
||
});
|
||
testWidgets('商城搜索与分类联动并显示空结果', (tester) async {
|
||
await tester.pumpWidget(MaterialApp(home: ShopPage(repository: A1FixtureRepository())));
|
||
await tester.pumpAndSettle();
|
||
await tester.enterText(find.byType(TextField), '报警');
|
||
await tester.pumpAndSettle();
|
||
expect(find.text('燃气报警器'), findsOneWidget);
|
||
expect(find.text('15kg家用液化气'), findsNothing);
|
||
await tester.enterText(find.byType(TextField), '不存在');
|
||
await tester.pumpAndSettle();
|
||
expect(find.textContaining('暂无符合条件'), findsOneWidget);
|
||
});
|
||
test('旧响应缺少 allowed_actions 时不从状态码推测权限', () {
|
||
final order = OrderSummary.fromRecord(
|
||
const ClientRecord(identity: 'o', title: '', subtitle: '', status: 16, raw: {}),
|
||
);
|
||
expect(order.actions, isEmpty);
|
||
expect(order.amount, isNull);
|
||
});
|
||
}
|