@@ -884,4 +884,310 @@ void main() {
884884 },
885885 );
886886 });
887+
888+ group ('Poll events' , () {
889+ late StreamController <Object > wsStreamController;
890+ late MockWebSocketSink webSocketSink;
891+ const defaultFeedId = FeedId (group: 'group' , id: 'id' );
892+
893+ setUp (() async {
894+ wsStreamController = StreamController <Object >();
895+ webSocketSink = MockWebSocketSink ();
896+ WsTestConnection (
897+ wsStreamController: wsStreamController,
898+ webSocketSink: webSocketSink,
899+ webSocketChannel: webSocketChannel,
900+ ).setUp ();
901+
902+ await client.connect ();
903+ });
904+
905+ tearDown (() async {
906+ await webSocketSink.close ();
907+ await wsStreamController.close ();
908+ });
909+
910+ void setupMockFeed ({
911+ FeedId feedId = defaultFeedId,
912+ List <ActivityResponse > activities = const [],
913+ }) {
914+ // Setup default mock response
915+ when (
916+ () => feedsApi.getOrCreateFeed (
917+ feedGroupId: feedId.group,
918+ feedId: feedId.id,
919+ getOrCreateFeedRequest: any (named: 'getOrCreateFeedRequest' ),
920+ ),
921+ ).thenAnswer (
922+ (_) async => Result .success (
923+ createDefaultGetOrCreateFeedResponse ().copyWith (
924+ activities: activities,
925+ ),
926+ ),
927+ );
928+ }
929+
930+ test ('poll vote casted' , () async {
931+ final poll = createDefaultPollResponseData ();
932+ final pollId = poll.id;
933+ final firstOptionId = poll.options.first.id;
934+
935+ setupMockFeed (
936+ activities: [createDefaultActivityResponse (poll: poll).activity],
937+ );
938+
939+ final feed = client.feedFromId (defaultFeedId);
940+ await feed.getOrCreate ();
941+
942+ expect (poll.voteCount, 0 );
943+
944+ feed.notifier.stream.listen (
945+ expectAsync1 (
946+ (event) {
947+ expect (event, isA <FeedState >());
948+ expect (event.activities.first.poll? .id, pollId);
949+ expect (event.activities.first.poll? .voteCount, 1 );
950+ },
951+ ),
952+ );
953+ wsStreamController.add (
954+ jsonEncode (
955+ PollVoteCastedFeedEvent (
956+ createdAt: DateTime .now (),
957+ custom: const {},
958+ fid: 'fid' , // Feed Id doesn't matter for poll vote casted event
959+ poll: poll.copyWith (voteCount: 1 ),
960+ pollVote: PollVoteResponseData (
961+ createdAt: DateTime .now (),
962+ updatedAt: DateTime .now (),
963+ id: 'voteId1' ,
964+ optionId: firstOptionId,
965+ pollId: pollId,
966+ ),
967+ type: EventTypes .pollVoteCasted,
968+ ).toJson (),
969+ ),
970+ );
971+ });
972+
973+ test ('poll answer casted' , () async {
974+ final poll = createDefaultPollResponseData ();
975+ final pollId = poll.id;
976+ setupMockFeed (
977+ activities: [createDefaultActivityResponse (poll: poll).activity],
978+ );
979+
980+ final feed = client.feedFromId (defaultFeedId);
981+ await feed.getOrCreate ();
982+
983+ feed.notifier.stream.listen (
984+ expectAsync1 (
985+ (event) {
986+ expect (event, isA <FeedState >());
987+ expect (event.activities.first.poll? .id, pollId);
988+ expect (event.activities.first.poll? .answersCount, 1 );
989+ expect (event.activities.first.poll? .latestAnswers.length, 1 );
990+ },
991+ ),
992+ );
993+
994+ wsStreamController.add (
995+ jsonEncode (
996+ PollVoteCastedFeedEvent (
997+ createdAt: DateTime .now (),
998+ custom: const {},
999+ fid: 'fid' ,
1000+ poll: poll.copyWith (answersCount: 1 ),
1001+ pollVote: PollVoteResponseData (
1002+ createdAt: DateTime .now (),
1003+ updatedAt: DateTime .now (),
1004+ id: 'voteId1' ,
1005+ answerText: 'answerText1' ,
1006+ isAnswer: true ,
1007+ optionId: 'optionId1' ,
1008+ pollId: pollId,
1009+ ),
1010+ type: EventTypes .pollVoteCasted,
1011+ ),
1012+ ),
1013+ );
1014+ });
1015+
1016+ test ('poll answer removed' , () async {
1017+ final poll = createDefaultPollResponseData (
1018+ latestAnswers: [
1019+ PollVoteResponseData (
1020+ createdAt: DateTime .now (),
1021+ updatedAt: DateTime .now (),
1022+ id: 'voteId1' ,
1023+ answerText: 'answerText1' ,
1024+ isAnswer: true ,
1025+ optionId: 'optionId1' ,
1026+ pollId: 'pollId1' ,
1027+ ),
1028+ ],
1029+ );
1030+ final pollId = poll.id;
1031+ setupMockFeed (
1032+ activities: [createDefaultActivityResponse (poll: poll).activity],
1033+ );
1034+
1035+ final feed = client.feedFromId (defaultFeedId);
1036+ await feed.getOrCreate ();
1037+
1038+ expect (poll.answersCount, 1 );
1039+ expect (poll.latestAnswers.length, 1 );
1040+
1041+ feed.notifier.stream.listen (
1042+ expectAsync1 (
1043+ (event) {
1044+ expect (event, isA <FeedState >());
1045+ expect (event.activities.first.poll? .id, pollId);
1046+ expect (event.activities.first.poll? .answersCount, 0 );
1047+ expect (event.activities.first.poll? .latestAnswers.length, 0 );
1048+ },
1049+ ),
1050+ );
1051+
1052+ wsStreamController.add (
1053+ jsonEncode (
1054+ PollVoteRemovedFeedEvent (
1055+ createdAt: DateTime .now (),
1056+ custom: const {},
1057+ fid: 'fid' ,
1058+ poll: poll.copyWith (answersCount: 0 ),
1059+ pollVote: PollVoteResponseData (
1060+ createdAt: DateTime .now (),
1061+ updatedAt: DateTime .now (),
1062+ id: 'voteId1' ,
1063+ answerText: 'answerText1' ,
1064+ isAnswer: true ,
1065+ optionId: 'optionId1' ,
1066+ pollId: pollId,
1067+ ),
1068+ type: EventTypes .pollVoteRemoved,
1069+ ),
1070+ ),
1071+ );
1072+ });
1073+
1074+ test ('poll vote removed' , () async {
1075+ final poll = createDefaultPollResponseData (
1076+ latestVotesByOption: {
1077+ 'optionId1' : [
1078+ PollVoteResponseData (
1079+ createdAt: DateTime .now (),
1080+ updatedAt: DateTime .now (),
1081+ id: 'voteId1' ,
1082+ optionId: 'optionId1' ,
1083+ pollId: 'pollId1' ,
1084+ ),
1085+ ],
1086+ },
1087+ );
1088+ final pollId = poll.id;
1089+ setupMockFeed (
1090+ activities: [createDefaultActivityResponse (poll: poll).activity],
1091+ );
1092+
1093+ final feed = client.feedFromId (defaultFeedId);
1094+ await feed.getOrCreate ();
1095+
1096+ expect (poll.voteCount, 1 );
1097+ expect (poll.latestVotesByOption.length, 1 );
1098+
1099+ feed.notifier.stream.listen (
1100+ expectAsync1 (
1101+ (event) {
1102+ expect (event, isA <FeedState >());
1103+ expect (event.activities.first.poll? .id, pollId);
1104+ expect (event.activities.first.poll? .voteCount, 0 );
1105+ expect (event.activities.first.poll? .latestVotesByOption.length, 0 );
1106+ },
1107+ ),
1108+ );
1109+ wsStreamController.add (
1110+ jsonEncode (
1111+ PollVoteRemovedFeedEvent (
1112+ createdAt: DateTime .now (),
1113+ custom: const {},
1114+ fid: 'fid' ,
1115+ poll: poll.copyWith (voteCount: 0 , latestVotesByOption: {}),
1116+ pollVote: PollVoteResponseData (
1117+ createdAt: DateTime .now (),
1118+ updatedAt: DateTime .now (),
1119+ id: 'voteId1' ,
1120+ optionId: 'optionId1' ,
1121+ pollId: pollId,
1122+ ),
1123+ type: EventTypes .pollVoteRemoved,
1124+ ),
1125+ ),
1126+ );
1127+ });
1128+
1129+ test ('poll closed' , () async {
1130+ final poll = createDefaultPollResponseData ();
1131+ final pollId = poll.id;
1132+ setupMockFeed (
1133+ activities: [createDefaultActivityResponse (poll: poll).activity],
1134+ );
1135+
1136+ final feed = client.feedFromId (defaultFeedId);
1137+ await feed.getOrCreate ();
1138+
1139+ feed.notifier.stream.listen (
1140+ expectAsync1 (
1141+ (event) {
1142+ expect (event, isA <FeedState >());
1143+ expect (event.activities.first.poll? .id, pollId);
1144+ expect (event.activities.first.poll? .isClosed, true );
1145+ },
1146+ ),
1147+ );
1148+
1149+ wsStreamController.add (
1150+ jsonEncode (
1151+ PollClosedFeedEvent (
1152+ createdAt: DateTime .now (),
1153+ custom: const {},
1154+ fid: 'fid' ,
1155+ poll: poll.copyWith (isClosed: true ),
1156+ type: EventTypes .pollClosed,
1157+ ),
1158+ ),
1159+ );
1160+ });
1161+
1162+ test ('poll deleted' , () async {
1163+ final poll = createDefaultPollResponseData ();
1164+ setupMockFeed (
1165+ activities: [createDefaultActivityResponse (poll: poll).activity],
1166+ );
1167+
1168+ final feed = client.feedFromId (defaultFeedId);
1169+ await feed.getOrCreate ();
1170+
1171+ feed.notifier.stream.listen (
1172+ expectAsync1 (
1173+ (event) {
1174+ expect (event, isA <FeedState >());
1175+ expect (event.activities.first.poll, null );
1176+ },
1177+ ),
1178+ );
1179+
1180+ wsStreamController.add (
1181+ jsonEncode (
1182+ PollDeletedFeedEvent (
1183+ createdAt: DateTime .now (),
1184+ custom: const {},
1185+ fid: 'fid' ,
1186+ poll: poll,
1187+ type: EventTypes .pollDeleted,
1188+ ),
1189+ ),
1190+ );
1191+ });
1192+ });
8871193}
0 commit comments