Skip to content

Conversation

@andrebispo5
Copy link
Contributor

🎟️ Tracking

https://bitwarden.atlassian.net/browse/PM-23280
https://bitwarden.atlassian.net/browse/PM-26736

📔 Objective

This pull request updates how the PushNotificationLogOutReason is handled in push notification payloads, improving serialization and aligning field names with backend expectations. The main changes focus on serialization support and field renaming for consistency.

⏰ Reminders before review

  • Contributor guidelines followed
  • All formatters and local linters executed and passed
  • Written new unit and / or integration tests where applicable
  • Protected functional changes with optionality (feature flags)
  • Used internationalization (i18n) for all UI strings
  • CI builds passed
  • Communicated to DevOps any deployment requirements
  • Updated any necessary documentation (Confluence, contributing docs) or informed the documentation team

🦮 Reviewer guidelines

  • 👍 (:+1:) or similar for great changes
  • 📝 (:memo:) or ℹ️ (:information_source:) for notes or general info
  • ❓ (:question:) for questions
  • 🤔 (:thinking:) or 💭 (:thought_balloon:) for more open inquiry that's not quite a confirmed issue and could potentially benefit from discussion
  • 🎨 (:art:) for suggestions / improvements
  • ❌ (:x:) or ⚠️ (:warning:) for more significant problems or concerns needing attention
  • 🌱 (:seedling:) or ♻️ (:recycle:) for future improvements or indications of technical debt
  • ⛏ (:pick:) for minor or nitpick changes

@claude
Copy link
Contributor

claude bot commented Nov 3, 2025

Claude finished @andrebispo5's task —— View job


Code Review Complete ✅

I've reviewed the changes in this PR that fix push notification logout reason serialization. Overall, this is a well-implemented fix that properly addresses the serialization issues and aligns with backend expectations.


Summary

This PR makes three focused changes to fix how PushNotificationLogOutReason is serialized in push notification payloads:

  1. Added proper kotlinx.serialization support to PushNotificationLogOutReason enum
  2. Renamed the JSON field from "PushNotificationLogOutReason" to "Reason"
  3. Updated test data to match the new field name and format

Detailed Assessment

✅ What's Working Well

Architectural Compliance:

  • Follows established patterns from NotificationType (NotificationType.kt:11-69)
  • Uses BaseEnumeratedIntSerializer consistently with other integer-based enums
  • Proper use of @Keep, @Serializable, and @SerialName annotations
  • Changes are confined to the data layer as expected per docs/ARCHITECTURE.md

Serialization Implementation:

  • @Serializable(with = PushNotificationLogOutReasonSerializer::class) at PushNotificationLogOutReason.kt:11 enables proper serialization
  • BaseEnumeratedIntSerializer correctly handles integer-based enum serialization
  • @Keep annotation at line 17 prevents R8/ProGuard optimization issues
  • @SerialName("0") properly maps the KDF_CHANGE value

Field Naming:

  • New field name "Reason" is more concise and aligns with backend
  • @JsonNames("Reason", "reason") at NotificationPayload.kt:60 provides case-insensitive matching
  • Consistent with the pattern used for other fields in NotificationPayload

Test Coverage:

  • Test data updated correctly at PushManagerTest.kt:978
  • Changed from string "0" to integer 0 (correct format for BaseEnumeratedIntSerializer)
  • Existing test suite validates the functionality

📋 Review Status Update

Previous reviews identified the need to update test data - this has been properly addressed in commit f5e1988. The test payload now uses:

"Reason": 0

instead of the old:

"PushNotificationLogOutReason": "0"

Recommendations

No blocking issues found ✅

The implementation is solid and follows all established patterns in the codebase.

Optional Future Considerations

💭 Extensibility: Currently only KDF_CHANGE (0) is defined. When additional logout reasons are added in the future, they should follow the same pattern:

@SerialName("1")
ANOTHER_REASON,

📝 Documentation: The PR description clearly explains the changes. The KDoc on PushNotificationLogOutReason is adequate for the current scope.


Conclusion

This PR successfully fixes the push notification logout reason serialization bug. The changes are:

  • Architecturally sound - follows established patterns
  • Well-tested - test data properly updated
  • Consistent - matches serialization patterns used elsewhere
  • Complete - addresses all previously identified issues

Recommendation: Ready for merge pending any final team review preferences.


SaintPatrck
SaintPatrck previously approved these changes Nov 3, 2025
@andrebispo5 andrebispo5 enabled auto-merge November 3, 2025 19:53
/**
* Enumerated values to represent the possible reasons for a log out push notification
*/
@Serializable(with = PushNotificationLogOutReasonSerializer::class)
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 Excellent addition of the @Serializable annotation with custom serializer. This properly enables kotlinx.serialization support and uses BaseEnumeratedIntSerializer to handle integer-based enum serialization, consistent with other enums in the codebase like NotificationType.

