113 lines
3.7 KiB
Go
113 lines
3.7 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/metazla/meta-core/internal/claim"
|
|
)
|
|
|
|
func newUDLTestServer(t *testing.T) *Server {
|
|
t.Helper()
|
|
return &Server{storage: newTestStorage(t)}
|
|
}
|
|
|
|
func udlGet(t *testing.T, s *Server, uid, cid, key string) UDLRecordResponse {
|
|
t.Helper()
|
|
req := httptest.NewRequest(http.MethodGet, "/api/udl/record?uid="+uid+"&cid="+cid+"&key="+key, nil)
|
|
rr := httptest.NewRecorder()
|
|
s.handleUDLRecordGet(rr, req)
|
|
if rr.Code != http.StatusOK {
|
|
t.Fatalf("GET record = %d %s", rr.Code, rr.Body)
|
|
}
|
|
var resp UDLRecordResponse
|
|
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return resp
|
|
}
|
|
|
|
func udlPutBatch(t *testing.T, s *Server, claims ...claim.Claim) UDLPutBatchResponse {
|
|
t.Helper()
|
|
body, _ := json.Marshal(UDLPutBatchRequest{Records: claims})
|
|
req := httptest.NewRequest(http.MethodPut, "/api/udl/records", strings.NewReader(string(body)))
|
|
rr := httptest.NewRecorder()
|
|
s.handleUDLRecordsPut(rr, req)
|
|
if rr.Code != http.StatusOK {
|
|
t.Fatalf("PUT records = %d %s", rr.Code, rr.Body)
|
|
}
|
|
var resp UDLPutBatchResponse
|
|
if err := json.Unmarshal(rr.Body.Bytes(), &resp); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return resp
|
|
}
|
|
|
|
// The facade stores and returns MMUR2 claims: public values in clear,
|
|
// private ones as ciphertext, tombstones with their ts.
|
|
func TestUDLFacadeRoundTrip(t *testing.T) {
|
|
s := newUDLTestServer(t)
|
|
me := testSigner(t, 7)
|
|
res := udlPutBatch(t, s,
|
|
signed(t, me, "self", "profile:name", "Ada Lovelace", 100),
|
|
signed(t, me, "bagcsaaa", "like", "true", 100),
|
|
signed(t, me, "bagcsaaa", "seek", []byte("ciphertext"), 100),
|
|
)
|
|
for _, r := range res.Results {
|
|
if !r.Accepted {
|
|
t.Fatalf("not accepted: %+v", r)
|
|
}
|
|
}
|
|
got := udlGet(t, s, me.UID, "self", "profile:name")
|
|
if !got.Exists || got.Claim == nil || got.Claim.Value.Text != "Ada Lovelace" || got.Claim.Verify() != nil {
|
|
t.Fatalf("profile = %+v", got)
|
|
}
|
|
if seek := udlGet(t, s, me.UID, "bagcsaaa", "seek"); seek.Claim == nil || seek.Claim.Value.Kind != claim.KindBytes {
|
|
t.Fatalf("seek = %+v", seek)
|
|
}
|
|
if miss := udlGet(t, s, me.UID, "bagcsaaa", "nope"); miss.Exists || miss.Claim != nil {
|
|
t.Fatalf("missing cell = %+v", miss)
|
|
}
|
|
|
|
// Retraction: stored, returned with its ts, no longer "exists".
|
|
udlPutBatch(t, s, signed(t, me, "bagcsaaa", "like", nil, 200))
|
|
if tomb := udlGet(t, s, me.UID, "bagcsaaa", "like"); tomb.Exists || tomb.Claim == nil || tomb.Claim.TS != 200 {
|
|
t.Fatalf("tombstone = %+v", tomb)
|
|
}
|
|
|
|
rr := httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodGet, "/api/udl/cid/self/aggregate?keys=profile:name", nil)
|
|
req = withVars(req, map[string]string{"cid": "self"})
|
|
s.handleUDLAggregate(rr, req)
|
|
if !strings.Contains(rr.Body.String(), `"sample_size":1`) {
|
|
t.Fatalf("aggregate = %s", rr.Body)
|
|
}
|
|
}
|
|
|
|
// A stale claim in a batch is reported in its slot without failing the rest.
|
|
func TestUDLRecordsPut_StaleSlotDoesNotFailTheBatch(t *testing.T) {
|
|
s := newUDLTestServer(t)
|
|
me := testSigner(t, 7)
|
|
udlPutBatch(t, s, signed(t, me, "bagcsaaa", "seen:s01e01", "true", 400))
|
|
res := udlPutBatch(t, s,
|
|
signed(t, me, "bagcsaaa", "seen:s01e01", "false", 300),
|
|
signed(t, me, "bagcsaaa", "seen:s01e02", "true", 300),
|
|
)
|
|
if res.Results[0].Accepted || res.Results[0].Status != "stale" || !res.Results[1].Accepted {
|
|
t.Fatalf("results = %+v", res.Results)
|
|
}
|
|
}
|
|
|
|
func TestUDLRecordsPut_RejectsEmptyBatch(t *testing.T) {
|
|
s := newUDLTestServer(t)
|
|
req := httptest.NewRequest(http.MethodPut, "/api/udl/records", strings.NewReader(`{"records":[]}`))
|
|
rr := httptest.NewRecorder()
|
|
s.handleUDLRecordsPut(rr, req)
|
|
if rr.Code != http.StatusBadRequest {
|
|
t.Fatalf("empty batch = %d", rr.Code)
|
|
}
|
|
}
|