Skip to content

Conversation

@xsahil03x
Copy link
Member

@xsahil03x xsahil03x commented Dec 15, 2025

Summary by CodeRabbit

  • New Features

    • Real-time poll lifecycle and vote/answer updates reflected in feeds and activities; feed create/update/delete events handled live.
  • Improvements

    • Per-user reaction, vote and bookmark state surfaced consistently (shows “your” interactions).
    • Stable sorted upsert behavior preserves list order and improves sync across feeds, members, follows and bookmarks.
    • Polls unified into activity/display state for consistent UI.
  • Bug Fixes

    • Related comments, replies, reactions, bookmarks and poll data cleared when parent items are deleted.
  • Tests

    • Expanded test coverage and new tester helpers for feeds, reactions, comments, polls, members and bookmarks.

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link

coderabbitai bot commented Dec 15, 2025

Walkthrough

Threads currentUserId into list constructors; centralizes poll data under Activity relations; replaces many list mutations with sortedUpsert/updateWhere/upsert/remove patterns; expands event handlers for reactions, bookmarks, polls, feeds and comment lifecycles; adds extensive tests, test helpers, and dependency bumps.

Changes

Cohort / File(s) Summary
Config & Manifests
melos.yaml, packages/stream_feeds/pubspec.yaml, packages/stream_feeds_test/pubspec.yaml, packages/stream_feeds/dart_test.yaml
Bumped stream_core to ^0.3.3, added collection to test deps, reorganized test tags.
Client wiring
packages/stream_feeds/lib/src/client/feeds_client_impl.dart
Pass currentUserId (user.id) into constructed Feed, PollList, CommentList, CommentReplyList.
Model mutations & poll API
packages/stream_feeds/lib/src/models/activity_data.dart, .../poll_data.dart, .../mark_activity_data.dart
Added ActivityData.updateIf and comment-reaction upsert/remove helpers; renamed/refactored poll APIs to upsertOption/upsertVote/upsertAnswer/removeVote/removeAnswer; moved generic param to handle().
Activity state (single & generated)
packages/stream_feeds/lib/src/state/activity_state.dart, packages/stream_feeds/lib/src/state/activity_state.freezed.dart, packages/stream_feeds/lib/src/state/activity.dart
Removed explicit poll field from ActivityState (exposed via activity?.poll); added onActivityGet/onActivityDeleted and many reaction/bookmark/poll handlers; updated generated freezed output.
Activity list state & handlers
packages/stream_feeds/lib/src/state/activity_list_state.dart, packages/stream_feeds/lib/src/state/event/handler/activity_*.dart
Migrated map-based mutations to updateWhere/sortedUpsert; added per-activity and per-comment reaction/bookmark/poll handlers and expanded event branches.
Comment / Reaction / Reply states & handlers
packages/stream_feeds/lib/src/state/comment_list.dart, .../comment_list_state.dart, .../comment_reaction_list*.dart, .../comment_reply_list*.dart, .../event/handler/comment_*.dart
Threaded currentUserId into constructors/notifiers; replaced updates with sortedUpsert; added comment reaction handlers and deletion handlers; event handlers now receive query context and use matches(query.filter).
Polls & Votes state & handlers
packages/stream_feeds/lib/src/state/poll_list*.dart, .../poll_list_state.dart, .../poll_vote_list_state.dart, .../event/handler/poll_*.dart
Added currentUserId to PollList/notifier; added poll lifecycle and vote/answer upsert/remove handlers; mapped poll feed events to notifiers.
Feed / Followers / Members / Bookmarks state
packages/stream_feeds/lib/src/state/feed_state.dart, feed_list_state.dart, follow_list_state.dart, member_list_state.dart, bookmark_list_state.dart, bookmark_folder_list_state.dart
Introduced FeedState Freezed model and extension helpers (updateActivitiesWhere/removeActivitiesWhere, add/remove/update helpers); replaced direct mutations with sortedUpsert and unified update APIs; added onFeedAdded/onFollowAdded/onMemberAdded/onBookmarkAdded.
Event handler wiring (feed-level)
packages/stream_feeds/lib/src/state/event/handler/*.dart, feed_event_handler.dart, feed_list_event_handler.dart
Replaced local helper filters with model.matches(query.filter); added handling for feed/activity/poll/reaction/bookmark/member events; consistently use query.fid/rawValue checks.
Public API / Exports
packages/stream_feeds/lib/stream_feeds.dart
Exported MatchesExtensions from src/utils/filter.dart.
Tests & Test helpers
packages/stream_feeds/test/**, packages/stream_feeds_test/lib/src/testers/**, packages/stream_feeds_test/lib/src/helpers/**
Added broad test coverage and many tester helpers; new test factories (e.g., createDefaultReactionResponse); adjusted test data shapes (follow: sourceId/targetId); exported new testers.
Minor repo tweak
packages/stream_feeds/lib/src/repository/polls_repository.dart
Whitespace change only.

Sequence Diagram(s)

sequenceDiagram
    participant WS as WebSocket
    participant Handler as EventHandler
    participant Notifier as StateNotifier
    participant State as In-memory State
    participant API as Feeds API

    note over WS,Handler: real-time event arrives
    WS->>Handler: deliver event payload
    Handler->>Handler: validate IDs & query.matches(...)
    alt matches target
        Handler->>Notifier: invoke onXxx (e.g., onReactionAdded / onPollUpdated / onActivityDeleted)
        Notifier->>State: apply updateWhere / sortedUpsert / upsert/remove (may use currentUserId)
        State-->>Notifier: new state snapshot
    else not matching
        Handler-->>WS: ignore event
    end
    Note right of Notifier: API queries (get / queryMore) also merge via same helpers
    API->>Notifier: query response
    Notifier->>State: merge via sortedUpsert/updateWhere
    State-->>Notifier: updated snapshot
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

  • Areas needing extra attention:
    • Removal of ActivityState.poll — confirm all call sites now use activity?.poll.
    • Poll API renames and semantics around ownVotesAndAnswers and uniqueness enforcement.
    • Correctness of sortedUpsert / updateWhere implementations and comparator usage.
    • Event handler filtering: correct use of query.matches and fid/pollId/commentId scoping.
    • Threading currentUserId into constructors and its use in mutation helpers.
    • Test factory signature changes (e.g., createDefaultReactionResponse, createDefaultFollowResponse) and widespread test updates.

Possibly related PRs

Suggested reviewers

  • renefloor
  • Brazol

Poem

"I thumped my paws through events at dawn,
Upserted carrots in tidy rows so none are gone,
Polls snug in activity burrows tight,
Reactions hopped home, bookmarks tucked at night,
A rabbit's cheer — tests green and code delight!"

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description check ⚠️ Warning The pull request description is empty; the author did not complete any required sections from the description template. Add a comprehensive description including the issue/ticket reference, what changes were made, how to test them, and confirm CLA and code quality checklist items.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title 'feat(llc): handle missing events' is specific and reflects the main objective of adding missing event handlers throughout the codebase.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/add-missing-event-handlers

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov
Copy link

codecov bot commented Dec 15, 2025

Codecov Report

❌ Patch coverage is 97.65533% with 20 lines in your changes missing coverage. Please review.
✅ Project coverage is 83.89%. Comparing base (2390fe4) to head (4a62569).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
...ackages/stream_feeds/lib/src/models/poll_data.dart 60.86% 9 Missing ⚠️
...ackages/stream_feeds/lib/src/state/feed_state.dart 94.44% 9 Missing ⚠️
...stream_feeds/lib/src/state/comment_list_state.dart 96.42% 1 Missing ⚠️
...t/handler/comment_reaction_list_event_handler.dart 93.33% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff             @@
##             main      #71       +/-   ##
===========================================
+ Coverage   59.90%   83.89%   +23.98%     
===========================================
  Files         121      121               
  Lines        3774     4197      +423     
===========================================
+ Hits         2261     3521     +1260     
+ Misses       1513      676      -837     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@xsahil03x xsahil03x marked this pull request as ready for review December 16, 2025 23:30
@xsahil03x xsahil03x requested a review from a team as a code owner December 16, 2025 23:30
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/stream_feeds/lib/src/state/event/handler/activity_event_handler.dart (1)

112-152: Poll events lack activityId filtering unlike activity, reaction, and bookmark events.

While activity, reaction, and bookmark events guard with activityId checks, poll events process all instances regardless of activity scope. Since polls must be attached to an activity, poll event handlers should validate the activity context to avoid updating the wrong ActivityState when multiple activities are observed.

🧹 Nitpick comments (5)
packages/stream_feeds/lib/src/state/event/handler/activity_reaction_list_event_handler.dart (1)

23-45: LGTM! Consistent event handling with proper activity filtering.

The implementation correctly handles all reaction lifecycle events (add, update, delete) plus activity deletion. The early return pattern efficiently filters events by activity ID, and the use of toModel() follows the project's data mapping conventions.

Consider refactoring to use switch expressions for more idiomatic Dart pattern matching:

  @override
  void handleEvent(WsEvent event) {
-   if (event is api.ActivityDeletedEvent) {
-     // Only handle deletion for this specific activity
-     if (event.activity.id != activityId) return;
-     return state.onActivityDeleted();
-   }
-
-   if (event is api.ActivityReactionAddedEvent) {
-     // Only handle reactions for this specific activity
-     if (event.activity.id != activityId) return;
-     return state.onReactionAdded(event.reaction.toModel());
-   }
-
-   if (event is api.ActivityReactionUpdatedEvent) {
-     // Only handle reactions for this specific activity
-     if (event.activity.id != activityId) return;
-     return state.onReactionUpdated(event.reaction.toModel());
-   }
-
-   if (event is api.ActivityReactionDeletedEvent) {
-     // Only handle reactions for this specific activity
-     if (event.activity.id != activityId) return;
-     return state.onReactionRemoved(event.reaction.toModel());
-   }
-
-   // Handle other activity reaction events if needed
+   switch (event) {
+     case api.ActivityDeletedEvent(:final activity) when activity.id == activityId:
+       state.onActivityDeleted();
+     case api.ActivityReactionAddedEvent(:final activity, :final reaction) when activity.id == activityId:
+       state.onReactionAdded(reaction.toModel());
+     case api.ActivityReactionUpdatedEvent(:final activity, :final reaction) when activity.id == activityId:
+       state.onReactionUpdated(reaction.toModel());
+     case api.ActivityReactionDeletedEvent(:final activity, :final reaction) when activity.id == activityId:
+       state.onReactionRemoved(reaction.toModel());
+     default:
+       // Unhandled or non-matching event
+   }
  }

This pattern matching approach aligns with the coding guideline to "Use pattern matching with switch expressions in Dart" and provides better exhaustiveness checking.

packages/stream_feeds/lib/src/state/bookmark_folder_list_state.dart (1)

49-56: Consider adding an update callback for merge semantics.

The refactor to sortedUpsert improves consistency, but unlike FeedListStateNotifier.onFeedUpdated (line 63), this implementation doesn't provide an update callback to merge the existing folder with the updated one. If partial updates are expected, consider adding:

 final updatedFolders = state.bookmarkFolders.sortedUpsert(
   folder,
   key: (it) => it.id,
   compare: foldersSort.compare,
+  update: (existing, updated) => existing.updateWith(updated),
 );
packages/stream_feeds/lib/src/state/event/handler/activity_event_handler.dart (1)

104-110: Empty event handlers are confusing.

These empty if blocks explicitly match comment events but perform no action. If the intent is to document that these events are intentionally not handled here (but in CommentListEventHandler), a single comment would be clearer and avoid unnecessary type checks at runtime.

Consider removing the empty handlers or consolidating into a single comment:

-    // Comment events are not handled in the CommentListEventHandler
-    if (event is api.CommentAddedEvent) {}
-    if (event is api.CommentUpdatedEvent) {}
-    if (event is api.CommentDeletedEvent) {}
-    if (event is api.CommentReactionAddedEvent) {}
-    if (event is api.CommentReactionUpdatedEvent) {}
-    if (event is api.CommentReactionDeletedEvent) {}
+    // Comment events are handled by CommentListEventHandler, not here.
packages/stream_feeds/lib/src/state/comment_list_state.dart (1)

48-70: onCommentAdded and onCommentUpdated have identical implementations.

Both methods perform the same sortedUpsert operation with the same parameters. Consider having onCommentAdded delegate to onCommentUpdated (similar to the pattern used in other files like activity_list_state.dart line 158-160) for DRY compliance.

  /// Handles the addition of a new comment.
- void onCommentAdded(CommentData comment) {
-   final updatedComments = state.comments.sortedUpsert(
-     comment,
-     key: (it) => it.id,
-     compare: commentSort.compare,
-     update: (existing, updated) => existing.updateWith(updated),
-   );
-
-   state = state.copyWith(comments: updatedComments);
- }
+ void onCommentAdded(CommentData comment) => onCommentUpdated(comment);
packages/stream_feeds/lib/src/state/activity_state.dart (1)

105-130: onBookmarkAdded and onBookmarkUpdated have identical implementations.

Both methods call it.upsertBookmark(bookmark, currentUserId). Consider having onBookmarkAdded delegate to onBookmarkUpdated for consistency with patterns used elsewhere (e.g., onCommentAdded in activity_list_state.dart).

  /// Handles when a bookmark is added to the activity.
- void onBookmarkAdded(BookmarkData bookmark) {
-   final updatedActivity = state.activity?.let(
-     (it) => it.upsertBookmark(bookmark, currentUserId),
-   );
-
-   state = state.copyWith(activity: updatedActivity);
- }
+ void onBookmarkAdded(BookmarkData bookmark) => onBookmarkUpdated(bookmark);

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart (1)

20-25: currentUserId field is declared but unused in this handler.

The currentUserId is stored as a field but never referenced in handleEvent. If it's only needed by PollListStateNotifier (which already has its own currentUserId), consider removing it from this handler to avoid confusion.

 class PollListEventHandler implements StateEventHandler {
   const PollListEventHandler({
     required this.query,
     required this.state,
-    required this.currentUserId,
   });

   final PollsQuery query;
   final PollListStateNotifier state;
-  final String currentUserId;
packages/stream_feeds/lib/src/state/poll_list_state.dart (1)

82-102: onPollVoteCasted and onPollVoteChanged have identical implementations.

Both methods call upsertVote(poll, vote, currentUserId). While semantically distinct events, consider whether one could delegate to the other to reduce duplication, similar to how onCommentAdded delegates to onCommentUpdated in activity_list_state.dart.

   /// Handles the casting of a vote in a poll.
   void onPollVoteCasted(PollData poll, PollVoteData vote) {
-    final updatedPolls = state.polls.updateWhere(
-      (it) => it.id == poll.id,
-      update: (it) => it.upsertVote(poll, vote, currentUserId),
-      compare: pollsSort.compare,
-    );
-
-    state = state.copyWith(polls: updatedPolls);
+    return onPollVoteChanged(poll, vote);
   }
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a130241 and e5cd7df.

📒 Files selected for processing (3)
  • packages/stream_feeds/lib/src/state/activity_list_state.dart (4 hunks)
  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart (2 hunks)
  • packages/stream_feeds/lib/src/state/poll_list_state.dart (4 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/cursor-rules-location.mdc)

**/*.dart: Use the barrel_files package with @includeInBarrelFile annotations for public API management in Dart projects; keep implementation details in lib/src/ without annotations
Mark only classes, functions, and enums intended for external package usage with @includeInBarrelFile; keep repository classes, mappers, and internal state objects in lib/src/ without annotations

