Files
platforms/apps/user_app/test/ui/primary_pages_test.dart

148 lines
5.8 KiB
Dart
Raw Normal View History

// 功能描述:验证一级页面保留入口、游客数据边界、筛选及刷新错误恢复。
// 版本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);
});
}