Skip to content

[MBL-19894][Student] Fix dashboard course widget not showing all unread announcements#3614

Merged
tamaskozmer merged 2 commits intomasterfrom
MBL-19894-Dashboard-course-widget-does-not-shows-all-unread-announcements
Apr 2, 2026
Merged

[MBL-19894][Student] Fix dashboard course widget not showing all unread announcements#3614
tamaskozmer merged 2 commits intomasterfrom
MBL-19894-Dashboard-course-widget-does-not-shows-all-unread-announcements

Conversation

@tamaskozmer
Copy link
Copy Markdown
Contributor

@tamaskozmer tamaskozmer commented Apr 1, 2026

Summary

  • Fixed announcement unread status detection to use case-insensitive comparison for the readState field
  • Updated LoadCourseAnnouncementsUseCase to properly detect unread announcements when the API returns lowercase "unread" status
  • Updated DiscussionListHolder to show the unread indicator when readState is "unread" (case-insensitive)
  • Added unit test for case-insensitive unread status matching

Test plan

  • Open the Student app
  • Navigate to the Dashboard
  • Verify that course widgets correctly display the unread announcement count
  • Navigate to a course's Announcements tab
  • Verify that announcements with unread status show the unread indicator
  • Compare the unread count with web/iOS to ensure parity

refs: MBL-19894
affects: Student
release note: Fixed an issue where the dashboard course widget was not showing all unread announcements


  • Follow-up e2e test ticket created or not needed
  • Tested in dark mode
  • Tested in light mode
  • Test in landscape mode and/or tablet
  • A11y checked
  • Approve from product

🤖 Generated with Claude Code

Co-Authored-By: Claude [email protected]

Copy link
Copy Markdown

@claude claude Bot left a comment

Choose a reason for hiding this comment

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

Review Summary

This PR correctly identifies that the Canvas API can return readState in varying cases (e.g. "unread" vs "UNREAD") and adds case-insensitive comparison to handle this. The added test case in LoadCourseAnnouncementsUseCaseTest is a good demonstration of the intent.

Issues Found

  • Null safety bug (LoadCourseAnnouncementsUseCase.kt:38): announcement.readState.equals(...) is called on a nullable String? field, which will throw NullPointerException at runtime if readState is null. The fix in DiscussionListHolder.kt correctly uses ?.equals() == true — the same pattern should be applied here. (See inline comment)

  • Indentation regression (LoadCourseAnnouncementsUseCase.kt:38): The filter lambda body was dedented from 12 to 8 spaces, breaking the surrounding code style. (See inline comment)

  • status property not used (both files): DiscussionTopicHeader already exposes a typed status: ReadState computed property that maps the raw readState string to the enum. Using announcement.status == DiscussionTopicHeader.ReadState.UNREAD in both places would be cleaner, type-safe, and avoid the raw string comparison and null handling entirely. (See inline comments)

  • Missing newline at end of file: Both LoadCourseAnnouncementsUseCase.kt and LoadCourseAnnouncementsUseCaseTest.kt are missing a trailing newline (shown as \ No newline at end of file in the diff).

Positive Feedback

The test added in LoadCourseAnnouncementsUseCaseTest is well-structured — it exercises both "unread" and "Unread" variants and correctly asserts that the "read" item is excluded. The null-safe ?.equals() == true pattern used in DiscussionListHolder.kt is the right approach for nullable strings.

// Filter for unread announcements only
return announcements.filter { announcement ->
announcement.unreadCount > 0 || announcement.readState == DiscussionTopicHeader.ReadState.UNREAD.name
announcement.unreadCount > 0 || announcement.readState.equals(DiscussionTopicHeader.ReadState.UNREAD.name, ignoreCase = true)
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Null safety bug: readState is declared as String? (nullable), so calling .equals() directly will throw a NullPointerException at runtime if the API returns null for this field.

Use the safe-call pattern (consistent with how DiscussionListHolder.kt handles this in the same PR):

announcement.unreadCount > 0 || announcement.readState?.equals(DiscussionTopicHeader.ReadState.UNREAD.name, ignoreCase = true) == true

Alternatively, DiscussionTopicHeader already exposes a typed status: ReadState computed property (lines 147–157 of the model) that maps the raw string — using it would eliminate the null concern and the string comparison entirely:

announcement.unreadCount > 0 || announcement.status == DiscussionTopicHeader.ReadState.UNREAD

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 1, 2026

🧪 Unit Test Results

✅ 📱 Student App

  • Tests: 1252 total, 0 failed, 0 skipped
  • Duration: 0.000s
  • Success Rate: 100%

✅ 🌅 Horizon

  • Tests: 790 total, 0 failed, 0 skipped
  • Duration: 37.127s
  • Success Rate: 100%

✅ 📦 Submodules

  • Tests: 3348 total, 0 failed, 0 skipped
  • Duration: 60.297s
  • Success Rate: 100%

📊 Summary

  • Total Tests: 5390
  • Failed: 0
  • Skipped: 0
  • Status: ✅ All tests passed!

Last updated: Thu, 02 Apr 2026 11:46:53 GMT

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 1, 2026

📊 Code Coverage Report

✅ Student

  • PR Coverage: 42.65%
  • Master Coverage: 42.65%
  • Delta: +0.00%

✅ Teacher

  • PR Coverage: 25.37%
  • Master Coverage: 25.37%
  • Delta: +0.00%

✅ Pandautils

  • PR Coverage: 23.68%
  • Master Coverage: 23.68%
  • Delta: +0.00%

📈 Overall Average

  • PR Coverage: 30.57%
  • Master Coverage: 30.57%
  • Delta: +0.00%

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 1, 2026

Student Install Page

Copy link
Copy Markdown
Contributor

@kdeakinstructure kdeakinstructure left a comment

Choose a reason for hiding this comment

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

QA 👍

Copy link
Copy Markdown
Contributor

@adamNagy56 adamNagy56 left a comment

Choose a reason for hiding this comment

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

QA +1

@tamaskozmer tamaskozmer merged commit 5dc7273 into master Apr 2, 2026
27 checks passed
@tamaskozmer tamaskozmer deleted the MBL-19894-Dashboard-course-widget-does-not-shows-all-unread-announcements branch April 2, 2026 13:27
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.

4 participants