**/*.dart: Use @freezed mixed mode for data classes in Dart
Return Result<T> from all repository methods in Dart
Apply early return patterns consistently in Dart code
Use pattern matching with switch expressions in Dart
Mark public APIs with @includeInBarrelFile annotation in Dart
Follow enhanced enum vs sealed class guidelines in Dart
Use const constructors where possible in Dart
Implement proper disposal patterns in Dart StateNotifiers and providers
Ensure pure Dart compatibility across VM, Flutter, and Web environments
Plan for StateNotifier reactive patterns when implementing state management in Dart

**/*.dart: Use @freezed for all data classes with required id fields and const constructors
Implement StateNotifier-based reactive state management with automatic change notifications
Apply Result pattern for all async operations with explicit error handling
Use early return patterns for clean control flow in Dart code
Create extension functions for data mapping using .toModel() pattern instead of mapper classes
Mark public APIs with @includeInBarrelFile annotation for barrel file export management
Implement proper resource management with disposal and cleanup patterns in Dart code
Use constructor injection for all dependencies in Dart classes

**/*.dart: All data models should use @freezed with Dart's mixed mode syntax and include @OverRide annotations on fields
Mark classes for public export using @includeInBarrelFile annotation
Use extension functions with .toModel() convention for data mapping instead of dedicated mapper classes
All repository methods must return Result...

Files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
packages/stream_feeds/lib/src/state/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

packages/stream_feeds/lib/src/state/**/*.dart: State classes must use @freezed with const constructors
State class naming convention: Use *State suffix for state classes (e.g., FeedState, ActivityListState)

Files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
packages/stream_feeds/lib/src/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Use // for internal/private code documentation

Files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
packages/stream_feeds/lib/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Apply Dart analyzer configuration from analysis_options.yaml for code quality

Files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
🧠 Learnings (29)
📓 Common learnings
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events
Learnt from: xsahil03x
Repo: GetStream/stream-feeds-flutter PR: 71
File: packages/stream_feeds/lib/src/state/event/handler/bookmark_folder_list_event_handler.dart:23-40
Timestamp: 2025-12-16T23:49:25.329Z
Learning: In the Stream Feeds Flutter SDK, `BookmarkFolderAddedEvent` does not exist in the backend and SDK. Only `BookmarkFolderUpdatedEvent` and `BookmarkFolderDeletedEvent` are available for bookmark folder event handling.
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
  • packages/stream_feeds/lib/src/state/activity_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Keep public API minimal - most code should be in `lib/src/` internal directory

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/ws/events/**/*.dart : Real-time event handlers must use `freezed` for type-safe event handling in WebSocket layer

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Follow Effective Dart documentation guidelines for all public APIs

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Export public API classes from main library entry point `lib/stream_feeds.dart`

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
  • packages/stream_feeds/lib/src/state/activity_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : Use StateNotifier for reactive state management

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/generated/**/*.dart : Never manually edit generated files (`*.freezed.dart`, `*.g.dart`, `src/generated/`)

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*.dart : State class naming convention: Use `*State` suffix for state classes (e.g., `FeedState`, `ActivityListState`)

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
  • packages/stream_feeds/lib/src/state/activity_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Use `///` for public API documentation in exported classes and methods

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Follow Freezed 3.0 mixed mode syntax with `override` annotations for fields

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use Dart's type-safe queries for API operations with freezed query specifications

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Define separate query specifications from data models using freezed classes

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : Use extension functions for API-to-domain model mapping in repositories

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use extension functions on API response types for clean response transformation

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:37:05.876Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-12-05T14:37:05.876Z
Learning: Applies to **/*.dart : Implement StateNotifier-based reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-16T23:49:25.329Z
Learnt from: xsahil03x
Repo: GetStream/stream-feeds-flutter PR: 71
File: packages/stream_feeds/lib/src/state/event/handler/bookmark_folder_list_event_handler.dart:23-40
Timestamp: 2025-12-16T23:49:25.329Z
Learning: In the Flutter Stream Feeds SDK, BookmarkFolderAddedEvent does not exist in either backend or SDK. Review all event handling in the bookmark_folder_list_event_handler.dart (and related handler files) to rely only on BookmarkFolderUpdatedEvent and BookmarkFolderDeletedEvent. Remove any references to BookmarkFolderAddedEvent, adjust parsing/dispatch logic accordingly, and update tests and documentation to reflect supported events.

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields

Applied to files:

  • packages/stream_feeds/lib/src/state/activity_list_state.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use StateNotifier for reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:36:55.335Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/planit-mode.mdc:0-0
Timestamp: 2025-12-05T14:36:55.335Z
Learning: Applies to **/*.dart : Plan for StateNotifier reactive patterns when implementing state management in Dart

Applied to files:

  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : StateNotifier naming convention: Use `*StateNotifier` suffix for StateNotifier implementations (e.g., `FeedStateNotifier`)

Applied to files:

  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Model naming convention: Use `*Data` suffix for model classes (e.g., `ActivityData`, `FeedData`)

Applied to files:

  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Query naming convention: Use `*Query` suffix for query classes (e.g., `ActivitiesQuery`, `FeedsQuery`)

Applied to files:

  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Use `freezed` for all data classes in the Stream Feeds SDK

Applied to files:

  • packages/stream_feeds/lib/src/state/activity_list_state.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Use connection pooling and gzip compression for efficient HTTP connection management and reduced bandwidth when communicating with Stream Feeds API

Applied to files:

  • packages/stream_feeds/lib/src/state/activity_list_state.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Use batch operations for bulk activity creation and updates to optimize API performance

Applied to files:

  • packages/stream_feeds/lib/src/state/activity_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Test through public APIs only, not internal StateNotifier implementations

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Implement reactive state management with StateNotifier-based state management and automatic notifications

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Implement reactive state management with automatic change notifications using StateNotifier

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list_state.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: stream_feeds
🔇 Additional comments (13)
packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart (2)

27-84: Event handling logic is well-structured.

The handler correctly:

  • Applies query filters before updating state for PollUpdatedFeedEvent and PollClosedFeedEvent
  • Converts API models to domain models via toModel() before passing to state
  • Delegates all state mutations to PollListStateNotifier

59-63: No changes needed. The code is correct as written. PollAnswerCastedFeedEvent and PollAnswerRemovedFeedEvent are exported from resolvers.dart (imported directly on line 6), so they are available without the api. prefix. Meanwhile, PollVoteCastedFeedEvent and PollVoteRemovedFeedEvent come from api.models.dart (imported as api on line 3), requiring the prefix. This is proper namespace management, not an inconsistency.

packages/stream_feeds/lib/src/state/poll_list_state.dart (4)

17-28: Constructor and field setup follows StateNotifier conventions.

The currentUserId field is properly initialized and will be used by the vote/answer handling methods to determine user-specific state updates.


50-60: onPollUpdated correctly preserves existing state while applying updates.

Using sortedUpsert with existing.updateWith(updated) ensures that local state (e.g., accumulated votes) is preserved while server-side changes are merged in.


62-71: onPollClosed correctly preserves existing poll state.

The implementation now properly uses the existing poll it from the list and only updates the isClosed flag, preserving all accumulated local state.


142-166: PollListState follows freezed conventions correctly.

The state class uses const constructor, @override annotations on fields, and provides a useful canLoadMore computed getter.

packages/stream_feeds/lib/src/state/activity_list_state.dart (7)

21-32: Constructor and imports are properly set up for expanded poll handling.


54-61: Signature change from ActivityData to String activityId is appropriate.

Deletion events typically provide only the ID. This change simplifies the API and avoids requiring a full object when only the identifier is needed.


87-125: Reaction handlers follow a consistent pattern.

All three methods (onReactionAdded, onReactionUpdated, onReactionRemoved) use updateWhere with reaction.activityId to locate the target activity and delegate to the appropriate activity-level mutation method.


157-180: Comment handlers correctly use comment.objectId to locate parent activity.

onCommentAdded properly delegates to onCommentUpdated, following DRY principles.


269-284: onPollVoteCasted correctly delegates to onPollVoteChanged.

This DRY approach mirrors the pattern used in onCommentAddedonCommentUpdated.


286-296: Doc comment now correctly describes onPollAnswerRemoved.

The previously flagged documentation mismatch has been addressed.


315-339: ActivityListState follows freezed conventions correctly.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (1)
packages/stream_feeds/lib/src/state/poll_list_state.dart (1)

98-129: Consider DRY refactoring for poll update handlers.

All poll vote/answer handlers follow the same pattern:

final updatedPolls = state.polls.updateWhere(
  (it) => it.id == poll.id,
  update: (it) => it.someMethod(poll, data, currentUserId),
  compare: pollsSort.compare,
);
state = state.copyWith(polls: updatedPolls);

Consider extracting this into a private helper method to reduce duplication:

void _updatePoll(String pollId, PollData Function(PollData) updater) {
  final updatedPolls = state.polls.updateWhere(
    (it) => it.id == pollId,
    update: updater,
    compare: pollsSort.compare,
  );
  state = state.copyWith(polls: updatedPolls);
}

Then each handler becomes:

void onPollVoteChanged(PollData poll, PollVoteData vote) {
  _updatePoll(poll.id, (it) => it.upsertVote(poll, vote, currentUserId));
}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e5cd7df and 483fd9c.

📒 Files selected for processing (3)
  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart (2 hunks)
  • packages/stream_feeds/lib/src/state/poll_list.dart (2 hunks)
  • packages/stream_feeds/lib/src/state/poll_list_state.dart (4 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/cursor-rules-location.mdc)

**/*.dart: Use the barrel_files package with @includeInBarrelFile annotations for public API management in Dart projects; keep implementation details in lib/src/ without annotations
Mark only classes, functions, and enums intended for external package usage with @includeInBarrelFile; keep repository classes, mappers, and internal state objects in lib/src/ without annotations

**/*.dart: Use @freezed mixed mode for data classes in Dart
Return Result<T> from all repository methods in Dart
Apply early return patterns consistently in Dart code
Use pattern matching with switch expressions in Dart
Mark public APIs with @includeInBarrelFile annotation in Dart
Follow enhanced enum vs sealed class guidelines in Dart
Use const constructors where possible in Dart
Implement proper disposal patterns in Dart StateNotifiers and providers
Ensure pure Dart compatibility across VM, Flutter, and Web environments
Plan for StateNotifier reactive patterns when implementing state management in Dart

**/*.dart: Use @freezed for all data classes with required id fields and const constructors
Implement StateNotifier-based reactive state management with automatic change notifications
Apply Result pattern for all async operations with explicit error handling
Use early return patterns for clean control flow in Dart code
Create extension functions for data mapping using .toModel() pattern instead of mapper classes
Mark public APIs with @includeInBarrelFile annotation for barrel file export management
Implement proper resource management with disposal and cleanup patterns in Dart code
Use constructor injection for all dependencies in Dart classes

**/*.dart: All data models should use @freezed with Dart's mixed mode syntax and include @OverRide annotations on fields
Mark classes for public export using @includeInBarrelFile annotation
Use extension functions with .toModel() convention for data mapping instead of dedicated mapper classes
All repository methods must return Result...

Files:

  • packages/stream_feeds/lib/src/state/poll_list.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
packages/stream_feeds/lib/src/state/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

packages/stream_feeds/lib/src/state/**/*.dart: State classes must use @freezed with const constructors
State class naming convention: Use *State suffix for state classes (e.g., FeedState, ActivityListState)

Files:

  • packages/stream_feeds/lib/src/state/poll_list.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
packages/stream_feeds/lib/src/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Use // for internal/private code documentation

Files:

  • packages/stream_feeds/lib/src/state/poll_list.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
packages/stream_feeds/lib/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Apply Dart analyzer configuration from analysis_options.yaml for code quality

Files:

  • packages/stream_feeds/lib/src/state/poll_list.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
🧠 Learnings (24)
📓 Common learnings
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events
Learnt from: xsahil03x
Repo: GetStream/stream-feeds-flutter PR: 71
File: packages/stream_feeds/lib/src/state/event/handler/bookmark_folder_list_event_handler.dart:23-40
Timestamp: 2025-12-16T23:49:25.329Z
Learning: In the Stream Feeds Flutter SDK, `BookmarkFolderAddedEvent` does not exist in the backend and SDK. Only `BookmarkFolderUpdatedEvent` and `BookmarkFolderDeletedEvent` are available for bookmark folder event handling.
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Implement reactive state management with StateNotifier-based state management and automatic notifications

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : Use StateNotifier for reactive state management

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Implement reactive state management with automatic change notifications using StateNotifier

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use StateNotifier for reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:37:05.876Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-12-05T14:37:05.876Z
Learning: Applies to **/*.dart : Implement StateNotifier-based reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list.dart
  • packages/stream_feeds/lib/src/state/poll_list_state.dart
  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : StateNotifier naming convention: Use `*StateNotifier` suffix for StateNotifier implementations (e.g., `FeedStateNotifier`)

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Test through public APIs only, not internal StateNotifier implementations

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list_state.dart
  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Keep public API minimal - most code should be in `lib/src/` internal directory

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list_state.dart
  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:36:55.335Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/planit-mode.mdc:0-0
Timestamp: 2025-12-05T14:36:55.335Z
Learning: Applies to **/*.dart : Plan for StateNotifier reactive patterns when implementing state management in Dart

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Define separate query specifications from data models using freezed classes

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list_state.dart
  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Query naming convention: Use `*Query` suffix for query classes (e.g., `ActivitiesQuery`, `FeedsQuery`)

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list_state.dart
  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use Dart's type-safe queries for API operations with freezed query specifications

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list_state.dart
  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Use connection pooling and gzip compression for efficient HTTP connection management and reduced bandwidth when communicating with Stream Feeds API

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : Use extension functions for API-to-domain model mapping in repositories

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list_state.dart
  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Model naming convention: Use `*Data` suffix for model classes (e.g., `ActivityData`, `FeedData`)

Applied to files:

  • packages/stream_feeds/lib/src/state/poll_list_state.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/ws/events/**/*.dart : Real-time event handlers must use `freezed` for type-safe event handling in WebSocket layer

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Follow Effective Dart documentation guidelines for all public APIs

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement structured error handling for Stream Feeds API responses including 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests, and 500 Internal Server Error status codes

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Export public API classes from main library entry point `lib/stream_feeds.dart`

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use extension functions on API response types for clean response transformation

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
📚 Learning: 2025-12-16T23:49:25.329Z
Learnt from: xsahil03x
Repo: GetStream/stream-feeds-flutter PR: 71
File: packages/stream_feeds/lib/src/state/event/handler/bookmark_folder_list_event_handler.dart:23-40
Timestamp: 2025-12-16T23:49:25.329Z
Learning: In the Flutter Stream Feeds SDK, BookmarkFolderAddedEvent does not exist in either backend or SDK. Review all event handling in the bookmark_folder_list_event_handler.dart (and related handler files) to rely only on BookmarkFolderUpdatedEvent and BookmarkFolderDeletedEvent. Remove any references to BookmarkFolderAddedEvent, adjust parsing/dispatch logic accordingly, and update tests and documentation to reflect supported events.

Applied to files:

  • packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build
  • GitHub Check: stream_feeds
🔇 Additional comments (8)
packages/stream_feeds/lib/src/state/poll_list.dart (1)

29-47: LGTM!

The currentUserId is correctly threaded through to PollListStateNotifier to enable user-scoped poll operations (votes, answers). The pattern aligns with similar changes across Feed, Comment, and Activity state components.

packages/stream_feeds/lib/src/state/event/handler/poll_list_event_handler.dart (3)

27-29: LGTM!

The PollDeletedFeedEvent handler correctly removes the poll from the list by ID.


41-49: The filter check for closed polls is appropriate. isClosed is an explicit filterable field in PollsFilterField, and the filter check is consistent with how PollUpdatedFeedEvent works (verified by the test showing polls are removed when they no longer match filters). If a user filters for isClosed: false, closed polls should be removed from the list, making the current behavior correct.


51-79: No changes needed. The event type references are correct and intentional.

The types PollAnswerCastedFeedEvent and PollAnswerRemovedFeedEvent are defined in the resolvers package and exported via resolvers.dart (line 6 import), making them directly accessible without the api. prefix. In contrast, PollVoteCastedFeedEvent, PollVoteChangedFeedEvent, and PollVoteRemovedFeedEvent are API-generated models in generated/api/models.dart and require the api. prefix. This difference reflects their different source locations and is correct design, not an inconsistency.

Likely an incorrect or invalid review comment.

packages/stream_feeds/lib/src/state/poll_list_state.dart (4)

20-23: LGTM!

The currentUserId field enables user-scoped poll operations for votes and answers. The implementation is correct and consistent with the broader state management pattern.


62-71: LGTM!

The onPollClosed method correctly preserves existing poll state by using it.copyWith(isClosed: true), addressing the issue from the previous review. The signature change to accept String pollId instead of PollData is also cleaner.


51-60: updateWith method correctly merges poll data while preserving local state.

The onPollUpdated method uses sortedUpsert with existing.updateWith(updated) to merge poll updates. The updateWith method on PollData explicitly preserves the ownVotesAndAnswers field from the existing instance when merging, preventing unreliable server data from overwriting user-specific voting information—a sound approach to maintaining local state integrity during WebSocket events.


82-96: No issues found with upsertVote method or semantic handling.

The upsertVote method exists on PollData (line 207 in poll_data.dart) and uses an upsert operation that correctly handles both casting a new vote and changing an existing one. The onPollVoteCasted delegation to onPollVoteChanged is semantically correct since both represent the same state mutation—adding or updating a vote in the poll's vote list.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (1)
packages/stream_feeds/test/state/poll_list_test.dart (1)

28-86: Verify block uses stale pagination state.

The issue identified in the previous review remains: the verify block at lines 75-78 reads tester.pollListState.pagination?.next after the body completes. At that point, line 72 asserts this value is null, so the verification constructs a query with next: null rather than the 'next-cursor' value actually used during the API call.

🔎 Suggested fix

Capture the expected cursor value before state mutation or use the known cursor from setUp:

      verify: (tester) {
        final nextPageQuery = tester.pollList.query.copyWith(
-         next: tester.pollListState.pagination?.next,
+         next: 'next-cursor',
        );

        tester.verifyApi(
          (api) => api.queryPolls(
            queryPollsRequest: nextPageQuery.toRequest(),
          ),
        );
      },
🧹 Nitpick comments (3)
packages/stream_feeds/test/state/activity_comment_list_test.dart (1)

1-2: Verify necessity of the lint suppression.

The avoid_redundant_argument_values ignore directive suppresses warnings for the entire file. While explicitness in tests can aid readability, consider whether all redundant argument values are necessary or if some can be removed to reduce noise.

packages/stream_feeds/test/state/poll_list_test.dart (1)

378-467: Consider clarifying event resolution comments.

The comments at lines 394 and 447 mention event resolution (e.g., "resolved to PollAnswerCastedFeedEvent") but don't explain the mechanism. While the tests are functionally correct, adding a brief note about why the SDK resolves these events (e.g., "SDK determines event type based on payload structure") would improve maintainability.

Example clarification
-        // Emit PollVoteCastedFeedEvent (resolved to PollAnswerCastedFeedEvent)
+        // Emit PollVoteCastedFeedEvent (SDK resolves to answer event when pollVote contains answerText)
packages/stream_feeds/test/state/comment_reaction_list_test.dart (1)

287-328: Consider making the initial reaction type explicit in setUp.

The test assumes the first reaction has type 'like' (line 295), but the setUp doesn't explicitly configure this—it relies on the default behavior of createDefaultReactionResponse. While this likely works correctly, making the expected reaction type explicit in the setUp would improve test clarity and resilience to future changes in test data defaults.

