aboutsummaryrefslogtreecommitdiff
path: root/internal/api/plc_compatibility_test.go
diff options
context:
space:
mode:
authorFuwn <[email protected]>2026-02-26 20:20:09 -0800
committerFuwn <[email protected]>2026-02-26 20:20:09 -0800
commit80dc07bf7bbf3ee9f7191a0446199d74cbb2d341 (patch)
tree746f1518723b64a5270131a1e19b6c6f5a312926 /internal/api/plc_compatibility_test.go
parentchore: remove accidentally committed binary (diff)
downloadplutia-test-80dc07bf7bbf3ee9f7191a0446199d74cbb2d341.tar.xz
plutia-test-80dc07bf7bbf3ee9f7191a0446199d74cbb2d341.zip
fix: align PLC compatibility read endpoints with plc.directory schema
Diffstat (limited to 'internal/api/plc_compatibility_test.go')
-rw-r--r--internal/api/plc_compatibility_test.go122
1 files changed, 109 insertions, 13 deletions
diff --git a/internal/api/plc_compatibility_test.go b/internal/api/plc_compatibility_test.go
index fe7ee82..45428d8 100644
--- a/internal/api/plc_compatibility_test.go
+++ b/internal/api/plc_compatibility_test.go
@@ -21,25 +21,55 @@ import (
"time"
)
-func TestPLCCompatibilityGetDIDMatchesStoredDocument(t *testing.T) {
- ts, store, _, cleanup := newCompatibilityServer(t)
+func TestPLCCompatibilityGetDIDShape(t *testing.T) {
+ ts, _, _, cleanup := newCompatibilityServer(t)
defer cleanup()
- state, ok, err := store.GetState("did:plc:alice")
+ resp, err := http.Get(ts.URL + "/did:plc:alice")
if err != nil {
- t.Fatalf("get state: %v", err)
+ t.Fatalf("get did: %v", err)
}
- if !ok {
- t.Fatalf("state not found")
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusOK {
+ t.Fatalf("status: got %d want 200", resp.StatusCode)
}
- resp, err := http.Get(ts.URL + "/did:plc:alice")
+ if got := resp.Header.Get("Content-Type"); !strings.Contains(got, "application/did+ld+json") {
+ t.Fatalf("content-type mismatch: %s", got)
+ }
+
+ var body map[string]any
+
+ if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
+ t.Fatalf("decode body: %v", err)
+ }
+
+ if _, ok := body["@context"].([]any); !ok {
+ t.Fatalf("missing or invalid @context: %#v", body["@context"])
+ }
+
+ if got, _ := body["id"].(string); got != "did:plc:alice" {
+ t.Fatalf("id mismatch: got %q want %q", got, "did:plc:alice")
+ }
+
+ if _, ok := body["authentication"]; ok {
+ t.Fatalf("unexpected authentication field in compatibility did document")
+ }
+}
+
+func TestPLCCompatibilityGetDataShape(t *testing.T) {
+ ts, _, _, cleanup := newCompatibilityServer(t)
+
+ defer cleanup()
+
+ resp, err := http.Get(ts.URL + "/did:plc:alice/data")
if err != nil {
- t.Fatalf("get did: %v", err)
+ t.Fatalf("get data: %v", err)
}
defer resp.Body.Close()
@@ -48,14 +78,34 @@ func TestPLCCompatibilityGetDIDMatchesStoredDocument(t *testing.T) {
t.Fatalf("status: got %d want 200", resp.StatusCode)
}
- if got := resp.Header.Get("Content-Type"); !strings.Contains(got, "application/did+ld+json") {
- t.Fatalf("content-type mismatch: %s", got)
+ var body map[string]any
+
+ if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
+ t.Fatalf("decode body: %v", err)
}
- body, _ := io.ReadAll(resp.Body)
+ required := []string{"did", "verificationMethods", "rotationKeys", "alsoKnownAs", "services"}
+
+ for _, key := range required {
+ if _, ok := body[key]; !ok {
+ t.Fatalf("missing key %q in /data response", key)
+ }
+ }
- if strings.TrimSpace(string(body)) != strings.TrimSpace(string(state.DIDDocument)) {
- t.Fatalf("did document mismatch\n got: %s\nwant: %s", string(body), string(state.DIDDocument))
+ if _, ok := body["verificationMethods"].(map[string]any); !ok {
+ t.Fatalf("verificationMethods has wrong type: %#v", body["verificationMethods"])
+ }
+
+ if _, ok := body["rotationKeys"].([]any); !ok {
+ t.Fatalf("rotationKeys has wrong type: %#v", body["rotationKeys"])
+ }
+
+ if _, ok := body["alsoKnownAs"].([]any); !ok {
+ t.Fatalf("alsoKnownAs has wrong type: %#v", body["alsoKnownAs"])
+ }
+
+ if _, ok := body["services"].(map[string]any); !ok {
+ t.Fatalf("services has wrong type: %#v", body["services"])
}
}
@@ -164,6 +214,20 @@ func TestPLCCompatibilityPostIsMethodNotAllowed(t *testing.T) {
if allow := resp.Header.Get("Allow"); allow != http.MethodGet {
t.Fatalf("allow header mismatch: got %q want %q", allow, http.MethodGet)
}
+
+ var body map[string]any
+
+ if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
+ t.Fatalf("decode body: %v", err)
+ }
+
+ if _, ok := body["message"].(string); !ok {
+ t.Fatalf("expected PLC-style message field, got: %v", body)
+ }
+
+ if _, ok := body["error"]; ok {
+ t.Fatalf("unexpected internal error field in compatibility response: %v", body)
+ }
}
func TestPLCCompatibilityNoVerificationMetadataLeak(t *testing.T) {
@@ -206,6 +270,38 @@ func TestPLCCompatibilityProofEndpointStillWorks(t *testing.T) {
}
}
+func TestPLCCompatibilityNotFoundUsesPLCErrorShape(t *testing.T) {
+ ts, _, _, cleanup := newCompatibilityServer(t)
+
+ defer cleanup()
+
+ resp, err := http.Get(ts.URL + "/did:plc:not-registered")
+
+ if err != nil {
+ t.Fatalf("get missing did: %v", err)
+ }
+
+ defer resp.Body.Close()
+
+ if resp.StatusCode != http.StatusNotFound {
+ t.Fatalf("status: got %d want 404", resp.StatusCode)
+ }
+
+ var body map[string]any
+
+ if err := json.NewDecoder(resp.Body).Decode(&body); err != nil {
+ t.Fatalf("decode body: %v", err)
+ }
+
+ if _, ok := body["message"].(string); !ok {
+ t.Fatalf("expected message field for 404, got: %v", body)
+ }
+
+ if _, ok := body["error"]; ok {
+ t.Fatalf("unexpected error field in compatibility 404 body: %v", body)
+ }
+}
+
func newCompatibilityServer(t *testing.T) (*httptest.Server, *storage.PebbleStore, []types.ExportRecord, func()) {
t.Helper()