halkyon/halkyon_learn_flutter/test/app/instance_gate_test.dart

158 lines
5.3 KiB
Dart
Raw Normal View History

import 'package:flutter_test/flutter_test.dart';
import 'package:halkyon_learn_flutter/src/app/instance_gate.dart';
import 'package:halkyon_learn_flutter/src/app/person_app.dart';
import 'package:halkyon_learn_flutter/src/core/instance/instance.dart';
import 'package:halkyon_learn_flutter/src/core/instance/instance_choice.dart';
import 'package:halkyon_learn_flutter/src/feature/auth/widget/session_gate.dart';
import 'package:halkyon_learn_flutter/src/feature/settings/widget/settings_screen.dart';
import 'package:material_ui/material_ui.dart';
import '../support/fake_instance_checker.dart';
import '../support/memory_device_settings_store.dart';
import '../support/memory_instance_store.dart';
import '../support/pump_app.dart';
import '../support/test_dependencies.dart';
void main() {
final builtIn = Instance.parse('learn.halkyon.eu')!;
final other = Instance.parse('learn.example.org')!;
late MemoryInstanceStore store;
late List<Instance> opened;
late List<Instance> forgotten;
setUp(() {
store = MemoryInstanceStore();
opened = [];
forgotten = [];
});
/// Starts the app on a device that [usedBefore] the choice existed, with
/// [answering] instances answering a check.
Future<InstanceChoice> start(
WidgetTester tester, {
bool usedBefore = false,
Set<Instance> answering = const {},
}) async {
tester.view.physicalSize = const Size(412, 900);
tester.view.devicePixelRatio = 1;
addTearDown(tester.view.reset);
final choice = InstanceChoice(
store,
builtIn: builtIn,
forget: (instance) async => forgotten.add(instance),
);
await choice.load(usedBefore: usedBefore);
await tester.pumpWidget(
InstanceGate(
choice: choice,
checker: FakeInstanceChecker(answering),
deviceSettings: MemoryDeviceSettingsStore(),
open: (instance) async {
opened.add(instance);
return testDependencies();
},
app: SessionGate(app: (person) => PersonApp(person: person)),
),
);
await tester.pumpAndSettle();
return choice;
}
/// Opens Settings › Switch account, further down Settings.
Future<void> openSwitcher(WidgetTester tester) async {
await openTab(tester, 'Profile');
await tester.tap(find.byTooltip('Settings'));
await tester.pumpAndSettle();
await tester.scrollUntilVisible(
find.text('Switch account'),
200,
// Settings' list; its citation preview is a scroll view of its own.
scrollable: find
.descendant(
of: find.byType(SettingsScreen),
matching: find.byType(Scrollable),
)
.first,
);
// Built, but perhaps still below the window's edge.
await tester.ensureVisible(find.text('Switch account'));
await tester.pumpAndSettle();
await tester.tap(find.text('Switch account'));
await tester.pumpAndSettle();
}
testWidgets('a new install asks for the instance first, and opens the '
"build's in one tap", (tester) async {
await start(tester);
// The wordmark says it to screen readers.
expect(find.bySemanticsLabel('Welcome to Halkyon Learn'), findsOneWidget);
expect(opened, isEmpty, reason: 'nothing made anywhere yet');
expect(find.byType(TextField), findsNothing, reason: 'no address asked');
await tester.tap(find.text('learn.halkyon.eu'));
await tester.pumpAndSettle();
expect(opened, [builtIn]);
expect(tab('Home'), findsOneWidget);
});
testWidgets('another instance is checked before the app moves there', (
tester,
) async {
await start(tester, answering: {other});
await tester.tap(find.text('Another instance'));
await tester.pumpAndSettle();
expect(
FocusManager.instance.primaryFocus?.context
?.findAncestorWidgetOfExactType<TextField>(),
isNotNull,
reason: 'the address is typed at once',
);
await tester.enterText(find.byType(TextField), 'nowhere.example.org');
await tester.tap(find.text('Continue'));
await tester.pumpAndSettle();
expect(
find.text(
'No instance of Halkyon Learn answers at nowhere.example.org.',
),
findsOneWidget,
);
expect(opened, isEmpty);
await tester.enterText(find.byType(TextField), 'learn.example.org');
await tester.tap(find.text('Continue'));
await tester.pumpAndSettle();
expect(opened, [other]);
});
testWidgets('an install from before goes on without asking', (tester) async {
await start(tester, usedBefore: true);
expect(opened, [builtIn]);
expect(tab('Home'), findsOneWidget);
});
testWidgets('Settings switches between the accounts on the device, and '
'removes one not in use', (tester) async {
store = MemoryInstanceStore((current: builtIn, known: [builtIn, other]));
await start(tester);
await openSwitcher(tester);
expect(find.text('learn.halkyon.eu'), findsWidgets);
await tester.tap(find.text('learn.example.org'));
await tester.pumpAndSettle();
expect(opened, [builtIn, other]);
expect(tab('Home'), findsOneWidget, reason: 'a new app, on Home');
await openSwitcher(tester);
await tester.tap(find.byTooltip('Remove account'));
await tester.pumpAndSettle();
await tester.tap(find.widgetWithText(FilledButton, 'Remove'));
await tester.pumpAndSettle();
expect(forgotten, [builtIn]);
expect(store.kept?.known, [other]);
});
}