1+ // ignore_for_file: avoid_redundant_argument_values
2+
13import 'dart:async' ;
24import 'dart:convert' ;
35
@@ -64,7 +66,7 @@ void main() {
6466 });
6567 });
6668
67- group ('Poll events' , () {
69+ group ('WS events' , () {
6870 late StreamController <Object > wsStreamController;
6971 late MockWebSocketSink webSocketSink;
7072
@@ -85,8 +87,11 @@ void main() {
8587 await wsStreamController.close ();
8688 });
8789
88- void setupMockActivity ({GetActivityResponse ? activity}) {
89- const activityId = 'id' ;
90+ void setupMockActivity ({
91+ String activityId = 'id' ,
92+ GetActivityResponse ? activity,
93+ GetCommentsResponse ? comments,
94+ }) {
9095 when (() => feedsApi.getActivity (id: activityId)).thenAnswer (
9196 (_) async =>
9297 Result .success (activity ?? createDefaultActivityResponse ()),
@@ -98,10 +103,53 @@ void main() {
98103 depth: 3 ,
99104 ),
100105 ).thenAnswer (
101- (_) async => Result .success (createDefaultCommentsResponse ()),
106+ (_) async =>
107+ Result .success (comments ?? createDefaultCommentsResponse ()),
102108 );
103109 }
104110
111+ test ('poll updated' , () async {
112+ final originalDate = DateTime (2021 , 1 , 1 );
113+ final updatedDate = DateTime (2021 , 1 , 2 );
114+
115+ final poll = createDefaultPollResponseData (updatedAt: originalDate);
116+ setupMockActivity (
117+ activity: createDefaultActivityResponse (poll: poll),
118+ );
119+
120+ final activity = client.activity (
121+ activityId: 'id' ,
122+ fid: const FeedId (group: 'group' , id: 'id' ),
123+ );
124+ await activity.get ();
125+
126+ expect (poll.voteCount, 0 );
127+ expect (poll.updatedAt, originalDate);
128+
129+ activity.notifier.stream.listen (
130+ expectAsync1 (
131+ (event) {
132+ expect (event, isA <ActivityState >());
133+ expect (event.poll? .id, 'poll-id' );
134+ expect (event.poll? .voteCount, 1 );
135+ expect (event.poll? .updatedAt, updatedDate);
136+ },
137+ ),
138+ );
139+
140+ wsStreamController.add (
141+ jsonEncode (
142+ PollUpdatedFeedEvent (
143+ createdAt: DateTime .now (),
144+ custom: const {},
145+ fid: 'fid' ,
146+ poll: poll.copyWith (voteCount: 1 , updatedAt: updatedDate),
147+ type: EventTypes .pollUpdated,
148+ ).toJson (),
149+ ),
150+ );
151+ });
152+
105153 test ('poll vote casted' , () async {
106154 final poll = createDefaultPollResponseData ();
107155 final pollId = poll.id;
@@ -379,5 +427,202 @@ void main() {
379427 ),
380428 );
381429 });
430+
431+ test ('comment added' , () async {
432+ const activityId = 'activity-id' ;
433+ const fid = FeedId (group: 'group' , id: 'id' );
434+ final comment1 = createDefaultCommentResponse (
435+ objectId: activityId,
436+ id: 'comment-id-1' ,
437+ text: 'comment-text-1' ,
438+ );
439+ final comment2 = createDefaultCommentResponse (
440+ objectId: activityId,
441+ id: 'comment-id-2' ,
442+ text: 'comment-text-2' ,
443+ );
444+
445+ final initialComments = createDefaultCommentsResponse (
446+ comments: [ThreadedCommentResponse .fromJson (comment1.toJson ())],
447+ );
448+
449+ setupMockActivity (
450+ activityId: activityId,
451+ activity: createDefaultActivityResponse (
452+ id: activityId,
453+ comments: [comment1],
454+ ),
455+ comments: initialComments,
456+ );
457+
458+ final activity = client.activity (
459+ activityId: activityId,
460+ fid: fid,
461+ );
462+ final activityData = await activity.get ();
463+ expect (activityData, isA <Result <ActivityData >>());
464+ expect (activityData.getOrNull ()? .id, activityId);
465+ expect (activityData.getOrNull ()? .comments.length, 1 );
466+
467+ expect (activity.state.activity? .commentCount, 1 );
468+ expect (activity.state.comments.length, 1 );
469+
470+ // The event will trigger twice, first with updated count and then with the new comment.
471+ var count = 0 ;
472+ activity.notifier.stream.listen (
473+ expectAsync1 (
474+ count: 2 ,
475+ (event) {
476+ count++ ;
477+ if (count == 1 ) {
478+ expect (event, isA <ActivityState >());
479+ expect (event.activity? .commentCount, 2 );
480+ }
481+ if (count == 2 ) {
482+ expect (event, isA <ActivityState >());
483+ expect (event.comments.length, 2 );
484+ }
485+ },
486+ ),
487+ );
488+ wsStreamController.add (
489+ jsonEncode (
490+ CommentAddedEvent (
491+ type: EventTypes .commentAdded,
492+ activity: createDefaultActivityResponse ().activity,
493+ createdAt: DateTime .now (),
494+ custom: const {},
495+ fid: fid.rawValue,
496+ comment: comment2,
497+ ),
498+ ),
499+ );
500+ });
501+
502+ test ('comment updated' , () async {
503+ const activityId = 'activity-id' ;
504+ const fid = FeedId (group: 'group' , id: 'id' );
505+ final comment = createDefaultCommentResponse (
506+ objectId: activityId,
507+ id: 'comment-id' ,
508+ text: 'comment-text' ,
509+ );
510+
511+ final initialComments = createDefaultCommentsResponse (
512+ comments: [ThreadedCommentResponse .fromJson (comment.toJson ())],
513+ );
514+
515+ setupMockActivity (
516+ activityId: activityId,
517+ activity: createDefaultActivityResponse (
518+ id: activityId,
519+ comments: [comment],
520+ ),
521+ comments: initialComments,
522+ );
523+
524+ final activity = client.activity (
525+ activityId: activityId,
526+ fid: fid,
527+ );
528+ final activityData = await activity.get ();
529+ expect (activityData, isA <Result <ActivityData >>());
530+ expect (activityData.getOrNull ()? .id, activityId);
531+ expect (activityData.getOrNull ()? .comments.length, 1 );
532+
533+ expect (activity.state.activity? .commentCount, 1 );
534+ expect (activity.state.comments.first.text, 'comment-text' );
535+
536+ // The event will trigger twice, first with updated count and then with the new comment.
537+ var count = 0 ;
538+ activity.notifier.stream.listen (
539+ expectAsync1 (
540+ count: 2 ,
541+ (event) {
542+ count++ ;
543+ expect (event, isA <ActivityState >());
544+ expect (event.activity? .commentCount, 1 );
545+ if (count == 2 ) {
546+ expect (event.comments.first.text, 'comment-text-2' );
547+ }
548+ },
549+ ),
550+ );
551+ wsStreamController.add (
552+ jsonEncode (
553+ CommentUpdatedEvent (
554+ type: EventTypes .commentUpdated,
555+ createdAt: DateTime .now (),
556+ custom: const {},
557+ fid: fid.rawValue,
558+ comment: comment.copyWith (text: 'comment-text-2' ),
559+ ),
560+ ),
561+ );
562+ });
563+
564+ test ('comment removed' , () async {
565+ const activityId = 'activity-id' ;
566+ const fid = FeedId (group: 'group' , id: 'id' );
567+ final comment = createDefaultCommentResponse (
568+ objectId: activityId,
569+ id: 'comment-id' ,
570+ text: 'comment-text' ,
571+ );
572+
573+ final initialComments = createDefaultCommentsResponse (
574+ comments: [ThreadedCommentResponse .fromJson (comment.toJson ())],
575+ );
576+
577+ setupMockActivity (
578+ activityId: activityId,
579+ activity: createDefaultActivityResponse (
580+ id: activityId,
581+ comments: [comment],
582+ ),
583+ comments: initialComments,
584+ );
585+
586+ final activity = client.activity (
587+ activityId: activityId,
588+ fid: fid,
589+ );
590+ final activityData = await activity.get ();
591+ expect (activityData, isA <Result <ActivityData >>());
592+ expect (activityData.getOrNull ()? .id, activityId);
593+ expect (activityData.getOrNull ()? .comments.length, 1 );
594+
595+ expect (activity.state.activity? .commentCount, 1 );
596+ expect (activity.state.comments.length, 1 );
597+
598+ // The event will trigger twice, first with updated count and then with the new comment.
599+ var count = 0 ;
600+ activity.notifier.stream.listen (
601+ expectAsync1 (
602+ count: 2 ,
603+ (event) {
604+ count++ ;
605+ if (count == 1 ) {
606+ expect (event, isA <ActivityState >());
607+ expect (event.activity? .commentCount, 0 );
608+ }
609+ if (count == 2 ) {
610+ expect (event.comments, isEmpty);
611+ }
612+ },
613+ ),
614+ );
615+ wsStreamController.add (
616+ jsonEncode (
617+ CommentDeletedEvent (
618+ type: EventTypes .commentDeleted,
619+ createdAt: DateTime .now (),
620+ custom: const {},
621+ fid: fid.rawValue,
622+ comment: comment,
623+ ),
624+ ),
625+ );
626+ });
382627 });
383628}
0 commit comments