import 'dart:async'; import 'package:flutter_test/flutter_test.dart'; import 'package:iop_client/main.dart'; import 'package:iop_client/src/integrations/nexo/nexo_notification_host_integration.dart'; import 'support/client_test_harness.dart'; void main() { testWidgets( 'notification stream from NexoNotificationHostIntegration connects to UI snackbar', (WidgetTester tester) async { final fakeClient = FakeClientWireClient(shouldSuccess: true); final fakeStatusRepo = FakeControlPlaneStatusRepository(); // Create a fake NexoNotificationClient that emits a notification. final notificationController = StreamController>(); final fakeNexoClient = FakeNexoClientsForUiTest(notificationController); final fakeHost = NexoNotificationHostIntegration( pushClient: fakeNexoClient, ); await tester.pumpWidget( IopClientApp( testClient: fakeClient, statusRepository: fakeStatusRepo, notificationHost: fakeHost, ), ); await tester.pump(); await tester.pump(const Duration(milliseconds: 100)); // Verify wire status shows connected. expect(find.text('CONNECTED'), findsOneWidget); // Emit a notification message through the fake client. notificationController.add(const { 'type': 'message', 'message': 'Hello from Nexo', 'channel_name': 'general', 'sender_name': 'test-user', }); await tester.pump(); // Verify the SnackBar appears in the UI. expect(find.textContaining('Hello from Nexo'), findsOneWidget); await notificationController.close(); }, ); testWidgets( 'notification stream shows channel-only message when sender is empty', (WidgetTester tester) async { final fakeClient = FakeClientWireClient(shouldSuccess: true); final fakeStatusRepo = FakeControlPlaneStatusRepository(); final notificationController = StreamController>(); final fakeNexoClient = FakeNexoClientsForUiTest(notificationController); final fakeHost = NexoNotificationHostIntegration( pushClient: fakeNexoClient, ); await tester.pumpWidget( IopClientApp( testClient: fakeClient, statusRepository: fakeStatusRepo, notificationHost: fakeHost, ), ); await tester.pump(); await tester.pump(const Duration(milliseconds: 100)); expect(find.text('CONNECTED'), findsOneWidget); // Emit notification with empty sender — should show just the message. notificationController.add(const { 'type': 'message', 'message': 'Direct message content', 'channel_name': 'alerts', 'sender_name': '', }); await tester.pump(); // When sender is empty, only message content is shown. expect(find.textContaining('Direct message content'), findsOneWidget); await notificationController.close(); }, ); testWidgets('notification stream ignores non-message events (e.g. system)', ( WidgetTester tester, ) async { final fakeClient = FakeClientWireClient(shouldSuccess: true); final fakeStatusRepo = FakeControlPlaneStatusRepository(); final notificationController = StreamController>(); final fakeNexoClient = FakeNexoClientsForUiTest(notificationController); final fakeHost = NexoNotificationHostIntegration( pushClient: fakeNexoClient, ); await tester.pumpWidget( IopClientApp( testClient: fakeClient, statusRepository: fakeStatusRepo, notificationHost: fakeHost, ), ); await tester.pump(); await tester.pump(const Duration(milliseconds: 100)); // Emit a non-message type. notificationController.add(const { 'type': 'system', 'message': 'System notification', }); await tester.pump(); // No SnackBar should appear for non-message types. expect(find.textContaining('System notification'), findsNothing); await notificationController.close(); }); }