// This is a basic Flutter widget test. // // To perform an interaction with a widget in your test, use the WidgetTester // utility in the flutter_test package. For example, you can send tap and scroll // gestures. You can also use WidgetTester to find child widgets in the widget // tree, read text, and verify that the values of widget properties are correct. import 'package:app_upgrade_plugin_example/main.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:yx_app_upgrade_flutter/app_upgrade_plugin.dart'; import 'package:yx_app_upgrade_flutter/app_upgrade_plugin_platform_interface.dart'; /// Mock implementation of AppUpgradePluginPlatform for testing class MockAppUpgradePluginPlatform extends AppUpgradePluginPlatform { MockAppUpgradePluginPlatform() : super(); @override Future getPlatformVersion() async => 'Mock Platform 1.0.0'; @override Future getAndroidSdkVersion() async => 33; @override Future openInstallPermissionSettings() async => true; @override Future?> getDeviceInfo() async => { 'manufacturer': 'Mock Manufacturer', 'model': 'Mock Model', 'androidVersion': '13', }; @override Future> getInstalledMarkets() async => ['huawei', 'xiaomi']; @override void configureHttp(HttpConfig config) { // Mock implementation } @override Future> getAppInfo() async => { 'appName': 'app_upgrade_plugin_example', 'packageName': 'com.example.app_upgrade_plugin_example', 'version': '1.0.0', 'buildNumber': '1', }; @override Future checkUpdate(String url, {Map? params}) async { // Return null to simulate no update available return null; } @override Future downloadApk( String url, { Function(DownloadProgress)? onProgress, String? savePath, }) async { // Simulate download progress if (onProgress != null) { onProgress(DownloadProgress(received: 50, total: 100)); await Future.delayed(const Duration(milliseconds: 10)); onProgress(DownloadProgress(received: 100, total: 100)); } return '/mock/path/to/downloaded.apk'; } @override Future installApk(String filePath) async => true; @override Future installApkWithSystemFlow(String filePath) async => true; @override Future installApkWithConfig(String filePath, InstallConfig config) async => true; @override Future goToAppStore(String url, {required BuildContext context}) async => true; @override Future getDownloadPath({bool checkPermission = true}) async => '/mock/download/path'; @override Future checkApkExists(String version, String? md5) async => false; } void main() { // Ensure test bindings are initialized TestWidgetsFlutterBinding.ensureInitialized(); setUp(() { // Set up mock method channel handlers for platform channels TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler( const MethodChannel('plugins.flutter.io/package_info_plus'), (MethodCall methodCall) async { if (methodCall.method == 'getAll') { return { 'appName': 'app_upgrade_plugin_example', 'packageName': 'com.example.app_upgrade_plugin_example', 'version': '1.0.0', 'buildNumber': '1', }; } return null; }, ); // Mock local notifications channel TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler( const MethodChannel('dexterous.com/flutter/local_notifications'), (MethodCall methodCall) async => null, ); // Mock connectivity channel TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler( const MethodChannel('dev.flutter.plugins/connectivity'), (MethodCall methodCall) async { if (methodCall.method == 'check') { return 'wifi'; } return null; }, ); // Set mock platform implementation AppUpgradePluginPlatform.instance = MockAppUpgradePluginPlatform(); }); tearDown(() { // Clean up method channel handlers TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler( const MethodChannel('plugins.flutter.io/package_info_plus'), null, ); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler( const MethodChannel('dexterous.com/flutter/local_notifications'), null, ); TestDefaultBinaryMessengerBinding.instance.defaultBinaryMessenger.setMockMethodCallHandler( const MethodChannel('dev.flutter.plugins/connectivity'), null, ); }); group('App Upgrade Plugin Widget Tests', () { testWidgets('App should launch successfully', (WidgetTester tester) async { // Build the app await tester.pumpWidget(const MyApp()); // Verify that the app widget is present expect(find.byType(MyApp), findsOneWidget); expect(find.byType(HomePage), findsOneWidget); // Verify that the app bar is present expect(find.text('App Upgrade Plugin 示例'), findsOneWidget); // Verify that the check update button is present expect(find.text('检查更新'), findsOneWidget); }); testWidgets('App should display home page correctly', (WidgetTester tester) async { await tester.pumpWidget(const MyApp()); await tester.pumpAndSettle(); // Verify UI elements expect(find.byType(Scaffold), findsOneWidget); expect(find.byType(AppBar), findsOneWidget); expect(find.byType(ElevatedButton), findsOneWidget); }); testWidgets('Check update button should be tappable', (WidgetTester tester) async { await tester.pumpWidget(const MyApp()); await tester.pumpAndSettle(); // Find and tap the check update button final button = find.text('检查更新'); expect(button, findsOneWidget); // Tap the button await tester.tap(button); await tester.pump(); // Button should still be present after tap expect(button, findsOneWidget); }); }); group('App Upgrade Plugin Platform Tests', () { test('getPlatformVersion should return mock version', () async { final platform = AppUpgradePluginPlatform.instance; final version = await platform.getPlatformVersion(); expect(version, isNotNull); expect(version, equals('Mock Platform 1.0.0')); }); test('getAppInfo should return mock app info', () async { final platform = AppUpgradePluginPlatform.instance; final appInfo = await platform.getAppInfo(); expect(appInfo, isNotNull); expect(appInfo['appName'], equals('app_upgrade_plugin_example')); expect(appInfo['version'], equals('1.0.0')); }); test('checkUpdate should return null when no update available', () async { final platform = AppUpgradePluginPlatform.instance; final upgradeInfo = await platform.checkUpdate('https://example.com/check'); expect(upgradeInfo, isNull); }); test('getDownloadPath should return mock path', () async { final platform = AppUpgradePluginPlatform.instance; final path = await platform.getDownloadPath(); expect(path, isNotNull); expect(path, equals('/mock/download/path')); }); test('checkApkExists should return false for non-existent APK', () async { final platform = AppUpgradePluginPlatform.instance; final exists = await platform.checkApkExists('1.0.0', null); expect(exists, isFalse); }); }); group('AppUpgradeVersion Model Tests', () { test('AppUpgradeVersion should be created correctly', () { final version = AppUpgradeVersion( versionName: '1.0.1', versionBuildNumber: 2, updateContent: 'Test update content', downloadUrl: 'https://example.com/app.apk', isForce: false, ); expect(version.versionName, equals('1.0.1')); expect(version.versionBuildNumber, equals(2)); expect(version.updateContent, equals('Test update content')); expect(version.downloadUrl, equals('https://example.com/app.apk')); expect(version.isForce, isFalse); }); test('AppUpgradeVersion with force update should work', () { final version = AppUpgradeVersion( versionName: '1.0.1', versionBuildNumber: 2, updateContent: 'Force update', isForce: true, ); expect(version.isForce, isTrue); }); test('AppUpgradeVersion.getAppStoreByUrl should generate correct URL', () { final url = AppUpgradeVersion.getAppStoreByUrl('123456'); expect(url, equals('https://apps.apple.com/cn/app/123456')); }); test('AppUpgradeVersion.getAppStoreByItunes should generate correct URL', () { final url = AppUpgradeVersion.getAppStoreByItunes('123456'); expect(url, equals('itms-apps://itunes.apple.com/app/id123456')); }); }); group('DownloadProgress Model Tests', () { test('DownloadProgress should calculate progress correctly', () { final progress = DownloadProgress(received: 50, total: 100); expect(progress.progress, equals(0.5)); expect(progress.percentage, equals(50)); }); test('DownloadProgress with zero total should handle gracefully', () { final progress = DownloadProgress(received: 0, total: 0); expect(progress.progress, equals(0.0)); expect(progress.percentage, equals(0)); }); test('DownloadProgress should calculate percentage correctly', () { final progress = DownloadProgress(received: 75, total: 100); expect(progress.percentage, equals(75)); }); }); }