aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/SmsXmlTest.kt
blob: 9945ec13d1942dea37684421a1646e0c48932083 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
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))
    }
}