aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/DocSyncTest.kt
blob: f53110b233637694f94b9d2725ffe313f8728700 (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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
package org.meshbay.client

import org.json.JSONObject
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals
import org.junit.Assert.assertNull
import org.junit.Assert.assertThrows
import org.junit.Test
import org.meshbay.client.phonesync.Destination
import org.meshbay.client.phonesync.DestinationChannels
import org.meshbay.client.phonesync.DocPlan
import org.json.JSONArray
import org.meshbay.client.bridge.Refused
import java.util.TimeZone

class DocSyncTest {
    private val utc = TimeZone.getTimeZone("UTC")
    // 2026-10-09 12:00:00 UTC
    private val oct9 = 1791547200000L

    private fun settings(account: String = "bob", folder: String = "Backups") = JSONObject()
        .put("account", account).put("groupId", "g1").put("groupName", "Mine").put("folder", folder)

    @Test fun `each kind goes into a folder of its own named for the account`() {
        val c = Destination.fromJson(settings(folder = "/Backups/Phone/"))
        assertEquals("Backups/Phone/bob-contacts", DocPlan.dirFor(c, "contacts"))
        assertEquals("Backups/Phone/bob-messages", DocPlan.dirFor(c, "messages"))
    }

    @Test fun `a file is named for when it was taken, in the phone's time`() {
        assertEquals("contacts-2026-10-09-1200.vcf", DocPlan.nameFor("contacts", "vcf", oct9, utc))
        assertEquals("contacts-2026-10-09-1400.vcf",
                     DocPlan.nameFor("contacts", "vcf", oct9, TimeZone.getTimeZone("Europe/Paris")))
    }

    @Test fun `a folder that climbs out or an account that is not a name is refused`() {
        for (bad in listOf("../etc", "Backups/../x", "Backups//x", "./x", "")) {
            assertThrows(bad, IllegalArgumentException::class.java) { Destination.fromJson(settings(folder = bad)) }
        }
        for (bad in listOf("../bob", "bob/x", "", "-bob")) {
            assertThrows(bad, IllegalArgumentException::class.java) { Destination.fromJson(settings(account = bad)) }
        }
    }

    @Test fun `settings survive being stored`() {
        val c = Destination.fromJson(settings())
        assertEquals(c, Destination.parse(c.toJson().toString()))
        assertNull(Destination.parse("{not json"))
    }

    @Test fun `another group or folder is another backup`() {
        val a = Destination.fromJson(settings())
        assertNotEquals(a.ledgerKey, Destination.fromJson(settings(folder = "Other")).ledgerKey)
        assertNotEquals(a.ledgerKey, Destination.fromJson(settings().put("groupId", "g2")).ledgerKey)
        assertEquals(a.ledgerKey, Destination.fromJson(settings().put("groupName", "Renamed")).ledgerKey)
    }

    @Test fun `every kind is told when the destination moves, and only then`() {
        val store = DestinationChannels(FakePrefs())
        var told = 0
        store.onChange { told++ }
        store.call("phonesync:set-destination", JSONArray().put(settings()))
        assertEquals(1, told)
        store.call("phonesync:set-destination", JSONArray().put(settings().put("groupName", "Renamed")))
        assertEquals("a new name for the same place is not a new backup", 1, told)
        store.call("phonesync:set-destination", JSONArray().put(settings(folder = "Other")))
        assertEquals(2, told)
        store.call("phonesync:set-destination", JSONArray())
        assertEquals(3, told)
        assertNull(store.get())
    }

    @Test fun `a destination the page got wrong is refused and the old one kept`() {
        val store = DestinationChannels(FakePrefs())
        store.call("phonesync:set-destination", JSONArray().put(settings()))
        assertThrows(Refused::class.java) {
            store.call("phonesync:set-destination", JSONArray().put(settings(folder = "../x")))
        }
        assertEquals("Backups", store.get()!!.folder)
    }
}