package com.peachpasswords.ui.vault import com.peachpasswords.vault.PasskeyData import com.peachpasswords.vault.VaultEntry import org.junit.Assert.assertEquals import org.junit.Assert.assertTrue import org.junit.Test class VaultSearchParityTest { @Test fun recent_sort_uses_last_used_then_modified_time() { val entries = listOf( entry(id = "created-only", title = "Created only", modifiedAt = 10), entry(id = "login-used", title = "Login used", modifiedAt = 20, lastUsedAt = 300), entry(id = "modified-fallback", title = "Modified fallback", modifiedAt = 200), ) val sorted = filterAndSortVaultEntries(entries, SortOrder.NEWEST, "") assertEquals(listOf("login-used", "modified-fallback", "created-only"), sorted.map { it.id }) } @Test fun fuzzy_search_matches_notes_passkeys_and_additional_urls() { val note = entry(id = "note", type = "note", title = "Notebook", notes = "recovery codes") val passkey = entry( id = "passkey", title = "Loginless", passkey = passkeyData(rpId = "example.com", userDisplayName = "Passkey User"), ) val alias = entry( id = "alias", title = "Primary", url = "https://example.com", additionalUrls = listOf("https://billing.example.com"), ) assertEquals(listOf("note"), filterAndSortVaultEntries(listOf(note), SortOrder.SMART, "rcvry").map { it.id }) assertEquals(listOf("passkey"), filterAndSortVaultEntries(listOf(passkey), SortOrder.SMART, "psky usr").map { it.id }) assertEquals(listOf("alias"), filterAndSortVaultEntries(listOf(alias), SortOrder.SMART, "billing").map { it.id }) } @Test fun exact_prefix_search_beats_newer_fuzzy_match() { val exact = entry(id = "exact", title = "GitHub", modifiedAt = 10) val fuzzyNewer = entry(id = "fuzzy", title = "Work login", username = "github-user", modifiedAt = 500) val sorted = filterAndSortVaultEntries(listOf(fuzzyNewer, exact), SortOrder.SMART, "git") assertEquals(listOf("exact", "fuzzy"), sorted.map { it.id }) } @Test fun fuzzy_match_allows_non_contiguous_letters() { assertTrue(fuzzyMatch("gthb", "GitHub")) } private fun entry( id: String, title: String, type: String = "login", username: String? = null, url: String? = null, additionalUrls: List? = null, notes: String? = null, passkey: PasskeyData? = null, createdAt: Long = 1, modifiedAt: Long = 1, lastUsedAt: Long? = null, ) = VaultEntry( id = id, title = title, type = type, username = username, url = url, additionalUrls = additionalUrls, notes = notes, passkey = passkey, createdAt = createdAt, modifiedAt = modifiedAt, lastUsedAt = lastUsedAt, ) private fun passkeyData( rpId: String, userDisplayName: String, ) = PasskeyData( credentialId = "cred", publicKeyCose = "cose", rpId = rpId, userHandle = "handle", userName = "passkey-user", userDisplayName = userDisplayName, ) }