Skip to content

Increase unit test coverage and optimize Paparazzi snapshots#6555

Open
andremion wants to merge 6 commits into
developfrom
feature/and-1297-unit-test-coverage-quick-wins
Open

Increase unit test coverage and optimize Paparazzi snapshots#6555
andremion wants to merge 6 commits into
developfrom
feature/and-1297-unit-test-coverage-quick-wins

Conversation

@andremion

@andremion andremion commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Goal

Increase unit test coverage with a package of quick wins: tests for classes that are plain JVM logic and currently have low or zero coverage. While adding snapshot tests, we also found ways to make the Paparazzi suite cheaper and more complete, so this PR includes that work too.

Resolves AND-1297

📈 Coverage highlights

About 220 new unit tests across 4 modules:

Module New tests Areas
core 90 Model builders, computed properties, channel extensions
client 62 Offline mappers, poll converters, HTTP logging interceptor
ui-common 42 Audio player controller, typing buffer, user lookup
compose 28 ViewModels, channel options and swipe action snapshots

Blended line and branch coverage per class, measured from the merged Kover report:

Class Before After
AudioPlayerController 0% 88%
HttpLoggingInterceptor 0% 92%
QuerySortParser 0% 94%
Poll converters (Answer/Option/Vote) 13% 100%
User 13% 79%
AttachmentMapper 23% 94%
Reaction 25% 98%
DraftMessage 30% 84%
Channel 34% 86%
Message 37% 88%
ChannelOptions 8% 81%

Estimated overall Sonar impact: about +3 percentage points (68.9% today). The exact number comes from the CI Sonar run.

📸 Paparazzi snapshot optimization

All snapshot tests now render at hdpi with the SHRINK rendering mode (shared PIXEL_2_HDPI / PIXEL_4A_HDPI configs), and the dark/light helpers use weight(fill = false). Goldens contain only content, no device frame filler, while visual quality stays on par with the previous snapshots.

Metric Before After Delta
Goldens 379 394 +15
Total pixels 178.6M 126.6M -29%
Total bytes 9.9MB 9.65MB -2.6%
xychart-beta
    title "Golden set size (millions of pixels)"
    x-axis ["Before", "After"]
    y-axis "Megapixels" 0 --> 200
    bar [178.6, 126.6]
Loading

Fewer pixels means cheaper snapshot comparisons on every CI run, and the set grew by 15 goldens at the same time.

An audit of all snapshot tests also:

  • completed missing dark mode variants (channel options, media gallery screens, channels list),
  • fixed goldens where the side-by-side theme layout truncated content (command and mention suggestion lists, quoted message, giphy message content).

Implementation

  • Reused existing patterns and fixtures: random* helpers, sibling converter/mapper tests, the FakeChain harness, and PaparazziComposeTest. Plain JUnit 5 everywhere, no new Robolectric usage, so CI time stays flat.
  • New randomAnswerEntity / randomOptionEntity / randomVoteEntity fixtures in the client test Mother.kt.
  • One production fix rode along: MessageReminder.Builder(reminder) now copies cid and messageId (the setters existed but the copy constructor skipped both, so a builder round trip silently dropped them).
  • The interceptor tests install a recording logger and assert the exact log line per body-classification branch; the previous silent logger meant those branches were unobservable.
  • Tests document two remaining builder asymmetries as current behavior: Channel.Builder does not carry pendingMessages and Reaction.Builder does not carry skipPush. Fixing those needs new setters (API additions), so they are candidates for separate tickets.

🎨 UI Changes

No production UI changes. All golden image changes come from the rendering density and layout changes described above.

Testing

  • ./gradlew :testCoverage passes (all unit tests of the coverage modules, including the new ones).
  • ./gradlew :stream-chat-android-compose:verifyPaparazziDebug passes against the re-recorded goldens (394 goldens, one per snapshot test).
  • spotlessCheck, detekt, and apiCheck are clean (the production fix does not change the API surface).

To review the snapshot changes: open a few re-recorded goldens in the diff and check that content is complete and readable, and that dark and light variants are present.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled, or the PR is bot-authored.
  • An issue is linked (Linear ticket or GitHub issue), or the PR is bot-authored.

🎉 Great job! This PR is ready for review.

@andremion andremion added the pr:test Test-only changes label Jul 7, 2026
@andremion

Copy link
Copy Markdown
Contributor Author

@CodeRabbit review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

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.

@github-actions

github-actions Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

SDK Size Comparison 📏

SDK Before After Difference Status
stream-chat-android-client 5.93 MB 5.93 MB 0.00 MB 🟢
stream-chat-android-ui-components 11.20 MB 11.20 MB 0.00 MB 🟢
stream-chat-android-compose 12.67 MB 12.67 MB 0.00 MB 🟢

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Walkthrough

This PR adds extensive new unit test coverage across client offline mapping/converters, core model classes, ui-common features, and Compose UI/ViewModels, and migrates Compose Paparazzi snapshot tests from DeviceConfig presets to new HDPI-scaled device configurations with explicit rendering modes.

Changes

Client and Core Test Coverage