🔎 Optional enhancement
 commentReactionListTest(
   'CommentReactionUpdatedEvent - should replace user reaction',
   build: (client) => client.commentReactionList(query),
-  setUp: (tester) => tester.get(),
+  setUp: (tester) => tester.get(
+    modifyResponse: (response) => response.copyWith(
+      reactions: [
+        createDefaultReactionResponse(
+          commentId: query.commentId,
+          reactionType: 'like',
+        ),
+      ],
+    ),
+  ),
   body: (tester) async {
     // Initial state - has 'like' reaction
     final existingReaction =
         tester.commentReactionListState.reactions.first;
     expect(existingReaction.type, 'like');
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 361a3d4 and a972e78.

📒 Files selected for processing (12)
  • packages/stream_feeds/lib/stream_feeds.dart (1 hunks)
  • packages/stream_feeds/test/state/activity_comment_list_test.dart (9 hunks)
  • packages/stream_feeds/test/state/activity_list_test.dart (4 hunks)
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/activity_test.dart (13 hunks)
  • packages/stream_feeds/test/state/comment_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/comment_reply_list_test.dart (17 hunks)
  • packages/stream_feeds/test/state/poll_list_test.dart (3 hunks)
  • packages/stream_feeds_test/lib/src/helpers/event_types.dart (3 hunks)
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart (10 hunks)
  • packages/stream_feeds_test/pubspec.yaml (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
🧰 Additional context used
📓 Path-based instructions (4)
**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/cursor-rules-location.mdc)

**/*.dart: Use the barrel_files package with @includeInBarrelFile annotations for public API management in Dart projects; keep implementation details in lib/src/ without annotations
Mark only classes, functions, and enums intended for external package usage with @includeInBarrelFile; keep repository classes, mappers, and internal state objects in lib/src/ without annotations

**/*.dart: Use @freezed mixed mode for data classes in Dart
Return Result<T> from all repository methods in Dart
Apply early return patterns consistently in Dart code
Use pattern matching with switch expressions in Dart
Mark public APIs with @includeInBarrelFile annotation in Dart
Follow enhanced enum vs sealed class guidelines in Dart
Use const constructors where possible in Dart
Implement proper disposal patterns in Dart StateNotifiers and providers
Ensure pure Dart compatibility across VM, Flutter, and Web environments
Plan for StateNotifier reactive patterns when implementing state management in Dart

**/*.dart: Use @freezed for all data classes with required id fields and const constructors
Implement StateNotifier-based reactive state management with automatic change notifications
Apply Result pattern for all async operations with explicit error handling
Use early return patterns for clean control flow in Dart code
Create extension functions for data mapping using .toModel() pattern instead of mapper classes
Mark public APIs with @includeInBarrelFile annotation for barrel file export management
Implement proper resource management with disposal and cleanup patterns in Dart code
Use constructor injection for all dependencies in Dart classes

**/*.dart: All data models should use @freezed with Dart's mixed mode syntax and include @OverRide annotations on fields
Mark classes for public export using @includeInBarrelFile annotation
Use extension functions with .toModel() convention for data mapping instead of dedicated mapper classes
All repository methods must return Result...

Files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/lib/stream_feeds.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/event_types.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
packages/stream_feeds/test/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

packages/stream_feeds/test/**/*.dart: Test through public APIs only, not internal StateNotifier implementations
Use HTTP interceptors instead of mocking repositories in tests
Mirror the lib/ structure in test/ directory organization

Files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
packages/stream_feeds/lib/stream_feeds.dart

📄 CodeRabbit inference engine (AGENTS.md)

packages/stream_feeds/lib/stream_feeds.dart: Use /// for public API documentation in exported classes and methods
Follow Effective Dart documentation guidelines for all public APIs
Include examples for complex APIs in documentation
Keep public API minimal - most code should be in lib/src/ internal directory
Export public API classes from main library entry point lib/stream_feeds.dart

Files:

  • packages/stream_feeds/lib/stream_feeds.dart
packages/stream_feeds/lib/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

Apply Dart analyzer configuration from analysis_options.yaml for code quality

Files:

  • packages/stream_feeds/lib/stream_feeds.dart
🧠 Learnings (32)
📓 Common learnings
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events
Learnt from: xsahil03x
Repo: GetStream/stream-feeds-flutter PR: 71
File: packages/stream_feeds/lib/src/state/event/handler/bookmark_folder_list_event_handler.dart:23-40
Timestamp: 2025-12-16T23:49:28.671Z
Learning: In the Stream Feeds Flutter SDK, `BookmarkFolderAddedEvent` does not exist in the backend and SDK. Only `BookmarkFolderUpdatedEvent` and `BookmarkFolderDeletedEvent` are available for bookmark folder event handling.
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Test through public APIs only, not internal StateNotifier implementations

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/lib/stream_feeds.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/event_types.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Include examples for complex APIs in documentation

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/lib/stream_feeds.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Use HTTP interceptors instead of mocking repositories in tests

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds_test/pubspec.yaml
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/event_types.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Mirror the `lib/` structure in `test/` directory organization

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/lib/stream_feeds.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : Use StateNotifier for reactive state management

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
📚 Learning: 2025-12-05T14:37:05.876Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-12-05T14:37:05.876Z
Learning: Applies to **/*.dart : Implement StateNotifier-based reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement structured error handling for Stream Feeds API responses including 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests, and 500 Internal Server Error status codes

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement circuit breaker pattern for automatic failure recovery in Stream Feeds API interactions

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Query naming convention: Use `*Query` suffix for query classes (e.g., `ActivitiesQuery`, `FeedsQuery`)

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement proper authentication using API keys and user tokens via the StreamFeedsClient with tokenProvider parameter

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Follow Effective Dart documentation guidelines for all public APIs

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/lib/stream_feeds.dart
  • packages/stream_feeds_test/pubspec.yaml
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/event_types.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Export public API classes from main library entry point `lib/stream_feeds.dart`

Applied to files:

  • packages/stream_feeds/lib/stream_feeds.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/event_types.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Keep public API minimal - most code should be in `lib/src/` internal directory

Applied to files:

  • packages/stream_feeds/lib/stream_feeds.dart
  • packages/stream_feeds_test/pubspec.yaml
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/event_types.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Use `///` for public API documentation in exported classes and methods

Applied to files:

  • packages/stream_feeds/lib/stream_feeds.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/event_types.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/generated/**/*.dart : Never manually edit generated files (`*.freezed.dart`, `*.g.dart`, `src/generated/`)

Applied to files:

  • packages/stream_feeds/lib/stream_feeds.dart
  • packages/stream_feeds_test/lib/src/helpers/event_types.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/**/*.dart : Use `//` for internal/private code documentation

Applied to files:

  • packages/stream_feeds/lib/stream_feeds.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : Use extension functions for API-to-domain model mapping in repositories

Applied to files:

  • packages/stream_feeds/lib/stream_feeds.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/generated/**/*.dart : Never manually edit OpenAPI-generated API code files in `src/generated/`

Applied to files:

  • packages/stream_feeds/lib/stream_feeds.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use extension functions on API response types for clean response transformation

Applied to files:

  • packages/stream_feeds/lib/stream_feeds.dart
📚 Learning: 2025-12-05T14:37:05.876Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-12-05T14:37:05.876Z
Learning: Applies to **/*.dart : Create extension functions for data mapping using `.toModel()` pattern instead of mapper classes

Applied to files:

  • packages/stream_feeds/lib/stream_feeds.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use extension functions with `.toModel()` convention for data mapping instead of dedicated mapper classes

Applied to files:

  • packages/stream_feeds/lib/stream_feeds.dart
📚 Learning: 2025-12-05T14:36:35.233Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/cursor-rules-location.mdc:0-0
Timestamp: 2025-12-05T14:36:35.233Z
Learning: Applies to **/*.dart : Mark only classes, functions, and enums intended for external package usage with includeInBarrelFile; keep repository classes, mappers, and internal state objects in lib/src/ without annotations

Applied to files:

  • packages/stream_feeds/lib/stream_feeds.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/pubspec.yaml : Pure Dart SDK: The stream_feeds package must have no platform-specific dependencies and work outside of Flutter

Applied to files:

  • packages/stream_feeds_test/pubspec.yaml
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*.dart : State class naming convention: Use `*State` suffix for state classes (e.g., `FeedState`, `ActivityListState`)

Applied to files:

  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Request naming convention: Use `*Request` suffix for request classes (e.g., `FeedAddActivityRequest`)

Applied to files:

  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds_test/lib/src/helpers/event_types.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Model naming convention: Use `*Data` suffix for model classes (e.g., `ActivityData`, `FeedData`)

Applied to files:

  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds_test/lib/src/helpers/event_types.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Use batch operations for bulk activity creation and updates to optimize API performance

Applied to files:

  • packages/stream_feeds/test/state/activity_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/**/*.dart : Apply Dart analyzer configuration from `analysis_options.yaml` for code quality

Applied to files:

  • packages/stream_feeds/test/state/poll_list_test.dart
📚 Learning: 2025-12-16T23:49:28.671Z
Learnt from: xsahil03x
Repo: GetStream/stream-feeds-flutter PR: 71
File: packages/stream_feeds/lib/src/state/event/handler/bookmark_folder_list_event_handler.dart:23-40
Timestamp: 2025-12-16T23:49:28.671Z
Learning: In the Stream Feeds Flutter SDK, `BookmarkFolderAddedEvent` does not exist in the backend and SDK. Only `BookmarkFolderUpdatedEvent` and `BookmarkFolderDeletedEvent` are available for bookmark folder event handling.

Applied to files:

  • packages/stream_feeds_test/lib/src/helpers/event_types.dart
🔇 Additional comments (42)
packages/stream_feeds_test/pubspec.yaml (1)

10-10: Collection dependency is appropriate for test utilities.

The addition of collection: ^1.18.0 is well-suited for test helper packages. The version exists and has no known security issues.

packages/stream_feeds/test/state/comment_reply_list_test.dart (3)

1-2: Appropriate use of lint directive for test clarity.

Suppressing avoid_redundant_argument_values in test files is a reasonable choice—explicit argument values make test intent clearer and improve maintainability.


296-322: Well-structured test for parent comment deletion behavior.

The test correctly verifies that when the parent comment is deleted, all child replies are cleared and pagination is reset. The event construction properly omits parentId since the deleted comment is a top-level comment.


958-961: Consistent use of factory functions for test data.

The refactoring to use createDefaultReactionResponse across all reaction-related tests improves maintainability and aligns with the broader test data factory pattern. The updated test at line 1030 with its more specific description and the addition of latestReactions in the event construction properly exercises the new reaction update semantics.

Also applies to: 986-990, 1015-1018, 1042-1046, 1072-1084, 1141-1145

packages/stream_feeds/test/state/activity_comment_list_test.dart (3)

555-559: LGTM! Consistent migration to test helpers.

The migration from direct FeedsReactionResponse construction to createDefaultReactionResponse helper improves maintainability and reduces boilerplate. The consistent pattern across all usages is well-executed.

Also applies to: 584-589, 614-620, 621-626, 649-653, 677-681, 729-734


572-572: LGTM! Clear and consistent test description.

The test description follows the established pattern and clearly describes the expected behavior.


747-892: LGTM! Comprehensive test coverage for activity deletion.

The new test group provides excellent coverage for activity deletion scenarios:

  • Verifies complete comment clearing including pagination reset
  • Tests nested reply clearing to ensure cascading deletion
  • Includes negative test case to verify activity ID filtering

The tests follow established patterns, use test helpers consistently, and align with coding guidelines for testing through public APIs.

packages/stream_feeds/test/state/poll_list_test.dart (6)

1-12: LGTM! Clean test setup.

The imports, const query setup, and feature organization headers are appropriate for the test structure.


14-26: LGTM! Initial query test is well-structured.

The test properly validates the initial poll query operation and result structure.


88-118: LGTM! Empty pagination handling is correct.

The test properly validates the behavior when no more polls are available.


125-323: LGTM! Comprehensive event handling coverage.

The tests thoroughly validate poll event mutations including deletion, updates, closures, and vote changes. The assertions properly verify both counts and state transformations.


325-376: LGTM! Vote removal logic is properly tested.

The test correctly validates that removing a vote updates both the vote count and removes the vote from the option's collection.


474-567: LGTM! Filtering behavior is thoroughly validated.

The local filtering tests comprehensively cover scenarios where polls should be removed when they no longer match filters, and verify that polls remain when no filter is applied. The test structure clearly demonstrates the expected filter behavior.

packages/stream_feeds/test/state/comment_reaction_list_test.dart (1)

1-441: Excellent comprehensive test coverage!

This test suite thoroughly covers comment reaction list functionality with well-structured tests for:

  • Query operations (initial fetch, pagination, edge cases)
  • Event handling (added/updated/deleted events with proper filtering by commentId)
  • Comment deletion impact on reactions
  • State mutations and pagination cursor management

The consistent use of the test helper pattern, comprehensive assertions, and inclusion of both positive and negative test cases (e.g., verifying events for different comments are ignored) demonstrates strong test design. This aligns well with the PR's objective to expand event coverage.

packages/stream_feeds_test/lib/src/helpers/test_data.dart (9)

1-4: LGTM!

The ignore directive for parameter_assignments is appropriately scoped to this file since parameter reassignment is intentionally used for default value computation in the factory functions below.


98-118: LGTM!

The reaction group aggregation logic correctly:

  • Falls back to ownReactions when latestReactions is empty
  • Uses fold/update pattern to aggregate by reaction type
  • Properly tracks first/last reaction timestamps using collection's .min/.max extensions

176-206: Verify: ownVotes assignment may include answers unintentionally.

Line 206 assigns ownVotes: ownVotesAndAnswers, which includes both votes and answers. However, latestVotesAndAnswers is correctly partitioned into separate latestAnswers and latestVotes lists. Should ownVotes be similarly partitioned to exclude answers?

If the API's ownVotes field is expected to contain only votes (not answers), consider applying the same partition:

final (ownAnswers, ownVotes) = ownVotesAndAnswers.partition(
  (vote) => vote.isAnswer ?? false,
);

Then use ownVotes at line 206.


257-270: LGTM!

The name and description parameters are correctly added and wired, providing test flexibility for feed response creation.


498-513: LGTM!

The new createDefaultActivityPinResponse factory follows the established pattern and provides necessary flexibility for testing pin-related functionality.


612-665: LGTM!

The new factory functions follow the established patterns:

  • createDefaultReactionResponse provides a flexible reaction builder
  • Query response factories (QueryActivityReactionsResponse, QueryCommentReactionsResponse, QueryCommentsResponse) consistently include pagination (next/prev) and duration fields

670-693: LGTM!

The status parameter addition and new createDefaultQueryFeedMembersResponse factory follow established patterns and provide necessary test flexibility.


695-711: LGTM!

The refactored parameters (sourceId, targetId, followerRole) provide better test flexibility. The hardcoded 'user' groupId is reasonable for default follow test scenarios.


713-764: LGTM!

The name parameter addition and new query response factories (QueryBookmarkFoldersResponse, QueryBookmarksResponse, QueryFeedsResponse) follow established patterns and complete the test data helpers for the expanded query APIs.

packages/stream_feeds/test/state/activity_list_test.dart (10)

1-12: Well-structured test setup.

The test file has clean imports and properly scoped constants. The use of shared constants (activityId, userId, reactionType, query) improves maintainability and reduces duplication.


18-90: Good coverage of activity feedback hide/unhide flows.

The tests properly verify both hiding (value: 'true') and unhiding (value: 'false') scenarios, with correct initial state setup and final assertions.


96-202: Comprehensive query operations coverage.

The tests cover:

  • Initial activity query with result validation
  • Pagination with cursor-based navigation
  • Edge case when no more activities are available

The pagination tests properly verify both the returned results and state mutations.


208-305: Good event handling coverage for activity lifecycle.

Tests properly cover the three core activity events (added, updated, deleted) with appropriate initial states and final assertions. The tests verify both the event processing and state mutations.


311-456: Solid reaction event handling tests.

The tests properly verify reaction add/update/delete flows. The update test correctly demonstrates the replacement semantics where a user's reaction is replaced rather than accumulated.


462-591: Bookmark event handling looks good.

Tests cover all bookmark lifecycle events. The update test properly verifies that custom data is preserved during updates.


597-741: Good comment event handling coverage.

The tests properly verify comment add/update/delete flows, including the commentCount property which is important for UI display.


747-937: Comment reaction tests are comprehensive.

Tests properly verify reaction operations on comments, including the replacement semantics for updates.


943-1323: Excellent poll coverage.

The tests comprehensively cover:

  • Poll lifecycle events (closed, deleted, updated)
  • Vote operations (cast, change, remove)
  • Answer operations (cast, remove)

State verification includes vote counts, vote distribution by option, and answer counts.


1329-1530: Good local filtering test coverage.

The tests properly verify:

  • Activities not matching filters are not added
  • Activities matching filters are added
  • Updated activities are removed when they no longer match filters
  • AND/OR filter logic behaves correctly
  • No-filter case allows all activities

This is important for maintaining UI consistency with server-side filtering.

packages/stream_feeds/test/state/activity_test.dart (8)

1-7: Clean test setup.

The use of FeedId type for the fid constant is more type-safe than using raw strings.


13-198: Comprehensive query operation tests.

Good coverage of:

  • Activity fetching
  • Comment pagination with cursor handling
  • Individual comment retrieval
  • Poll and poll option queries

The tests properly mock API calls and verify both responses and state updates.


204-445: Good activity method coverage.

Tests cover:

  • Activity feedback API and events
  • Pin/unpin operations
  • Activity update and delete events
  • Important edge case: delete event for different activity is ignored

The separation between API calls and event handling tests demonstrates proper understanding of the dual update paths.


451-733: Good comment operation coverage.

The tests properly cover:

  • CRUD operations via API
  • Batch comment addition
  • Importantly, the test at line 508-560 verifies that API call + real-time event together doesn't duplicate comments (idempotency)

The use of registerFallbackValue in setUpAll ensures mock matchers work correctly.


739-944: Comment reaction tests are solid.

Good coverage of add/delete operations, with the important idempotency test for API + event together scenario.


950-1118: Good activity reaction event coverage.

The tests properly use a currentUser context for testing ownReactions. The edge case test at line 1087-1116 ensures reactions for different activities are correctly ignored.


1124-1279: Good bookmark event coverage.

Tests properly verify bookmark add/update/delete flows. The edge case test at line 1251-1277 correctly verifies that bookmarks for different activities are ignored.


1285-2071: Excellent poll test coverage.

The tests comprehensively cover:

  • All poll API operations (close, delete, update variants, option CRUD, vote CRUD)
  • Poll lifecycle events
  • Vote and answer operations via events

The poll test suite is thorough and tests both the API layer and event-driven updates.

packages/stream_feeds_test/lib/src/helpers/event_types.dart (1)

1-64: Well-organized event types constants.

The constants are logically grouped by category and follow a consistent naming pattern (feeds.<entity>.<action>). The new additions align with the expanded event handling across the codebase.

Based on retrieved learnings, BookmarkFolderAddedEvent doesn't exist in the backend/SDK, so its absence is correct.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (6)
packages/stream_feeds/test/state/member_list_test.dart (1)

75-87: Fix verification to use the correct query parameters.

The verify block constructs the query using the current pagination state (after the API call), where next is now null (as confirmed on Line 73). However, the actual API call was made with next: 'next-cursor' from the initial setup. This means the verification is checking for the wrong parameters and may not correctly validate the API interaction.

Store the cursor value before making the call to ensure correct verification.

🔎 Proposed fix
 body: (tester) async {
   // Initial state - has members
   expect(tester.memberListState.members, hasLength(3));
   expect(tester.memberListState.canLoadMore, isTrue);
 
+  final nextCursor = tester.memberListState.pagination?.next;
   final nextPageQuery = tester.memberList.query.copyWith(
-    next: tester.memberListState.pagination?.next,
+    next: nextCursor,
   );
 
   tester.mockApi(
     (api) => api.queryFeedMembers(
       feedGroupId: nextPageQuery.fid.group,
       feedId: nextPageQuery.fid.id,
       queryFeedMembersRequest: nextPageQuery.toRequest(),
     ),
     result: createDefaultQueryFeedMembersResponse(
       members: [
         createDefaultFeedMemberResponse(id: 'member-4'),
       ],
     ),
   );
 
   // Query more members
   final result = await tester.memberList.queryMoreMembers();
 
   expect(result.isSuccess, isTrue);
   final members = result.getOrNull();
   expect(members, isNotNull);
   expect(members, hasLength(1));
 
   // Verify state was updated with merged members
   expect(tester.memberListState.members, hasLength(4));
   expect(tester.memberListState.canLoadMore, isFalse);
 },
 verify: (tester) {
+  final nextCursor = 'next-cursor'; // Use the cursor from setUp
   final nextPageQuery = tester.memberList.query.copyWith(
-    next: tester.memberListState.pagination?.next,
+    next: nextCursor,
   );
 
   tester.verifyApi(
     (api) => api.queryFeedMembers(
       feedGroupId: nextPageQuery.fid.group,
       feedId: nextPageQuery.fid.id,
       queryFeedMembersRequest: nextPageQuery.toRequest(),
     ),
   );
 },
packages/stream_feeds_test/lib/src/helpers/test_data.dart (1)

309-313: Inconsistent timestamp usage in ifAbsent callback.

This has already been flagged: the ifAbsent callback uses DateTime.timestamp() for firstReactionAt/lastReactionAt, while the equivalent code in createDefaultActivityResponse (lines 113-114) correctly uses curr.createdAt.

packages/stream_feeds/test/state/activity_comment_list_test.dart (1)

100-115: Verify block uses stale pagination state.

The verify block runs after body completes. At that point, pagination?.next is null (line 98 asserts canLoadMore is false). The nextPageQuery will have next: null, which doesn't match the query used in body.

Consider using the expected cursor value from setUp:

      verify: (tester) {
        final nextPageQuery = tester.activityCommentList.query.copyWith(
-         next: tester.activityCommentListState.pagination?.next,
+         next: 'next-cursor', // Use the known cursor from setUp
        );

        tester.verifyApi(
          (api) => api.getComments(
            objectId: nextPageQuery.objectId,
            objectType: nextPageQuery.objectType,
            depth: nextPageQuery.depth,
            sort: nextPageQuery.sort,
            limit: nextPageQuery.limit,
            next: nextPageQuery.next,
          ),
        );
      },
packages/stream_feeds/test/state/activity_reaction_list_test.dart (1)

89-100: Verify block uses stale pagination state.

The verify block runs after body completes. At that point, pagination?.next is null (line 87 asserts canLoadMore is false). This means the nextPageQuery constructed in verify will have next: null, which differs from the query actually used during body.

Consider using the expected cursor value from setUp:

      verify: (tester) {
        final nextPageQuery = tester.activityReactionList.query.copyWith(
-         next: tester.activityReactionListState.pagination?.next,
+         next: 'next-cursor', // Use the known cursor from setUp
        );

        tester.verifyApi(
          (api) => api.queryActivityReactions(
            activityId: activityId,
            queryActivityReactionsRequest: nextPageQuery.toRequest(),
          ),
        );
      },
packages/stream_feeds/test/state/activity_list_test.dart (1)

159-169: Verify block uses stale pagination state.

The verify block runs after body completes. At that point, pagination?.next is null (line 157 asserts canLoadMore is false). The nextPageQuery will have next: null, which doesn't match the query used in body.

Consider using the expected cursor value from setUp:

      verify: (tester) {
        final nextPageQuery = tester.activityList.query.copyWith(
-         next: tester.activityListState.pagination?.next,
+         next: 'next-cursor', // Use the known cursor from setUp
        );

        tester.verifyApi(
          (api) => api.queryActivities(
            queryActivitiesRequest: nextPageQuery.toRequest(),
          ),
        );
      },
packages/stream_feeds/test/state/poll_vote_list_test.dart (1)

74-86: Verify block uses stale pagination state.

The verify block reads tester.pollVoteListState.pagination?.next after the body completes. At that point, the state has been updated with the response from line 54-60 (which has no next field), so pagination?.next will be null. The constructed query won't match what was actually used during the API call in line 50-53.

Capture the expected cursor value directly from the setUp:

      verify: (tester) {
        final nextPageQuery = tester.pollVoteList.query.copyWith(
-         next: tester.pollVoteListState.pagination?.next,
+         next: 'next-cursor', // Use the known cursor from setUp (line 32)
        );

        tester.verifyApi(
          (api) => api.queryPollVotes(
            pollId: nextPageQuery.pollId,
            queryPollVotesRequest: nextPageQuery.toRequest(),
          ),
        );
      },
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between a972e78 and 413635b.

📒 Files selected for processing (19)
  • packages/stream_feeds/dart_test.yaml (1 hunks)
  • packages/stream_feeds/test/state/activity_comment_list_test.dart (12 hunks)
  • packages/stream_feeds/test/state/activity_list_test.dart (2 hunks)
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/activity_test.dart (13 hunks)
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/bookmark_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/comment_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/comment_reply_list_test.dart (21 hunks)
  • packages/stream_feeds/test/state/feed_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/follow_list_test.dart (3 hunks)
  • packages/stream_feeds/test/state/member_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/moderation_config_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/poll_list_test.dart (3 hunks)
  • packages/stream_feeds/test/state/poll_vote_list_test.dart (2 hunks)
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart (11 hunks)
  • packages/stream_feeds_test/lib/src/testers/moderation_config_list_tester.dart (1 hunks)
  • packages/stream_feeds_test/lib/stream_feeds_test.dart (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • packages/stream_feeds/test/state/bookmark_list_test.dart
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds_test/lib/stream_feeds_test.dart
🧰 Additional context used
📓 Path-based instructions (2)
**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/cursor-rules-location.mdc)

**/*.dart: Use the barrel_files package with @includeInBarrelFile annotations for public API management in Dart projects; keep implementation details in lib/src/ without annotations
Mark only classes, functions, and enums intended for external package usage with @includeInBarrelFile; keep repository classes, mappers, and internal state objects in lib/src/ without annotations

**/*.dart: Use @freezed mixed mode for data classes in Dart
Return Result<T> from all repository methods in Dart
Apply early return patterns consistently in Dart code
Use pattern matching with switch expressions in Dart
Mark public APIs with @includeInBarrelFile annotation in Dart
Follow enhanced enum vs sealed class guidelines in Dart
Use const constructors where possible in Dart
Implement proper disposal patterns in Dart StateNotifiers and providers
Ensure pure Dart compatibility across VM, Flutter, and Web environments
Plan for StateNotifier reactive patterns when implementing state management in Dart

**/*.dart: Use @freezed for all data classes with required id fields and const constructors
Implement StateNotifier-based reactive state management with automatic change notifications
Apply Result pattern for all async operations with explicit error handling
Use early return patterns for clean control flow in Dart code
Create extension functions for data mapping using .toModel() pattern instead of mapper classes
Mark public APIs with @includeInBarrelFile annotation for barrel file export management
Implement proper resource management with disposal and cleanup patterns in Dart code
Use constructor injection for all dependencies in Dart classes

**/*.dart: All data models should use @freezed with Dart's mixed mode syntax and include @OverRide annotations on fields
Mark classes for public export using @includeInBarrelFile annotation
Use extension functions with .toModel() convention for data mapping instead of dedicated mapper classes
All repository methods must return Result...

Files:

  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/moderation_config_list_tester.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
packages/stream_feeds/test/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

packages/stream_feeds/test/**/*.dart: Test through public APIs only, not internal StateNotifier implementations
Use HTTP interceptors instead of mocking repositories in tests
Mirror the lib/ structure in test/ directory organization

Files:

  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
🧠 Learnings (31)
📓 Common learnings
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events
Learnt from: xsahil03x
Repo: GetStream/stream-feeds-flutter PR: 71
File: packages/stream_feeds/lib/src/state/event/handler/bookmark_folder_list_event_handler.dart:23-40
Timestamp: 2025-12-16T23:49:28.671Z
Learning: In the Stream Feeds Flutter SDK, `BookmarkFolderAddedEvent` does not exist in the backend and SDK. Only `BookmarkFolderUpdatedEvent` and `BookmarkFolderDeletedEvent` are available for bookmark folder event handling.
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Test through public APIs only, not internal StateNotifier implementations

Applied to files:

  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds/dart_test.yaml
  • packages/stream_feeds_test/lib/src/testers/moderation_config_list_tester.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Include examples for complex APIs in documentation

Applied to files:

  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/moderation_config_list_tester.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Use HTTP interceptors instead of mocking repositories in tests

Applied to files:

  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/moderation_config_list_tester.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events

Applied to files:

  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Query naming convention: Use `*Query` suffix for query classes (e.g., `ActivitiesQuery`, `FeedsQuery`)

Applied to files:

  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Mirror the `lib/` structure in `test/` directory organization

Applied to files:

  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds/dart_test.yaml
  • packages/stream_feeds_test/lib/src/testers/moderation_config_list_tester.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement structured error handling for Stream Feeds API responses including 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests, and 500 Internal Server Error status codes

Applied to files:

  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Follow Effective Dart documentation guidelines for all public APIs

Applied to files:

  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/dart_test.yaml
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields

Applied to files:

  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/dart_test.yaml
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Keep public API minimal - most code should be in `lib/src/` internal directory

Applied to files:

  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds/dart_test.yaml
  • packages/stream_feeds_test/lib/src/testers/moderation_config_list_tester.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement circuit breaker pattern for automatic failure recovery in Stream Feeds API interactions

Applied to files:

  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
📚 Learning: 2025-12-16T23:49:28.671Z
Learnt from: xsahil03x
Repo: GetStream/stream-feeds-flutter PR: 71
File: packages/stream_feeds/lib/src/state/event/handler/bookmark_folder_list_event_handler.dart:23-40
Timestamp: 2025-12-16T23:49:28.671Z
Learning: In the Stream Feeds Flutter SDK, `BookmarkFolderAddedEvent` does not exist in the backend and SDK. Only `BookmarkFolderUpdatedEvent` and `BookmarkFolderDeletedEvent` are available for bookmark folder event handling.

Applied to files:

  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
📚 Learning: 2025-12-05T14:36:35.233Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/cursor-rules-location.mdc:0-0
Timestamp: 2025-12-05T14:36:35.233Z
Learning: Applies to test/**/*.dart : Mirror test structure to lib structure in test/ directory with corresponding test file organization following lib/src/ architecture layers

Applied to files:

  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*.dart : State class naming convention: Use `*State` suffix for state classes (e.g., `FeedState`, `ActivityListState`)

Applied to files:

  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Request naming convention: Use `*Request` suffix for request classes (e.g., `FeedAddActivityRequest`)

Applied to files:

  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Export public API classes from main library entry point `lib/stream_feeds.dart`

Applied to files:

  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds/dart_test.yaml
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Use `///` for public API documentation in exported classes and methods

Applied to files:

  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/**/*.dart : Use `//` for internal/private code documentation

Applied to files:

  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement proper authentication using API keys and user tokens via the StreamFeedsClient with tokenProvider parameter

Applied to files:

  • packages/stream_feeds/test/state/member_list_test.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Use batch operations for bulk activity creation and updates to optimize API performance

Applied to files:

  • packages/stream_feeds/test/state/activity_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Follow Freezed 3.0 mixed mode syntax with `override` annotations for fields

Applied to files:

  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/generated/**/*.dart : Never manually edit OpenAPI-generated API code files in `src/generated/`

Applied to files:

  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/dart_test.yaml
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : Use StateNotifier for reactive state management

Applied to files:

  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/generated/**/*.dart : Never manually edit generated files (`*.freezed.dart`, `*.g.dart`, `src/generated/`)

Applied to files:

  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/dart_test.yaml
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/**/*.dart : Apply Dart analyzer configuration from `analysis_options.yaml` for code quality

Applied to files:

  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds/dart_test.yaml
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use Dart's type-safe queries for API operations with freezed query specifications

Applied to files:

  • packages/stream_feeds/test/state/moderation_config_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Model naming convention: Use `*Data` suffix for model classes (e.g., `ActivityData`, `FeedData`)

Applied to files:

  • packages/stream_feeds/dart_test.yaml
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:37:05.876Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-12-05T14:37:05.876Z
Learning: Applies to **/*.dart : Implement StateNotifier-based reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use StateNotifier for reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Use `freezed` for all data classes in the Stream Feeds SDK

Applied to files:

  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
🔇 Additional comments (34)
packages/stream_feeds/dart_test.yaml (1)

1-17: LGTM! Test tag organization supports expanded coverage.

The new test tags appropriately reflect the expanded test suite for reactions, bookmarks, comments, feeds, members, and moderation config lists, aligning well with the PR's objective of handling missing events.

packages/stream_feeds/test/state/bookmark_folder_list_test.dart (3)

1-7: LGTM!

Clean test setup with well-defined constants for reuse across test cases. The use of const for immutable query objects is appropriate.


121-193: LGTM!

Comprehensive event handling tests covering BookmarkFolderUpdatedEvent and BookmarkFolderDeletedEvent. Based on learnings, these are the only available events for bookmark folders (no BookmarkFolderAddedEvent exists in the SDK), so coverage is complete.

The tests correctly verify state mutations after event emission with appropriate assertions.


199-265: LGTM!

Well-structured tests for local filtering behavior. Good coverage of both scenarios:

  1. Filter removes non-matching updated folders
  2. No filter preserves all folders regardless of updates

This validates the filter integration with event handling correctly.

packages/stream_feeds/test/state/moderation_config_list_test.dart (4)

1-10: LGTM!

Imports and test structure are well-organized. The group name clearly describes the test scope and follows the established testing patterns.


12-24: LGTM!

Clean test for initial config query. Appropriately validates both the Result type and the expected list length.


65-75: Verify block may construct incorrect query due to state mutation.

After body executes, queryMoreConfigs() updates the state with the response from lines 48-50, which has no next cursor. At verify time (line 67), tester.moderationConfigListState.pagination?.next will be null/empty rather than 'next-cursor'. This means the query constructed in verify won't match the actual API call made during body.

Consider capturing the expected query before state mutation, or verify using a hardcoded cursor value that matches the setUp:

🔎 Suggested fix
     verify: (tester) {
-      final nextPageQuery = tester.moderationConfigList.query.copyWith(
-        next: tester.moderationConfigListState.pagination?.next,
-      );
+      // Use the cursor value from setUp, not the post-body state
+      final nextPageQuery = tester.moderationConfigList.query.copyWith(
+        next: 'next-cursor',
+      );

       tester.verifyApi(
         (api) => api.queryModerationConfigs(
           queryModerationConfigsRequest: nextPageQuery.toRequest(),
         ),
       );
     },

78-100: LGTM!

Good edge case coverage for when no more configs are available. Correctly verifies that queryMoreConfigs returns an empty list and state remains unchanged.

packages/stream_feeds_test/lib/src/testers/moderation_config_list_tester.dart (4)

1-9: LGTM!

Imports are appropriate and well-organized. Using dart:async for FutureOr, package:meta for @istest, and properly importing internal helpers.


11-63: LGTM!

Excellent documentation with a complete example demonstrating proper usage. The function signature follows the established pattern from other testers, with appropriate optional parameters and sensible defaults.


70-126: LGTM!

The tester class is well-structured:

  • Uses final class for immutability
  • Private constructor prevents external instantiation
  • Clean getters for accessing subject, state, and stream
  • The get() method uses pattern matching with switch expression per coding guidelines
  • Default response with 3 configs provides consistent test data

128-150: LGTM!

Proper resource management with test.addTearDown ensuring the subject is disposed after each test. The factory function correctly wires up all dependencies.

packages/stream_feeds/test/state/comment_reply_list_test.dart (2)

1-470: LGTM! Comprehensive test coverage for comment reply list.

The test file demonstrates excellent coverage of:

  • Query operations with pagination via canLoadMore assertions
  • Event handling for comment add/update/delete at multiple nesting levels
  • Parent comment deletion clearing all replies (new test at lines 287-313)
  • Proper filtering of top-level comments vs replies

The test structure follows best practices by testing through public APIs using the commentReplyListTest helper with HTTP interceptors. Based on learnings, this aligns with the coding guidelines.


949-954: Good adoption of createDefaultReactionResponse helper.

The reaction tests consistently use the new helper function with named parameters (reactionType, userId, commentId), which improves readability and maintainability compared to inline construction.

Also applies to: 1006-1010, 1071-1075

packages/stream_feeds_test/lib/src/helpers/test_data.dart (3)

84-157: Well-structured derived computation for reaction groups.

The createDefaultActivityResponse properly derives latestReactions from ownReactions when empty, and computes reactionGroups with correct timestamp handling using curr.createdAt (lines 113-114). This pattern ensures test data consistency.


612-626: Good addition of createDefaultReactionResponse helper.

This helper provides a clean, reusable way to construct FeedsReactionResponse objects in tests with sensible defaults. It improves test readability by allowing callers to specify only the relevant parameters.


159-214: Well-designed poll response helper with vote/answer partitioning.

The updated createDefaultPollResponse properly handles:

  • Deriving latestVotesAndAnswers from ownVotesAndAnswers when empty
  • Using partition to separate answers from votes based on isAnswer flag
  • Computing latestVotesByOption by folding votes

This provides flexible test data construction while maintaining realistic data relationships.

packages/stream_feeds/test/state/follow_list_test.dart (3)

1-134: Comprehensive query operations test coverage.

The query operations group properly tests:

  • Initial fetch via get
  • Pagination with queryMoreFollows including cursor handling
  • Edge case when no more follows are available

The use of canLoadMore assertions ensures pagination state is correctly tracked.


140-251: Good event handling test coverage for follows.

The event handling tests properly verify:

  • Adding follows via FollowCreatedEvent
  • Updating follows with status changes via FollowUpdatedEvent
  • Removing follows via FollowDeletedEvent

The shared initialFollows setup reduces duplication while maintaining test isolation. Based on learnings, this aligns with implementing WebSocket event handlers for real-time updates.


253-336: Solid local filtering test coverage.

The filtering tests correctly validate:

  • Status-based filtering removes follows that no longer match
  • No filter specified preserves all follows regardless of status changes

This ensures the filter logic works correctly for both constrained and unconstrained queries.

packages/stream_feeds/test/state/comment_list_test.dart (3)

1-112: Well-structured query operations tests for comment list.

The test file establishes a clean pattern with:

  • Top-level query constant for reuse
  • Query operations covering initial fetch, pagination, and empty results
  • Proper canLoadMore assertions tracking pagination state

118-390: Excellent event handling coverage including reaction lifecycle.

The event handling tests provide comprehensive coverage:

  • Comment lifecycle events (add, update, delete)
  • Reaction lifecycle events with proper currentUser context
  • Reaction replacement via CommentReactionUpdatedEvent (line 279)

The use of user: currentUser parameter in reaction tests ensures proper user-scoped verification.


392-461: Consistent local filtering test pattern.

The filtering tests follow the established pattern from other list tests, validating:

  • Status-based filtering removes comments that no longer match
  • No filter specified preserves all comments regardless of status changes
packages/stream_feeds/test/state/feed_list_test.dart (3)

1-101: Comprehensive query operations test coverage for feed list.

The query operations group properly tests:

  • Initial fetch via get
  • Pagination with queryMoreFeeds including cursor handling
  • Edge case when no more feeds are available

107-209: Good event handling test coverage for feeds.

The event handling tests properly verify:

  • Adding feeds via FeedCreatedEvent with complete user context
  • Updating feed properties via FeedUpdatedEvent
  • Removing feeds via FeedDeletedEvent

Based on learnings, this aligns with implementing WebSocket event handlers for real-time Stream Feeds updates.


211-278: Consistent local filtering test pattern.

The filtering tests follow the established pattern, validating:

  • Visibility-based filtering removes feeds that no longer match
  • No filter specified preserves all feeds regardless of visibility changes

The group name update to "Feed List - Local filtering" maintains naming consistency across test files.

packages/stream_feeds/test/state/activity_reaction_list_test.dart (1)

1-405: LGTM! Comprehensive test coverage for Activity Reaction List.

The test suite effectively covers:

  • Query operations with pagination
  • Event-driven state updates (add/update/delete reactions)
  • Activity deletion clearing reactions
  • Edge cases (non-matching activity IDs)

Tests properly use public APIs, HTTP interceptors, and validate state mutations. As per coding guidelines.

packages/stream_feeds/test/state/poll_list_test.dart (1)

1-564: LGTM! Comprehensive test coverage for Poll List.

The test suite effectively covers:

  • Query operations with pagination
  • Multiple poll-related events (delete, update, close, vote operations, answers)
  • Local filtering scenarios with isClosed filter
  • State mutations and validation

Tests properly follow coding guidelines using public APIs and HTTP interceptors.

Note: The pagination issue in lines 74-85 has already been flagged in a previous review.

packages/stream_feeds/test/state/activity_comment_list_test.dart (1)

1-887: LGTM! Comprehensive test coverage for Activity Comment List.

The test suite effectively covers:

  • Query operations with pagination
  • Comment lifecycle (add, update, delete)
  • Nested and deeply nested replies
  • Comment reactions (add, update, delete)
  • Activity deletion cascading to comments
  • Edge cases (non-matching activity IDs)

Tests properly follow coding guidelines using public APIs and HTTP interceptors.

packages/stream_feeds/test/state/activity_list_test.dart (1)

1-1527: LGTM! Exceptional test coverage for Activity List.

The test suite provides comprehensive coverage across:

  • Activity feedback (hide/unhide)
  • Query operations with pagination
  • Activity lifecycle events (add, update, delete)
  • Reactions, bookmarks, comments, and polls
  • Complex filtering scenarios (AND/OR logic)
  • Edge cases and filter matching behavior

Tests properly follow coding guidelines using public APIs and HTTP interceptors.

packages/stream_feeds/test/state/activity_test.dart (2)

77-84: Correct pagination verification pattern.

This verify block correctly uses the hardcoded cursor value 'next-cursor' from setUp instead of reading from state. This is the recommended approach demonstrated in this test.


1-2068: LGTM! Comprehensive test coverage for Activity.

The test suite provides exceptional coverage:

  • Query operations (activity, comments, polls, poll options)
  • Activity methods (feedback, pin/unpin)
  • Comment lifecycle with batch operations
  • Comment and activity reactions
  • Bookmarks (add, update, delete)
  • Extensive poll operations (close, delete, update, options, votes, answers)
  • Both API-driven and event-driven state updates
  • Edge cases (different activity IDs, non-matching events)

Tests properly follow coding guidelines using public APIs and HTTP interceptors. The verify blocks correctly use expected values rather than stale state.

packages/stream_feeds/test/state/poll_vote_list_test.dart (2)

118-415: Comprehensive event handling coverage.

The event handling tests thoroughly cover all poll vote event types with both matching and non-matching scenarios. The defensive tests (e.g., lines 216-244 verifying that pollVote.pollId is checked even when poll.id matches) demonstrate good validation practices for real-time event processing.


417-486: Excellent filter edge case coverage.

The local filtering tests properly verify that vote updates respect the query filter — votes are removed when they change to non-matching values (lines 428-458) and retained when no filter is specified (lines 460-485). This ensures correct client-side filtering behavior for real-time updates.

@xsahil03x
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Dec 19, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (5)
packages/stream_feeds/CHANGELOG.md (1)

1-2: Consider expanding the changelog entry for clarity.

While the entry accurately describes the changes, it could be more specific to help users understand the scope and benefits. Compare with the detail provided in the 0.5.0 section above (e.g., mentioning specific event types: reactions, bookmarks, polls, comments). This would align with the project's existing changelog style and make it more informative for users reviewing the upcoming release notes.

packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart (2)

11-17: Documentation formatting issue: split doc comment block.

The doc comment block is split by a blank line at line 17, which causes the second part (lines 18-41) to be interpreted as a separate doc comment rather than a continuation. This results in the parameter documentation being detached from the main function description.

🔎 Proposed fix to merge documentation blocks
 /// Test helper for comment reaction list operations.
 ///
 /// Automatically sets up WebSocket connection, client, and test infrastructure.
 /// Tests are tagged with 'comment-reaction-list' by default for filtering.
 ///
-/// [user] is optional, the authenticated user for the test client (defaults to luke_skywalker).
-
-/// [build] constructs the [CommentReactionList] under test using the provided [StreamFeedsClient].
+/// Parameters:
+/// - [user] is optional, the authenticated user for the test client (defaults to luke_skywalker).
+/// - [build] constructs the [CommentReactionList] under test using the provided [StreamFeedsClient].
 /// [setUp] is optional and runs before [body] for setting up mocks and test state.

149-150: Incorrect comment: refers to "comment list" instead of "comment reaction list".

The teardown comment is misleading and likely copy-pasted from a different tester.

🔎 Proposed fix
-  // Dispose comment list after test
+  // Dispose comment reaction list after test
   test.addTearDown(subject.dispose);
packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart (2)

11-17: Documentation formatting issue: split doc comment block.

Same issue as in comment_reaction_list_tester.dart - the doc comment is split by a blank line at line 17, causing parameter documentation to be detached.

🔎 Proposed fix to merge documentation blocks
 /// Test helper for activity reaction list operations.
 ///
 /// Automatically sets up WebSocket connection, client, and test infrastructure.
 /// Tests are tagged with 'activity-reaction-list' by default for filtering.
 ///
-/// [user] is optional, the authenticated user for the test client (defaults to luke_skywalker).
-
-/// [build] constructs the [ActivityReactionList] under test using the provided [StreamFeedsClient].
+/// Parameters:
+/// - [user] is optional, the authenticated user for the test client (defaults to luke_skywalker).
+/// - [build] constructs the [ActivityReactionList] under test using the provided [StreamFeedsClient].
 /// [setUp] is optional and runs before [body] for setting up mocks and test state.

150-151: Incorrect comment: refers to "comment list" instead of "activity reaction list".

The teardown comment appears to be copy-pasted and refers to the wrong entity type.

🔎 Proposed fix
-  // Dispose comment list after test
+  // Dispose activity reaction list after test
   test.addTearDown(subject.dispose);
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1b4217b and f53dd04.

📒 Files selected for processing (4)
  • packages/stream_feeds/CHANGELOG.md (1 hunks)
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart (1 hunks)
  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart (1 hunks)
  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart
🧰 Additional context used
📓 Path-based instructions (1)
**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/cursor-rules-location.mdc)

**/*.dart: Use the barrel_files package with @includeInBarrelFile annotations for public API management in Dart projects; keep implementation details in lib/src/ without annotations
Mark only classes, functions, and enums intended for external package usage with @includeInBarrelFile; keep repository classes, mappers, and internal state objects in lib/src/ without annotations

**/*.dart: Use @freezed mixed mode for data classes in Dart
Return Result<T> from all repository methods in Dart
Apply early return patterns consistently in Dart code
Use pattern matching with switch expressions in Dart
Mark public APIs with @includeInBarrelFile annotation in Dart
Follow enhanced enum vs sealed class guidelines in Dart
Use const constructors where possible in Dart
Implement proper disposal patterns in Dart StateNotifiers and providers
Ensure pure Dart compatibility across VM, Flutter, and Web environments
Plan for StateNotifier reactive patterns when implementing state management in Dart

**/*.dart: Use @freezed for all data classes with required id fields and const constructors
Implement StateNotifier-based reactive state management with automatic change notifications
Apply Result pattern for all async operations with explicit error handling
Use early return patterns for clean control flow in Dart code
Create extension functions for data mapping using .toModel() pattern instead of mapper classes
Mark public APIs with @includeInBarrelFile annotation for barrel file export management
Implement proper resource management with disposal and cleanup patterns in Dart code
Use constructor injection for all dependencies in Dart classes

**/*.dart: All data models should use @freezed with Dart's mixed mode syntax and include @OverRide annotations on fields
Mark classes for public export using @includeInBarrelFile annotation
Use extension functions with .toModel() convention for data mapping instead of dedicated mapper classes
All repository methods must return Result...

Files:

  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
🧠 Learnings (10)
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events

Applied to files:

  • packages/stream_feeds/CHANGELOG.md
  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Test through public APIs only, not internal StateNotifier implementations

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Use HTTP interceptors instead of mocking repositories in tests

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Mirror the `lib/` structure in `test/` directory organization

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Include examples for complex APIs in documentation

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
📚 Learning: 2025-12-05T14:37:05.876Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-12-05T14:37:05.876Z
Learning: Applies to **/*.dart : Implement StateNotifier-based reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : Use StateNotifier for reactive state management

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Keep public API minimal - most code should be in `lib/src/` internal directory

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Use `///` for public API documentation in exported classes and methods

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
🔇 Additional comments (6)
packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart (3)

42-68: LGTM!

The commentReactionListTest function correctly delegates to testWithTester with appropriate parameters. The use of @isTest annotation ensures proper test discovery, and the default tags enable filtering.


75-93: LGTM!

The CommentReactionListTester class is well-structured with clear accessors for state and stream. The use of final class and private constructor with named parameters follows Dart best practices.


102-136: LGTM!

The get() method correctly:

  • Uses the query from the reaction list to construct default responses
  • Supports response customization via modifyResponse callback
  • Uses pattern matching with switch expression per coding guidelines
  • Returns the proper Result type
packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart (3)

42-68: LGTM!

The activityReactionListTest function correctly follows the established pattern, delegating to testWithTester with appropriate tag defaults for filtering.


75-94: LGTM!

The ActivityReactionListTester class provides clean accessors for state and stream, following the same well-structured pattern as the comment reaction list tester.


103-137: LGTM!

The get() method correctly uses the query's activityId for constructing default responses and properly delegates to queryActivityReactions. The switch expression for response modification follows coding guidelines.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/stream_feeds_test/lib/src/helpers/test_data.dart (1)

449-450: Use fixed timestamps for test determinism.

The DateTime.timestamp() calls create reactions with the current time, which makes test data non-deterministic. For consistency with the rest of the file (which uses fixed dates like DateTime(2021, 1, 1)), consider using fixed timestamps.

🔎 Proposed fix for deterministic test data

Replace DateTime.timestamp() with fixed dates. For example, in createDefaultReactionResponse:

 FeedsReactionResponse createDefaultReactionResponse({
   String activityId = 'activity-id',
   String? commentId,
   String userId = 'user-id',
   String reactionType = 'like',
 }) {
   return FeedsReactionResponse(
     activityId: activityId,
     commentId: commentId,
     type: reactionType,
-    createdAt: DateTime.timestamp(),
-    updatedAt: DateTime.timestamp(),
+    createdAt: DateTime(2021, 1, 1),
+    updatedAt: DateTime(2021, 2, 1),
     user: createDefaultUserResponse(id: userId),
   );
 }

Apply the same pattern to all other reaction factory functions using DateTime.timestamp().

Also applies to: 475-476, 587-588, 605-606, 622-623

🧹 Nitpick comments (3)
packages/stream_feeds/test/state/follow_list_test.dart (1)

252-331: LGTM! Local filtering tests validate filter interaction with events.

The tests effectively validate the interaction between query filters and event-driven updates:

  • Filtered lists correctly remove non-matching items after status changes
  • Unfiltered lists retain all items regardless of updates

Optional suggestion for consistency:

The fid values differ between test groups ('user:john' in Event Handling vs 'user:follow-1' here). While this doesn't affect test behavior, standardizing these values across the test file would improve maintainability.

🔎 Optional: Standardize fid values
         follow: createDefaultFollowResponse(
           sourceId: 'source-1',
           targetId: 'target-1',
           status: FollowResponseStatus.rejected,
         ),
-        fid: 'user:follow-1',
+        fid: 'user:john',
       ),
     );

