1package com.peachpasswords.ui.vault23import com.peachpasswords.vault.VaultEntry4import com.peachpasswords.vault.VaultSettings5import org.junit.Assert.assertEquals6import org.junit.Assert.assertTrue7import org.junit.Test8import java.time.LocalDate910class ExportRoundTripTest {1112 13 14 private fun entry() = VaultEntry(15 id = "11111111-2222-3333-4444-555555555555", title = "GitHub", type = "login",16 username = "june", password = "hunter2", url = "https://github.com",17 notes = "my note", totp = "JBSWY3DPEHPK3PXP", createdAt = 0, modifiedAt = 0,18 )1920 @Test fun csv_formula_injection_is_guarded() {21 assertEquals("'=1+1", CsvExport.encodeField("=1+1"))22 assertEquals("'@cmd", CsvExport.encodeField("@cmd"))23 assertEquals("'-2", CsvExport.encodeField("-2"))24 }2526 @Test fun csv_quotes_fields_with_commas_and_quotes() {27 assertEquals("\"a,b\"", CsvExport.encodeField("a,b"))28 assertEquals("\"he\"\"llo\"", CsvExport.encodeField("he\"llo"))29 assertEquals("plain", CsvExport.encodeField("plain"))30 }3132 @Test fun csv_has_header_and_row() {33 val csv = CsvExport.toCsv(listOf(entry()))34 val lines = csv.trim().split("\r\n")35 assertEquals("title,username,password,url,notes", lines[0])36 assertTrue(lines[1].startsWith("GitHub,june,hunter2,"))37 }3839 @Test fun peachscript_export_is_peachscript_text() {40 val out = PeachScriptExport.buildEncrypted(listOf(entry()), "backup-pass-12")41 assertTrue(PeachScriptImport.looksLikePeachScript(out))42 assertTrue(PeachScriptImport.isEncrypted(out))43 }4445 @Test fun peachscript_encrypted_round_trips_with_correct_password() {46 val blob = PeachScriptExport.buildEncrypted(listOf(entry()), "backup-pass-12")47 assertTrue(PeachScriptImport.isEncrypted(blob))48 val ok = PeachScriptImport.decryptAndParse(blob, "backup-pass-12")49 assertTrue(ok is PeachScriptImport.DecryptResult.Success)50 ok as PeachScriptImport.DecryptResult.Success51 assertEquals(1, ok.entries.size)52 assertEquals("hunter2", ok.entries[0].password)53 assertEquals("june", ok.entries[0].username)54 assertEquals("my note", ok.entries[0].notes)55 assertEquals("JBSWY3DPEHPK3PXP", ok.entries[0].totp)56 }5758 @Test fun peachscript_encrypted_rejects_wrong_password() {59 val blob = PeachScriptExport.buildEncrypted(listOf(entry()), "backup-pass-12")60 val r = PeachScriptImport.decryptAndParse(blob, "wrong-password")61 assertTrue(r is PeachScriptImport.DecryptResult.WrongPassword)62 }6364 @Test fun peachscript_round_trips_settings_and_license_metadata() {65 val settings = VaultSettings(accentColor = "sage", reduceMotion = true)66 val blob = PeachScriptExport.buildEncrypted(67 entries = listOf(entry()),68 backupPassword = "backup-pass-12",69 settings = settings,70 licenseKey = "PPK-test-license",71 licenseActivatedAt = 1_782_000_000_000L,72 )7374 val ok = PeachScriptImport.decryptAndParse(blob, "backup-pass-12")7576 assertTrue(ok is PeachScriptImport.DecryptResult.Success)77 ok as PeachScriptImport.DecryptResult.Success78 assertEquals("sage", ok.settings.accentColor)79 assertTrue(ok.settings.reduceMotion)80 assertEquals("PPK-test-license", ok.licenseKey)81 assertEquals(1_782_000_000_000L, ok.licenseActivatedAt)82 }8384 @Test fun export_file_names_match_browser_date_format() {85 val date = LocalDate.of(2026, 6, 26)86 assertEquals("peach-backup-2026-06-26.peach", exportFileName("peach-backup", "peach", date))87 assertEquals("peach-export-2026-06-26.csv", exportFileName("peach-export", "csv", date))88 }89}