Skip to content

[Test Improver] Add unit tests for connectId response parsers (LinkHqWorker and RetrieveChannelEncryptionKey)#3626

Open
github-actions[bot] wants to merge 6 commits into
masterfrom
test-assist/connectid-response-parsers-20260318-bc79730ac1f7b737
Open

[Test Improver] Add unit tests for connectId response parsers (LinkHqWorker and RetrieveChannelEncryptionKey)#3626
github-actions[bot] wants to merge 6 commits into
masterfrom
test-assist/connectid-response-parsers-20260318-bc79730ac1f7b737

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

🤖 Test Improver — automated AI assistant

Goal and Rationale

LinkHqWorkerResponseParser and RetrieveChannelEncryptionKeyResponseParser are connectId network parsers with zero test coverage. Both handle mutations to persistent model objects and trigger database writes — silent bugs here would cause worker linking state or channel encryption keys to be incorrectly stored.

Why it matters: Incorrect worker-linked state would break job eligibility logic; a wrong or unset channel encryption key would prevent secure messaging.

Approach

Two new test classes in app/unit-tests/src/org/commcare/connect/network/connectId/parser/:

LinkHqWorkerResponseParserTest

Test What it verifies
testParse_setsWorkerLinkedTrue_andReturnsTrue parse() sets appRecord.workerLinked = true and returns true
testParse_workerLinkedFalseBeforeParse_trueAfter Confirms flag starts false, becomes true after parse (no toggle, only set)
testParse_callsStoreApp_once ConnectAppDatabaseUtil.storeApp(context, appRecord) is called exactly once

RetrieveChannelEncryptionKeyResponseParserTest

Test What it verifies
testParse_validJson_setsKeyOnChannel_andReturnsTrue {"key": "abc123-encryption-key"}channel.getKey() == "abc123-encryption-key", returns true
testParse_emptyResponse_channelKeyUnchanged_andReturnsTrue Empty body → channel.getKey() remains null, returns true, no exception
testParse_emptyResponse_doesNotCallStoreMessagingChannel Empty body → storeMessagingChannel is never called (guard path verified)
testParse_callsStoreMessagingChannel_once Non-empty body → ConnectMessagingDatabaseHelper.storeMessagingChannel(context, channel) called once
testParse_invalidJson_throwsRuntimeException Malformed JSON → RuntimeException (wrapping JSONException)
testParse_missingKeyField_throwsRuntimeException JSON without key field → RuntimeException (wrapping JSONException)

Static database methods are isolated using mockStatic (Mockito 5.5.0 — already a test dependency). Tests follow the @Config(application = CommCareTestApplication::class) / @RunWith(AndroidJUnit4::class) pattern used across the suite.

Coverage Impact

Both LinkHqWorkerResponseParser.kt and RetrieveChannelEncryptionKeyResponseParser.kt previously had 0% coverage. This PR covers all branches of parse() in both classes:

  • LinkHqWorkerResponseParser.parse(): single path (no branching)
  • RetrieveChannelEncryptionKeyResponseParser.parse(): the isNotEmpty() guard, the happy path, and the JSONException catch

Trade-offs

  • storeApp and storeMessagingChannel are static void methods — mocked with mockStatic to prevent database access in unit tests. This is the same pattern used in ReportIntegrityResponseParserTest.
  • LinkHqWorkerResponseParser ignores responseCode and responseData entirely; tests pass an empty ByteArrayInputStream for correctness without additional noise.

Test Status

Build not runnable locally (requires ../commcare-core/ sibling directory, checked out only in CI). ktlintFile Gradle task unavailable in this environment due to a Gradle wrapper lock file issue (infrastructure constraint). Files follow the style of existing tests in the same package.

To run:

./gradlew testCommcareDebug --tests "org.commcare.connect.network.connectId.parser.LinkHqWorkerResponseParserTest"
./gradlew testCommcareDebug --tests "org.commcare.connect.network.connectId.parser.RetrieveChannelEncryptionKeyResponseParserTest"

Generated by Daily Test Improver ·

To install this agentic workflow, run

gh aw add githubnext/agentics/workflows/daily-test-improver.md@346204513ecfa08b81566450d7d599556807389f

…yptionKeyResponseParser

Tests cover:
- LinkHqWorkerResponseParser: workerLinked flag mutation, return value, storeApp call
- RetrieveChannelEncryptionKeyResponseParser: key parsing, empty response guard,
  storeMessagingChannel call, invalid JSON and missing key error paths

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

@conroy-ricketts conroy-ricketts left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No-go

