Skip to content

Conversation

@Jignesh-dimagi
Copy link
Contributor

Technical Summary

https://dimagi.atlassian.net/browse/QA-8226

Server is sending 200 response whenever back up is wrong with attempt number, so application cannot expect username, dbkey and password in that response. Handled server response separately for attempt (wrong back up code), error code (locked account) and valid response.

Labels and Review

  • Do we need to enhance the manual QA test coverage ? If yes, the "QA Note" label is set correctly
  • Does the PR introduce any major changes worth communicating ? If yes, the "Release Note" label is set and a "Release Note" is specified in PR description.
  • Risk label is set correctly
  • The set of people pinged as reviewers is appropriate for the level of risk of the change

@coderabbitai
Copy link

coderabbitai bot commented Nov 13, 2025

📝 Walkthrough

Walkthrough

The changes refactor the backup code response parsing logic in ConfirmBackupCodeResponseParser.java to conditionally extract credentials. Previously, username, dbKey, and password were always parsed from the response. Now, credential extraction only occurs when the response indicates success (neither attempts_left nor error_code is present). For successful validation, the parser also sets invited_user. The control flow now prioritizes error conditions (attempts_left, error_code) with an else branch handling successful cases. Corresponding tests have been updated to verify that credentials remain null when error conditions exist and new test cases cover wrong backup code and locked account scenarios.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

  • Simple conditional logic refactoring (moving credential extraction into an else branch)
  • Straightforward test additions covering existing error scenarios
  • Focused changes limited to a single parser and its tests
  • Clear intent with no complex interdependencies

Possibly related PRs

Suggested reviewers

  • OrangeAndGreen
  • conroy-ricketts

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description check ⚠️ Warning The description provides the related ticket link and technical rationale, but lacks critical sections including Product Description, Safety Assurance, and specific QA Plan details required by the template. Add Product Description section explaining user-facing effects, expand Safety Assurance with testing confidence and data impact details, provide specific QA Plan with regression testing approach, and complete the checklist items.
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the primary change: fixing an app crash when entering a wrong backup code, which aligns with the root cause and solution in the changeset.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch jignesh/fix/qa-8226

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 and usage tips.

Copy link

@coderabbitai coderabbitai bot left a 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 (4)
app/src/org/commcare/connect/network/connectId/parser/ConfirmBackupCodeResponseParser.java (3)

24-24: Fix typo in comment.

The comment contains a typo: "responed" should be "responds".

