package org.meshbay.client import org.json.JSONObject import org.junit.Assert.assertEquals import org.junit.Assert.assertFalse import org.junit.Assert.assertNull import org.junit.Assert.assertTrue import org.junit.Rule import org.junit.Test import org.junit.rules.TemporaryFolder import org.meshbay.client.phonesync.ManifestLog import java.io.File import java.util.TimeZone class ManifestLogTest { @get:Rule val tmp = TemporaryFolder() private fun line(n: Int) = JSONObject().put("node", "d/$n.jpg").put("source", "DCIM/Camera/$n.jpg") private fun nodes(f: File) = f.readLines().filter { it.isNotBlank() }.map { JSONObject(it).getString("node") } @Test fun `nothing waiting means nothing to send`() { val log = ManifestLog(File(tmp.root, "m")) assertFalse(log.waiting()) assertNull(log.issue()) } @Test fun `what was sent is described once the node has the manifest, and only then forgotten`() { val log = ManifestLog(File(tmp.root, "m")) log.append(line(1)); log.append(line(2)) assertTrue(log.waiting()) assertEquals(listOf("d/1.jpg", "d/2.jpg"), nodes(log.issue()!!)) log.confirm() assertFalse(log.waiting()) assertNull(log.issue()) } @Test fun `a manifest that did not arrive goes again, with what came since`() { val log = ManifestLog(File(tmp.root, "m")) log.append(line(1)) log.issue() // sent, never confirmed: the run was cut short log.append(line(2)) val again = ManifestLog(File(tmp.root, "m")) // a restart in between assertTrue(again.waiting()) assertEquals(listOf("d/1.jpg", "d/2.jpg"), nodes(again.issue()!!)) } @Test fun `manifests are named for when they were written`() { assertEquals("manifest-2026-10-09-120000.jsonl", ManifestLog.nameFor(1791547200000L, TimeZone.getTimeZone("UTC"))) } }