admin: search matches the nickname too
The list renamed nicknamed contacts to "Nickname (Name)" while
matches? still only tried the FN, so the displayed name was the one
thing search could not find.

Assisted-by: GLM-5.3 via pi
change pktxrttmxumsqmwznxwrwpsulwurxpxw
commit 34607bd5a7d5fbdf77c10091d38628c74a37a32c
author Alpha Chen <alpha@kejadlen.dev>
date
parent xuyrzyxn
diff --git a/lib/pro_tacts/admin/contacts_index.rb b/lib/pro_tacts/admin/contacts_index.rb
index 9e59544..a68a80c 100644
--- a/lib/pro_tacts/admin/contacts_index.rb
+++ b/lib/pro_tacts/admin/contacts_index.rb
@@ -61,10 +61,14 @@ module ProTacts
         nickname || name || contact.id
       end
 
+      # Match generously (docs/DESIGN.md): a contact is findable by
+      # name — the nickname too, being the name it lists under — any
+      # of its values, or the groups it belongs to.
       #: (Row row, String query) -> bool
       def matches?(row, query)
         q = query.downcase
         return true if row.contact.name&.downcase&.include?(q)
+        return true if row.contact.nickname&.downcase&.include?(q)
         return true if row.contact.phones.any? { it.value.downcase.include?(q) }
         return true if row.contact.emails.any? { it.value.downcase.include?(q) }
 
diff --git a/test/pro_tacts/admin/test_contacts_pages.rb b/test/pro_tacts/admin/test_contacts_pages.rb
index 2d68126..e6b423b 100644
--- a/test/pro_tacts/admin/test_contacts_pages.rb
+++ b/test/pro_tacts/admin/test_contacts_pages.rb
@@ -193,6 +193,18 @@ class AdminContactsPagesTest < Minitest::Test
     end
   end
 
+  # The nickname is a name the contact lists under, so it finds the
+  # contact the same way the name does.
+  def test_search_matches_the_nickname
+    red = ADA.sub("FN:Ada Lovelace", "FN:Sarah\r\nNICKNAME:Red").sub("UID:ada", "UID:red")
+
+    with_contacts({"red" => red}) do
+      get "/", q: "red"
+
+      assert_includes last_response.body, "Red (Sarah)"
+    end
+  end
+
   def test_search_with_no_matches_says_so
     with_contacts({"ada" => ADA}) do
       get "/", q: "nobody"