Apply similar change at line 319.

packages/stream_feeds/test/state/bookmark_folder_list_test.dart (1)

83-109: Consider adding verification that no API call was made.

The test correctly validates that queryMoreBookmarkFolders returns an empty list when canLoadMore is false. To strengthen this test, consider adding a verification that no API call was made (if the test framework supports this, e.g., verifyNever or similar).

packages/stream_feeds/test/state/member_list_test.dart (1)

28-83: Consider using the separate verify: parameter for consistency.

The test correctly captures the cursor in nextPageQuery at lines 46-48 before the API call, so the verification logic is sound. However, calling verifyApi inside the body block (lines 75-81) is inconsistent with the memberListTest helper's design, which provides a dedicated verify: parameter for post-execution assertions.

🔎 Refactor to use the verify parameter
 memberListTest(
   'queryMoreMembers - should load more members via API',
   build: (client) => client.memberList(query),
   setUp: (tester) => tester.get(
     modifyResponse: (response) => response.copyWith(
       next: 'next-cursor',
       members: [
         createDefaultFeedMemberResponse(id: 'member-1'),
         createDefaultFeedMemberResponse(id: 'member-2'),
         createDefaultFeedMemberResponse(id: 'member-3'),
       ],
     ),
   ),
   body: (tester) async {
     // Initial state - has members
     expect(tester.memberListState.members, hasLength(3));
     expect(tester.memberListState.canLoadMore, isTrue);

     final nextPageQuery = tester.memberList.query.copyWith(
       next: tester.memberListState.pagination?.next,
     );

     tester.mockApi(
       (api) => api.queryFeedMembers(
         feedGroupId: nextPageQuery.fid.group,
         feedId: nextPageQuery.fid.id,
         queryFeedMembersRequest: nextPageQuery.toRequest(),
       ),
       result: createDefaultQueryFeedMembersResponse(
         members: [
           createDefaultFeedMemberResponse(id: 'member-4'),
         ],
       ),
     );

     // Query more members
     final result = await tester.memberList.queryMoreMembers();

     expect(result.isSuccess, isTrue);
     final members = result.getOrNull();
     expect(members, isNotNull);
     expect(members, hasLength(1));

     // Verify state was updated with merged members
     expect(tester.memberListState.members, hasLength(4));
     expect(tester.memberListState.canLoadMore, isFalse);
-
-    tester.verifyApi(
-      (api) => api.queryFeedMembers(
-        feedGroupId: nextPageQuery.fid.group,
-        feedId: nextPageQuery.fid.id,
-        queryFeedMembersRequest: nextPageQuery.toRequest(),
-      ),
-    );
   },
+  verify: (tester) {
+    final nextPageQuery = tester.memberList.query.copyWith(
+      next: 'next-cursor', // Use the cursor from setUp
+    );
+
+    tester.verifyApi(
+      (api) => api.queryFeedMembers(
+        feedGroupId: nextPageQuery.fid.group,
+        feedId: nextPageQuery.fid.id,
+        queryFeedMembersRequest: nextPageQuery.toRequest(),
+      ),
+    );
+  },
 );
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Disabled knowledge base sources:

  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between f53dd04 and 4a62569.

