diff --git a/cmd/server/tests/contract_pins_test.go b/cmd/server/tests/contract_pins_test.go index e839aa37..83732b81 100644 --- a/cmd/server/tests/contract_pins_test.go +++ b/cmd/server/tests/contract_pins_test.go @@ -1214,6 +1214,30 @@ func pinAnnotationLifecycle(t *testing.T, setup *TestServerSetup, fx contractFix require.NoError(t, json.Unmarshal(raw, &body2)) assertResponseShape(t, "annotation "+kind+" update", body2, rowKeys, rowKeys) + // The restore half of the round trip: what the reader fetches + // when the book is reopened must return the persisted annotation + // with the update applied — written to the DB, read back through + // the same list endpoint the UI loads on open. + t.Run(kind+" GET list restores the annotation", func(t *testing.T) { + resp3 := doReq(t, "GET", annotationURL(setup.Server.URL, fx.itemID, kind, ""), nil, setup.RegularToken) + defer resp3.Body.Close() + require.Equal(t, http.StatusOK, resp3.StatusCode, "list must stay 200") + var list []map[string]interface{} + require.NoError(t, json.NewDecoder(resp3.Body).Decode(&list)) + var found map[string]interface{} + for _, row := range list { + if row["id"] == id { + found = row + break + } + } + require.NotNil(t, found, "created %s must come back in the list that restores a reopened book", kind) + updates, _ := updateBody.(map[string]interface{}) + for key, want := range updates { + assert.Equal(t, want, found[key], "%s field must round-trip from the DB on restore", key) + } + }) + t.Run(kind+" DELETE response", func(t *testing.T) { resp3 := doReq(t, "DELETE", annotationURL(setup.Server.URL, fx.itemID, kind, id), nil, setup.RegularToken) defer resp3.Body.Close()