Comment on lines +17 to +22
@Keep
private class PushNotificationLogOutReasonSerializer :
BaseEnumeratedIntSerializer<PushNotificationLogOutReason>(
className = "PushNotificationLogOutReason",
values = PushNotificationLogOutReason.entries.toTypedArray(),
)
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 Good use of @Keep annotation to prevent R8/ProGuard from removing this serializer during code optimization. This follows the same pattern as NotificationType and other enums using BaseEnumeratedIntSerializer in the codebase.

val date: ZonedDateTime?,

@JsonNames("PushNotificationLogOutReason", "pushNotificationLogOutReason")
@JsonNames("Reason", "reason")
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Critical Issue: Test data needs to be updated

This field name change from "PushNotificationLogOutReason" to "Reason" breaks existing test data. The test file PushManagerTest.kt at line 978 still uses the old field name:

private val LOGOUT_KDF_NOTIFICATION_MAP = mapOf(
    ...
    "payload" to """{
      "UserId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
      "Date": "2023-10-27T12:00:00.000Z",
      "PushNotificationLogOutReason": "0"  // ❌ Should be "Reason": "0"
    }""",
)

Action Required: Update the test payload to use "Reason": "0" to match the new serialization field name. This will cause deserialization to fail in tests otherwise.

📝 Note: The @JsonNames annotation includes both "Reason" and "reason" (lowercase), which is good for backward compatibility with different casing from the backend. However, the old field name "PushNotificationLogOutReason" is completely different and won't be recognized.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Can we update all the test JSON to reflect these changes

@github-actions
Copy link
Contributor

github-actions bot commented Nov 3, 2025

Logo
Checkmarx One – Scan Summary & Detailsdde4017a-eba4-4504-a32d-baf4a171c56b

Great job! No new security vulnerabilities introduced in this pull request

"UserId": "078966a2-93c2-4618-ae2a-0a2394c88d37",
"Date": "2023-10-27T12:00:00.000Z",
"PushNotificationLogOutReason": "0"
"Reason": 0
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 Excellent fix! The test data has been properly updated to match the new field name and format:

  • Field renamed from "PushNotificationLogOutReason" to "Reason" (matching backend expectations)
  • Value changed from string "0" to integer 0 (correct format for BaseEnumeratedIntSerializer)

This aligns with how other serialized enums work in the codebase (e.g., NotificationType).

/**
* Enumerated values to represent the possible reasons for a log out push notification
*/
@Serializable(with = PushNotificationLogOutReasonSerializer::class)
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 Perfect addition of proper kotlinx.serialization support! The @Serializable annotation with PushNotificationLogOutReasonSerializer follows the established pattern used throughout the codebase (see NotificationType.kt:11 for reference).

Using BaseEnumeratedIntSerializer ensures this enum is serialized as an integer value, which is consistent with how the backend sends the data.

KDF_CHANGE,
}

@Keep
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 Good use of @Keep annotation! This prevents R8/ProGuard from removing the serializer during code optimization, which is critical for runtime serialization. This matches the pattern in NotificationType.kt:65.

val date: ZonedDateTime?,

@JsonNames("PushNotificationLogOutReason", "pushNotificationLogOutReason")
@JsonNames("Reason", "reason")
Copy link
Contributor

Choose a reason for hiding this comment

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

👍 Good field rename from "PushNotificationLogOutReason" to "Reason" - this aligns with backend expectations and is more concise.

📝 The @JsonNames annotation correctly provides both "Reason" and "reason" for case-insensitive matching, following the same pattern as other fields in this class (lines 29, 42, 53, 57).

@codecov
Copy link

codecov bot commented Nov 3, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 84.90%. Comparing base (845a5de) to head (f5e1988).
⚠️ Report is 4 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6116   +/-   ##
=======================================
  Coverage   84.90%   84.90%           
=======================================
  Files         723      724    +1     
  Lines       52753    52768   +15     
  Branches     7659     7665    +6     
=======================================
+ Hits        44789    44802   +13     
  Misses       5277     5277           
- Partials     2687     2689    +2     

☔ 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.

@andrebispo5 andrebispo5 added this pull request to the merge queue Nov 3, 2025
Merged via the queue into main with commit 0959284 Nov 3, 2025
18 of 24 checks passed
@andrebispo5 andrebispo5 deleted the pm-26736/logout-push-bug branch November 3, 2025 21:03
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