You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
basedFood-app/test/ui/navigation/main_navigation_scaffold_te...

252 lines
9.3 KiB

import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:app_boilerplate/ui/navigation/main_navigation_scaffold.dart';
import 'package:app_boilerplate/ui/navigation/app_router.dart';
import 'package:app_boilerplate/data/local/local_storage_service.dart';
import 'package:app_boilerplate/data/nostr/nostr_service.dart';
import 'package:app_boilerplate/data/nostr/models/nostr_keypair.dart';
import 'package:app_boilerplate/data/sync/sync_engine.dart';
import 'package:app_boilerplate/data/session/session_service.dart';
import 'package:app_boilerplate/data/firebase/firebase_service.dart';
import 'package:app_boilerplate/core/service_locator.dart';
import 'main_navigation_scaffold_test.mocks.dart';
@GenerateMocks([
LocalStorageService,
NostrService,
SyncEngine,
SessionService,
FirebaseService,
])
void main() {
late MockLocalStorageService mockLocalStorageService;
late MockNostrService mockNostrService;
late MockSyncEngine mockSyncEngine;
late MockSessionService mockSessionService;
late MockFirebaseService mockFirebaseService;
setUp(() {
mockLocalStorageService = MockLocalStorageService();
mockNostrService = MockNostrService();
mockSyncEngine = MockSyncEngine();
mockSessionService = MockSessionService();
mockFirebaseService = MockFirebaseService();
// Set default return values for mocks
when(mockSessionService.isLoggedIn).thenReturn(false);
when(mockSessionService.currentUser).thenReturn(null);
when(mockFirebaseService.isEnabled).thenReturn(false);
when(mockNostrService.getRelays()).thenReturn([]);
// Stub NostrService methods that might be called by UI
final mockKeyPair = NostrKeyPair.generate();
when(mockNostrService.generateKeyPair()).thenReturn(mockKeyPair);
// Register services with ServiceLocator
ServiceLocator.instance.registerServices(
localStorageService: mockLocalStorageService,
nostrService: mockNostrService,
syncEngine: mockSyncEngine,
sessionService: mockSessionService,
firebaseService: mockFirebaseService,
);
});
tearDown(() {
// Reset ServiceLocator after each test
ServiceLocator.instance.reset();
});
Widget createTestWidget() {
final appRouter = AppRouter(
sessionService: mockSessionService,
localStorageService: mockLocalStorageService,
nostrService: mockNostrService,
syncEngine: mockSyncEngine,
firebaseService: mockFirebaseService,
);
return MaterialApp(
onGenerateRoute: appRouter.generateRoute,
home: const MainNavigationScaffold(),
);
}
group('MainNavigationScaffold - Navigation', () {
testWidgets('displays bottom navigation bar with correct tabs', (WidgetTester tester) async {
await tester.pumpWidget(createTestWidget());
await tester.pumpAndSettle();
// Check for navigation icons (custom bottom nav, not standard BottomNavigationBar)
expect(find.byIcon(Icons.home), findsWidgets);
expect(find.byIcon(Icons.menu_book), findsWidgets);
expect(find.byIcon(Icons.favorite), findsWidgets);
expect(find.byIcon(Icons.person), findsWidgets);
// Check for labels
expect(find.text('Home'), findsWidgets);
expect(find.text('Recipes'), findsWidgets);
expect(find.text('Favourites'), findsWidgets);
expect(find.text('User'), findsWidgets);
});
testWidgets('displays Add Recipe button in center of bottom nav', (WidgetTester tester) async {
await tester.pumpWidget(createTestWidget());
await tester.pumpAndSettle();
// Find the add icon in the bottom navigation (should be in center)
expect(find.byIcon(Icons.add), findsWidgets);
// The add button is now part of the custom bottom nav, not a FloatingActionButton
});
testWidgets('renders Home screen by default', (WidgetTester tester) async {
await tester.pumpWidget(createTestWidget());
await tester.pumpAndSettle();
// Home text should appear in AppBar
expect(find.text('Home'), findsWidgets);
expect(find.byIcon(Icons.home), findsWidgets);
});
testWidgets('can navigate to Recipes screen', (WidgetTester tester) async {
await tester.pumpWidget(createTestWidget());
await tester.pumpAndSettle();
// Tap Recipes tab
final recipesTab = find.text('Recipes');
expect(recipesTab, findsWidgets);
await tester.tap(recipesTab);
await tester.pumpAndSettle();
// Verify Recipes screen is shown
expect(find.text('Recipes Screen'), findsOneWidget);
expect(find.text('Recipes'), findsWidgets);
});
testWidgets('can navigate to Favourites screen', (WidgetTester tester) async {
await tester.pumpWidget(createTestWidget());
await tester.pumpAndSettle();
// Tap Favourites tab
final favouritesTab = find.text('Favourites');
expect(favouritesTab, findsWidgets);
await tester.tap(favouritesTab);
await tester.pumpAndSettle();
// Verify Favourites screen is shown
expect(find.text('Favourites Screen'), findsOneWidget);
expect(find.text('Favourites'), findsWidgets);
});
testWidgets('can navigate to User/Session screen', (WidgetTester tester) async {
await tester.pumpWidget(createTestWidget());
await tester.pumpAndSettle();
// Tap User tab
final userTab = find.text('User');
expect(userTab, findsWidgets);
await tester.tap(userTab);
await tester.pumpAndSettle();
// Verify User screen is shown
expect(find.text('User'), findsWidgets);
});
testWidgets('Add Recipe button navigates to Add Recipe screen', (WidgetTester tester) async {
await tester.pumpWidget(createTestWidget());
await tester.pumpAndSettle();
// Find all add icons (Home screen has its own FAB, bottom nav has the Add Recipe button)
final addButtons = find.byIcon(Icons.add);
expect(addButtons, findsWidgets);
// The bottom nav add button is in a Material widget with CircleBorder
// Find it by looking for Material widgets with CircleBorder that contain add icons
// We'll tap the last add icon found (should be the bottom nav one, after Home screen's FAB)
final allAddIcons = addButtons.evaluate().toList();
if (allAddIcons.length > 1) {
// Tap the last one (bottom nav button)
await tester.tap(find.byIcon(Icons.add).last);
} else {
// Only one found, tap it
await tester.tap(addButtons.first);
}
await tester.pump(); // Initial pump
await tester.pumpAndSettle(const Duration(seconds: 1)); // Wait for navigation
// Verify Add Recipe screen is shown (check for AppBar title)
// If navigation worked, we should see "Add Recipe" in the AppBar
expect(find.text('Add Recipe'), findsWidgets);
});
testWidgets('settings icon appears in AppBar', (WidgetTester tester) async {
await tester.pumpWidget(createTestWidget());
await tester.pumpAndSettle();
// Settings icon should be in AppBar actions
expect(find.byIcon(Icons.settings), findsWidgets);
});
testWidgets('settings icon is tappable and triggers navigation', (WidgetTester tester) async {
await tester.pumpWidget(createTestWidget());
await tester.pumpAndSettle();
// Find settings icon in AppBar
final settingsIcons = find.byIcon(Icons.settings);
expect(settingsIcons, findsWidgets);
// Verify we're on Home screen initially
expect(find.text('Home'), findsWidgets);
// Tap the first settings icon (should be in AppBar)
// This should trigger navigation to Relay Management
await tester.tap(settingsIcons.first);
await tester.pump(); // Just pump once to trigger navigation
// Verify navigation was attempted (no errors thrown)
// The actual screen content depends on service availability in test environment
});
});
group('MainNavigationScaffold - Screen Rendering', () {
testWidgets('renders all main screens correctly', (WidgetTester tester) async {
await tester.pumpWidget(createTestWidget());
await tester.pumpAndSettle();
// Verify scaffold structure exists
// Custom bottom nav (not standard BottomNavigationBar)
expect(find.byType(Scaffold), findsWidgets);
expect(find.byType(IndexedStack), findsOneWidget);
// Verify navigation icons are present
expect(find.byIcon(Icons.home), findsWidgets);
});
testWidgets('all screens have settings icon in AppBar', (WidgetTester tester) async {
await tester.pumpWidget(createTestWidget());
await tester.pumpAndSettle();
// Check Home screen
expect(find.byIcon(Icons.settings), findsWidgets);
// Navigate to Recipes
await tester.tap(find.text('Recipes'));
await tester.pumpAndSettle();
expect(find.byIcon(Icons.settings), findsWidgets);
// Navigate to Favourites
await tester.tap(find.text('Favourites'));
await tester.pumpAndSettle();
expect(find.byIcon(Icons.settings), findsWidgets);
// Navigate to User
await tester.tap(find.text('User'));
await tester.pumpAndSettle();
expect(find.byIcon(Icons.settings), findsWidgets);
});
});
}

Powered by TurnKey Linux.