📒 Files selected for processing (19)
  • packages/stream_feeds/test/state/activity_comment_list_test.dart (12 hunks)
  • packages/stream_feeds/test/state/activity_list_test.dart (2 hunks)
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/activity_test.dart (13 hunks)
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/bookmark_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/comment_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/comment_reply_list_test.dart (21 hunks)
  • packages/stream_feeds/test/state/feed_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/follow_list_test.dart (3 hunks)
  • packages/stream_feeds/test/state/member_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/moderation_config_list_test.dart (1 hunks)
  • packages/stream_feeds/test/state/poll_list_test.dart (3 hunks)
  • packages/stream_feeds/test/state/poll_vote_list_test.dart (2 hunks)
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart (11 hunks)
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart (1 hunks)
  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart (1 hunks)
  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/stream_feeds/test/state/feed_list_test.dart
  • packages/stream_feeds/test/state/bookmark_list_test.dart
🧰 Additional context used
📓 Path-based instructions (2)
**/*.dart

📄 CodeRabbit inference engine (.cursor/rules/cursor-rules-location.mdc)

**/*.dart: Use the barrel_files package with @includeInBarrelFile annotations for public API management in Dart projects; keep implementation details in lib/src/ without annotations
Mark only classes, functions, and enums intended for external package usage with @includeInBarrelFile; keep repository classes, mappers, and internal state objects in lib/src/ without annotations

**/*.dart: Use @freezed mixed mode for data classes in Dart
Return Result<T> from all repository methods in Dart
Apply early return patterns consistently in Dart code
Use pattern matching with switch expressions in Dart
Mark public APIs with @includeInBarrelFile annotation in Dart
Follow enhanced enum vs sealed class guidelines in Dart
Use const constructors where possible in Dart
Implement proper disposal patterns in Dart StateNotifiers and providers
Ensure pure Dart compatibility across VM, Flutter, and Web environments
Plan for StateNotifier reactive patterns when implementing state management in Dart

**/*.dart: Use @freezed for all data classes with required id fields and const constructors
Implement StateNotifier-based reactive state management with automatic change notifications
Apply Result pattern for all async operations with explicit error handling
Use early return patterns for clean control flow in Dart code
Create extension functions for data mapping using .toModel() pattern instead of mapper classes
Mark public APIs with @includeInBarrelFile annotation for barrel file export management
Implement proper resource management with disposal and cleanup patterns in Dart code
Use constructor injection for all dependencies in Dart classes

**/*.dart: All data models should use @freezed with Dart's mixed mode syntax and include @OverRide annotations on fields
Mark classes for public export using @includeInBarrelFile annotation
Use extension functions with .toModel() convention for data mapping instead of dedicated mapper classes
All repository methods must return Result...

Files:

  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart
  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
packages/stream_feeds/test/**/*.dart

📄 CodeRabbit inference engine (AGENTS.md)

packages/stream_feeds/test/**/*.dart: Test through public APIs only, not internal StateNotifier implementations
Use HTTP interceptors instead of mocking repositories in tests
Mirror the lib/ structure in test/ directory organization

Files:

  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
🧠 Learnings (34)
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Test through public APIs only, not internal StateNotifier implementations

Applied to files:

  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart
  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement WebSocket event handlers for real-time Stream Feeds updates including activity events, reaction events, follow events, and member events

Applied to files:

  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart
  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Use HTTP interceptors instead of mocking repositories in tests

Applied to files:

  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart
  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/test/**/*.dart : Mirror the `lib/` structure in `test/` directory organization

Applied to files:

  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart
  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Include examples for complex APIs in documentation

Applied to files:

  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart
  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Keep public API minimal - most code should be in `lib/src/` internal directory

Applied to files:

  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart
  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Stream Feeds API integration should be implemented according to the Activity Streams specification with structured actor, verb, object, and target fields

