carlos / platform Public

domainclaim: add JSON schema validation test; soften ListForApp doc

Add assertion to TestGetRoundTripsAndKeyShape that validates the on-disk
JSON keys to catch struct tag typos. Update ListForApp doc comment to
accurately reflect that ANY Get error (not just parse errors) skips claims.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Paul Campbell 0f1c79ccf28fccdbf9bb209ffc260e3ba3c3178c parent f9a8fec
2 files changed, +37 −2
  • internal/domainclaim/domainclaim.go +3 −2
  • internal/domainclaim/domainclaim_test.go +34 −0
diff --git a/internal/domainclaim/domainclaim.go b/internal/domainclaim/domainclaim.go
index b0987ad13..6127510f4 100644
--- a/internal/domainclaim/domainclaim.go
+++ b/internal/domainclaim/domainclaim.go
@@ -70,8 +70,9 @@ func Delete(ctx context.Context, s release.Store, host string) error {
}
// ListForApp returns the claims held by one account+app pair. Claims that
-// fail to parse are skipped: a malformed claim is #151's reconciler's
-// problem to surface, not a reason to blank an app's Settings list.
+// cannot be read or parsed are skipped: a malformed or unreachable claim is
+// #151's reconciler's problem to surface, not a reason to blank an app's
+// Settings list.
func ListForApp(ctx context.Context, s release.Store, account, app string) ([]Claim, error) {
keys, err := s.List(ctx, prefix)
if err != nil {
diff --git a/internal/domainclaim/domainclaim_test.go b/internal/domainclaim/domainclaim_test.go
index ca890d286..37f404cbe 100644
--- a/internal/domainclaim/domainclaim_test.go
+++ b/internal/domainclaim/domainclaim_test.go
@@ -3,7 +3,9 @@ package domainclaim
import (
"context"
+ "encoding/json"
"errors"
+ "sort"
"testing"
"time"
@@ -40,6 +42,38 @@ func TestGetRoundTripsAndKeyShape(t *testing.T) {
if out != in {
t.Fatalf("round trip: got %+v want %+v", out, in)
}
+
+ // Verify JSON schema: assert that the on-disk bytes have exactly the expected keys
+ // to catch typos in struct tags (e.g. "account" → "accnt").
+ rawBody, _, err := s.Get(ctx, Key("example.com"))
+ if err != nil {
+ t.Fatalf("raw Get: %v", err)
+ }
+ var m map[string]any
+ if err := json.Unmarshal(rawBody, &m); err != nil {
+ t.Fatalf("unmarshal: %v", err)
+ }
+ gotKeys := make([]string, 0, len(m))
+ for k := range m {
+ gotKeys = append(gotKeys, k)
+ }
+ sort.Strings(gotKeys)
+ wantKeys := []string{"account", "app", "created_at", "host", "route", "schema"}
+ if !equal(gotKeys, wantKeys) {
+ t.Fatalf("JSON keys: got %v, want %v", gotKeys, wantKeys)
+ }
+}
+
+func equal(a, b []string) bool {
+ if len(a) != len(b) {
+ return false
+ }
+ for i := range a {
+ if a[i] != b[i] {
+ return false
+ }
+ }
+ return true
}
func TestListForAppFiltersOtherOwners(t *testing.T) {