diff --git a/README.md b/README.md
index 8fd8b77..a446920 100644
--- a/README.md
+++ b/README.md
@@ -256,6 +256,15 @@ Special thanks to:
Preeti Das
+
+
+
+
+ Jatin Sharma
+
+ |
+
+
@@ -263,8 +272,6 @@ Special thanks to:
Shaik Zainab
|
-
-
@@ -300,6 +307,8 @@ Special thanks to:
Ananya Singh
|
+
+
@@ -307,8 +316,6 @@ Special thanks to:
DMounas
|
-
-
@@ -323,13 +330,6 @@ Special thanks to:
GAURI
|
-
-
-
-
- Jatin Sharma
-
- |
diff --git a/test/ui/screens/splash_screen_test.dart b/test/ui/screens/splash_screen_test.dart
new file mode 100644
index 0000000..28721b6
--- /dev/null
+++ b/test/ui/screens/splash_screen_test.dart
@@ -0,0 +1,348 @@
+import 'package:flutter/material.dart';
+import 'package:flutter_test/flutter_test.dart';
+import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:mockito/mockito.dart';
+import 'package:mockito/annotations.dart';
+
+import 'package:texterra/cubit/canvas_cubit.dart';
+import 'package:texterra/cubit/canvas_state.dart';
+import 'package:texterra/constants/color_constants.dart';
+import 'package:texterra/ui/screens/saved_pages.dart';
+
+// Generate mocks
+@GenerateMocks([CanvasCubit])
+import 'saved_pages_test.mocks.dart';
+
+void main() {
+ late MockCanvasCubit mockCanvasCubit;
+
+ setUp(() {
+ mockCanvasCubit = MockCanvasCubit();
+
+ // Setup default state
+ when(mockCanvasCubit.state).thenReturn(CanvasState.initial());
+ when(mockCanvasCubit.stream)
+ .thenAnswer((_) => Stream.value(CanvasState.initial()));
+ });
+
+ Widget createTestWidget() {
+ return MaterialApp(
+ home: BlocProvider.value(
+ value: mockCanvasCubit,
+ child: const SavedPagesScreen(),
+ ),
+ );
+ }
+
+ group('SavedPagesScreen Widget Tests', () {
+ testWidgets('displays empty state when no pages saved',
+ (WidgetTester tester) async {
+ // Arrange
+ when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => []);
+ when(mockCanvasCubit.getPagePreview(any)).thenAnswer((_) async => null);
+
+ // Act
+ await tester.pumpWidget(createTestWidget());
+ await tester.pumpAndSettle();
+
+ // Assert
+ expect(find.byIcon(Icons.description_outlined), findsOneWidget);
+ expect(find.text('No saved pages yet'), findsOneWidget);
+ expect(find.text('Create and save your first page!'), findsOneWidget);
+ });
+
+ testWidgets('displays list of saved pages', (WidgetTester tester) async {
+ // Arrange
+ final mockPages = ['Page 1', 'Page 2', 'Page 3'];
+ when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => mockPages);
+
+ for (var pageName in mockPages) {
+ when(mockCanvasCubit.getPagePreview(pageName)).thenAnswer((_) async => {
+ 'name': pageName,
+ 'textCount': 5,
+ 'backgroundColor': ColorConstants.dialogTextBlack,
+ 'timestamp': DateTime.now().millisecondsSinceEpoch,
+ 'lastModified': DateTime.now(),
+ 'label': '',
+ });
+ }
+
+ // Act
+ await tester.pumpWidget(createTestWidget());
+ await tester.pumpAndSettle();
+
+ // Assert
+ expect(find.text('Page 1'), findsOneWidget);
+ expect(find.text('Page 2'), findsOneWidget);
+ expect(find.text('Page 3'), findsOneWidget);
+ expect(find.byType(Card), findsNWidgets(3));
+ });
+
+ testWidgets('displays correct text count for pages',
+ (WidgetTester tester) async {
+ // Arrange
+ when(mockCanvasCubit.getSavedPages())
+ .thenAnswer((_) async => ['Test Page']);
+ when(mockCanvasCubit.getPagePreview('Test Page'))
+ .thenAnswer((_) async => {
+ 'name': 'Test Page',
+ 'textCount': 3,
+ 'backgroundColor': ColorConstants.dialogTextBlack,
+ 'timestamp': DateTime.now().millisecondsSinceEpoch,
+ 'lastModified': DateTime.now(),
+ 'label': '',
+ });
+
+ // Act
+ await tester.pumpWidget(createTestWidget());
+ await tester.pumpAndSettle();
+
+ // Assert
+ expect(find.text('3 text items'), findsOneWidget);
+ });
+
+ testWidgets('has refresh button in app bar', (WidgetTester tester) async {
+ // Arrange
+ when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => []);
+
+ // Act
+ await tester.pumpWidget(createTestWidget());
+ await tester.pumpAndSettle();
+
+ // Assert
+ expect(find.byIcon(Icons.refresh), findsOneWidget);
+ });
+
+ testWidgets('displays description icon when no label',
+ (WidgetTester tester) async {
+ // Arrange
+ when(mockCanvasCubit.getSavedPages())
+ .thenAnswer((_) async => ['No Label']);
+ when(mockCanvasCubit.getPagePreview('No Label')).thenAnswer((_) async => {
+ 'name': 'No Label',
+ 'textCount': 2,
+ 'backgroundColor': ColorConstants.dialogTextBlack,
+ 'timestamp': DateTime.now().millisecondsSinceEpoch,
+ 'lastModified': DateTime.now(),
+ 'label': '',
+ });
+
+ // Act
+ await tester.pumpWidget(createTestWidget());
+ await tester.pumpAndSettle();
+
+ // Assert
+ expect(find.byIcon(Icons.description), findsOneWidget);
+ });
+
+ testWidgets('shows open and delete buttons for each page',
+ (WidgetTester tester) async {
+ // Arrange
+ when(mockCanvasCubit.getSavedPages())
+ .thenAnswer((_) async => ['Test Page']);
+ when(mockCanvasCubit.getPagePreview('Test Page'))
+ .thenAnswer((_) async => {
+ 'name': 'Test Page',
+ 'textCount': 2,
+ 'backgroundColor': ColorConstants.dialogTextBlack,
+ 'timestamp': DateTime.now().millisecondsSinceEpoch,
+ 'lastModified': DateTime.now(),
+ 'label': '',
+ });
+
+ // Act
+ await tester.pumpWidget(createTestWidget());
+ await tester.pumpAndSettle();
+
+ // Assert
+ expect(find.byIcon(Icons.open_in_new), findsOneWidget);
+ expect(find.byIcon(Icons.delete_outline), findsOneWidget);
+ });
+
+ testWidgets('tapping page card calls loadPage',
+ (WidgetTester tester) async {
+ // Arrange
+ when(mockCanvasCubit.getSavedPages())
+ .thenAnswer((_) async => ['Clickable Page']);
+ when(mockCanvasCubit.getPagePreview('Clickable Page'))
+ .thenAnswer((_) async => {
+ 'name': 'Clickable Page',
+ 'textCount': 2,
+ 'backgroundColor': ColorConstants.dialogTextBlack,
+ 'timestamp': DateTime.now().millisecondsSinceEpoch,
+ 'lastModified': DateTime.now(),
+ 'label': '',
+ });
+ when(mockCanvasCubit.loadPage('Clickable Page')).thenAnswer((_) async {});
+
+ // Act
+ await tester.pumpWidget(createTestWidget());
+ await tester.pumpAndSettle();
+
+ await tester.tap(find.byType(InkWell).first);
+ await tester.pumpAndSettle();
+
+ // Assert
+ verify(mockCanvasCubit.loadPage('Clickable Page')).called(1);
+ });
+
+ testWidgets('confirming delete calls deletePage',
+ (WidgetTester tester) async {
+ // Arrange
+ when(mockCanvasCubit.getSavedPages())
+ .thenAnswer((_) async => ['Delete Me']);
+ when(mockCanvasCubit.getPagePreview('Delete Me'))
+ .thenAnswer((_) async => {
+ 'name': 'Delete Me',
+ 'textCount': 2,
+ 'backgroundColor': ColorConstants.dialogTextBlack,
+ 'timestamp': DateTime.now().millisecondsSinceEpoch,
+ 'lastModified': DateTime.now(),
+ 'label': '',
+ });
+ when(mockCanvasCubit.deletePage('Delete Me')).thenAnswer((_) async {});
+
+ // Act
+ await tester.pumpWidget(createTestWidget());
+ await tester.pumpAndSettle();
+
+ await tester.tap(find.byIcon(Icons.delete_outline));
+ await tester.pumpAndSettle();
+
+ await tester.tap(find.widgetWithText(ElevatedButton, 'Delete'));
+ await tester.pumpAndSettle();
+
+ // Assert
+ verify(mockCanvasCubit.deletePage('Delete Me')).called(1);
+ });
+
+ testWidgets('canceling delete closes dialog without deleting',
+ (WidgetTester tester) async {
+ // Arrange
+ when(mockCanvasCubit.getSavedPages())
+ .thenAnswer((_) async => ['Keep Me']);
+ when(mockCanvasCubit.getPagePreview('Keep Me')).thenAnswer((_) async => {
+ 'name': 'Keep Me',
+ 'textCount': 2,
+ 'backgroundColor': ColorConstants.dialogTextBlack,
+ 'timestamp': DateTime.now().millisecondsSinceEpoch,
+ 'lastModified': DateTime.now(),
+ 'label': '',
+ });
+
+ // Act
+ await tester.pumpWidget(createTestWidget());
+ await tester.pumpAndSettle();
+
+ await tester.tap(find.byIcon(Icons.delete_outline));
+ await tester.pumpAndSettle();
+
+ await tester.tap(find.text('Cancel'));
+ await tester.pumpAndSettle();
+
+ // Assert
+ verifyNever(mockCanvasCubit.deletePage('Keep Me'));
+ expect(find.text('Delete Page'), findsNothing);
+ });
+
+ testWidgets('refresh button reloads pages', (WidgetTester tester) async {
+ // Arrange
+ when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => []);
+
+ // Act
+ await tester.pumpWidget(createTestWidget());
+ await tester.pumpAndSettle();
+
+ await tester.tap(find.byIcon(Icons.refresh));
+ await tester.pumpAndSettle();
+
+ // Assert
+ verify(mockCanvasCubit.getSavedPages()).called(greaterThan(1));
+ });
+ });
+
+ group('SavedPagesScreen Time Formatting Tests', () {
+ testWidgets('displays "Just now" for recent pages',
+ (WidgetTester tester) async {
+ // Arrange
+ when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => ['Recent']);
+ when(mockCanvasCubit.getPagePreview('Recent')).thenAnswer((_) async => {
+ 'name': 'Recent',
+ 'textCount': 1,
+ 'backgroundColor': ColorConstants.dialogTextBlack,
+ 'timestamp': DateTime.now().millisecondsSinceEpoch,
+ 'lastModified': DateTime.now(),
+ 'label': '',
+ });
+
+ // Act
+ await tester.pumpWidget(createTestWidget());
+ await tester.pumpAndSettle();
+
+ // Assert
+ expect(find.textContaining('Just now'), findsOneWidget);
+ });
+
+ testWidgets('displays hours ago for pages modified hours ago',
+ (WidgetTester tester) async {
+ // Arrange
+ final twoHoursAgo = DateTime.now().subtract(const Duration(hours: 2));
+ when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => ['Old']);
+ when(mockCanvasCubit.getPagePreview('Old')).thenAnswer((_) async => {
+ 'name': 'Old',
+ 'textCount': 1,
+ 'backgroundColor': ColorConstants.dialogTextBlack,
+ 'timestamp': twoHoursAgo.millisecondsSinceEpoch,
+ 'lastModified': twoHoursAgo,
+ 'label': '',
+ });
+
+ // Act
+ await tester.pumpWidget(createTestWidget());
+ await tester.pumpAndSettle();
+
+ // Assert
+ expect(find.textContaining('2 hours ago'), findsOneWidget);
+ });
+
+ testWidgets('displays days ago for pages modified days ago',
+ (WidgetTester tester) async {
+ // Arrange
+ final threeDaysAgo = DateTime.now().subtract(const Duration(days: 3));
+ when(mockCanvasCubit.getSavedPages()).thenAnswer((_) async => ['Older']);
+ when(mockCanvasCubit.getPagePreview('Older')).thenAnswer((_) async => {
+ 'name': 'Older',
+ 'textCount': 1,
+ 'backgroundColor': ColorConstants.dialogTextBlack,
+ 'timestamp': threeDaysAgo.millisecondsSinceEpoch,
+ 'lastModified': threeDaysAgo,
+ 'label': '',
+ });
+
+ // Act
+ await tester.pumpWidget(createTestWidget());
+ await tester.pumpAndSettle();
+
+ // Assert
+ expect(find.textContaining('3 days ago'), findsOneWidget);
+ });
+ });
+
+ group('SavedPagesScreen Error Handling Tests', () {
+ testWidgets('handles null preview gracefully', (WidgetTester tester) async {
+ // Arrange
+ when(mockCanvasCubit.getSavedPages())
+ .thenAnswer((_) async => ['Bad Page']);
+ when(mockCanvasCubit.getPagePreview('Bad Page'))
+ .thenAnswer((_) async => null);
+
+ // Act
+ await tester.pumpWidget(createTestWidget());
+ await tester.pumpAndSettle();
+
+ // Assert - Should still display the page with default values
+ expect(find.text('Bad Page'), findsOneWidget);
+ expect(find.text('0 text items'), findsOneWidget);
+ });
+ });
+}
|