Add addressbook listing and contact fetching
Assisted-by: Claude Opus 4.5 via Claude Code
change zmmoskqzkvswkmxpsswsyomtkpqxrwtv
commit 4136fedd99103dd7afd840361d9798a3f4b79f10
author Alpha Chen <alpha@kejadlen.dev>
date
parent myzspwxt
diff --git a/lib/pro_tacts/web.rb b/lib/pro_tacts/web.rb
index d1a67c5..687e1a5 100644
--- a/lib/pro_tacts/web.rb
+++ b/lib/pro_tacts/web.rb
@@ -67,6 +67,40 @@ module ProTacts
           XML
         end
       end
+
+      r.on "addressbook" do
+        r.propfind do
+          response["Content-Type"] = "text/xml"
+          response.status = 207
+
+          <<~XML
+            <?xml version="1.0" encoding="UTF-8"?>
+            <d:multistatus xmlns:d="DAV:" xmlns:card="urn:ietf:params:xml:ns:carddav">
+              <d:response>
+                <d:href>/addressbook/test-contact.vcf</d:href>
+                <d:propstat>
+                  <d:prop>
+                    <d:getetag>"etag-123"</d:getetag>
+                  </d:prop>
+                  <d:status>HTTP/1.1 200 OK</d:status>
+                </d:propstat>
+              </d:response>
+            </d:multistatus>
+          XML
+        end
+
+        r.get String do |uid|
+          response["Content-Type"] = "text/vcard"
+
+          <<~VCARD
+            BEGIN:VCARD
+            VERSION:3.0
+            FN:Test Contact
+            N:Contact;Test;;;
+            END:VCARD
+          VCARD
+        end
+      end
     end
   end
 end
diff --git a/test/pro_tacts/test_web.rb b/test/pro_tacts/test_web.rb
index 7c7f7bb..4a81471 100644
--- a/test/pro_tacts/test_web.rb
+++ b/test/pro_tacts/test_web.rb
@@ -36,4 +36,22 @@ class WebTest < Minitest::Test
     assert_includes last_response.body, "multistatus"
     assert_includes last_response.body, "/addressbook/"
   end
+
+  def test_propfind_addressbook
+    request "/addressbook/", method: "PROPFIND"
+
+    assert_equal 207, last_response.status
+    assert_equal "text/xml", last_response["Content-Type"]
+    assert_includes last_response.body, "multistatus"
+    assert_includes last_response.body, ".vcf"
+  end
+
+  def test_get_contact
+    get "/addressbook/test-contact.vcf"
+
+    assert_equal 200, last_response.status
+    assert_equal "text/vcard", last_response["Content-Type"]
+    assert_includes last_response.body, "BEGIN:VCARD"
+    assert_includes last_response.body, "END:VCARD"
+  end
 end