mirror of
https://github.com/1f349/go-webdav.git
synced 2024-12-22 16:24:14 +00:00
carddav: end-to-end test address book discovery
As the implementation evolves, it will be necessary to have more tests to assert we don't break anything when making changes. This commit introduces a test setup to test that server and client can handle the address book discovery with various parameters. The test setup should be easily extendable to cover even more ground as needed.
This commit is contained in:
parent
987c9eef0b
commit
4a3cd0510f
174
carddav/carddav_test.go
Normal file
174
carddav/carddav_test.go
Normal file
@ -0,0 +1,174 @@
|
|||||||
|
package carddav
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"net/http"
|
||||||
|
"net/http/httptest"
|
||||||
|
"strings"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/emersion/go-vcard"
|
||||||
|
"github.com/emersion/go-webdav"
|
||||||
|
)
|
||||||
|
|
||||||
|
type testBackend struct{}
|
||||||
|
|
||||||
|
type contextKey string
|
||||||
|
|
||||||
|
var (
|
||||||
|
aliceData = `BEGIN:VCARD
|
||||||
|
VERSION:4.0
|
||||||
|
UID:urn:uuid:4fbe8971-0bc3-424c-9c26-36c3e1eff6b1
|
||||||
|
FN;PID=1.1:Alice Gopher
|
||||||
|
N:Gopher;Alice;;;
|
||||||
|
EMAIL;PID=1.1:alice@example.com
|
||||||
|
CLIENTPIDMAP:1;urn:uuid:53e374d9-337e-4727-8803-a1e9c14e0551
|
||||||
|
END:VCARD`
|
||||||
|
alicePath = "urn:uuid:4fbe8971-0bc3-424c-9c26-36c3e1eff6b1.vcf"
|
||||||
|
|
||||||
|
currentUserPrincipalKey = "test:currentUserPrincipal"
|
||||||
|
homeSetPathKey = "test:homeSetPath"
|
||||||
|
addressBookPathKey = "test:addressBookPath"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (*testBackend) CurrentUserPrincipal(ctx context.Context) (string, error) {
|
||||||
|
r := ctx.Value(currentUserPrincipalKey).(string)
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*testBackend) AddressbookHomeSetPath(ctx context.Context) (string, error) {
|
||||||
|
r := ctx.Value(homeSetPathKey).(string)
|
||||||
|
return r, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*testBackend) AddressBook(ctx context.Context) (*AddressBook, error) {
|
||||||
|
p := ctx.Value(addressBookPathKey).(string)
|
||||||
|
return &AddressBook{
|
||||||
|
Path: p,
|
||||||
|
Name: "My contacts",
|
||||||
|
Description: "Default address book",
|
||||||
|
MaxResourceSize: 1024,
|
||||||
|
SupportedAddressData: nil,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*testBackend) GetAddressObject(ctx context.Context, path string, req *AddressDataRequest) (*AddressObject, error) {
|
||||||
|
if path == alicePath {
|
||||||
|
card, err := vcard.NewDecoder(strings.NewReader(aliceData)).Decode()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &AddressObject{
|
||||||
|
Path: path,
|
||||||
|
Card: card,
|
||||||
|
}, nil
|
||||||
|
} else {
|
||||||
|
return nil, webdav.NewHTTPError(404, fmt.Errorf("Not found"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *testBackend) ListAddressObjects(ctx context.Context, req *AddressDataRequest) ([]AddressObject, error) {
|
||||||
|
alice, err := b.GetAddressObject(ctx, alicePath, req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return []AddressObject{*alice}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*testBackend) QueryAddressObjects(ctx context.Context, query *AddressBookQuery) ([]AddressObject, error) {
|
||||||
|
panic("TODO: implement")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*testBackend) PutAddressObject(ctx context.Context, path string, card vcard.Card, opts *PutAddressObjectOptions) (loc string, err error) {
|
||||||
|
panic("TODO: implement")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (*testBackend) DeleteAddressObject(ctx context.Context, path string) error {
|
||||||
|
panic("TODO: implement")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestAddressBookDiscovery(t *testing.T) {
|
||||||
|
for _, tc := range []struct {
|
||||||
|
name string
|
||||||
|
currentUserPrincipal string
|
||||||
|
homeSetPath string
|
||||||
|
addressBookPath string
|
||||||
|
}{
|
||||||
|
// TODO this used to work, but is currently broken.
|
||||||
|
//{
|
||||||
|
// name: "all-at-root",
|
||||||
|
// currentUserPrincipal: "/",
|
||||||
|
// homeSetPath: "/",
|
||||||
|
// addressBookPath: "/",
|
||||||
|
//},
|
||||||
|
{
|
||||||
|
name: "simple-home-set-path",
|
||||||
|
currentUserPrincipal: "/",
|
||||||
|
homeSetPath: "/contacts/",
|
||||||
|
addressBookPath: "/contacts/",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "all-at-different-paths",
|
||||||
|
currentUserPrincipal: "/",
|
||||||
|
homeSetPath: "/contacts/",
|
||||||
|
addressBookPath: "/contacts/work",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "nothing-at-root",
|
||||||
|
currentUserPrincipal: "/test/",
|
||||||
|
homeSetPath: "/test/contacts/",
|
||||||
|
addressBookPath: "/test/contacts/private",
|
||||||
|
},
|
||||||
|
} {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
|
||||||
|
h := Handler{&testBackend{}}
|
||||||
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
ctx := r.Context()
|
||||||
|
ctx = context.WithValue(ctx, currentUserPrincipalKey, tc.currentUserPrincipal)
|
||||||
|
ctx = context.WithValue(ctx, homeSetPathKey, tc.homeSetPath)
|
||||||
|
ctx = context.WithValue(ctx, addressBookPathKey, tc.addressBookPath)
|
||||||
|
r = r.WithContext(ctx)
|
||||||
|
(&h).ServeHTTP(w, r)
|
||||||
|
}))
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
// client supports .well-known discovery if explicitly pointed to it
|
||||||
|
startURL := ts.URL
|
||||||
|
if tc.currentUserPrincipal != "/" {
|
||||||
|
startURL = ts.URL + "/.well-known/carddav"
|
||||||
|
}
|
||||||
|
|
||||||
|
client, err := NewClient(nil, startURL)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error creating client: %s", err)
|
||||||
|
}
|
||||||
|
cup, err := client.FindCurrentUserPrincipal()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error finding user principal url: %s", err)
|
||||||
|
}
|
||||||
|
if cup != tc.currentUserPrincipal {
|
||||||
|
t.Fatalf("Found current user principal URL '%s', expected '%s'", cup, tc.currentUserPrincipal)
|
||||||
|
}
|
||||||
|
hsp, err := client.FindAddressBookHomeSet(cup)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error finding home set path: %s", err)
|
||||||
|
}
|
||||||
|
if hsp != tc.homeSetPath {
|
||||||
|
t.Fatalf("Found home set path '%s', expected '%s'", hsp, tc.homeSetPath)
|
||||||
|
}
|
||||||
|
abs, err := client.FindAddressBooks(hsp)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error finding address books: %s", err)
|
||||||
|
}
|
||||||
|
if len(abs) != 1 {
|
||||||
|
t.Fatalf("Found %d address books, expected 1", len(abs))
|
||||||
|
}
|
||||||
|
if abs[0].Path != tc.addressBookPath {
|
||||||
|
t.Fatalf("Found address book at %s, expected %s", abs[0].Path, tc.addressBookPath)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user