ImportParsersTest.kt

5.5 KB · raw

1package com.peachpasswords.ui.vault23import com.peachpasswords.vault.VaultEntry4import org.junit.Assert.assertEquals5import org.junit.Assert.assertFalse6import org.junit.Assert.assertNull7import org.junit.Assert.assertTrue8import org.junit.Test910class ImportParsersTest {1112    @Test fun detect_blank_is_null() {13        assertNull(CsvImport.detectProvider(""))14        assertNull(CsvImport.detectProvider("   \n  "))15    }1617    @Test fun chrome_csv_detects_and_parses() {18        val csv = "name,url,username,password\nGitHub,https://github.com,june,hunter2\n"19        assertEquals(CsvImport.CHROME_CSV, CsvImport.detectProvider(csv))20        val rows = CsvImport.parse(csv, CsvImport.CHROME_CSV)21        assertEquals(1, rows.size)22        assertEquals("GitHub", rows[0].title)23        assertEquals("https://github.com", rows[0].url)24        assertEquals("june", rows[0].username)25        assertEquals("hunter2", rows[0].password)26    }2728    @Test fun csv_quoted_fields_with_commas_are_preserved() {29        val rows = CsvImport.parseCsv("name,url,username,password\n\"Bank, NA\",https://b.com,j,\"p,w\"\n")30        // Header + 1 data row.31        assertEquals(2, rows.size)32        assertEquals(listOf("Bank, NA", "https://b.com", "j", "p,w"), rows[1])33    }3435    @Test fun csv_doubled_quotes_unescape() {36        assertEquals(listOf("a\"b", "c"), CsvImport.splitCsvLine("\"a\"\"b\",c"))37    }3839    @Test fun detect_and_parse_returns_success_for_chrome() {40        val csv = "name,url,username,password\nA,https://a.com,u,p\nB,https://b.com,u2,p2\n"41        val r = CsvImport.detectAndParse(csv)42        assertTrue(r is ImportParseResult.Success)43        r as ImportParseResult.Success44        assertEquals(2, r.entries.size)45    }4647    @Test fun proton_pass_json_detects_and_parses_login_items() {48        val json = """49            {50              "vaults": {51                "main": {52                  "name": "Personal",53                  "items": [54                    {55                      "data": {56                        "type": "login",57                        "metadata": { "name": "Proton Site", "note": "saved note" },58                        "content": {59                          "username": "june",60                          "password": "hunter2",61                          "urls": ["https://example.com"],62                          "totpUri": "otpauth://totp/Example:june?secret=JBSWY3DPEHPK3PXP"63                        }64                      }65                    }66                  ]67                },68                "trash": {69                  "name": "Recycle Bin",70                  "items": [71                    {72                      "data": {73                        "type": "login",74                        "metadata": { "name": "Deleted" },75                        "content": { "username": "x", "password": "y" }76                      }77                    }78                  ]79                }80              }81            }82        """.trimIndent()8384        assertEquals(CsvImport.PROTONPASS_JSON, CsvImport.detectProvider(json))85        val rows = CsvImport.parse(json, CsvImport.PROTONPASS_JSON)8687        assertEquals(1, rows.size)88        assertEquals("Proton Site", rows[0].title)89        assertEquals("june", rows[0].username)90        assertEquals("hunter2", rows[0].password)91        assertEquals("https://example.com", rows[0].url)92        assertEquals("saved note", rows[0].notes)93        assertEquals("otpauth://totp/Example:june?secret=JBSWY3DPEHPK3PXP", rows[0].totp)94    }9596    @Test fun peachscript_export_is_recognised() {97        val out = PeachScriptExport.buildEncrypted(98            listOf(99                VaultEntry(100                    id = "11111111-2222-3333-4444-555555555555", type = "login",101                    title = "GH", username = "u", password = "p", createdAt = 0, modifiedAt = 0,102                ),103            ),104            "backup-pass-123",105        )106        assertTrue(PeachScriptImport.looksLikePeachScript(out))107        assertTrue(PeachScriptImport.isEncrypted(out))108    }109110    @Test fun non_peachscript_text_is_rejected() {111        assertFalse(PeachScriptImport.looksLikePeachScript("just text"))112        // The old JSON marker is not PeachScript anymore (PUA-encoded binary only).113        assertFalse(PeachScriptImport.looksLikePeachScript("""{"peachscript":1,"encrypted":true}"""))114    }115116    @Test fun file_picker_routes_peachscript_files_to_peachscript_restore() {117        val out = PeachScriptExport.buildEncrypted(118            listOf(119                VaultEntry(120                    id = "11111111-2222-3333-4444-555555555555", type = "login",121                    title = "GH", username = "u", password = "p", createdAt = 0, modifiedAt = 0,122                ),123            ),124            "backup-pass-123",125        )126127        assertTrue(shouldRouteFileToPeachScript("backup.txt", out))128        assertTrue(shouldRouteFileToPeachScript("backup.peach", "not yet decoded"))129        assertFalse(shouldRouteFileToPeachScript("export.csv", "name,url,username,password\nA,https://a.com,u,p\n"))130    }131132    @Test fun import_errors_match_browser_recovery_copy() {133        assertEquals(134            "Wrong backup password. This is the password you chose when you created the backup.",135            ImportErrors.WRONG_PASSWORD,136        )137        assertEquals(138            "This Peach backup file looks corrupted or incomplete.",139            ImportErrors.CORRUPTED,140        )141        assertEquals(142            "No importable password entries were found in that file.",143            ImportErrors.NO_ENTRIES,144        )145    }146}