Files
photo-live/apps/mobile/test/pages/share_qr_dialog_test.dart
T
2026-09-21 17:20:43 +08:00

113 lines
3.8 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/// 分享二维码对话框 widget 测试(UI-01 §4.5 分层重构)。
///
/// 覆盖:分层结构(相册标题 → 白底二维码 → URL 文本 → 复制为主/浏览器
/// 打开为次)、QrImageView 以 viewer URL({VIEWER_BASE}/a/{token})渲染、
/// 复制按钮写入剪贴板并提示、「在浏览器中打开」经注入的替身启动器
/// 打开 URL 并关闭对话框。
library;
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:photo_live/core/config.dart';
import 'package:photo_live/l10n/app_localizations.dart';
import 'package:photo_live/pages/share_qr_dialog.dart';
import 'package:qr_flutter/qr_flutter.dart';
void main() {
const token = 'sharetoken000000000001';
Future<void> pumpDialog(
WidgetTester tester, {
String? albumTitle,
UrlLauncher? launcher,
}) async {
await tester.pumpWidget(
ProviderScope(
overrides: [
if (launcher != null)
urlLauncherProvider.overrideWith((ref) => launcher),
],
child: MaterialApp(
localizationsDelegates: AppLocalizations.localizationsDelegates,
supportedLocales: AppLocalizations.supportedLocales,
// 复制提示走 ScaffoldMessenger:包一层 Scaffold 供 SnackBar 挂载。
home: Scaffold(
body: Center(
child: ShareQrDialog(
publicToken: token,
albumTitle: albumTitle,
),
),
),
),
),
);
await tester.pumpAndSettle();
}
testWidgets('分层渲染:相册标题 → 二维码(data 为观众链接)→ URL 文本',
(tester) async {
await pumpDialog(tester, albumTitle: 'Opening Gala');
final url = ApiConfig.viewerAlbumUrl(token);
// qr_flutter 4.1 未公开 QrImageView.data(私有 _data),以同源的
// SelectableText 文本断言 URL 构造(二维码与文本同用该局部变量)。
expect(find.byType(QrImageView), findsOneWidget);
expect(
tester.widget<SelectableText>(find.byType(SelectableText)).data,
url,
);
expect(url, 'http://10.0.2.2:5175/a/$token');
// 分层:主标题 = 相册名,副标题 = 通用标题,脚注 = 扫码/链接提示。
expect(find.text('Opening Gala'), findsOneWidget);
expect(find.text('Share QR code'), findsOneWidget);
expect(find.text('Scan the code or open the link to view'), findsOneWidget);
});
testWidgets('复制按钮(主操作)→ 剪贴板收到 URL + 已复制提示', (tester) async {
final clipboardCalls = <MethodCall>[];
tester.binding.defaultBinaryMessenger.setMockMethodCallHandler(
SystemChannels.platform,
(call) async {
clipboardCalls.add(call);
return null;
},
);
await pumpDialog(tester);
await tester.tap(find.text('Copy link'));
await tester.pumpAndSettle();
final url = ApiConfig.viewerAlbumUrl(token);
expect(
clipboardCalls.any(
(c) =>
c.method == 'Clipboard.setData' &&
(c.arguments as Map<String, dynamic>)['text'] == url,
),
isTrue,
);
expect(find.text('Copied'), findsOneWidget);
});
testWidgets('在浏览器中打开(次操作)→ 启动器收到 URL + 关闭对话框',
(tester) async {
final launchedUrls = <String>[];
await pumpDialog(
tester,
launcher: (url) async {
launchedUrls.add(url);
return true;
},
);
await tester.tap(find.text('Open in browser'));
await tester.pumpAndSettle();
expect(launchedUrls, [ApiConfig.viewerAlbumUrl(token)]);
expect(find.byType(ShareQrDialog), findsNothing, reason: '打开成功后关闭');
});
}