Files
ReelShort/test/account/account_pages_test.dart
T

230 lines
7.5 KiB
Dart

// Author: fruit.com.cn
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:fruitshorts/core/data/models/auth_session.dart';
import 'package:fruitshorts/core/data/repositories/account_repository.dart';
import 'package:fruitshorts/core/data/remote/api_client.dart';
import 'package:fruitshorts/core/data/remote/auth_api.dart';
import 'package:fruitshorts/core/data/services/auth_controller.dart';
import 'package:fruitshorts/core/data/services/auth_session_store.dart';
import 'package:fruitshorts/l10n/app_localizations.dart';
import 'package:fruitshorts/pages/account/account_deactivate_page.dart';
import 'package:fruitshorts/pages/account/account_devices_page.dart';
import 'package:fruitshorts/pages/account/account_export_page.dart';
import 'package:fruitshorts/pages/account/account_profile_page.dart';
import 'package:provider/provider.dart';
import 'package:shared_preferences_platform_interface/in_memory_shared_preferences_async.dart';
import 'package:shared_preferences_platform_interface/shared_preferences_async_platform_interface.dart';
import '../support/fake_account_repository.dart';
void main() {
testWidgets('should_fill_profile_and_save_nickname', (tester) async {
final repository = FakeAccountRepository();
final auth = await _signedInAuth();
await _pumpPage(
tester,
AccountProfilePage(),
repository: repository,
auth: auth,
locale: const Locale('zh'),
);
final nickname = find.byKey(const Key('account-nickname'));
expect(find.byKey(const Key('account-birthday')), findsNothing);
expect(find.text('保存'), findsOneWidget);
expect(tester.widget<TextField>(nickname).controller?.text, 'Nadia');
await tester.enterText(nickname, 'Nadia Baru');
await tester.tap(find.byKey(const Key('account-profile-save')));
await tester.pumpAndSettle();
expect(repository.lastUpdate?.nickname, 'Nadia Baru');
expect(repository.lastUpdate?.birthday, isNull);
});
testWidgets('should_show_device_empty_state_when_list_is_empty', (
tester,
) async {
final repository = FakeAccountRepository();
final auth = await _signedInAuth();
await _pumpPage(
tester,
AccountDevicesPage(),
repository: repository,
auth: auth,
);
expect(find.byKey(const Key('account-devices-empty')), findsOneWidget);
});
testWidgets('should_confirm_before_deactivation_and_show_schedule', (
tester,
) async {
final repository = FakeAccountRepository();
final auth = await _signedInAuth();
await _pumpPage(
tester,
AccountDeactivatePage(),
repository: repository,
auth: auth,
);
await tester.enterText(
find.byKey(const Key('account-deactivate-reason')),
'不再使用',
);
await tester.tap(find.byKey(const Key('account-deactivate-submit')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('account-deactivate-confirm')), findsOneWidget);
await tester.tap(find.byKey(const Key('account-deactivate-confirm')));
await tester.pumpAndSettle();
expect(repository.lastDeactivateReason, '不再使用');
expect(
find.byKey(const Key('account-deactivate-scheduled')),
findsOneWidget,
);
expect(auth.isSignedIn, isFalse);
});
testWidgets('should_retry_export_after_failure', (tester) async {
final repository = FakeAccountRepository()..failExport = true;
final auth = await _signedInAuth();
await _pumpPage(
tester,
AccountExportPage(),
repository: repository,
auth: auth,
);
expect(find.byKey(const Key('account-export-error')), findsOneWidget);
repository.failExport = false;
await tester.tap(find.byKey(const Key('account-export-retry')));
await tester.pumpAndSettle();
expect(find.byKey(const Key('account-export-content')), findsOneWidget);
});
testWidgets('should_show_localized_network_copy_when_profile_load_fails', (
tester,
) async {
final repository = FakeAccountRepository()..throwUnexpected = true;
final auth = await _signedInAuth();
await _pumpPage(
tester,
AccountProfilePage(),
repository: repository,
auth: auth,
locale: const Locale('zh'),
);
final l10n = await AppLocalizations.delegate.load(const Locale('zh'));
expect(find.text(l10n.networkError), findsOneWidget);
expect(find.text('accountProfileLoadFailed'), findsNothing);
});
testWidgets('should_show_localized_network_copy_when_profile_save_fails', (
tester,
) async {
final repository = FakeAccountRepository();
final auth = await _signedInAuth();
await _pumpPage(
tester,
AccountProfilePage(),
repository: repository,
auth: auth,
);
repository.throwUnexpected = true;
await tester.enterText(
find.byKey(const Key('account-nickname')),
'Nadia Baru',
);
await tester.tap(find.byKey(const Key('account-profile-save')));
await tester.pumpAndSettle();
final l10n = await AppLocalizations.delegate.load(const Locale('en'));
expect(find.text(l10n.networkError), findsOneWidget);
expect(find.text('accountProfileSaveFailed'), findsNothing);
});
testWidgets('should_show_localized_network_copy_when_devices_fail', (
tester,
) async {
final repository = FakeAccountRepository()..throwUnexpected = true;
final auth = await _signedInAuth();
await _pumpPage(
tester,
AccountDevicesPage(),
repository: repository,
auth: auth,
locale: const Locale('id'),
);
final l10n = await AppLocalizations.delegate.load(const Locale('id'));
expect(find.text(l10n.networkError), findsOneWidget);
expect(find.text('accountDevicesLoadFailed'), findsNothing);
});
testWidgets('should_show_localized_network_copy_when_export_fails', (
tester,
) async {
final repository = FakeAccountRepository()..throwUnexpected = true;
final auth = await _signedInAuth();
await _pumpPage(
tester,
AccountExportPage(),
repository: repository,
auth: auth,
);
final l10n = await AppLocalizations.delegate.load(const Locale('en'));
expect(find.text(l10n.networkError), findsOneWidget);
expect(find.text('accountExportLoadFailed'), findsNothing);
});
}
Future<AuthController> _signedInAuth() async {
SharedPreferencesAsyncPlatform.instance =
InMemorySharedPreferencesAsync.empty();
await AuthSessionStore().save(
const AuthSession(
accessToken: 'access',
refreshToken: 'refresh',
user: AuthUser(uid: 'U-K19', nickname: 'Nadia'),
),
);
final client = ApiClient(baseUrl: 'http://127.0.0.1:8081');
final auth = AuthController(AuthApi(client), AuthSessionStore());
await auth.load();
return auth;
}
Future<void> _pumpPage(
WidgetTester tester,
Widget page, {
required FakeAccountRepository repository,
required AuthController auth,
Locale locale = const Locale('en'),
}) async {
tester.view.physicalSize = const Size(390, 844);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.resetPhysicalSize);
addTearDown(tester.view.resetDevicePixelRatio);
await tester.pumpWidget(
MultiProvider(
providers: [
Provider<AccountRepository>.value(value: repository),
ChangeNotifierProvider<AuthController>.value(value: auth),
],
child: MaterialApp(
locale: locale,
supportedLocales: AppLocalizations.supportedLocales,
localizationsDelegates: AppLocalizations.localizationsDelegates,
home: Theme(data: ThemeData.dark(), child: page),
),
),
);
await tester.pumpAndSettle();
}