Skip to content

Commit 8441c78

Browse files
shubham1g5claude
andcommitted
[AI] test(ccct-3829): expand null/malformed date coverage in OpportunitiesParserTest
Add cases for null and malformed top-level start_date and end_date, plus claim end_date and date_claimed. Each test places a valid record before the invalid one and verifies only the valid record is passed to storeJobs. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 1ac650d commit 8441c78

1 file changed

Lines changed: 112 additions & 0 deletions

File tree

app/unit-tests/src/org/commcare/connect/network/connect/parser/ConnectOpportunitiesParserTest.kt

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,11 @@ class ConnectOpportunitiesParserTest {
8787
put("learn_modules", JSONArray())
8888
}
8989

90+
private fun claimedJobJson(
91+
id: Int,
92+
claim: JSONObject,
93+
): JSONObject = validJobJson(id).apply { put("claim", claim) }
94+
9095
private fun jsonArrayOf(vararg objects: JSONObject): ByteArrayInputStream {
9196
val array = JSONArray().apply { objects.forEach { put(it) } }
9297
return ByteArrayInputStream(array.toString().toByteArray())
@@ -225,4 +230,111 @@ class ConnectOpportunitiesParserTest {
225230
}
226231
verify(exactly = 1) { ConnectJobUtils.storeJobs(any(), match { it.size == 1 && it[0].jobId == 1 }, true) }
227232
}
233+
234+
@Test
235+
fun `parse stores valid job and skips job with malformed end_date`() {
236+
val malformedJob = validJobJson(10).apply { put("end_date", "not-a-date") }
237+
val inputStream = jsonArrayOf(validJobJson(1), malformedJob)
238+
every { ConnectJobUtils.storeJobs(any(), any(), any()) } returns 1
239+
every { ConnectReleaseTogglesWorker.scheduleOneTimeFetch(any()) } just Runs
240+
241+
assertThrows(JSONException::class.java) {
242+
parser.parse(200, inputStream, null)
243+
}
244+
verify(exactly = 1) { ConnectJobUtils.storeJobs(any(), match { it.size == 1 && it[0].jobId == 1 }, true) }
245+
}
246+
247+
@Test
248+
fun `parse stores valid job and skips job with null start_date`() {
249+
val nullStartJob = validJobJson(10).apply { put("start_date", JSONObject.NULL) }
250+
val inputStream = jsonArrayOf(validJobJson(1), nullStartJob)
251+
every { ConnectJobUtils.storeJobs(any(), any(), any()) } returns 1
252+
every { ConnectReleaseTogglesWorker.scheduleOneTimeFetch(any()) } just Runs
253+
254+
assertThrows(JSONException::class.java) {
255+
parser.parse(200, inputStream, null)
256+
}
257+
verify(exactly = 1) { ConnectJobUtils.storeJobs(any(), match { it.size == 1 && it[0].jobId == 1 }, true) }
258+
}
259+
260+
@Test
261+
fun `parse stores valid job and skips job with malformed start_date`() {
262+
val malformedJob = validJobJson(10).apply { put("start_date", "not-a-date") }
263+
val inputStream = jsonArrayOf(validJobJson(1), malformedJob)
264+
every { ConnectJobUtils.storeJobs(any(), any(), any()) } returns 1
265+
every { ConnectReleaseTogglesWorker.scheduleOneTimeFetch(any()) } just Runs
266+
267+
assertThrows(JSONException::class.java) {
268+
parser.parse(200, inputStream, null)
269+
}
270+
verify(exactly = 1) { ConnectJobUtils.storeJobs(any(), match { it.size == 1 && it[0].jobId == 1 }, true) }
271+
}
272+
273+
@Test
274+
fun `parse stores valid job and skips claimed job with null claim end_date`() {
275+
val claim =
276+
JSONObject().apply {
277+
put("end_date", JSONObject.NULL)
278+
put("date_claimed", "2025-01-15")
279+
}
280+
val inputStream = jsonArrayOf(validJobJson(1), claimedJobJson(10, claim))
281+
every { ConnectJobUtils.storeJobs(any(), any(), any()) } returns 1
282+
every { ConnectReleaseTogglesWorker.scheduleOneTimeFetch(any()) } just Runs
283+
284+
assertThrows(JSONException::class.java) {
285+
parser.parse(200, inputStream, null)
286+
}
287+
verify(exactly = 1) { ConnectJobUtils.storeJobs(any(), match { it.size == 1 && it[0].jobId == 1 }, true) }
288+
}
289+
290+
@Test
291+
fun `parse stores valid job and skips claimed job with malformed claim end_date`() {
292+
val claim =
293+
JSONObject().apply {
294+
put("end_date", "not-a-date")
295+
put("date_claimed", "2025-01-15")
296+
}
297+
val inputStream = jsonArrayOf(validJobJson(1), claimedJobJson(10, claim))
298+
every { ConnectJobUtils.storeJobs(any(), any(), any()) } returns 1
299+
every { ConnectReleaseTogglesWorker.scheduleOneTimeFetch(any()) } just Runs
300+
301+
assertThrows(JSONException::class.java) {
302+
parser.parse(200, inputStream, null)
303+
}
304+
verify(exactly = 1) { ConnectJobUtils.storeJobs(any(), match { it.size == 1 && it[0].jobId == 1 }, true) }
305+
}
306+
307+
@Test
308+
fun `parse stores valid job and skips claimed job with null date_claimed`() {
309+
val claim =
310+
JSONObject().apply {
311+
put("end_date", "2025-12-31")
312+
put("date_claimed", JSONObject.NULL)
313+
}
314+
val inputStream = jsonArrayOf(validJobJson(1), claimedJobJson(10, claim))
315+
every { ConnectJobUtils.storeJobs(any(), any(), any()) } returns 1
316+
every { ConnectReleaseTogglesWorker.scheduleOneTimeFetch(any()) } just Runs
317+
318+
assertThrows(JSONException::class.java) {
319+
parser.parse(200, inputStream, null)
320+
}
321+
verify(exactly = 1) { ConnectJobUtils.storeJobs(any(), match { it.size == 1 && it[0].jobId == 1 }, true) }
322+
}
323+
324+
@Test
325+
fun `parse stores valid job and skips claimed job with malformed date_claimed`() {
326+
val claim =
327+
JSONObject().apply {
328+
put("end_date", "2025-12-31")
329+
put("date_claimed", "not-a-date")
330+
}
331+
val inputStream = jsonArrayOf(validJobJson(1), claimedJobJson(10, claim))
332+
every { ConnectJobUtils.storeJobs(any(), any(), any()) } returns 1
333+
every { ConnectReleaseTogglesWorker.scheduleOneTimeFetch(any()) } just Runs
334+
335+
assertThrows(JSONException::class.java) {
336+
parser.parse(200, inputStream, null)
337+
}
338+
verify(exactly = 1) { ConnectJobUtils.storeJobs(any(), match { it.size == 1 && it[0].jobId == 1 }, true) }
339+
}
228340
}

0 commit comments

Comments
 (0)