Skip to content

Commit

Permalink
Create unit tests for robot notifications (#51)
Browse files Browse the repository at this point in the history
Co-authored-by: Gold87 <[email protected]>
  • Loading branch information
EmeraldWither and Gold872 authored Jul 12, 2024
1 parent b0d5f56 commit 942f7b0
Show file tree
Hide file tree
Showing 3 changed files with 206 additions and 1 deletion.
78 changes: 78 additions & 0 deletions test/pages/dashboard_page_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'dart:io';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';

import 'package:elegant_notification/elegant_notification.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:shared_preferences/shared_preferences.dart';
Expand Down Expand Up @@ -912,4 +913,81 @@ void main() {

expect(find.byType(SettingsDialog), findsOneWidget);
});

testWidgets(
'Robot Notifications',
(widgetTester) async {
FlutterError.onError = ignoreOverflowErrors;
final Map<String, dynamic> data = {
'title': 'Robot Notification Title',
'description': 'Robot Notification Description',
'level': 'INFO'
};

MockNTConnection connection = createMockOnlineNT4(virtualTopics: [
NT4Topic(
name: '/Elastic/RobotNotifications',
type: NT4TypeStr.kString,
properties: {},
)
], virtualValues: {
'/Elastic/RobotNotifications': jsonEncode(data)
});
MockNT4Subscription mockSub = MockNT4Subscription();

List<Function(Object?, int)> listeners = [];
when(mockSub.listen(any)).thenAnswer(
(realInvocation) {
listeners.add(realInvocation.positionalArguments[0]);
mockSub.updateValue(jsonEncode(data), 0);
},
);

when(mockSub.updateValue(any, any)).thenAnswer(
(invoc) {
for (var value in listeners) {
value.call(
invoc.positionalArguments[0], invoc.positionalArguments[1]);
}
},
);

when(connection.subscribeAll(any, any)).thenAnswer(
(realInvocation) {
return mockSub;
},
);

final notificationWidget =
find.widgetWithText(ElegantNotification, data['title']);

await widgetTester.pumpWidget(
MaterialApp(
home: DashboardPage(
ntConnection: connection,
preferences: preferences,
version: '0.0.0.0',
),
),
);
expect(notificationWidget, findsNothing);

await widgetTester.pumpAndSettle();
connection
.subscribeAll('/Elastic/robotnotifications', 0.2)
.updateValue(jsonEncode(data), 1);

await widgetTester.pump();

expect(notificationWidget, findsOneWidget);

await widgetTester.pumpAndSettle();

expect(notificationWidget, findsNothing);

connection
.subscribeAll('/Elastic/robotnotifications', 0.2)
.updateValue(jsonEncode(data), 1);
},
);
}
114 changes: 114 additions & 0 deletions test/services/robot_notifications_listener_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import 'dart:convert';

import 'package:flutter/material.dart';

import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';

import 'package:elastic_dashboard/services/robot_notifications_listener.dart';
import '../test_util.dart';
import '../test_util.mocks.dart';

class MockNotificationCallback extends Mock {
void call(String? title, String? description, Icon? icon);
}

void main() {
test("Robot Notifications (Initial Connection | No Existing Data) ", () {
MockNTConnection mockConnection = createMockOnlineNT4();

// Create a mock for the onNotification callback
MockNotificationCallback mockOnNotification = MockNotificationCallback();

RobotNotificationsListener notifications = RobotNotificationsListener(
ntConnection: mockConnection,
onNotification: mockOnNotification.call,
);

notifications.listen();

// Verify that subscribeAll was called with the specific parameters
verify(mockConnection.subscribeAll('/Elastic/robotnotifications', 0.2))
.called(1);
verify(mockConnection.addDisconnectedListener(any)).called(1);

// Verify that no other interactions have been made with the mockConnection
verifyNoMoreInteractions(mockConnection);

// Verify that the onNotification callback was never called
verifyNever(mockOnNotification.call(any, any, any));
});

test("Robot Notifications (Initial Connection | Existing Data) ", () {
MockNTConnection mockConnection = createMockOnlineNT4();
MockNT4Subscription mockSub = MockNT4Subscription();

Map<String, dynamic> data = {
'title': 'Title1',
'description': 'Description1',
'level': 'Info'
};

List<Function(Object?, int)> listeners = [];
when(mockSub.listen(any)).thenAnswer(
(realInvocation) {
listeners.add(realInvocation.positionalArguments[0]);
mockSub.updateValue(jsonEncode(data), 0);
},
);

when(mockSub.updateValue(any, any)).thenAnswer(
(invoc) {
for (var value in listeners) {
value.call(
invoc.positionalArguments[0], invoc.positionalArguments[1]);
}
},
);

when(mockConnection.subscribeAll(any, any)).thenAnswer(
(realInvocation) {
mockSub.updateValue(jsonEncode(data), 0);
return mockSub;
},
);

// Create a mock for the onNotification callback
MockNotificationCallback mockOnNotification = MockNotificationCallback();

RobotNotificationsListener notifications = RobotNotificationsListener(
ntConnection: mockConnection,
onNotification: mockOnNotification.call,
);

notifications.listen();

// Verify that subscribeAll was called with the specific parameters
verify(mockConnection.subscribeAll('/Elastic/robotnotifications', 0.2))
.called(1);
verify(mockConnection.addDisconnectedListener(any)).called(1);

// Verify that no other interactions have been made with the mockConnection
verifyNoMoreInteractions(mockConnection);

// Verify that the onNotification callback was never called
verifyNever(mockOnNotification(any, any, any));

// Publish some data and expect an update
data['title'] = 'Title2';
data['description'] = 'Description2';
data['level'] = 'INFO';
mockSub.updateValue(jsonEncode(data), 2);

verify(mockOnNotification(data['title'], data['description'], any));

// Try malformed data
data['title'] = null;
data['description'] = null;
data['level'] = 'malformedlevel';

mockSub.updateValue(jsonEncode(data), 3);
reset(mockOnNotification);
verifyNever(mockOnNotification(any, any, any));
});
}
15 changes: 14 additions & 1 deletion test/test_util.dart
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,8 @@ MockNTConnection createMockOnlineNT4({

Map<int, NT4Topic> virtualTopicsMap = {};

List<Function(Object?, int)> subscriptionListeners = [];

for (int i = 0; i < virtualTopics.length; i++) {
virtualTopicsMap.addAll({i + 1: virtualTopics[i]});
}
Expand Down Expand Up @@ -139,7 +141,18 @@ MockNTConnection createMockOnlineNT4({
when(topicSubscription.periodicStream(yieldAll: anyNamed('yieldAll')))
.thenAnswer((_) => Stream.value(virtualValues?[topic.name]));

when(topicSubscription.listen(any)).thenAnswer((realInvocation) {});
when(topicSubscription.listen(any)).thenAnswer((realInvocation) {
subscriptionListeners.add(realInvocation.positionalArguments[0]);
});

when(topicSubscription.updateValue(any, any)).thenAnswer(
(invoc) {
for (var value in subscriptionListeners) {
value.call(
invoc.positionalArguments[0], invoc.positionalArguments[1]);
}
},
);

when(mockNT4Connection.getLastAnnouncedValue(topic.name))
.thenAnswer((_) => virtualValues?[topic.name]);
Expand Down

0 comments on commit 942f7b0

Please sign in to comment.