[WOOMOB-3442] Fix crash when toggling the unread reviews filter#16260
Conversation
|
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## trunk #16260 +/- ##
=========================================
Coverage 41.16% 41.16%
Complexity 13501 13501
=========================================
Files 2503 2503
Lines 146456 146456
Branches 21760 21760
=========================================
Hits 60283 60283
Misses 80076 80076
Partials 6097 6097 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
94e0179 to
bfcd628
Compare
There was a problem hiding this comment.
Pull request overview
This PR fixes a crash in the Reviews screen when toggling the “Unread reviews only” filter for merchants with multiple connected stores by ensuring cached review lookups are properly scoped to the selected site (preventing duplicate Compose LazyColumn keys due to cross-site ID collisions).
Changes:
- Scope
ProductReviewsDao.getProductReviews(ids)bylocalSiteIdto avoid returning reviews from other sites with the same remote review ID. - Thread the selected
SiteModelthroughReviewListRepository → WCProductStore → ProductReviewsDaofor the unread-review cached lookup path. - Add a regression test that validates cross-site duplicate review IDs do not produce duplicate results when querying a single site.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
| WooCommerce/src/main/kotlin/com/woocommerce/android/ui/reviews/ReviewListRepository.kt | Passes the selected site into the cached unread-reviews lookup to keep results site-scoped. |
| libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/store/WCProductStore.kt | Updates the store API to require site when fetching reviews by review ID, enforcing correct scoping. |
| libs/fluxc-plugin/src/main/kotlin/org/wordpress/android/fluxc/persistence/dao/ProductReviewsDao.kt | Fixes the underlying Room query to filter by localSiteId when selecting by review IDs. |
| libs/fluxc-plugin/src/test/java/org/wordpress/android/fluxc/persistence/dao/ProductReviewsDaoTest.kt | Adds a test covering duplicate review IDs across sites to prevent regressions. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
AI Code Review - No issues found. The changes look good.
The fix scopes the getProductReviews(ids) Room query by localSiteId, which is consistent with every other query in ProductReviewsDao (all of which are already site-scoped). The site parameter is threaded correctly through WCProductStore.getProductReviewsByReviewId and ReviewListRepository.getCachedUnreadProductReviews, and the only caller in the repo is updated. The added regression test correctly exercises the cross-site duplicate-ID scenario (same review IDs cached under two localSiteIds) and asserts no cross-site duplicates leak through — which is exactly the condition that produced the duplicate LazyColumn keys crash.
Automatic review · claude-opus-4-8 · Workflow run
How to reply to a finding
Reply on this review (or inline at the line the finding refers to) with one of:
@claude addressed- I made the change. Bot verifies against the next diff before marking resolved.@claude rejected: <reason>- Will not fix; reason gets quoted on the next review.@claude not-applicable- Finding does not apply (wrong file, already covered elsewhere, etc.).
The bot honours these on the next review pass.

Description
Fixes WOOMOB-3442
Root cause: The Reviews list is a Compose
LazyColumnkeyed byreview.remoteId, which requires globally unique keys. The unread-filter path resolves review ids from the selected site's notifications and reads them back viaProductReviewsDao.getProductReviews(ids)— the only query in that DAO that filtered solely byremoteProductReviewId IN (:ids), without scoping tolocalSiteId(every sibling query is site-scoped). Because WordPress review/comment ids are per-site, a merchant with more than one store can have the same review id cached under twolocalSiteIds. The un-scoped query then returned both rows, producing two reviews with the sameremoteId→ duplicateLazyColumnkey → crash.Fix: Scope
getProductReviews(ids)tolocalSiteId(matching the pattern of every other query in the DAO) and thread the selected site through the single call chain:Test Steps
Requires an account with two connected stores whose product reviews have overlapping ids (natural for fresh test stores, which number reviews
1, 2, 3…), and at least one unread review on the selected store (so the "Unread reviews only" switch and the mark-all-read ✓ appear).Images/gif
N/A
RELEASE-NOTES.txtif necessary. Use the "[Internal]" label for non-user-facing changes.