-
Notifications
You must be signed in to change notification settings - Fork 1
Simplify logic to update poll votes #176
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
PR checklist ✅All required conditions are satisfied:
🎉 Great job! This PR is ready for review. |
|
SDK Size Comparison 📏
|
WalkthroughThis PR refactors poll voting operations to simplify local state computation by accepting updated PollData from WebSocket events and propagating it throughout the state management layer, replacing poll ID strings with full PollData objects. Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
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. Comment |
There was a problem hiding this 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 (3)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImplTest.kt (1)
390-400: LGTM!Good coverage for the non-matching poll scenario on vote removal.
Minor naming observation: The new test method names (e.g.,
onPollVoteUpserted...) omit theonprefix pattern used elsewhere in this file (e.g.,on onPollUpdated, then...). This is a minor inconsistency that doesn't affect functionality.stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImplTest.kt (1)
902-910: Consider removing unused helper function.The
pollWithVotehelper function appears to be unused in the current test file. If it's no longer needed after the refactoring, consider removing it to reduce dead code.♻️ Suggested removal
- private fun pollWithVote(pollId: String, vote: PollVoteData): PollData = - pollData( - pollId, - "Test Poll", - voteCount = 1, - ownVotes = listOf(vote), - latestVotesByOption = mapOf(vote.optionId to listOf(vote)), - voteCountsByOption = mapOf(vote.optionId to 1), - )stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImpl.kt (1)
131-145: Consider enriching KDoc parameter descriptions.The parameter descriptions
@param poll The poll.are minimal. Consider adding context about the poll's role.📝 Suggested documentation improvement
/** * Called when a poll vote is added or updated. * - * @param poll The poll. + * @param poll The updated poll data from the WebSocket event. * @param vote The vote that was added or updated. */ fun onPollVoteUpserted(poll: PollData, vote: PollVoteData) /** * Called when a poll vote is removed. * - * @param poll The poll. + * @param poll The updated poll data from the WebSocket event. * @param vote The vote that was removed. */ fun onPollVoteRemoved(poll: PollData, vote: PollVoteData)
📜 Review details
Configuration used: Repository UI
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.
📒 Files selected for processing (26)
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/model/PollOperations.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepository.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/StateUpdateEvent.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandler.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandlerTest.ktstream-feeds-android-network/src/main/kotlin/io/getstream/feeds/android/network/models/PollVoteResponse.kt
🧰 Additional context used
📓 Path-based instructions (6)
**/*.{kt,kts}
📄 CodeRabbit inference engine (AGENTS.md)
Kotlin code targeting JVM 11, using Gradle Kotlin DSL with shared logic in
buildSrc/
Files:
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/StateUpdateEvent.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandler.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepository.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImpl.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/model/PollOperations.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImpl.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImplTest.ktstream-feeds-android-network/src/main/kotlin/io/getstream/feeds/android/network/models/PollVoteResponse.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandler.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImpl.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandlerTest.kt
**/*.kt
📄 CodeRabbit inference engine (AGENTS.md)
**/*.kt: Run Spotless (ktfmt) to enforce Kotlin style with 4 spaces and no wildcard imports
Run Detekt static analysis before committing and fix all findings
Use PascalCase for type names, camelCase for members
Files:
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/StateUpdateEvent.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandler.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepository.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImpl.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/model/PollOperations.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImpl.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImplTest.ktstream-feeds-android-network/src/main/kotlin/io/getstream/feeds/android/network/models/PollVoteResponse.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandler.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImpl.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandlerTest.kt
stream-feeds-android-client/**/*.kt
📄 CodeRabbit inference engine (AGENTS.md)
stream-feeds-android-client/**/*.kt: Enforce explicit API visibility for public APIs
Provide KDoc documentation for all public APIs
Log viaStreamLoggerwith actionable context and no secrets
Files:
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/StateUpdateEvent.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandler.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepository.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImpl.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/model/PollOperations.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImpl.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandler.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImpl.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandlerTest.kt
**/*.{kt,properties,gradle}
📄 CodeRabbit inference engine (AGENTS.md)
Scrub sensitive data from logs and configs
Files:
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/StateUpdateEvent.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandler.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepository.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandler.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImpl.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/model/PollOperations.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImpl.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImplTest.ktstream-feeds-android-network/src/main/kotlin/io/getstream/feeds/android/network/models/PollVoteResponse.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandler.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImplTest.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImpl.ktstream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImpl.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandlerTest.kt
**/src/test/kotlin/**/*.kt
📄 CodeRabbit inference engine (AGENTS.md)
**/src/test/kotlin/**/*.kt: Place tests under each module'ssrc/test/kotlin, mirroring package names
Cover success, retry, and failure paths for feed mutations, token refresh, and connectivity loss in tests
Use MockWebServer, fakes, Turbine, and coroutines-test for deterministic test assertions
Use backticked test names when helpful for readability
Files:
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandlerTest.kt
stream-feeds-android-network/**/*.kt
📄 CodeRabbit inference engine (AGENTS.md)
stream-feeds-android-network/**/*.kt: Use Retrofit, OkHttp, and Moshi (KSP) for networking and serialization
Keep coroutines structured and thread safe around token refresh, pagination, and realtime updates
Reuse shared retry/backoff helpers instead of implementing bespoke networking logic
Files:
stream-feeds-android-network/src/main/kotlin/io/getstream/feeds/android/network/models/PollVoteResponse.kt
🧠 Learnings (4)
📚 Learning: 2025-12-18T09:06:42.772Z
Learnt from: CR
Repo: GetStream/stream-feeds-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T09:06:42.772Z
Learning: Applies to **/src/test/kotlin/**/*.kt : Cover success, retry, and failure paths for feed mutations, token refresh, and connectivity loss in tests
Applied to files:
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandlerTest.kt
📚 Learning: 2025-12-18T09:06:42.772Z
Learnt from: CR
Repo: GetStream/stream-feeds-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T09:06:42.772Z
Learning: Applies to **/src/test/kotlin/**/*.kt : Use MockWebServer, fakes, Turbine, and coroutines-test for deterministic test assertions
Applied to files:
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandlerTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImplTest.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandlerTest.kt
📚 Learning: 2025-12-18T09:06:42.772Z
Learnt from: CR
Repo: GetStream/stream-feeds-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T09:06:42.772Z
Learning: Applies to stream-feeds-android-client/**/*.kt : Enforce explicit API visibility for public APIs
Applied to files:
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImpl.ktstream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandlerTest.kt
📚 Learning: 2025-12-18T09:06:42.772Z
Learnt from: CR
Repo: GetStream/stream-feeds-android PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-18T09:06:42.772Z
Learning: Applies to stream-feeds-android-network/**/*.kt : Keep coroutines structured and thread safe around token refresh, pagination, and realtime updates
Applied to files:
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImpl.kt
🧬 Code graph analysis (15)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImplTest.kt (2)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/test/TestData.kt (2)
pollVoteData(516-533)pollData(535-571)stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImplTest.kt (1)
setupActivityWithPoll(891-895)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImplTest.kt (1)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/test/TestData.kt (2)
pollData(535-571)pollVoteData(516-533)
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImpl.kt (2)
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImpl.kt (1)
updatePoll(261-265)stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/model/PollOperations.kt (2)
removeVote(133-134)upsertVote(119-126)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandlerTest.kt (2)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/test/TestData.kt (2)
pollData(535-571)pollVoteData(516-533)stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/BaseEventHandlerTest.kt (1)
testParams(44-48)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImplTest.kt (2)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/test/TestData.kt (4)
pollData(535-571)activityData(206-261)activityPin(385-392)pollVoteData(516-533)stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/FeedImplTest.kt (1)
setupInitialState(817-830)
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/model/PollOperations.kt (1)
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/utils/List.kt (1)
upsert(53-66)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandlerTest.kt (1)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/BaseEventHandlerTest.kt (1)
testParams(44-48)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImplTest.kt (1)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/test/TestData.kt (3)
pollData(535-571)activityData(206-261)pollVoteData(516-533)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandlerTest.kt (1)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/BaseEventHandlerTest.kt (1)
testParams(44-48)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandlerTest.kt (2)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/test/TestData.kt (2)
pollData(535-571)pollVoteData(516-533)stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/BaseEventHandlerTest.kt (1)
testParams(44-48)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImplTest.kt (2)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/test/TestData.kt (2)
pollResponseData(573-596)pollVoteResponseData(831-839)stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/repository/RepositoryTestUtils.kt (2)
testDelegation(25-29)testDelegation(31-40)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImplTest.kt (2)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/PollListImplTest.kt (1)
setupInitialState(105-115)stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/test/TestData.kt (2)
pollData(535-571)pollVoteData(516-533)
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImpl.kt (1)
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/core/result/ResultUtils.kt (1)
runSafely(31-39)
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImpl.kt (1)
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/StateUpdateEvent.kt (4)
poll(183-183)poll(185-185)poll(187-187)poll(189-189)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandlerTest.kt (2)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/test/TestData.kt (2)
pollData(535-571)pollVoteData(516-533)stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/BaseEventHandlerTest.kt (1)
testParams(44-48)
🔇 Additional comments (40)
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandlerTest.kt (2)
25-25: LGTM: Import addition supports test refactoring.The import of
pollDatafactory function is necessary for constructing PollData objects in the updated event creation, consistent with the existingpollVoteDataimport.
61-89: LGTM: Event construction correctly updated to use PollData.The refactoring properly updates all poll vote event constructors to accept
PollDataobjects instead of plain poll ID strings, aligning with the PR's objective to pass full poll data from WebSocket events. Test coverage is maintained across matching and non-matching poll scenarios for all vote event types.The unchanged verification blocks correctly reflect that the underlying state methods still expect the same parameters, confirming the refactoring doesn't alter the handler's behavior—just its input signature.
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImplTest.kt (5)
325-334: LGTM!The test correctly validates the new signature and behavior: the updated poll from the WebSocket event is used as the base, and
ownVotesis computed locally to include the current user's vote. This aligns with the PR objective of simplifying the logic.
336-348: LGTM!Good coverage for the case where another user votes—verifies that the current user's
ownVotesare preserved while accepting the updated poll data from the WebSocket event.
350-360: LGTM!Correctly tests the guard condition: when the update targets a different poll than the one in state, the existing poll remains unchanged.
362-374: LGTM!Properly validates vote removal: the poll is updated from the WebSocket event and
ownVotesis locally computed to exclude the removed vote.
376-388: LGTM!Correctly verifies that when another user's vote is removed, the current user's
ownVotesare preserved.stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/model/PollOperations.kt (1)
115-162: Excellent refactoring that achieves the PR objectives.The new
changeVotesabstraction successfully simplifies vote handling by:
- Centralizing the merge logic between
upsertVoteandremoveVote- Computing only
ownVoteslocally when the vote belongs to the current user (line 155)- Taking all other poll data from the
updatedparameter (WebSocket event data)- Using the
inlinekeyword appropriately for the lambda parameterThe ownership check with
vote.user?.id == currentUserIdcorrectly handles null users by preserving existingownVotesunchanged. TheenforceUniqueVotehandling at line 121 properly replaces all votes when unique voting is enforced.stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollVoteListEventHandler.kt (1)
41-54: Consistent update to poll-first data model.The changes correctly reference
event.poll.idinstead ofevent.pollIdacross all three poll vote event handlers (PollVoteCasted,PollVoteChanged,PollVoteRemoved), aligning with the broader refactor to propagate fullPollDataobjects through the event system.stream-feeds-android-network/src/main/kotlin/io/getstream/feeds/android/network/models/PollVoteResponse.kt (1)
28-29: Backward-compatible API extension.Adding the nullable
pollfield with a default value ofnullsafely extends thePollVoteResponsedata class to include poll data alongside vote data. The explicit nullability makes it clear to consumers that poll data may not always be present.stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandlerTest.kt (1)
193-206: Test updates correctly reflect the new poll-first semantics.The three poll vote test cases (
PollVoteCasted,PollVoteChanged,PollVoteRemoved) are properly updated to:
- Construct events using
pollData()objects instead of poll ID strings- Verify that state update methods receive both the
PollDataandPollVoteDatainstancesThe use of the
pollData()factory method works correctly with MockK verification since data classes use structural equality.stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImpl.kt (1)
113-125: Richer response payload enables simplified state management.Both
castPollVoteanddeletePollVotenow returnPair<PollVoteData?, PollData?>, providing:
- The vote data from the operation
- The updated poll state from the server response
The explicit nullable types in the return signature make it clear that callers must handle cases where either value may be absent. The use of Kotlin's
tooperator for Pair construction is idiomatic and readable.Also applies to: 142-156
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandlerTest.kt (1)
70-71: LGTM! Consistent migration to poll-first semantics.The test cases correctly reflect the updated event constructors that now accept
PollDataobjects instead of poll IDs, and the verification blocks properly validate the newonPollVoteUpserted(poll, vote)andonPollVoteRemoved(poll, vote)signatures.Also applies to: 75-76, 80-81
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImpl.kt (2)
326-344: Consistent implementation for vote removal.The
deletePollVotemethod follows the same pattern ascastPollVote, ensuring consistency across vote operations.
311-324: Null checks are necessary and properly justified.The repository returns
Result<Pair<PollVoteData?, PollData?>>where both elements are nullable, butStateUpdateEvent.PollVoteCastedrequires non-nullable constructor parameters. The checks on lines 316-320 defensively ensure both values are present before event emission, preventing NPE. The implementation correctly handles this type contract mismatch and safely returns only the vote data to maintain the method's signature.stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandler.kt (1)
215-220: LGTM! Event handlers correctly updated to poll-first semantics.All three poll vote event handlers now correctly pass
(poll, vote)to the state update methods, consistent with the refactor across the codebase.stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/FeedEventHandlerTest.kt (1)
440-441: LGTM! Tests correctly validate poll-first semantics.The parameterized tests properly construct events with
pollobjects and verify that state methods are called with(poll, pollVote)in the correct order.Also applies to: 445-446, 450-451
stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityImplTest.kt (2)
365-381: Test correctly validates poll vote deletion.The test follows the same pattern as
castPollVote, ensuring consistency. The assertion on Line 379 expectsownVotes = emptyList()after vote deletion, which is the correct behavior.
346-362: Test correctly validates poll vote casting with proper state computation.The test properly verifies that:
- The method returns only the vote (not the poll)
- The state is updated via event handling to include the new vote in
ownVotes- The emitted event contains the updated poll from the repository
The architecture is correct: the repository returns the poll without
ownVotescomputed, and the state layer computesownVoteslocally by checking ifvote.user?.id == currentUserIdin thechangeVotesoperation. The test assertion correctly verifies this computed state.stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityEventHandler.kt (1)
119-123: LGTM!The event handler correctly passes the full
PollDataobject from WebSocket events to the state update methods. This aligns with the PR objective to simplify vote handling by leveraging poll data from WS events rather than recomputing it locally.stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/PollListEventHandler.kt (1)
50-60: LGTM!The poll vote event handling is correctly updated to pass the full
PollDataobject. The lack of filter checks here is appropriate since vote events modify existing polls that have already passed the filter.stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepositoryImplTest.kt (2)
218-229: LGTM!The test correctly verifies that
castPollVotenow returns aPair<PollVoteData?, PollData?>containing both the vote and updated poll data from the API response. The use oftofor Pair creation is idiomatic Kotlin.
260-272: LGTM!The
deletePollVotetest is correctly updated to verify the new return type. Both cast and delete vote operations now consistently return poll data alongside vote data.Based on learnings, consider adding failure path tests for these repository methods to ensure robust error handling coverage.
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandler.kt (1)
84-86: LGTM!The changes are consistent with the other event handlers, correctly passing
PollDataandPollVoteDatato the state update methods.stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/repository/PollsRepository.kt (2)
141-145: LGTM!The return type change to
Pair<PollVoteData?, PollData?>appropriately captures both the vote and updated poll data from the API response. Since this is an internal interface, usingPairis acceptable and aligns with the PR objective.
162-167: LGTM!Consistent return type change for
deletePollVote, matchingcastPollVote. This ensures callers receive the updated poll state after vote deletion.stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/event/handler/ActivityListEventHandlerTest.kt (1)
224-238: LGTM!The parameterized test cases are correctly updated to construct poll vote events with
PollDataobjects and verify the corresponding state update method calls. The test structure maintains consistency with other event handler tests.stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityStateImpl.kt (2)
154-160: LGTM!The implementation correctly leverages the updated
PollDatafrom WebSocket events. By passing thepollparameter toremoveVote/upsertVote, the state update can take external data (like vote counts) from the WS event while computing only theownVoteslocally—exactly matching the PR objective and the pattern used inActivityData.upsertBookmark.
302-316: LGTM!The interface changes are well-documented with updated KDoc. The new signatures with
poll: PollDataas the first parameter provide the necessary context for downstream state updates to merge WS event data with locally-computed own votes.stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImplTest.kt (1)
338-400: LGTM! Comprehensive test coverage for the new poll-vote API.The tests properly verify the new poll-first semantics:
- Current user votes are correctly added/removed from
ownVotes- Different user votes preserve existing
ownVotesupdatedPollfrom WS event is used as the base, with onlyownVotescomputed locallyThis aligns well with the PR objective to rely on WS events for external data while computing only "own" properties locally.
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/ActivityListStateImpl.kt (2)
197-211: LGTM! Clean implementation of the simplified poll-vote API.The implementation correctly:
- Accepts
PollDatafrom WS events and usespoll.idfor matching- Delegates to
removeVote/upsertVotewith the fullPollDataobject- Allows the model layer to take external data (counts, etc.) from the poll while computing
ownVoteslocally
348-362: KDoc accurately reflects the new API.The parameter documentation is updated correctly from
pollIdtopollwith appropriate descriptions.stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/event/StateUpdateEvent.kt (2)
185-189: LGTM! Event payloads now carry full PollData.The updated data classes properly carry
poll: PollDatainstead ofpollId: String, enabling downstream state handlers to access all poll properties from the WS event. This is the foundation for the simplified vote logic.
328-335: LGTM! WS event mapping correctly constructs new event payloads.The
toModel()extension properly converts WS events to the newStateUpdateEventtypes usingpoll.toModel()for the poll parameter.stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImpl.kt (2)
353-363: LGTM! Consistent implementation with ActivityListStateImpl.The implementation correctly:
- Uses
poll.idfor matching activities- Delegates to
removeVote/upsertVotewith the fullPollData- Applies updates to both regular and pinned activities via
updateActivitiesWhere
556-560: Interface signatures correctly updated.The
FeedStateUpdatesinterface now accepts(poll: PollData, vote: PollVoteData)for both vote methods, consistent with the other state interfaces.stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/FeedStateImplTest.kt (1)
514-597: LGTM! Thorough test coverage for FeedStateImpl poll voting.The tests comprehensively verify:
- Current user vote upsert/removal updates
ownVotescorrectly- Different user votes preserve existing
ownVotes- Both
activitiesandpinnedActivitiesare updated- Non-matching poll IDs leave existing polls unchanged
This provides good confidence in the refactored implementation.
stream-feeds-android-client/src/main/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImpl.kt (1)
85-95: LGTM! Implementation consistent with other state classes.The
PollListStateImplcorrectly implements the new poll-vote API, usingpoll.idfor matching and delegating to the model layer for vote updates.stream-feeds-android-client/src/test/kotlin/io/getstream/feeds/android/client/internal/state/PollListStateImplTest.kt (2)
95-168: LGTM! Complete test coverage for PollListStateImpl vote operations.The tests thoroughly cover:
- Current user vote upsert/removal affecting
ownVotes- Different user votes preserving existing
ownVotes- Non-matching poll IDs leaving the list unchanged
Test naming follows clear conventions (backticked names for readability), consistent with coding guidelines.
66-91: Good test naming update.Renaming from "non-existent poll" to "non-matching poll" better reflects the test semantics—the poll exists but has a different ID than the one in the state.


Goal
AND-931: Simplify PollData.upsertVote
The logic to update poll votes had some fairly complex logic, but that's unneeded because we know that the only things that we need to compute locally are "own" properties and we can take the other ones (e.g. counts) from the WS event, like we do in similar cases
Implementation
The implementation mirrors what we are already doing in cases like
ActivityData.upsertBookmark. So we take the updated poll data and we only compute the own votes.Testing
Cast/change votes in a poll and verify that it updates correctly.
Checklist
Summary by CodeRabbit
✏️ Tip: You can customize this high-level summary in your review settings.