169 lines
5.6 KiB
Dart
169 lines
5.6 KiB
Dart
import 'package:drift/native.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:focus_seed/src/app/focus_seed_app.dart';
|
|
import 'package:focus_seed/src/data/focus_seed_store.dart';
|
|
import 'package:focus_seed/src/data/local/focus_seed_database.dart';
|
|
import 'package:focus_seed/src/models/language_preference.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
void main() {
|
|
setUp(() {
|
|
SharedPreferences.setMockInitialValues({});
|
|
});
|
|
|
|
test('locale policy defaults to English for release and Chinese for dev', () {
|
|
expect(focusSeedDefaultLocale(isRelease: true), const Locale('en'));
|
|
expect(focusSeedDefaultLocale(), const Locale('zh'));
|
|
});
|
|
|
|
testWidgets('Today guides the user from intention to focus', (tester) async {
|
|
await pumpFocusSeedApp(tester, locale: const Locale('en'));
|
|
|
|
expect(find.text('Focus Seed'), findsOneWidget);
|
|
expect(find.text("TODAY'S FOCUS"), findsOneWidget);
|
|
expect(find.text("Set today's focus"), findsOneWidget);
|
|
|
|
await tester.tap(find.text("Name today's focus"));
|
|
await tester.pumpAndSettle();
|
|
await tester.enterText(
|
|
find.byType(TextField),
|
|
'Finish the launch checklist',
|
|
);
|
|
await tester.tap(find.text('Save'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('Finish the launch checklist'), findsOneWidget);
|
|
expect(find.text('Start 25 min'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('bottom navigation exposes Journey and Me', (tester) async {
|
|
await pumpFocusSeedApp(tester, locale: const Locale('en'));
|
|
|
|
await tester.tap(find.text('Journey'));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('Progress'), findsOneWidget);
|
|
|
|
await tester.tap(find.text('Me'));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('Your garden'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('Me manages local data without JSON tools', (tester) async {
|
|
await pumpFocusSeedApp(tester, locale: const Locale('en'));
|
|
|
|
await tester.tap(find.text('Me'));
|
|
await tester.pumpAndSettle();
|
|
|
|
final meScroll = find.byType(Scrollable).first;
|
|
expect(find.text('Local records'), findsOneWidget);
|
|
expect(find.text('Clear today'), findsOneWidget);
|
|
await tester.scrollUntilVisible(
|
|
find.text('Delete all data'),
|
|
180,
|
|
scrollable: meScroll,
|
|
);
|
|
expect(find.text('Delete all data'), findsOneWidget);
|
|
expect(find.text('Export JSON'), findsNothing);
|
|
expect(find.text('Import JSON'), findsNothing);
|
|
});
|
|
|
|
testWidgets('Journey opens history detail with empty states', (tester) async {
|
|
await pumpFocusSeedApp(tester, locale: const Locale('en'));
|
|
|
|
await tester.tap(find.text('Journey'));
|
|
await tester.pumpAndSettle();
|
|
|
|
final journeyScroll = find.byType(Scrollable).first;
|
|
await tester.scrollUntilVisible(
|
|
find.text('7-day rhythm'),
|
|
180,
|
|
scrollable: journeyScroll,
|
|
);
|
|
expect(find.text('7-day rhythm'), findsOneWidget);
|
|
await tester.scrollUntilVisible(
|
|
find.text('Record library'),
|
|
180,
|
|
scrollable: journeyScroll,
|
|
);
|
|
expect(find.text('Record library'), findsOneWidget);
|
|
|
|
await tester.tap(find.text('Record library'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('History'), findsOneWidget);
|
|
expect(find.text('No focus sessions yet'), findsOneWidget);
|
|
|
|
await tester.tap(find.text('Notes'));
|
|
await tester.pumpAndSettle();
|
|
expect(find.text('No notes yet'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('Today remains usable at narrow width and 200 percent text', (
|
|
tester,
|
|
) async {
|
|
tester.view.physicalSize = const Size(320, 700);
|
|
tester.view.devicePixelRatio = 1;
|
|
tester.platformDispatcher.textScaleFactorTestValue = 2;
|
|
addTearDown(() {
|
|
tester.view.resetPhysicalSize();
|
|
tester.view.resetDevicePixelRatio();
|
|
tester.platformDispatcher.clearTextScaleFactorTestValue();
|
|
});
|
|
|
|
await pumpFocusSeedApp(tester, locale: const Locale('en'));
|
|
|
|
expect(find.text('Focus Seed'), findsOneWidget);
|
|
expect(find.byType(Scrollable), findsWidgets);
|
|
expect(tester.takeException(), isNull);
|
|
});
|
|
|
|
testWidgets('development default uses concise Chinese copy', (tester) async {
|
|
await pumpFocusSeedApp(tester);
|
|
|
|
expect(find.text('Focus Seed'), findsOneWidget);
|
|
expect(find.text('\u4eca\u65e5\u91cd\u70b9'), findsOneWidget);
|
|
expect(find.text('\u8bbe\u7f6e\u4eca\u65e5\u91cd\u70b9'), findsOneWidget);
|
|
await tester.scrollUntilVisible(
|
|
find.text('\u8ba1\u5212\u4e00\u4e2a\u660e\u786e\u4efb\u52a1'),
|
|
180,
|
|
);
|
|
expect(
|
|
find.text('\u8ba1\u5212\u4e00\u4e2a\u660e\u786e\u4efb\u52a1'),
|
|
findsOneWidget,
|
|
);
|
|
});
|
|
|
|
testWidgets('development language switch changes the active locale', (
|
|
tester,
|
|
) async {
|
|
await pumpFocusSeedApp(tester);
|
|
|
|
await tester.tap(find.text('\u6211\u7684'));
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('\u8bed\u8a00'), findsOneWidget);
|
|
final languageSegments = find.byType(SegmentedButton<LanguagePreference>);
|
|
final widget = tester.widget<SegmentedButton<LanguagePreference>>(
|
|
languageSegments,
|
|
);
|
|
widget.onSelectionChanged?.call({LanguagePreference.english});
|
|
await tester.pumpAndSettle();
|
|
|
|
expect(find.text('Language'), findsOneWidget);
|
|
expect(find.text('Development only'), findsOneWidget);
|
|
});
|
|
}
|
|
|
|
Future<void> pumpFocusSeedApp(WidgetTester tester, {Locale? locale}) async {
|
|
final database = FocusSeedDatabase(NativeDatabase.memory());
|
|
addTearDown(database.close);
|
|
await tester.pumpWidget(
|
|
FocusSeedApp(
|
|
locale: locale,
|
|
focusSeedStore: FocusSeedStore(database: database),
|
|
),
|
|
);
|
|
await tester.pumpAndSettle();
|
|
}
|