-        if (json.has("attempts_left")) {    // whenever wrong code is entered, server responed with attempts_left
+        if (json.has("attempts_left")) {    // whenever wrong code is entered, server responds with attempts_left

26-26: Fix typo in comment.

Same typo as above: "responed" should be "responds".

-        } else if (json.has("error_code")) {    // whenever account is locked, server responed with error_code
+        } else if (json.has("error_code")) {    // whenever account is locked, server responds with error_code

37-38: Consider simplifying error message wording.

The phrase "amongst" is less commonly used than "among" in modern English. Consider simplifying for better readability.

-                throw new IllegalStateException(
-                        "Any of the fields amongst username, db_key or password cannot be empty");
+                throw new IllegalStateException(
+                        "Fields username, db_key, and password cannot be empty");
app/unit-tests/src/org/commcare/connect/network/connectId/parser/ConfirmBackupCodeResponseParserTest.kt (1)

49-86: Consider adding edge case tests for ambiguous responses.

While the current tests cover the three main branches, consider adding tests for edge cases where multiple indicators are present (e.g., both attempts_left and username). This would document the priority order and ensure it's intentional.

Example test case:

@Test
fun testParsePrioritizesAttemptsLeftWhenMultipleIndicatorsPresent() {
    // Arrange - Response contains both attempts_left and credentials
    val json = JSONObject().apply {
        put("attempts_left", 2)
        put("username", "test-user")
        put("db_key", "test-key")
        put("password", "test-pass")
    }

    // Act
    parser.parse(json, sessionData)

    // Assert - Only attempts_left should be processed
    assertEquals(2, sessionData.attemptsLeft)
    assertEquals(null, sessionData.personalId)
}
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a8694a0 and 7b2c8e1.

📒 Files selected for processing (2)
  • app/src/org/commcare/connect/network/connectId/parser/ConfirmBackupCodeResponseParser.java (2 hunks)
  • app/unit-tests/src/org/commcare/connect/network/connectId/parser/ConfirmBackupCodeResponseParserTest.kt (2 hunks)
🧰 Additional context used
🧠 Learnings (3)
📚 Learning: 2025-01-21T18:20:43.883Z
Learnt from: OrangeAndGreen
Repo: dimagi/commcare-android PR: 2912
File: app/src/org/commcare/fragments/connectId/ConnectIdPasswordVerificationFragment.java:206-213
Timestamp: 2025-01-21T18:20:43.883Z
Learning: In the Connect ID feature, server responses containing user data should be parsed using ConnectUserResponseParser to ensure consistent handling of payment information (owner_name and phone_number) and secondary phone verification across all authentication flows.

Applied to files:

  • app/src/org/commcare/connect/network/connectId/parser/ConfirmBackupCodeResponseParser.java
📚 Learning: 2025-02-04T21:22:56.537Z
Learnt from: pm-dimagi
Repo: dimagi/commcare-android PR: 2949
File: app/src/org/commcare/fragments/connectId/ConnectIdPinFragment.java:244-275
Timestamp: 2025-02-04T21:22:56.537Z
Learning: Direct JSONObject parsing is acceptable for handling user data responses in ConnectIdPinFragment, as decided by the team. No need to enforce ConnectUserResponseParser usage in this context.

Applied to files:

  • app/src/org/commcare/connect/network/connectId/parser/ConfirmBackupCodeResponseParser.java
📚 Learning: 2025-06-13T15:53:12.951Z
Learnt from: OrangeAndGreen
Repo: dimagi/commcare-android PR: 3108
File: app/src/org/commcare/connect/network/PersonalIdApiHandler.java:51-56
Timestamp: 2025-06-13T15:53:12.951Z
Learning: For `PersonalIdApiHandler`, the team’s convention is to propagate `JSONException` as an unchecked `RuntimeException` so the app crashes, signalling a contract/implementation bug rather than attempting a graceful retry.

Applied to files:

  • app/src/org/commcare/connect/network/connectId/parser/ConfirmBackupCodeResponseParser.java
🧬 Code graph analysis (1)
app/src/org/commcare/connect/network/connectId/parser/ConfirmBackupCodeResponseParser.java (1)
app/src/org/commcare/utils/JsonExtensions.kt (1)
  • optStringSafe (7-10)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Lint Code Base
🔇 Additional comments (4)
app/unit-tests/src/org/commcare/connect/network/connectId/parser/ConfirmBackupCodeResponseParserTest.kt (3)

28-47: LGTM!

The test correctly validates the success case, verifying all credentials and the invited_user flag are properly set.


69-86: Test logic is sound, but verify default assumption.

The test correctly validates the locked account scenario. However, similar to the previous test, verify that invitedUser defaults to false (same verification as above).


49-67: Default value assumption is correct.

The invitedUser field in PersonalIdSessionData is initialized with a default value of false, confirming the test's assertion is valid. The test properly verifies that when parsing a wrong backup code response (failure case), invitedUser remains at its default value while only attemptsLeft is populated.

app/src/org/commcare/connect/network/connectId/parser/ConfirmBackupCodeResponseParser.java (1)

24-46: No changes required—server contract is validated by comprehensive tests.

The test file (app/unit-tests/src/org/commcare/connect/network/connectId/parser/ConfirmBackupCodeResponseParserTest.kt) confirms the if-else structure's assumptions. Tests explicitly validate three mutually exclusive response scenarios: attempts_left-only (wrong code), error_code-only (locked account), and credentials-only (success). No test combines multiple indicators, confirming the server contract truly sends them exclusively. The parser's priority order and behavior are correct and well-tested.

sessionData.setOauthPassword(password);

if (json.has("attempts_left")) {
if (json.has("attempts_left")) { // whenever wrong code is entered, server responed with attempts_left
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: typo on responed vs responds

@Jignesh-dimagi Jignesh-dimagi merged commit 2bea6f7 into master Nov 13, 2025
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

skip-integration-tests Skip android tests.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants