ultisuite-backend/internal/nextcloud/contacts_test.go
R3D347HR4Y f232aaf960 Enhance Contacts API with new features and improvements
- Updated the Contacts API to support contact synchronization with incremental updates using sync tokens.
- Added functionality for merging duplicate contacts on the server side.
- Introduced new endpoints for enriching contact interactions, including mail, meetings, and files.
- Implemented ETag support for contact updates to ensure data integrity.
- Enhanced validation for sync tokens and interaction queries.
- Updated project checklist to reflect the completion of Contacts API enhancements.
2026-05-22 20:50:46 +02:00

103 lines
3.0 KiB
Go

package nextcloud
import (
"strings"
"testing"
)
func TestBuildSyncCollectionRequest(t *testing.T) {
initial := buildSyncCollectionRequest("")
if strings.Contains(initial, "sync-token") {
t.Fatal("initial sync must omit sync-token element")
}
if !strings.Contains(initial, "sync-collection") {
t.Fatal("expected sync-collection request")
}
incremental := buildSyncCollectionRequest(`http://nc/sync/1`)
if !strings.Contains(incremental, "<d:sync-token>http://nc/sync/1</d:sync-token>") {
t.Fatalf("unexpected incremental body: %s", incremental)
}
}
func TestParseContactSyncResponse(t *testing.T) {
body := strings.NewReader(`<?xml version="1.0" encoding="utf-8"?>
<d:multistatus xmlns:d="DAV:" xmlns:card="urn:ietf:params:xml:ns:carddav">
<d:sync-token>http://nc/sync/2</d:sync-token>
<d:response>
<d:href>/remote.php/dav/addressbooks/users/alice/contacts/ada.vcf</d:href>
<d:propstat>
<d:prop>
<d:getetag>"etag-1"</d:getetag>
<card:address-data>BEGIN:VCARD
UID:ada@ulti
FN:Ada Lovelace
EMAIL:ada@example.com
END:VCARD</card:address-data>
</d:prop>
<d:status>HTTP/1.1 200 OK</d:status>
</d:propstat>
</d:response>
<d:response>
<d:href>/remote.php/dav/addressbooks/users/alice/contacts/old.vcf</d:href>
<d:status>HTTP/1.1 404 Not Found</d:status>
</d:response>
</d:multistatus>`)
result, err := parseContactSyncResponse(body)
if err != nil {
t.Fatal(err)
}
if result.SyncToken != "http://nc/sync/2" {
t.Fatalf("sync token: got %q", result.SyncToken)
}
if len(result.Contacts) != 1 {
t.Fatalf("contacts: got %d", len(result.Contacts))
}
c := result.Contacts[0]
if c.FullName != "Ada Lovelace" || c.Path != "/remote.php/dav/addressbooks/users/alice/contacts/ada.vcf" {
t.Fatalf("unexpected contact: %+v", c)
}
if c.ETag != "\"etag-1\"" {
t.Fatalf("etag: got %q", c.ETag)
}
if len(result.Deleted) != 1 || result.Deleted[0] != "/remote.php/dav/addressbooks/users/alice/contacts/old.vcf" {
t.Fatalf("deleted: %+v", result.Deleted)
}
}
func TestParseContactListSetsPathAndETag(t *testing.T) {
body := strings.NewReader(`<?xml version="1.0" encoding="utf-8"?>
<d:multistatus xmlns:d="DAV:" xmlns:card="urn:ietf:params:xml:ns:carddav">
<d:response>
<d:href>/remote.php/dav/addressbooks/users/alice/contacts/</d:href>
<d:propstat><d:prop/></d:propstat>
</d:response>
<d:response>
<d:href>/remote.php/dav/addressbooks/users/alice/contacts/bob.vcf</d:href>
<d:propstat>
<d:prop>
<d:getetag>"e2"</d:getetag>
<card:address-data>BEGIN:VCARD
FN:Bob
END:VCARD</card:address-data>
</d:prop>
</d:propstat>
</d:response>
</d:multistatus>`)
contacts, err := parseContactList(body)
if err != nil {
t.Fatal(err)
}
if len(contacts) != 1 {
t.Fatalf("contacts: got %d", len(contacts))
}
if contacts[0].Path != "/remote.php/dav/addressbooks/users/alice/contacts/bob.vcf" {
t.Fatalf("path: %q", contacts[0].Path)
}
if contacts[0].ETag != "\"e2\"" {
t.Fatalf("etag: %q", contacts[0].ETag)
}
}