Layer / File(s) Summary
HTTP logging interceptor tests
stream-chat-android-client/.../HttpLoggingInterceptorTest.kt
New test suite covering request/response body handling, gzip decoding, and exception propagation with fake bodies and chains.
Test data factories
stream-chat-android-client/.../Mother.kt
Adds factories for attachment, reply-attachment, answer, option, and vote entities.
Converter and parser tests
AnswerConverterTest.kt, OptionConverterTest.kt, VoteConverterTest.kt, QuerySortParserTest.kt
New round-trip and error-handling tests for poll/vote converters and query sort parsing.
Attachment and message mapper tests
AttachmentMapperTest.kt, MessageMapperTest.kt
New/expanded tests for attachment upload-state mapping and message reply/draft/reminder/poll mapping.
Core model tests
AttachmentTest.kt, ChannelTest.kt, DraftMessageTest.kt, MemberTest.kt, MessageReminderTest.kt, MessageTest.kt, ReactionGroupTest.kt, ReactionTest.kt, UserTest.kt
New builder, copy-constructor, and getComparableField tests for core domain models.
UI-common feature tests
CompatUserLookupHandlerTest.kt, AudioPlayerControllerTest.kt, DefaultTypingUpdatesBufferTest.kt
New tests for user lookup compat handling, audio player controller behavior, and typing buffer timing.

Compose Paparazzi Migration and UI Tests

Layer / File(s) Summary
HDPI device config helper
PaparazziComposeTest.kt
Adds PIXEL_2_HDPI/PIXEL_4A_HDPI constants via atHdpi() and fixes Box weight modifiers.
Bulk Paparazzi config migration
~90 Compose test files
Switches deviceConfig from DeviceConfig.PIXEL_2/PIXEL_4A to HDPI constants and sets renderingMode = SHRINK.
New channel/swipe/options UI tests
ChannelsTest.kt, DefaultChannelSwipeActionsTest.kt, SwipeActionItemTest.kt, SwipeableChannelItemTest.kt, ChannelOptionsTest.kt
New snapshot tests for channel swipe actions and channel options menus.
New ViewModel tests
AudioPlayerViewModelTest.kt, PollOptionVotesViewModelTest.kt, PollResultsViewModelTest.kt, ReactionsMenuViewModelTest.kt
New coroutine-based tests for view model state/loading/pagination behavior.

Estimated code review effort: 3 (Moderate) | ~30 minutes

Possibly related PRs

Suggested reviewers: gpunto, VelikovPetar

Poem

A rabbit hops through tests anew,
Converters, mappers, models too 🐇
Paparazzi's lens now sharper, bright,
HDPI pixels shine with light.
Hop, click, snapshot — all in view,
Green checks bloom like carrots do! 🥕

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed The title accurately summarizes the main changes: added unit tests and Paparazzi snapshot optimization.
Description check ✅ Passed The description covers goal, implementation, UI changes, and testing, with detailed metrics and validation.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/and-1297-unit-test-coverage-quick-wins

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (2)
stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/avatar/ChannelAvatarTest.kt (1)

21-32: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Magic screenHeight = 2182 lacks explanatory comment.

The switch from DeviceConfig.PIXEL_4A.copy(screenHeight = 4000) to PIXEL_4A_HDPI.copy(screenHeight = 2182) is consistent with the PR's HDPI migration, but the specific pixel value isn't self-explanatory. A brief comment on why 2182 was chosen (vs. the default HDPI height) would aid future maintainers.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/avatar/ChannelAvatarTest.kt`
around lines 21 - 32, Add a brief explanatory comment in ChannelAvatarTest
around the Paparazzi deviceConfig setup so the custom PIXEL_4A_HDPI screenHeight
= 2182 value is clearly justified. Keep the note near the paparazzi rule and
mention that this height was chosen to match the HDPI migration/test baseline
rather than using the default height, so future readers understand why the magic
number is needed.
stream-chat-android-client/src/test/java/io/getstream/chat/android/client/internal/offline/Mother.kt (1)

210-305: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Duplicate randomAttachmentEntity/randomReplyAttachmentEntity bodies.

Both factories share identical parameter lists and construction logic, differing only in the return type. Could extract a shared parameter holder or builder to avoid drift between the two as AttachmentEntity/ReplyAttachmentEntity evolve.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@stream-chat-android-client/src/test/java/io/getstream/chat/android/client/internal/offline/Mother.kt`
around lines 210 - 305, The two factory helpers randomAttachmentEntity and
randomReplyAttachmentEntity are duplicated and can drift apart as
AttachmentEntity and ReplyAttachmentEntity change. Refactor the shared parameter
list and construction logic into a common helper or parameter holder, then have
both functions delegate to it while preserving their distinct return types.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@stream-chat-android-client/src/test/java/io/getstream/chat/android/client/internal/offline/Mother.kt`:
- Around line 210-305: The two factory helpers randomAttachmentEntity and
randomReplyAttachmentEntity are duplicated and can drift apart as
AttachmentEntity and ReplyAttachmentEntity change. Refactor the shared parameter
list and construction logic into a common helper or parameter holder, then have
both functions delegate to it while preserving their distinct return types.

In
`@stream-chat-android-compose/src/test/kotlin/io/getstream/chat/android/compose/ui/components/avatar/ChannelAvatarTest.kt`:
- Around line 21-32: Add a brief explanatory comment in ChannelAvatarTest around
the Paparazzi deviceConfig setup so the custom PIXEL_4A_HDPI screenHeight = 2182
value is clearly justified. Keep the note near the paparazzi rule and mention
that this height was chosen to match the HDPI migration/test baseline rather
than using the default height, so future readers understand why the magic number
is needed.

@sonarqubecloud

sonarqubecloud Bot commented Jul 7, 2026

Copy link
Copy Markdown

@andremion andremion marked this pull request as ready for review July 7, 2026 15:24
@andremion andremion requested a review from a team as a code owner July 7, 2026 15:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:test Test-only changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant