aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-android/app/src/test/kotlin/org/meshbay/client/DriveTest.kt
blob: e661bd1c582c79fd713d6c36ca2a8910a6056b39 (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
82
83
84
85
86
87
88
89
90
package org.meshbay.client

import org.junit.Assert.assertEquals
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.drive.DriveFile
import org.meshbay.client.drive.DriveLedger
import org.meshbay.client.drive.DrivePlan
import org.meshbay.client.photos.PhotoPlan
import org.meshbay.client.photos.PhotoSource
import java.util.TimeZone

class DriveTest {
    @get:Rule val tmp = TemporaryFolder()

    private val utc = TimeZone.getTimeZone("UTC")
    private val tree = "content://tree/primary%3ADocuments"
    private val names = mapOf(tree to "Documents")

    private fun file(id: String, sub: String = "", size: Long = 10, modified: Long = 1000) =
        DriveFile(tree, "primary:Documents/" + (if (sub.isEmpty()) "" else "$sub/") + id, sub, id, size, modified,
                  "application/pdf")

    private fun plan(files: List<DriveFile>, sent: Map<String, DriveLedger.Entry> = emptyMap(),
                     skip: Set<String> = emptySet(), same: Boolean = false) =
        DrivePlan.plan(files, "Backups/bob-drive", names, { sent[it] }, skip, utc) { _, _ -> same }

    private fun entry(f: DriveFile) = DriveLedger.Entry(f.docId, f.modified, f.size, "h", "d", f.name, 1)

    @Test fun `media folders and a whole volume cannot be chosen`() {
        assertEquals("whole_storage", DrivePlan.refusal("primary:"))
        assertEquals("whole_storage", DrivePlan.refusal("1234-ABCD:"))
        assertEquals("media_folder", DrivePlan.refusal("primary:DCIM"))
        assertEquals("media_folder", DrivePlan.refusal("primary:DCIM/Camera"))
        assertEquals("media_folder", DrivePlan.refusal("primary:Pictures/Screenshots"))
        assertEquals("media_folder", DrivePlan.refusal("1234-ABCD:movies"))
        assertNull(DrivePlan.refusal("primary:Documents"))
        assertNull(DrivePlan.refusal("primary:Download/Invoices"))
        assertNull(DrivePlan.refusal("primary:Documents/Pictures"))
    }

    @Test fun `files go under the chosen folder's name, sub-folders kept`() {
        val out = plan(listOf(file("a.pdf"), file("b.pdf", sub = "Tax/2026")))
        assertEquals(setOf("Backups/bob-drive/Documents", "Backups/bob-drive/Documents/Tax/2026"),
                     out.map { it.dir }.toSet())
    }

    @Test fun `smallest first, hidden files and photo-backed files left out`() {
        val out = plan(listOf(file("big.pdf", size = 900), file("small.pdf", size = 5), file(".secret"),
                              file("scan.jpg", sub = "Scans")),
                       skip = setOf("documents/scans/scan.jpg"))
        assertEquals(listOf("small.pdf", "big.pdf"), out.map { it.name })
    }

    @Test fun `a file already sent is not sent again, a changed one goes beside it`() {
        val f = file("a.pdf")
        assertTrue(plan(listOf(f), sent = mapOf(f.docId to entry(f))).isEmpty())
        val changed = f.copy(size = 20, modified = 86_400_000)
        val out = plan(listOf(changed), sent = mapOf(f.docId to entry(f)))
        assertEquals("a-modified-19700102-000000.pdf", out.single().name)
        assertTrue(out.single().edited)
        val touched = f.copy(modified = 5000)
        assertTrue(plan(listOf(touched), sent = mapOf(f.docId to entry(f)), same = true).isEmpty())
    }

    @Test fun `names the node would refuse are mended, not dropped`() {
        assertEquals("report.pdf", DrivePlan.safeName("report.pdf"))
        assertEquals("a_b_c.txt", DrivePlan.safeName("a:b?c.txt"))
        assertEquals("file-.env", DrivePlan.safeName(".env"))
        assertEquals("file-_draft", DrivePlan.safeName("_draft"))
        assertTrue(PhotoPlan.UPLOAD_NAME.matches(DrivePlan.safeName("x".repeat(300) + ".pdf")))
        assertTrue(PhotoPlan.UPLOAD_NAME.matches(DrivePlan.safeName("end. ")))
    }

    @Test fun `the ledger remembers across a restart`() {
        val path = tmp.newFile("d.jsonl")
        DriveLedger(path).apply { record(entry(file("a.pdf"))); record(entry(file("a.pdf")).copy(sha256 = "z")) }
        val again = DriveLedger(path)
        assertEquals(1, again.size)
        assertEquals("z", again["primary:Documents/a.pdf"]!!.sha256)
    }

    @Test fun `a path from before Android 10 is read from the top of its volume`() {
        assertEquals("Documents/Scans/a.jpg", PhotoSource.volumeRelative("/storage/emulated/0/Documents/Scans/a.jpg"))
        assertEquals("x/a.jpg", PhotoSource.volumeRelative("/storage/1234-ABCD/x/a.jpg"))
    }
}