@Test
fun testParse_setsWorkerLinkedTrue_andReturnsTrue() {
// Arrange
val appRecord = ConnectLinkedAppRecord()

@Jignesh-dimagi Jignesh-dimagi Mar 24, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

/test-assist Create a class level member declaration something like
private lateinit var appRecord: ConnectLinkedAppRecord, intialize it in setUp() and use it in each test.


@Before
fun setUp() {
val context = ApplicationProvider.getApplicationContext<android.content.Context>()

@Jignesh-dimagi Jignesh-dimagi Mar 24, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

/test-assist Create a class-level member declaration something like
private lateinit var context: android.content.Context, initialise in setUp() and use it in each test.


@Before
fun setUp() {
val context = ApplicationProvider.getApplicationContext<android.content.Context>()

@Jignesh-dimagi Jignesh-dimagi Mar 24, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

/test-assist Simply initialise it by context = ApplicationProvider.getApplicationContext()

Comment on lines +91 to +92
val context = ApplicationProvider.getApplicationContext<android.content.Context>()
val channel = ConnectMessagingChannelRecord()

@Jignesh-dimagi Jignesh-dimagi Mar 24, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

/test-assist Create a class-level member declaration of context and channel variable, initialise in setUp() and use it in each test.


@Config(application = CommCareTestApplication::class)
@RunWith(AndroidJUnit4::class)
class LinkHqWorkerResponseParserTest {

@Jignesh-dimagi Jignesh-dimagi Mar 24, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

/test-assist Pass null to anyInputObject and add another test with @Test(expected = NullPointerException::class)


@Config(application = CommCareTestApplication::class)
@RunWith(AndroidJUnit4::class)
class RetrieveChannelEncryptionKeyResponseParserTest {

@Jignesh-dimagi Jignesh-dimagi Mar 24, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

/test-assist Pass null to anyInputObject and add another test with @Test(expected = NullPointerException::class)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

/test-assist Pass null to anyInputObject and add another test with @test(expected = NullPointerException::class)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

github-actions Bot commented Apr 1, 2026

Copy link
Copy Markdown
Contributor Author

Commit pushed: 05a5c5c

Generated by Daily Test Improver

…onnectId parser tests

- Promote context and appRecord/channel to class-level members initialized
  in setUp() to avoid repetition across tests
- Import Context directly instead of using fully qualified name
- Replace assertTrue(!x) with assertFalse(x) for clarity

🤖 PR Comment Handler
@github-actions

github-actions Bot commented Apr 4, 2026

Copy link
Copy Markdown
Contributor Author

Commit pushed: 9b0f322

Generated by PR Comment Handler

@github-actions

github-actions Bot commented Apr 4, 2026

Copy link
Copy Markdown
Contributor Author

🤖 PR Comment Handler here — I've processed the latest review feedback.

Implemented:

app/unit-tests/src/org/commcare/connect/network/connectId/parser/LinkHqWorkerResponseParserTest.kt:

  • Added class-level private lateinit var context: Context and private lateinit var appRecord: ConnectLinkedAppRecord, initialized in setUp() (addresses @Jignesh-dimagi's comments)
  • Replaced assertTrue(!appRecord.getWorkerLinked()) with assertFalse(appRecord.getWorkerLinked()) (addresses @conroy-ricketts's comment)
  • Added import android.content.Context and import org.junit.Assert.assertFalse
  • Removed redundant local context and appRecord declarations from individual tests

app/unit-tests/src/org/commcare/connect/network/connectId/parser/RetrieveChannelEncryptionKeyResponseParserTest.kt:

  • Added class-level private lateinit var context: Context and private lateinit var channel: ConnectMessagingChannelRecord, initialized in setUp() (addresses @Jignesh-dimagi's comment)
  • Changed ApplicationProvider.getApplicationContext(android.content.Context)() to use imported Context type (addresses @conroy-ricketts's suggestion)
  • Removed redundant local context and channel declarations from individual tests

Already present (no change needed):

  • testParse_nullInputObject_throwsNullPointerException exists in both test classes (addresses @Jignesh-dimagi's null input comments)

Please re-review the latest commit. Happy to make further adjustments.

Generated by PR Comment Handler ·

@github-actions github-actions Bot mentioned this pull request Apr 4, 2026
@github-actions

github-actions Bot commented Apr 6, 2026

Copy link
Copy Markdown
Contributor Author

🤖 PR Comment Handler here — I've reviewed the feedback and confirmed it has been addressed in prior commits.

Previously addressed (no further action needed):

From @conroy-ricketts:

  • assertFalse assertion in LinkHqWorkerResponseParserTest
  • Use Context type with import in RetrieveChannelEncryptionKeyResponseParserTest

From @Jignesh-dimagi:

  • Class-level appRecord member initialised in setUp() in LinkHqWorkerResponseParserTest
  • Class-level context member initialised via ApplicationProvider.getApplicationContext() in setUp()
  • Class-level context and channel members in RetrieveChannelEncryptionKeyResponseParserTest
  • @Test(expected = NullPointerException::class) test for null anyInputObject added in LinkHqWorkerResponseParserTest
  • @Test(expected = NullPointerException::class) test for null anyInputObject added in RetrieveChannelEncryptionKeyResponseParserTest

All 8 review threads appear to have been addressed. Please re-review and resolve the conversation threads when you get a chance.

Generated by PR Comment Handler ·

@Jignesh-dimagi Jignesh-dimagi marked this pull request as ready for review May 14, 2026 11:01
@codecov

codecov Bot commented May 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 23.36%. Comparing base (eb409cf) to head (4fb6523).
⚠️ Report is 5 commits behind head on master.

Additional details and impacted files
@@             Coverage Diff              @@
##             master    #3626      +/-   ##
============================================
+ Coverage     23.31%   23.36%   +0.04%     
- Complexity     3929     3938       +9     
============================================
  Files           924      924              
  Lines         56190    56194       +4     
  Branches       6654     6654              
============================================
+ Hits          13098    13127      +29     
+ Misses        41394    41369      -25     
  Partials       1698     1698              

☔ 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.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@conroy-ricketts conroy-ricketts left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

All new unit tests written in Kotlin should utilize backticks to write test names as natural-language sentences.

@github-actions

Copy link
Copy Markdown
Contributor Author

Commit pushed: b81d6ba

Generated by PR Comment Handler

@github-actions

Copy link
Copy Markdown
Contributor Author

🤖 PR Comment Handler

Implemented:

  • app/unit-tests/src/org/commcare/connect/network/connectId/parser/LinkHqWorkerResponseParserTest.kt: Converted all 4 @Test function names to backtick-quoted natural-language sentences (addresses @conroy-ricketts's 2026-05-18 request).
  • app/unit-tests/src/org/commcare/connect/network/connectId/parser/RetrieveChannelEncryptionKeyResponseParserTest.kt: Converted all 7 @Test function names to backtick-quoted natural-language sentences.

Verified the two files have no new ktlint violations vs. master (a handful of pre-existing auto-fixable violations in unrelated lines were left in place — out of scope for this feedback).

Please re-review.

Generated by PR Comment Handler ·

…-assist/connectid-response-parsers-20260318-bc79730ac1f7b737
@github-actions

github-actions Bot commented Jun 6, 2026

Copy link
Copy Markdown
Contributor Author

🤖 PR Comment Handler

I checked the open review threads against the current head (4fb6523). All outstanding feedback already appears implemented in the latest revision, so I made no code changes and pushed nothing.

Already addressed (these threads can likely be resolved):

  • @Jignesh-dimagi — class-level appRecord member initialised in setUp(): LinkHqWorkerResponseParserTest.kt lines 27 & 32.
  • @Jignesh-dimagi — class-level context member initialised via ApplicationProvider.getApplicationContext() in setUp(): LinkHqWorkerResponseParserTest.kt lines 26 & 31.
  • @Jignesh-dimagi — class-level context and channel members initialised in setUp(): RetrieveChannelEncryptionKeyResponseParserTest.kt lines 28–29 & 33–34.
  • @Jignesh-dimagi — pass null for the input object and add @Test(expected = NullPointerException::class): LinkHqWorkerResponseParserTest.kt lines 83–90 and RetrieveChannelEncryptionKeyResponseParserTest.kt lines 124–132.
  • @conroy-ricketts — Kotlin test names written as backtick-quoted natural-language sentences: applied throughout both files.

Merge status: No conflicts; the branch is up to date with master.

If any of the above doesn't match what you intended, leave a follow-up comment and I'll pick it up on the next run.

Generated by PR Comment Handler ·

@github-actions

github-actions Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor Author

🤖 PR Comment Handler

I reviewed the open (unresolved) review threads against the current head commit. Each requested change is already present in the code, so no new commits were pushed.

Already addressed (open threads):

  • @Jignesh-dimagi — "class-level appRecord member, initialise in setUp()": done in LinkHqWorkerResponseParserTest.kt (private lateinit var appRecord declared at line 27, initialised in setUp() at line 32).
  • @Jignesh-dimagi — "class-level context member, initialise in setUp()": done in LinkHqWorkerResponseParserTest.kt (line 26, initialised line 31).
  • @Jignesh-dimagi — "initialise via context = ApplicationProvider.getApplicationContext()": done in LinkHqWorkerResponseParserTest.kt line 31.
  • @Jignesh-dimagi — "class-level context and channel, initialise in setUp()": done in RetrieveChannelEncryptionKeyResponseParserTest.kt (lines 28-29, initialised lines 33-34).
  • @Jignesh-dimagi — "pass null to the input object and add a @Test(expected = NullPointerException::class) test": done in LinkHqWorkerResponseParserTest.kt (lines 83-90) and RetrieveChannelEncryptionKeyResponseParserTest.kt (lines 124-132).

No action taken:

  • No code changes were needed — the above are all implemented in the current head commit.
  • No merge conflicts: the branch merges cleanly into master (only the two new test files differ).

If these resolve the feedback, the open threads can be marked resolved.

Generated by PR Comment Handler ·

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants