Files
sharedinbox/test/widget/undo_shell_test.dart
Thomas SharedInboxandClaude Sonnet 4.6 651110b389 fix: do not show snackbar for stale undo actions on startup (#113)
Actions persisted to the database triggered a snackbar when the app
restarted. Added a 30-second recency check so only actions created in
the current session show the snackbar; added widget tests covering both
cases.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-16 09:23:49 +02:00

99 lines
3.0 KiB
Dart

import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:sharedinbox/core/models/undo_action.dart';
import 'package:sharedinbox/di.dart';
import 'package:sharedinbox/ui/widgets/undo_shell.dart';
import '../unit/undo_service_test.mocks.dart';
void main() {
late MockUndoRepository mockUndoRepo;
setUp(() {
mockUndoRepo = MockUndoRepository();
when(mockUndoRepo.saveAction(any)).thenAnswer((_) async {});
when(mockUndoRepo.deleteAction(any)).thenAnswer((_) async {});
when(mockUndoRepo.clearHistory()).thenAnswer((_) async {});
});
Widget buildShell(MockUndoRepository repo) {
return ProviderScope(
overrides: [undoRepositoryProvider.overrideWithValue(repo)],
child: const MaterialApp(
home: UndoShell(child: Scaffold(body: Text('content'))),
),
);
}
testWidgets(
'does not show snackbar for stale action loaded from persistence on startup',
(tester) async {
final staleAction = UndoAction(
id: '1',
accountId: 'acc1',
type: UndoType.move,
emailIds: ['e1'],
sourceMailboxPath: 'INBOX',
timestamp: DateTime.now().subtract(const Duration(hours: 1)),
);
when(mockUndoRepo.getHistory(limit: anyNamed('limit')))
.thenAnswer((_) async => [staleAction]);
await tester.pumpWidget(buildShell(mockUndoRepo));
await tester.pumpAndSettle();
expect(find.text('1 email(s) moved'), findsNothing);
},
);
testWidgets('shows snackbar for fresh action pushed in current session',
(tester) async {
when(mockUndoRepo.getHistory(limit: anyNamed('limit')))
.thenAnswer((_) async => []);
await tester.pumpWidget(buildShell(mockUndoRepo));
await tester.pumpAndSettle();
final context = tester.element(find.byType(UndoShell));
final freshAction = UndoAction(
id: '1',
accountId: 'acc1',
type: UndoType.move,
emailIds: ['e1'],
sourceMailboxPath: 'INBOX',
);
await ProviderScope.containerOf(context)
.read(undoServiceProvider.notifier)
.pushAction(freshAction);
await tester.pumpAndSettle();
expect(find.text('1 email(s) moved'), findsOneWidget);
});
testWidgets('shows correct text for delete action (moved to Trash)',
(tester) async {
when(mockUndoRepo.getHistory(limit: anyNamed('limit')))
.thenAnswer((_) async => []);
await tester.pumpWidget(buildShell(mockUndoRepo));
await tester.pumpAndSettle();
final context = tester.element(find.byType(UndoShell));
final deleteAction = UndoAction(
id: '2',
accountId: 'acc1',
type: UndoType.delete,
emailIds: ['e1', 'e2'],
sourceMailboxPath: 'INBOX',
);
await ProviderScope.containerOf(context)
.read(undoServiceProvider.notifier)
.pushAction(deleteAction);
await tester.pumpAndSettle();
expect(find.text('2 email(s) moved to Trash'), findsOneWidget);
});
}