Applied to files:

  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*.dart : State class naming convention: Use `*State` suffix for state classes (e.g., `FeedState`, `ActivityListState`)

Applied to files:

  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Follow Effective Dart documentation guidelines for all public APIs

Applied to files:

  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart
  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Use `///` for public API documentation in exported classes and methods

Applied to files:

  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement structured error handling for Stream Feeds API responses including 400 Bad Request, 401 Unauthorized, 403 Forbidden, 404 Not Found, 429 Too Many Requests, and 500 Internal Server Error status codes

Applied to files:

  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement circuit breaker pattern for automatic failure recovery in Stream Feeds API interactions

Applied to files:

  • packages/stream_feeds/test/state/member_list_test.dart
  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Implement proper authentication using API keys and user tokens via the StreamFeedsClient with tokenProvider parameter

Applied to files:

  • packages/stream_feeds/test/state/member_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/state/**/*StateNotifier.dart : Use StateNotifier for reactive state management

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart
📚 Learning: 2025-12-05T14:37:05.876Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-12-05T14:37:05.876Z
Learning: Applies to **/*.dart : Implement StateNotifier-based reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use StateNotifier for reactive state management with automatic change notifications

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
📚 Learning: 2025-12-05T14:36:55.335Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/planit-mode.mdc:0-0
Timestamp: 2025-12-05T14:36:55.335Z
Learning: Applies to **/*.dart : Plan for StateNotifier reactive patterns when implementing state management in Dart

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Query naming convention: Use `*Query` suffix for query classes (e.g., `ActivitiesQuery`, `FeedsQuery`)

Applied to files:

  • packages/stream_feeds/test/state/comment_reaction_list_test.dart
  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/activity_reaction_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/comment_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-16T23:49:28.671Z
Learnt from: xsahil03x
Repo: GetStream/stream-feeds-flutter PR: 71
File: packages/stream_feeds/lib/src/state/event/handler/bookmark_folder_list_event_handler.dart:23-40
Timestamp: 2025-12-16T23:49:28.671Z
Learning: In the Stream Feeds Flutter SDK, `BookmarkFolderAddedEvent` does not exist in the backend and SDK. Only `BookmarkFolderUpdatedEvent` and `BookmarkFolderDeletedEvent` are available for bookmark folder event handling.

Applied to files:

  • packages/stream_feeds/test/state/bookmark_folder_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/stream_feeds.dart : Export public API classes from main library entry point `lib/stream_feeds.dart`

Applied to files:

  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/**/*.dart : Apply Dart analyzer configuration from `analysis_options.yaml` for code quality

Applied to files:

  • packages/stream_feeds/test/state/poll_list_test.dart
  • packages/stream_feeds/test/state/moderation_config_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Request naming convention: Use `*Request` suffix for request classes (e.g., `FeedAddActivityRequest`)

Applied to files:

  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Model naming convention: Use `*Data` suffix for model classes (e.g., `ActivityData`, `FeedData`)

Applied to files:

  • packages/stream_feeds/test/state/activity_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
