230 lines
7.5 KiB
Dart
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();
|
|
}
|