1package com.peachpasswords.autofill23import com.peachpasswords.vault.VaultEntry4import org.junit.Assert.assertEquals5import org.junit.Assert.assertFalse6import org.junit.Assert.assertTrue7import org.junit.Test89class AutofillPickerSearchTest {1011 private fun entry(12 title: String,13 username: String? = null,14 email: String? = null,15 url: String? = null,16 ) = VaultEntry(17 id = title,18 title = title,19 username = username,20 email = email,21 url = url,22 createdAt = 0,23 modifiedAt = 0,24 )2526 @Test fun empty_query_matches_every_entry() {27 val gh = entry("GitHub", username = "june", url = "https://github.com")28 val fb = entry("Fastmail", email = "[email protected]")29 assertTrue(matchesPickerSearch(gh, ""))30 assertTrue(matchesPickerSearch(fb, ""))31 }3233 @Test fun whitespace_only_query_does_not_match_arbitrary_text() {34 35 36 37 38 val gh = entry("GitHub", username = "june")39 assertFalse(matchesPickerSearch(gh, " "))40 }4142 @Test fun matches_title_case_insensitively() {43 val gh = entry("GitHub", username = "june")44 assertTrue(matchesPickerSearch(gh, "github"))45 assertTrue(matchesPickerSearch(gh, "GITHUB"))46 assertTrue(matchesPickerSearch(gh, "git"))47 }4849 @Test fun matches_username_and_email() {50 val u = entry("Acme", username = "june.doe")51 val e = entry("Acme 2", email = "[email protected]")52 assertTrue(matchesPickerSearch(u, "doe"))53 assertTrue(matchesPickerSearch(e, "fastmail"))54 }5556 @Test fun matches_url_substring() {57 val gh = entry("GitHub", url = "https://github.com/june")58 assertTrue(matchesPickerSearch(gh, "github"))59 }6061 @Test fun rejects_when_no_field_matches() {62 val gh = entry("GitHub", username = "june", url = "https://github.com")63 assertFalse(matchesPickerSearch(gh, "fastmail"))64 assertFalse(matchesPickerSearch(gh, "x"))65 }6667 @Test fun null_fields_are_skipped_not_crashed() {68 val bare = entry("Bare Title")69 70 assertTrue(matchesPickerSearch(bare, "bare"))71 assertFalse(matchesPickerSearch(bare, "nope"))72 }7374 @Test fun pickerEntries_filter_pipeline_drops_unmatched_and_keeps_order() {75 val entries = listOf(76 entry("GitHub", username = "june", url = "https://github.com"),77 entry("Fastmail", email = "[email protected]"),78 entry("Peach", url = "https://peachpasswords.com"),79 )80 val filtered = entries.filter { matchesPickerSearch(it, "github") }81 assertEquals(listOf("GitHub"), filtered.map { it.title })82 }8384 @Test fun malformed_and_local_manual_origins_never_match() {85 val entry = entry("Bank", url = "https://bank.example.com/login")86 listOf(87 "",88 "localhost",89 "http://localhost:8080/login",90 "127.0.0.1",91 "https://127.0.0.1/login",92 "https://[::1]/login",93 "https://",94 "not a domain",95 ).forEach { origin ->96 assertTrue(97 "origin '$origin' must fail closed",98 AutofillResponseBuilder.matchEntries(listOf(entry), origin).all.isEmpty(),99 )100 }101 }102103 @Test fun web_origin_preselects_matching_entries_by_domain() {104 val entry = entry("Bank", url = "https://bank.example.com/login")105 val parsed = ParsedStructure(106 webDomain = "bank.example.com",107 originDomains = listOf("bank.example.com"),108 )109 assertEquals(listOf(entry), autofillPickerEntries(listOf(entry), parsed, limit = 12))110 }111112 @Test fun picker_search_locates_any_entry_via_substring() {113 114 115 val entries = listOf(116 entry("GitHub", username = "june", url = "https://github.com"),117 entry("Fastmail", email = "[email protected]"),118 entry("Peach", url = "https://peachpasswords.com"),119 )120 assertEquals(listOf("GitHub"), entries.filter { matchesPickerSearch(it, "git") }.map { it.title })121 assertEquals(listOf("Fastmail"), entries.filter { matchesPickerSearch(it, "fastmail") }.map { it.title })122 assertEquals(listOf("Peach"), entries.filter { matchesPickerSearch(it, "peach") }.map { it.title })123 assertEquals(124 listOf("GitHub", "Fastmail"),125 entries.filter { matchesPickerSearch(it, "june") }.map { it.title },126 )127 }128}