mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-08-31 13:17:09 +00:00
275 lines
7.9 KiB
Go
275 lines
7.9 KiB
Go
package pds
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"path/filepath"
|
|
"testing"
|
|
)
|
|
|
|
// TestGenerateDIDFromURL tests DID generation from various URL formats
|
|
func TestGenerateDIDFromURL(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
publicURL string
|
|
expectedDID string
|
|
}{
|
|
{
|
|
name: "standard HTTP with standard port",
|
|
publicURL: "http://hold.example.com",
|
|
expectedDID: "did:web:hold.example.com",
|
|
},
|
|
{
|
|
name: "standard HTTPS with standard port",
|
|
publicURL: "https://hold.example.com",
|
|
expectedDID: "did:web:hold.example.com",
|
|
},
|
|
{
|
|
name: "HTTP with non-standard port",
|
|
publicURL: "http://hold.example.com:8080",
|
|
expectedDID: "did:web:hold.example.com:8080",
|
|
},
|
|
{
|
|
name: "HTTPS with non-standard port",
|
|
publicURL: "https://hold.example.com:8443",
|
|
expectedDID: "did:web:hold.example.com:8443",
|
|
},
|
|
{
|
|
name: "localhost with port",
|
|
publicURL: "http://localhost:8080",
|
|
expectedDID: "did:web:localhost:8080",
|
|
},
|
|
{
|
|
name: "HTTP with explicit port 80",
|
|
publicURL: "http://hold.example.com:80",
|
|
expectedDID: "did:web:hold.example.com",
|
|
},
|
|
{
|
|
name: "HTTPS with explicit port 443",
|
|
publicURL: "https://hold.example.com:443",
|
|
expectedDID: "did:web:hold.example.com",
|
|
},
|
|
{
|
|
name: "subdomain",
|
|
publicURL: "https://hold1.atcr.io",
|
|
expectedDID: "did:web:hold1.atcr.io",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
did := GenerateDIDFromURL(tt.publicURL)
|
|
if did != tt.expectedDID {
|
|
t.Errorf("Expected DID %s, got %s", tt.expectedDID, did)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// TestGenerateDIDFromURL_InvalidURL tests handling of invalid URLs
|
|
func TestGenerateDIDFromURL_InvalidURL(t *testing.T) {
|
|
// Invalid URLs get parsed with empty hostname, which defaults to localhost
|
|
did := GenerateDIDFromURL("not a url")
|
|
if did != "did:web:localhost" {
|
|
t.Errorf("Expected did:web:localhost for invalid URL, got %s", did)
|
|
}
|
|
}
|
|
|
|
// TestGenerateDIDDocument tests DID document generation
|
|
func TestGenerateDIDDocument(t *testing.T) {
|
|
ctx := context.Background()
|
|
tmpDir := t.TempDir()
|
|
|
|
dbPath := filepath.Join(tmpDir, "pds.db")
|
|
keyPath := filepath.Join(tmpDir, "signing-key")
|
|
publicURL := "https://hold.example.com"
|
|
|
|
pds, err := NewHoldPDS(ctx, "did:web:hold.example.com", publicURL, dbPath, keyPath, false)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create PDS: %v", err)
|
|
}
|
|
|
|
doc, err := pds.GenerateDIDDocument(publicURL)
|
|
if err != nil {
|
|
t.Fatalf("Failed to generate DID document: %v", err)
|
|
}
|
|
|
|
// Verify required fields
|
|
if doc.ID != "did:web:hold.example.com" {
|
|
t.Errorf("Expected DID did:web:hold.example.com, got %s", doc.ID)
|
|
}
|
|
|
|
// Verify context
|
|
if len(doc.Context) != 3 {
|
|
t.Errorf("Expected 3 context entries, got %d", len(doc.Context))
|
|
}
|
|
|
|
expectedContexts := []string{
|
|
"https://www.w3.org/ns/did/v1",
|
|
"https://w3id.org/security/multikey/v1",
|
|
"https://w3id.org/security/suites/secp256k1-2019/v1",
|
|
}
|
|
for i, expected := range expectedContexts {
|
|
if doc.Context[i] != expected {
|
|
t.Errorf("Expected context[%d] = %s, got %s", i, expected, doc.Context[i])
|
|
}
|
|
}
|
|
|
|
// Verify alsoKnownAs
|
|
if len(doc.AlsoKnownAs) != 1 || doc.AlsoKnownAs[0] != "at://hold.example.com" {
|
|
t.Errorf("Expected alsoKnownAs=['at://hold.example.com'], got %v", doc.AlsoKnownAs)
|
|
}
|
|
|
|
// Verify verification method
|
|
if len(doc.VerificationMethod) != 1 {
|
|
t.Fatalf("Expected 1 verification method, got %d", len(doc.VerificationMethod))
|
|
}
|
|
|
|
vm := doc.VerificationMethod[0]
|
|
if vm.ID != "did:web:hold.example.com#atproto" {
|
|
t.Errorf("Expected verification method ID did:web:hold.example.com#atproto, got %s", vm.ID)
|
|
}
|
|
if vm.Type != "Multikey" {
|
|
t.Errorf("Expected type Multikey, got %s", vm.Type)
|
|
}
|
|
if vm.Controller != "did:web:hold.example.com" {
|
|
t.Errorf("Expected controller did:web:hold.example.com, got %s", vm.Controller)
|
|
}
|
|
if vm.PublicKeyMultibase == "" {
|
|
t.Error("Expected non-empty publicKeyMultibase")
|
|
}
|
|
|
|
// Verify authentication
|
|
if len(doc.Authentication) != 1 || doc.Authentication[0] != "did:web:hold.example.com#atproto" {
|
|
t.Errorf("Expected authentication=['did:web:hold.example.com#atproto'], got %v", doc.Authentication)
|
|
}
|
|
|
|
// Verify services
|
|
if len(doc.Service) != 2 {
|
|
t.Fatalf("Expected 2 services, got %d", len(doc.Service))
|
|
}
|
|
|
|
// Check PDS service
|
|
pdsService := doc.Service[0]
|
|
if pdsService.ID != "#atproto_pds" {
|
|
t.Errorf("Expected service ID #atproto_pds, got %s", pdsService.ID)
|
|
}
|
|
if pdsService.Type != "AtprotoPersonalDataServer" {
|
|
t.Errorf("Expected service type AtprotoPersonalDataServer, got %s", pdsService.Type)
|
|
}
|
|
if pdsService.ServiceEndpoint != publicURL {
|
|
t.Errorf("Expected service endpoint %s, got %s", publicURL, pdsService.ServiceEndpoint)
|
|
}
|
|
|
|
// Check hold service
|
|
holdService := doc.Service[1]
|
|
if holdService.ID != "#atcr_hold" {
|
|
t.Errorf("Expected service ID #atcr_hold, got %s", holdService.ID)
|
|
}
|
|
if holdService.Type != "AtcrHoldService" {
|
|
t.Errorf("Expected service type AtcrHoldService, got %s", holdService.Type)
|
|
}
|
|
if holdService.ServiceEndpoint != publicURL {
|
|
t.Errorf("Expected service endpoint %s, got %s", publicURL, holdService.ServiceEndpoint)
|
|
}
|
|
}
|
|
|
|
// TestGenerateDIDDocument_WithPort tests DID document with non-standard port
|
|
func TestGenerateDIDDocument_WithPort(t *testing.T) {
|
|
ctx := context.Background()
|
|
tmpDir := t.TempDir()
|
|
|
|
dbPath := filepath.Join(tmpDir, "pds.db")
|
|
keyPath := filepath.Join(tmpDir, "signing-key")
|
|
publicURL := "https://hold.example.com:8443"
|
|
|
|
pds, err := NewHoldPDS(ctx, "did:web:hold.example.com:8443", publicURL, dbPath, keyPath, false)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create PDS: %v", err)
|
|
}
|
|
|
|
doc, err := pds.GenerateDIDDocument(publicURL)
|
|
if err != nil {
|
|
t.Fatalf("Failed to generate DID document: %v", err)
|
|
}
|
|
|
|
// Verify DID includes port
|
|
if doc.ID != "did:web:hold.example.com:8443" {
|
|
t.Errorf("Expected DID did:web:hold.example.com:8443, got %s", doc.ID)
|
|
}
|
|
|
|
// Verify alsoKnownAs includes port
|
|
if doc.AlsoKnownAs[0] != "at://hold.example.com:8443" {
|
|
t.Errorf("Expected alsoKnownAs with port, got %s", doc.AlsoKnownAs[0])
|
|
}
|
|
}
|
|
|
|
// TestMarshalDIDDocument tests DID document JSON marshaling
|
|
func TestMarshalDIDDocument(t *testing.T) {
|
|
ctx := context.Background()
|
|
tmpDir := t.TempDir()
|
|
|
|
dbPath := filepath.Join(tmpDir, "pds.db")
|
|
keyPath := filepath.Join(tmpDir, "signing-key")
|
|
publicURL := "https://hold.example.com"
|
|
|
|
pds, err := NewHoldPDS(ctx, "did:web:hold.example.com", publicURL, dbPath, keyPath, false)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create PDS: %v", err)
|
|
}
|
|
|
|
jsonBytes, err := pds.MarshalDIDDocument()
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal DID document: %v", err)
|
|
}
|
|
|
|
// Verify it's valid JSON
|
|
var doc map[string]any
|
|
if err := json.Unmarshal(jsonBytes, &doc); err != nil {
|
|
t.Fatalf("Failed to unmarshal DID document JSON: %v", err)
|
|
}
|
|
|
|
// Verify required fields
|
|
if id, ok := doc["id"].(string); !ok || id != "did:web:hold.example.com" {
|
|
t.Errorf("Expected id='did:web:hold.example.com', got %v", doc["id"])
|
|
}
|
|
|
|
if _, ok := doc["@context"]; !ok {
|
|
t.Error("Expected @context field in JSON")
|
|
}
|
|
|
|
if _, ok := doc["verificationMethod"]; !ok {
|
|
t.Error("Expected verificationMethod field in JSON")
|
|
}
|
|
|
|
if _, ok := doc["service"]; !ok {
|
|
t.Error("Expected service field in JSON")
|
|
}
|
|
|
|
// Verify pretty-printed (has indentation)
|
|
if len(jsonBytes) < 100 {
|
|
t.Error("Expected pretty-printed JSON to be reasonably sized")
|
|
}
|
|
}
|
|
|
|
// TestGenerateDIDDocument_InvalidURL tests error handling
|
|
func TestGenerateDIDDocument_InvalidURL(t *testing.T) {
|
|
ctx := context.Background()
|
|
tmpDir := t.TempDir()
|
|
|
|
dbPath := filepath.Join(tmpDir, "pds.db")
|
|
keyPath := filepath.Join(tmpDir, "signing-key")
|
|
publicURL := "https://hold.example.com"
|
|
|
|
pds, err := NewHoldPDS(ctx, "did:web:hold.example.com", publicURL, dbPath, keyPath, false)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create PDS: %v", err)
|
|
}
|
|
|
|
// Try to generate DID document with invalid URL
|
|
_, err = pds.GenerateDIDDocument("ht!tp://invalid url")
|
|
if err == nil {
|
|
t.Error("Expected error for invalid URL, got nil")
|
|
}
|
|
}
|