Skip to content

Commit

Permalink
messy tests
Browse files Browse the repository at this point in the history
Signed-off-by: Zixuan James Li <[email protected]>
  • Loading branch information
PIG208 committed Jan 7, 2025
1 parent 06a99ff commit 5df2dd6
Show file tree
Hide file tree
Showing 3 changed files with 113 additions and 13 deletions.
21 changes: 11 additions & 10 deletions test/model/store_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -501,17 +501,18 @@ void main() {
users.map((expected) => (it) => it.fullName.equals(expected.fullName)));
}));

test('does not retry registerQueue on invalid API key', () => awaitFakeAsync((async) async {
await prepareStore();
test('GlobalStore.perAccount on INVALID_API_KEY', () => awaitFakeAsync((async) async {
addTearDown(testBinding.reset);

// Try to load, but the API key is told to be invalid.
globalStore.useCachedApiConnections = true;
connection.prepare(httpStatus: 400, json: {
'result': 'error', 'code': 'INVALID_API_KEY',
'msg': 'Invalid API key',
});
await check(UpdateMachine.load(globalStore, eg.selfAccount.id))
.throws<ZulipApiException>();
await testBinding.globalStore.insertAccount(eg.selfAccount.toCompanion(false));
testBinding.globalStore.loadPerAccountException = ZulipApiException(
routeName: '/register', code: 'INVALID_API_KEY', httpStatus: 400,
data: {}, message: '');
await check(testBinding.globalStore.perAccount(eg.selfAccount.id))
.throws<AccountNotFoundException>();

check(testBinding.globalStore.takeDoRemoveAccountCalls())
.single.equals(eg.selfAccount.id);
}));

// TODO test UpdateMachine.load starts polling loop
Expand Down
2 changes: 1 addition & 1 deletion test/widgets/actions_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ void main() {
check(findLoadingPage).findsNothing();

final removedRoutes = <Route<dynamic>>[];
testNavObserver.onRemoved = (route, prevRoute) => removedRoutes.add(route);
testNavObserver.onReplaced = (route, prevRoute) => removedRoutes.add(prevRoute!);

final context = tester.element(find.byType(MaterialApp));
final future = logOutAccount(GlobalStoreWidget.of(context), account1.id);
Expand Down
103 changes: 101 additions & 2 deletions test/widgets/store_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ import '../model/binding.dart';
import '../example_data.dart' as eg;
import '../model/store_checks.dart';
import '../model/test_store.dart';
import '../notifications/display_test.dart';
import '../test_navigation.dart';
import 'dialog_checks.dart';

/// A widget whose state uses [PerAccountStoreAwareStateMixin].
Expand Down Expand Up @@ -119,8 +121,103 @@ void main() {
.contains('consider MaterialAccountWidgetRoute');
});

testWidgets('PerAccountStoreWidget reset to choose-account page'
' when logging out on invalid API key', (tester) async {
// goal: test if there is remaining routes -> no route is pushed
// if there is none -> push a choose-account page route.

testWidgets('PerAccountStoreWidget push choose-account page route if removing the last route', (tester) async {
final testNavObserver = TestNavigatorObserver();
Route<void>? removedRoute;
Route<void>? newRoute, replacedRoute;
testNavObserver.onRemoved = (route, prevRoute) => removedRoute = route;
testNavObserver.onReplaced = (route, prevRoute) {
assert(newRoute == null && replacedRoute == null);
newRoute = route!;
replacedRoute = prevRoute!;
};

const selfAccountLoadDuration = Duration(seconds: 5);
testBinding.globalStore.loadPerAccountDuration = selfAccountLoadDuration;
testBinding.globalStore.loadPerAccountException = ZulipApiException(
routeName: '/register', code: 'INVALID_API_KEY', httpStatus: 400,
data: {}, message: '');
await tester.pumpWidget(ZulipApp(navigatorObservers: [testNavObserver]));
await tester.pump();

const otherAccountLoadDuration = Duration(seconds: 10);
testBinding.globalStore.loadPerAccountException = null;
await openNotification(tester, eg.otherAccount, eg.streamMessage());

assert(otherAccountLoadDuration > selfAccountLoadDuration);

await tester.pump(selfAccountLoadDuration);
// check(testBinding.globalStore.takeDoRemoveAccountCalls().single)
// .equals(eg.selfAccount.id);
check(removedRoute).isNull();
check(replacedRoute).isNotNull();
});

testWidgets('PerAccountStoreWidget does not remove or replace route if removing non-root route', (tester) async {
final testNavObserver = TestNavigatorObserver();
Route<void>? removedRoute;
Route<void>? newRoute, replacedRoute;
testNavObserver.onRemoved = (route, prevRoute) => removedRoute = route;
testNavObserver.onReplaced = (route, prevRoute) {
assert(newRoute == null && replacedRoute == null);
newRoute = route!;
replacedRoute = prevRoute!;
};
await tester.pumpWidget(ZulipApp(navigatorObservers: [testNavObserver]));
await tester.pump();

testBinding.globalStore.loadPerAccountException = ZulipApiException(
routeName: '/register', code: 'INVALID_API_KEY', httpStatus: 400,
data: {}, message: '');
await openNotification(tester, eg.otherAccount, eg.streamMessage());
await tester.pump();
await tester.pump(TestGlobalStore.removeAccountDuration);
await tester.pump(const Duration(milliseconds: 250));
check(testBinding.globalStore.takeDoRemoveAccountCalls().single)
.equals(eg.otherAccount.id);

await tester.pump();
check(removedRoute).isNull();
check(newRoute).isNull();
check(replacedRoute).isNull();
});

testWidgets('2 PerAccountStoreWidget reset to choose-account page when logging out on invalid API key', (tester) async {
await testBinding.globalStore.add(eg.selfAccount, eg.initialSnapshot());
addTearDown(testBinding.reset);

testBinding.globalStore.loadPerAccountException = ZulipApiException(
routeName: '/register', code: 'INVALID_API_KEY', httpStatus: 400,
data: {}, message: '');
final pushedRoutes = <Route<void>>[];
NavigatorObserver testNavObserver = TestNavigatorObserver()
..onPushed = (route, prevRoute) => pushedRoutes.add(route);
await tester.pumpWidget(ZulipApp(navigatorObservers: [testNavObserver]));
await tester.pump(); // start to load account
check(find.byType(CircularProgressIndicator)).findsOne();
check(find.byType(ChooseAccountPage)).findsNothing();
check(find.byType(BackButton)).findsNothing();

await tester.pump(Duration.zero); // wait for loading
await tester.pump(TestGlobalStore.removeAccountDuration);
await tester.pump(const Duration(milliseconds: 250)); // wait for animation
check(testBinding.globalStore.takeDoRemoveAccountCalls())
.single.equals(eg.selfAccount.id);
check(find.byType(CircularProgressIndicator)).findsNothing();
check(find.byType(ChooseAccountPage)).findsOne();
// Choose-account page's route should be at the root level.
check(find.byType(BackButton)).findsNothing();
checkErrorDialog(tester,
expectedTitle: 'Could not connect',
expectedMessage:
'Your account at https://chat.example/ could not be authenticated.'
' Please try logging in again or use another account.');
});

testWidgets('PerAccountStoreWidget reset to choose-account page when logging out on invalid API key', (tester) async {
await testBinding.globalStore.add(eg.selfAccount, eg.initialSnapshot());
addTearDown(testBinding.reset);

Expand All @@ -147,6 +244,8 @@ void main() {
await tester.pump(loadPerAccountDuration);
await tester.pump(TestGlobalStore.removeAccountDuration);
await tester.pump(const Duration(milliseconds: 250)); // wait for animation
check(testBinding.globalStore.takeDoRemoveAccountCalls())
.single.equals(eg.selfAccount.id);
check(find.byType(CircularProgressIndicator)).findsNothing();
check(find.byType(ChooseAccountPage)).findsOne();
// Choose-account page's route should be at the root level.
Expand Down

0 comments on commit 5df2dd6

Please sign in to comment.