Replace the Inbox badge button in MonthHeader with a bottom-nav tab (hidden when notification parsing is disabled). Redirect /inbox → /home when parsing is off, register the Inbox shell branch unconditionally, and add a settings action to the Inbox screen. Move the parsing tile to the top of the profile screen so settings stay reachable when the tab is hidden. Add tests for the nav tab visibility and inbox routing, plus a release-install PowerShell helper that preserves app data. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
83 lines
3.1 KiB
Dart
83 lines
3.1 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:google_fonts/google_fonts.dart';
|
|
import 'package:new_budget/l10n/app_localizations.dart';
|
|
import 'package:new_budget/src/app/theme/app_theme.dart';
|
|
import 'package:new_budget/src/shared/widgets/app_bottom_nav.dart';
|
|
|
|
Widget _build({
|
|
required bool showInbox,
|
|
int inboxCount = 0,
|
|
int activeIndex = 0,
|
|
ValueChanged<int>? onTap,
|
|
}) =>
|
|
MaterialApp(
|
|
theme: AppTheme.light(),
|
|
localizationsDelegates: AppLocalizations.localizationsDelegates,
|
|
supportedLocales: AppLocalizations.supportedLocales,
|
|
home: Scaffold(
|
|
bottomNavigationBar: AppBottomNav(
|
|
activeIndex: activeIndex,
|
|
onTap: onTap ?? (_) {},
|
|
showInbox: showInbox,
|
|
inboxCount: inboxCount,
|
|
),
|
|
),
|
|
);
|
|
|
|
void main() {
|
|
setUpAll(() {
|
|
GoogleFonts.config.allowRuntimeFetching = false;
|
|
});
|
|
|
|
testWidgets('при включённом парсинге видны все 5 вкладок', (tester) async {
|
|
await tester.pumpWidget(_build(showInbox: true));
|
|
|
|
expect(find.text('Home'), findsOneWidget);
|
|
expect(find.text('Inbox'), findsOneWidget);
|
|
expect(find.text('Analytics'), findsOneWidget);
|
|
expect(find.text('Accounts'), findsOneWidget);
|
|
expect(find.text('Profile'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('при выключенном парсинге вкладки Inbox нет', (tester) async {
|
|
await tester.pumpWidget(_build(showInbox: false));
|
|
|
|
expect(find.text('Inbox'), findsNothing);
|
|
expect(find.text('Home'), findsOneWidget);
|
|
expect(find.text('Profile'), findsOneWidget);
|
|
});
|
|
|
|
testWidgets('бэдж показывает счётчик и исчезает при нуле', (tester) async {
|
|
await tester.pumpWidget(_build(showInbox: true, inboxCount: 7));
|
|
expect(find.byType(Badge), findsOneWidget);
|
|
expect(find.text('7'), findsOneWidget);
|
|
|
|
await tester.pumpWidget(_build(showInbox: true, inboxCount: 0));
|
|
expect(find.byType(Badge), findsNothing);
|
|
});
|
|
|
|
testWidgets('тап отдаёт индекс ВЕТКИ, а не видимую позицию', (tester) async {
|
|
final tapped = <int>[];
|
|
await tester.pumpWidget(_build(showInbox: false, onTap: tapped.add));
|
|
|
|
// Inbox скрыт: «Аналитика» — вторая видимая, но её ветка — 2.
|
|
await tester.tap(find.text('Analytics'));
|
|
expect(tapped, [2]);
|
|
|
|
await tester.tap(find.text('Profile'));
|
|
expect(tapped, [2, 4]);
|
|
});
|
|
|
|
testWidgets('активная вкладка определяется по индексу ветки', (tester) async {
|
|
// activeIndex = 2 (аналитика) при скрытом Inbox: подсвечена именно она.
|
|
await tester.pumpWidget(_build(showInbox: false, activeIndex: 2));
|
|
|
|
final analyticsLabel =
|
|
tester.widget<Text>(find.text('Analytics')).style?.fontWeight;
|
|
final homeLabel = tester.widget<Text>(find.text('Home')).style?.fontWeight;
|
|
expect(analyticsLabel, FontWeight.w600);
|
|
expect(homeLabel, FontWeight.w400);
|
|
});
|
|
}
|