aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-android/app/src/test
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-10-10 14:40:05 +0200
committerChristophe Besson <cbesson@gmail.com>2026-10-10 14:40:05 +0200
commitaed32f20625a6206628b577d743d96552f81e91a (patch)
treeaf2eaf3336804f2e4af37445326e52a19b2af169 /packages/meshbay-android/app/src/test
parent2f2a9a6542d2194e50ffba6f382e4fdffd481838 (diff)
downloadmeshbay-aed32f20625a6206628b577d743d96552f81e91a.tar.gz
feat(android): back text messages up, in a build Play does not get
A Messages section sends the SMS added since the last copy, as restorable <smses> XML, into <folder>/<account>-messages/YYYY. A play flavor has neither READ_SMS nor the code that reads messages; full is the default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'packages/meshbay-android/app/src/test')
-rw-r--r--packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/SmsXmlTest.kt66
1 files changed, 66 insertions, 0 deletions
diff --git a/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/SmsXmlTest.kt b/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/SmsXmlTest.kt
new file mode 100644
index 0000000..9945ec1
--- /dev/null
+++ b/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/SmsXmlTest.kt
@@ -0,0 +1,66 @@
+package org.meshbay.client
+
+import org.junit.Assert.assertEquals
+import org.junit.Assert.assertFalse
+import org.junit.Assert.assertTrue
+import org.junit.Test
+import org.meshbay.client.phonesync.DocPlan
+import org.meshbay.client.phonesync.Sms
+import org.meshbay.client.phonesync.SmsXml
+import org.w3c.dom.Element
+import java.io.StringWriter
+import java.util.TimeZone
+import javax.xml.parsers.DocumentBuilderFactory
+
+class SmsXmlTest {
+ private val utc = TimeZone.getTimeZone("UTC")
+ // 2026-10-09 12:00:00 UTC
+ private val oct9 = 1791547200000L
+
+ private fun sms(id: Long, body: String, address: String = "+33600000000", name: String? = null) =
+ Sms(id, address, oct9, oct9 - 5000, 1, body, 1, -1, 0, 0, null, null, name)
+
+ private fun parse(xml: String): List<Element> {
+ val doc = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xml.byteInputStream())
+ assertEquals("smses", doc.documentElement.tagName)
+ val list = doc.getElementsByTagName("sms")
+ return (0 until list.length).map { list.item(it) as Element }
+ }
+
+ private fun write(vararg m: Sms) = StringWriter().also { SmsXml.write(m.toList(), it, utc) }.toString()
+
+ @Test fun `what a restore reads is there, with the count`() {
+ val xml = write(sms(1, "hello"), sms(2, "again", name = "Ada"))
+ assertTrue(xml.contains("<smses count=\"2\">"))
+ val rows = parse(xml)
+ assertEquals("hello", rows[0].getAttribute("body"))
+ assertEquals("+33600000000", rows[0].getAttribute("address"))
+ assertEquals(oct9.toString(), rows[0].getAttribute("date"))
+ assertEquals("1", rows[0].getAttribute("type"))
+ assertEquals("(Unknown)", rows[0].getAttribute("contact_name"))
+ assertEquals("Ada", rows[1].getAttribute("contact_name"))
+ assertEquals("9 Oct 2026 12:00:00", rows[0].getAttribute("readable_date"))
+ assertEquals("null", rows[0].getAttribute("subject"))
+ }
+
+ @Test fun `markup, quotes, line breaks and emoji come back as they were`() {
+ val body = "a < b & \"c\" > 'd'\nsecond line\r\n\ttab 🎉 é"
+ assertEquals(body, parse(write(sms(1, body)))[0].getAttribute("body"))
+ }
+
+ @Test fun `characters XML cannot carry are left out rather than breaking the file`() {
+ val rows = parse(write(sms(1, "a\u0000b\u0007c￿d")))
+ assertEquals("abcd", rows[0].getAttribute("body"))
+ }
+
+ @Test fun `an empty body or address is still a well-formed row`() {
+ val rows = parse(write(sms(1, "", address = "")))
+ assertEquals("", rows[0].getAttribute("body"))
+ assertFalse(rows[0].hasAttribute("missing"))
+ }
+
+ @Test fun `a file goes under the year it was written in`() {
+ assertEquals("2026", DocPlan.yearOf(oct9, utc))
+ assertEquals("sms-2026-10-09-1200.xml", DocPlan.nameFor("sms", "xml", oct9, utc))
+ }
+}