📚 Learning: 2025-12-05T14:37:17.519Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-api.mdc:0-0
Timestamp: 2025-12-05T14:37:17.519Z
Learning: Applies to {**/api/**/*.dart,**/*_api.dart,**/client/*.dart} : Use batch operations for bulk activity creation and updates to optimize API performance

Applied to files:

  • packages/stream_feeds/test/state/activity_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/**/*.dart : Use `//` for internal/private code documentation

Applied to files:

  • packages/stream_feeds/test/state/comment_reply_list_test.dart
  • packages/stream_feeds/test/state/activity_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
📚 Learning: 2025-12-05T14:37:05.876Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/project-overview.mdc:0-0
Timestamp: 2025-12-05T14:37:05.876Z
Learning: Applies to **/*.dart : Implement proper resource management with disposal and cleanup patterns in Dart code

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Implement proper disposal and cleanup patterns for resource management

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart
📚 Learning: 2025-12-05T14:36:55.335Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/planit-mode.mdc:0-0
Timestamp: 2025-12-05T14:36:55.335Z
Learning: Applies to **/*.dart : Implement proper disposal patterns in Dart StateNotifiers and providers

Applied to files:

  • packages/stream_feeds_test/lib/src/testers/member_list_tester.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/generated/**/*.dart : Never manually edit OpenAPI-generated API code files in `src/generated/`

Applied to files:

  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/generated/**/*.dart : Never manually edit generated files (`*.freezed.dart`, `*.g.dart`, `src/generated/`)

Applied to files:

  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:37:37.953Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: .cursor/rules/stream-feeds-sdk.mdc:0-0
Timestamp: 2025-12-05T14:37:37.953Z
Learning: Applies to **/*.dart : Use Dart's type-safe queries for API operations with freezed query specifications

Applied to files:

  • packages/stream_feeds/test/state/moderation_config_list_test.dart
  • packages/stream_feeds/test/state/poll_vote_list_test.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Follow Freezed 3.0 mixed mode syntax with `override` annotations for fields

Applied to files:

  • packages/stream_feeds/test/state/activity_comment_list_test.dart
  • packages/stream_feeds/test/state/follow_list_test.dart
  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/repository/**/*.dart : Use extension functions for API-to-domain model mapping in repositories

Applied to files:

  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
📚 Learning: 2025-12-05T14:38:02.662Z
Learnt from: CR
Repo: GetStream/stream-feeds-flutter PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-05T14:38:02.662Z
Learning: Applies to packages/stream_feeds/lib/src/models/**/*.dart : Use `freezed` for all data classes in the Stream Feeds SDK

Applied to files:

  • packages/stream_feeds_test/lib/src/helpers/test_data.dart
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (3)
  • GitHub Check: build
  • GitHub Check: analyze
  • GitHub Check: stream_feeds
🔇 Additional comments (71)
packages/stream_feeds/test/state/follow_list_test.dart (2)

11-129: LGTM! Query operations tests are comprehensive and well-structured.

The test coverage for query operations is thorough, including:

  • Initial fetch validation
  • Successful pagination with state merging
  • Edge case handling when no more follows are available

The tests properly use HTTP interceptors via mockApi/verifyApi and validate state changes through the public API.


135-246: LGTM! Event handling tests validate real-time updates effectively.

The event handling tests comprehensively cover:

  • Follow creation via FollowCreatedEvent
  • Follow updates via FollowUpdatedEvent with proper verification of field changes
  • Follow deletion via FollowDeletedEvent with null-check validation

The tests properly simulate real-time event processing and validate the resulting state changes.

packages/stream_feeds/test/state/comment_reply_list_test.dart (7)

1-2: LGTM - Test readability improvement.

The ignore directive allows explicit default values in test data creation, which improves test clarity and maintainability. This is acceptable practice in test code where explicitness is valued over brevity.


60-60: LGTM - Improved pagination semantics.

The switch from checking pagination?.next to using canLoadMore provides a cleaner, more semantic API. This improves test readability and aligns with best practices for state management.

Also applies to: 98-98, 132-132, 142-142


282-308: LGTM - Excellent coverage for cascade deletion.

This test case provides important coverage for the scenario where a parent comment is deleted, ensuring that all child replies are properly cleared and pagination is reset. The test structure is consistent with the existing test suite and the assertions are appropriate.


944-948: LGTM - Standardized test data creation.

The migration from direct FeedsReactionResponse constructor calls to the createDefaultReactionResponse helper function improves test maintainability by centralizing reaction data creation. This makes it easier to update reaction structures in the future and ensures consistency across all test cases.

Also applies to: 972-976, 1001-1005, 1028-1032, 1127-1131, 1202-1206, 1252-1256, 1287-1291, 1338-1342, 1365-1369, 1395-1399, 1423-1427, 1451-1455


1016-1016: LGTM - Improved test description.

The updated test description is more specific and clearly indicates both the event type being tested and the expected behavior (reaction replacement). This improves test documentation and makes the test suite easier to understand.


1058-1064: LGTM - Aligned with API contract.

The addition of the latestReactions field in the comment response ensures the test data matches the expected API response structure. This properly reflects how the backend would return updated comment data when a reaction is modified.


1-1465: Excellent test coverage and improvements.

This test file demonstrates comprehensive coverage of comment reply list functionality with well-structured test cases for:

  • Query operations with pagination
  • Event handling for comment lifecycle (added, updated, deleted)
  • Nested and deep-nested reply handling
  • Reaction management across all nesting levels
  • Edge cases and boundary conditions

The changes improve test maintainability through standardized helper usage, enhance readability with semantic properties like canLoadMore, and add important coverage for parent comment deletion cascading. The test structure follows best practices and aligns with the coding guidelines.

Based on learnings: Tests are structured to test through public APIs and mirror the lib/ directory structure as expected.

packages/stream_feeds/test/state/bookmark_folder_list_test.dart (5)

1-7: LGTM!

Good use of top-level constants for test data reuse across multiple test cases.


13-29: LGTM!

Clean test for initial query operation. The test correctly validates the Result type and checks folder contents.


31-81: LGTM! Pagination test correctly captures cursor before state mutation.

The test correctly captures nextPageQuery at lines 47-49 before the API call and state update, then reuses this same variable in the verify block. This ensures the verification uses the cursor value ('next-cursor') that was active when the API call was made.


116-188: LGTM! Comprehensive event handling tests.

The tests correctly cover BookmarkFolderUpdatedEvent and BookmarkFolderDeletedEvent scenarios. Based on learnings, these are the only two folder events available in the backend (no BookmarkFolderAddedEvent), so the coverage is complete.


194-260: LGTM! Good coverage of local filtering behavior.

The local filtering tests effectively validate two scenarios:

  1. Folder removal when an update causes it to no longer match the filter
  2. Folder retention when no filter is specified

This ensures the filtering logic behaves correctly in both constrained and unconstrained query contexts.

packages/stream_feeds/test/state/activity_test.dart (9)

1-11: LGTM! Clear test organization and setup.

The imports, constants, and feature organization provide a solid foundation for the comprehensive test suite.


13-195: LGTM! Comprehensive query operations coverage.

The test group demonstrates consistent patterns:

  • API-first testing approach
  • State verification after operations
  • Proper use of pagination cursors
  • Verification of API call parameters

Based on coding guidelines, tests properly access public APIs without directly testing internal StateNotifier implementations.


197-442: LGTM! Thorough activity methods and event handling.

Excellent coverage including:

  • API operations (feedback, pin, unpin)
  • Event handling (updated, deleted, feedback)
  • Edge case: verifying events for different activities don't affect current activity (lines 354-375)

The tests properly validate state mutations from both API calls and real-time events.


448-730: LGTM! Comprehensive comment operations testing.

Strong test coverage including:

  • CRUD operations for comments
  • Batch operations (addCommentsBatch)
  • Important deduplication test (lines 505-557) ensuring API + event don't create duplicates
  • Proper state verification via automatic callbacks

The use of registerFallbackValue for batch requests (line 453-455) aligns with Mocktail best practices.


732-941: LGTM! Comment reactions thoroughly tested.

The test group follows established patterns:

  • Add, delete operations via API
  • Deduplication test for API + event
  • Proper scoping of reactions to comments
  • Verification that reactions have correct type and user

Consistent with the comment testing patterns from the previous section.


943-1115: LGTM! Activity reactions event handling is comprehensive.

Strong event-driven test coverage:

  • Add, update, delete events properly handled
  • Update event correctly replaces existing reaction (lines 1006-1036)
  • Edge case: reactions for different activities ignored (lines 1084-1113)

Note: This section focuses on event handling. If there are API methods for adding/removing activity reactions, consider adding tests similar to the comment reactions section.


1117-1276: LGTM! Bookmark event handling is well-tested.

Thorough event coverage:

  • Add, update, delete events
  • Update verification includes custom field changes (line 1199)
  • Sequential test pattern (add → verify → update/delete → verify)
  • Edge case for different activities

Consistent pattern with activity reactions. Same note applies about considering API method tests if they exist.


1278-1722: LGTM! Comprehensive poll API operations coverage.

Excellent testing of poll lifecycle:

  • CRUD operations for polls (close, delete, update)
  • Poll option management (create, update, delete)
  • Vote operations (cast, delete)
  • All tests verify API calls and state updates
  • Consistent pattern: get poll ID from state, mock API, call method, verify

The poll functionality is thoroughly tested through the public API interface.


1724-2068: LGTM! Poll event handling is exceptionally thorough.

Outstanding event coverage including:

  • Basic poll events (closed, deleted, updated)
  • Vote operations with detailed state tracking:
    • Vote casted: updates count and latestVotesByOption (lines 1812-1866)
    • Vote changed: properly moves vote between options (lines 1868-1917)
    • Vote removed: cleans up state (lines 1919-1967)
  • Answer operations (casted, removed)

The tests verify both aggregate counts and detailed collections, ensuring state consistency across complex poll interactions.

packages/stream_feeds/test/state/member_list_test.dart (5)

14-26: LGTM!

The initial query test is well-structured and correctly validates the API interaction and result handling.


85-112: LGTM!

The test correctly validates the early-return behavior when no more members are available for pagination.


119-219: LGTM!

The event handling tests comprehensively validate member additions, updates, and removals through the event-driven architecture.


221-245: LGTM!

The test correctly validates feed ID matching to ensure events for different feeds don't affect the member list state.


252-317: LGTM!

The local filtering tests properly validate filter-based state mutations, ensuring members are removed when they no longer match the query filter and remain when no filter is specified.

packages/stream_feeds_test/lib/src/testers/member_list_tester.dart (4)

11-66: LGTM!

The memberListTest helper is well-documented with clear parameter descriptions and a practical example. The function signature properly exposes all necessary test lifecycle hooks (setUp, body, verify, tearDown) and configuration options.

Based on learnings, testing through public APIs is the recommended approach.


68-88: LGTM!

The MemberListTester class provides a clean, focused API surface with appropriately scoped accessors for the member list and its state stream.


89-122: LGTM!

The get() method is well-designed with clear documentation distinguishing between event tests (which need initial state) and API-only tests. The optional modifyResponse parameter provides good flexibility for test scenarios.


125-147: LGTM!

The factory function correctly registers resource cleanup via test.addTearDown(subject.dispose) at line 136, ensuring proper disposal after test completion. The comment accurately describes the cleanup action.

Based on learnings, proper disposal patterns are essential in Dart code.

packages/stream_feeds_test/lib/src/testers/comment_reaction_list_tester.dart (3)

1-68: LGTM! Well-structured test helper following established patterns.

The commentReactionListTest function and documentation are comprehensive. The pattern matching with switch on line 129-132 is idiomatic Dart. The test lifecycle hooks (setUp, body, verify, tearDown) provide good flexibility.


75-137: Clean tester implementation with good encapsulation.

The CommentReactionListTester class properly encapsulates WebSocket and API mocking. The get() method provides sensible defaults while allowing customization via modifyResponse.


139-161: Proper resource cleanup pattern.

The factory correctly registers subject.dispose via test.addTearDown to ensure cleanup after each test.

packages/stream_feeds_test/lib/src/testers/activity_reaction_list_tester.dart (2)

1-68: Well-documented test helper with consistent patterns.

The activityReactionListTest function follows the same structure as the comment reaction list tester, maintaining consistency across the test framework. The example in documentation helps with discoverability.


75-162: Clean implementation parallel to CommentReactionListTester.

The ActivityReactionListTester class and factory follow the same patterns, ensuring maintainability. State accessors and the get() method with modifyResponse customization are well-designed.

packages/stream_feeds/test/state/moderation_config_list_test.dart (1)

4-97: Comprehensive query operation tests following public API testing pattern.

The test suite covers the essential flows:

  • Initial query with 3 configs
  • Pagination with queryMoreConfigs and cursor handling
  • Edge case when no more configs are available

The tests correctly verify state updates (configs, canLoadMore) and API interactions via verifyApi. This aligns with the coding guideline to test through public APIs only. Based on learnings.

packages/stream_feeds/test/state/comment_list_test.dart (3)

1-107: Thorough query operations test coverage.

The query tests properly verify:

  • Initial fetch returning 3 comments
  • Pagination with queryMoreComments merging results (3 + 1 = 4)
  • Edge case returning empty list when canLoadMore is false

The tests follow the public API testing pattern correctly. Based on learnings.


109-385: Excellent event handling test coverage.

The event tests comprehensively cover the comment and reaction lifecycle:

  • Comment CRUD events (Added, Updated, Deleted)
  • Reaction CRUD events with proper ownReactions verification
  • Correctly uses currentUser to test reaction ownership

The tests verify state transitions after each event emission, ensuring the event handlers work correctly.


387-456: Good local filtering behavior tests.

The filtering tests verify:

  • Comments are removed when updated to non-matching status (with filter)
  • Comments remain when no filter is specified

These edge cases are important for ensuring the event handler respects query filters.

packages/stream_feeds/test/state/activity_reaction_list_test.dart (4)

5-15: Clear test setup with documented reaction ID computation.

The comment on lines 12-14 documenting the reaction ID formula ('$type-$userReactionsGroupId') helps future maintainers understand the expected behavior. This is good practice for complex computed values.


16-130: Thorough query operation tests with pagination coverage.

Tests cover:

  • Initial fetch with 3 reactions
  • Pagination with cursor and merged results
  • Empty list when no more reactions available

The verifyApi calls ensure the correct API methods are invoked with proper parameters.


132-302: Comprehensive event handling tests.

The event tests properly verify:

  • ActivityReactionAddedEvent adds new reaction
  • ActivityReactionUpdatedEvent replaces reaction type (love → fire)
  • ActivityReactionDeletedEvent removes reaction
  • Non-matching activityId events are ignored

This ensures the state notifier correctly filters and processes events.


304-399: Activity deletion tests verify complete cleanup.

The tests confirm that when an activity is deleted:

  • All reactions are cleared
  • Pagination is reset to null
  • canLoadMore becomes false

The test also verifies that deleting a different activity doesn't affect the current list, which is an important edge case.

packages/stream_feeds/test/state/poll_list_test.dart (3)

1-110: Well-structured Query Operations tests.

The test structure properly validates initial query, pagination, and empty result scenarios. The nextPageQuery is correctly captured at lines 46-48 before the state mutation occurs (the queryMorePolls call at line 63), so the pagination cursor will have the expected value when the verification happens at lines 74-78.


116-459: Comprehensive event handling coverage.

The tests properly cover all poll-related feed events including votes and answers. The documentation noting that PollVoteCastedFeedEvent resolves to PollAnswerCastedFeedEvent (line 385) and similar for removal (line 438) is helpful for understanding the event flow.


465-558: LGTM!

Local filtering tests properly validate filter behavior for poll updates and closures, including the important edge case where no filter is specified.

packages/stream_feeds/test/state/comment_reaction_list_test.dart (2)

1-118: Well-structured query and pagination tests.

The test file follows established patterns with proper separation of Query Operations. The pagination test at lines 29-87 correctly captures nextPageQuery before the state mutation.


124-428: Comprehensive event handling with proper boundary checks.

The tests thoroughly cover comment deletion and reaction events, including critical guards against applying changes to different comments. The consistent pattern of testing both matching and non-matching scenarios ensures robust event handling.

packages/stream_feeds/test/state/activity_comment_list_test.dart (4)

1-2: Appropriate lint ignore for test readability.

The avoid_redundant_argument_values ignore is reasonable for test files where explicit argument values improve test clarity and documentation.


57-98: Good use of canLoadMore computed property.

Using canLoadMore instead of manually checking pagination state is cleaner and more maintainable.


544-548: Consistent use of createDefaultReactionResponse helper.

The migration to the shared test helper improves consistency across test files and reduces duplication.


740-881: Thorough Activity Deletion test coverage.

The new tests properly verify that:

  1. All comments and pagination are cleared when the associated activity is deleted
  2. Nested reply structures are also cleared
  3. Comments for other activities are preserved

This ensures robust cleanup behavior for activity deletion events.

packages/stream_feeds/test/state/poll_vote_list_test.dart (3)

40-80: Pagination test correctly captures query before state mutation.

The nextPageQuery is captured at lines 45-47 before queryMorePollVotes() is called at line 63. At the capture point, tester.pollVoteListState.pagination?.next still contains 'next-cursor' from the setUp phase, so the verification at lines 74-79 will use the correct cursor value.


117-410: Comprehensive vote event handling with proper poll ID guards.

The tests thoroughly cover all poll vote events with consistent use of query.pollId and proper boundary testing for different poll scenarios. The filter-based rejection test at lines 241-274 ensures votes that don't match the query filter are correctly ignored.


416-481: LGTM!

Local filtering tests properly validate filter behavior for vote changes, consistent with the filtering patterns in other test files.

packages/stream_feeds/test/state/activity_list_test.dart (7)

1-2: Appropriate lint ignore for test readability.

Same rationale as other test files - explicit arguments improve test documentation.


18-90: Clear Activity Feedback event handling tests.

The tests properly demonstrate the ActivityFeedbackEvent pattern where the hide action combined with value: 'true'/'false' controls activity visibility. This is a clean API for toggling hidden state.


96-296: Standard query and event handling patterns.

Query Operations and Event Handling tests follow established patterns with proper state verification.


302-732: Comprehensive reaction, bookmark, and comment test coverage.

All three sections follow consistent patterns for add/update/delete operations with proper state verification.


738-928: Proper nested state updates for comment reactions.

Tests correctly verify that reaction events update the ownReactions on comments within activities, demonstrating proper handling of nested state structures.


934-1314: Extensive poll lifecycle and vote/answer operation coverage.

The poll tests comprehensively cover:

  • Poll state changes (close, delete, update)
  • Vote operations with proper count tracking and per-option verification
  • Answer operations using the appropriate events with resolver documentation

The nested Vote operations and Answer operations groups provide clear organization.


1320-1521: Thorough filter logic testing with AND/OR combinations.

The local filtering tests cover:

  • Basic filter matching/non-matching scenarios
  • AND filter logic where failure of any condition removes the activity
  • OR filter logic where matching any condition keeps the activity
  • No-filter baseline behavior

This ensures robust client-side filtering for real-time events.

packages/stream_feeds_test/lib/src/helpers/test_data.dart (7)

1-3: LGTM!

The collection package import is necessary for the sumOf, partition, min, and max methods used throughout the file. The parameter reassignment lint ignore is appropriate for test factory functions that compute defaults.


94-118: LGTM!

The reactionGroups aggregation logic correctly:

  • Defaults latestReactions to ownReactions when empty
  • Computes reactionGroups by folding over reactions and grouping by type
  • Tracks counts and uses min/max to maintain accurate firstReactionAt/lastReactionAt timestamps
  • Uses curr.createdAt for initial timestamps in the ifAbsent callback (consistent with the fix requested in the past review comment)

162-191: LGTM!

The poll data handling correctly:

  • Defaults latestVotesAndAnswers to ownVotesAndAnswers when empty
  • Uses partition to separate answers from votes
  • Builds latestVotesByOption by grouping votes by optionId

The pattern is consistent with the reaction grouping logic elsewhere in the file.


257-258: LGTM!

The name and description parameters provide better test data customization for FeedResponse instances.

Also applies to: 269-270


292-316: LGTM!

The reactionGroups aggregation logic for comments is consistent with the activity response implementation (lines 99-118) and correctly uses curr.createdAt for initial timestamps at lines 311-312, addressing the past review concern.


498-513: LGTM!

The new factory functions follow consistent patterns and provide comprehensive test data coverage for:

  • Activity pin responses
  • Reaction and query response types (activities, comments)
  • Feed member and bookmark queries
  • Moderation configs

All factories use appropriate defaults and maintain structural consistency with existing test helpers.

Also applies to: 612-626, 628-665, 682-693, 727-764, 860-886


670-670: LGTM!

The parameter additions enhance test data customization:

  • FeedMemberResponse now accepts status
  • FollowResponse refactored to use explicit sourceId/targetId with clearer feed construction
  • BookmarkFolderResponse now accepts name

These changes support more comprehensive test scenarios.

Also applies to: 676-676, 696-708, 715-715, 721-721

@xsahil03x
Copy link
Member Author

@coderabbitai review

@coderabbitai
Copy link

coderabbitai bot commented Dec 19, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@xsahil03x
Copy link
Member Author

@coderabbitai full review

@coderabbitai
Copy link

coderabbitai bot commented Dec 19, 2025

✅ Actions performed

Full review triggered.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (3)
packages/stream_feeds/lib/stream_feeds.dart (1)

7-7: Add @includeInBarrelFile annotation to MatchesExtensions.

The MatchesExtensions export requires the @includeInBarrelFile annotation as mandated by project guidelines for all public APIs. Add the annotation above the extension definition in packages/stream_feeds/lib/src/utils/filter.dart.

packages/stream_feeds/lib/src/state/event/handler/feed_event_handler.dart (1)

230-271: Add fid checks to poll event handlers to match other feed-scoped events.

Poll-related events have an fid field but don't check event.fid != query.fid.rawValue before processing. All other feed-scoped events perform this check. Without it, poll events from other feeds can incorrectly update this feed's state.

Additionally, lines 243 and 261 are missing the api. prefix on event types (PollAnswerCastedFeedEvent and PollAnswerRemovedFeedEvent), which is inconsistent with other events and may cause compilation errors.

🔎 Proposed fix
     if (event is api.PollClosedFeedEvent) {
+      if (event.fid != query.fid.rawValue) return;
       return state.onPollClosed(event.poll.id);
     }

     if (event is api.PollDeletedFeedEvent) {
+      if (event.fid != query.fid.rawValue) return;
       return state.onPollDeleted(event.poll.id);
     }

     if (event is api.PollUpdatedFeedEvent) {
+      if (event.fid != query.fid.rawValue) return;
       final poll = event.poll.toModel();
       return state.onPollUpdated(poll);
     }

-    if (event is PollAnswerCastedFeedEvent) {
+    if (event is api.PollAnswerCastedFeedEvent) {
+      if (event.fid != query.fid.rawValue) return;
       final poll = event.poll.toModel();
       final answer = event.pollVote.toModel();
       return state.onPollAnswerCasted(poll, answer);
     }

     if (event is api.PollVoteCastedFeedEvent) {
+      if (event.fid != query.fid.rawValue) return;
       final poll = event.poll.toModel();
       final vote = event.pollVote.toModel();
       return state.onPollVoteCasted(poll, vote);
     }

     if (event is api.PollVoteChangedFeedEvent) {
+      if (event.fid != query.fid.rawValue) return;
       final poll = event.poll.toModel();
       final vote = event.pollVote.toModel();
       return state.onPollVoteChanged(poll, vote);
     }

-    if (event is PollAnswerRemovedFeedEvent) {
+    if (event is api.PollAnswerRemovedFeedEvent) {
+      if (event.fid != query.fid.rawValue) return;
       final poll = event.poll.toModel();
       final answer = event.pollVote.toModel();
       return state.onPollAnswerRemoved(poll, answer);
     }

     if (event is api.PollVoteRemovedFeedEvent) {
+      if (event.fid != query.fid.rawValue) return;
       final poll = event.poll.toModel();
       final vote = event.pollVote.toModel();
       return state.onPollVoteRemoved(poll, vote);
     }
packages/stream_feeds/test/state/poll_vote_list_test.dart (1)

27-81: Verify block uses stale pagination state.

The verify block at lines 74-79 constructs nextPageQuery using tester.pollVoteListState.pagination?.next after the body completes. At that point, pagination?.next may already be null, causing the constructed query to mismatch what was actually used during the API call.

🔎 Proposed fix

Capture the pagination cursor before it changes:

       body: (tester) async {
         // Initial state - has votes
         expect(tester.pollVoteListState.votes, hasLength(3));
         expect(tester.pollVoteListState.canLoadMore, isTrue);
 
+        final expectedNext = tester.pollVoteListState.pagination?.next;
+
         final nextPageQuery = tester.pollVoteList.query.copyWith(
-          next: tester.pollVoteListState.pagination?.next,
+          next: expectedNext,
         );
 
         tester.mockApi(
           (api) => api.queryPollVotes(
             pollId: nextPageQuery.pollId,
             queryPollVotesRequest: nextPageQuery.toRequest(),
           ),
           result: PollVotesResponse(
             duration: DateTime.now().toIso8601String(),
             votes: [
               createDefaultPollVoteResponse(id: 'vote-4', pollId: query.pollId),
             ],
           ),
         );
 
         // Query more votes
         final result = await tester.pollVoteList.queryMorePollVotes();
 
         expect(result.isSuccess, isTrue);
         final votes = result.getOrNull();
         expect(votes, isNotNull);
         expect(votes, hasLength(1));
 
         // Verify state was updated with merged votes
         expect(tester.pollVoteListState.votes, hasLength(4));
         expect(tester.pollVoteListState.canLoadMore, isFalse);
 
         tester.verifyApi(
           (api) => api.queryPollVotes(
             pollId: nextPageQuery.pollId,
             queryPollVotesRequest: nextPageQuery.toRequest(),
           ),
         );
       },
🧹 Nitpick comments (3)
packages/stream_feeds/lib/src/state/follow_list_state.dart (1)

58-65: Consider adding an update parameter for data merging.

The refactored onFollowUpdated uses sortedUpsert without an update parameter. While this may be intentional if follows should be replaced entirely, consider whether partial updates should merge data rather than replace it.

For comparison, FeedListState.onFeedUpdated includes:

update: (existing, updated) => existing.updateWith(updated)

This allows merging fields from the update while preserving unchanged data. Verify whether FollowData supports partial updates and whether merging semantics are needed.

packages/stream_feeds/test/state/moderation_config_list_test.dart (1)

44-63: Consider making the pagination expectation explicit.

The test asserts canLoadMore is false after the second query, which relies on createDefaultQueryModerationConfigsResponse returning null for the next cursor by default. For clarity, consider explicitly setting next: null in the mock response:

result: createDefaultQueryModerationConfigsResponse(
  configs: [createDefaultModerationConfigResponse(key: 'config-2')],
  next: null, // Explicit: no more pages
),

This makes the test's intent clearer and protects against future changes to the helper's defaults.

packages/stream_feeds/lib/src/state/event/handler/activity_event_handler.dart (1)

104-110: Consider removing empty event handler blocks or adding context.

These empty blocks for comment events create noise. Either:

  1. Remove them entirely and add a catch-all comment at the end
  2. Add a note explaining why they're intentionally no-ops
🔎 Suggested improvement
-    // Comment events are not handled in the CommentListEventHandler
-    if (event is api.CommentAddedEvent) {}
-    if (event is api.CommentUpdatedEvent) {}
-    if (event is api.CommentDeletedEvent) {}
-    if (event is api.CommentReactionAddedEvent) {}
-    if (event is api.CommentReactionUpdatedEvent) {}
-    if (event is api.CommentReactionDeletedEvent) {}
-
     if (event is api.PollClosedFeedEvent) {

Or keep with improved comment:

-    // Comment events are not handled in the CommentListEventHandler
+    // Comment events are handled by CommentListEventHandler - intentionally skipped here
     if (event is api.CommentAddedEvent) {}

@xsahil03x xsahil03x merged commit d63b14c into main Dec 19, 2025
13 checks passed
@xsahil03x xsahil03x deleted the feat/add-missing-event-handlers branch December 19, 2025 14:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants