mirror of
https://github.com/MeshTender/MeshTender.git
synced 2026-09-02 10:03:43 +00:00
57 lines
1.5 KiB
Go
57 lines
1.5 KiB
Go
package web
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
type testCursor struct {
|
|
Name string `json:"n"`
|
|
ID int64 `json:"i"`
|
|
At time.Time `json:"t"`
|
|
}
|
|
|
|
func TestCursorRoundTrip(t *testing.T) {
|
|
want := testCursor{Name: "repeater-alpha", ID: 42, At: time.Unix(1_700_000_000, 0).UTC()}
|
|
got, ok := DecodeCursor[testCursor](EncodeCursor(want))
|
|
if !ok {
|
|
t.Fatal("DecodeCursor: ok=false for a token we just encoded")
|
|
}
|
|
if got.Name != want.Name || got.ID != want.ID || !got.At.Equal(want.At) {
|
|
t.Fatalf("round trip mismatch: got %+v want %+v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestCursorTokenIsURLSafe(t *testing.T) {
|
|
// RawURLEncoding must not emit '+', '/', or '=' — the token rides in a query
|
|
// parameter unescaped.
|
|
tok := EncodeCursor(testCursor{Name: "a/b+c==", ID: 1})
|
|
for _, r := range tok {
|
|
switch r {
|
|
case '+', '/', '=':
|
|
t.Fatalf("token %q contains non-URL-safe rune %q", tok, r)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestDecodeCursorRejectsBadInput(t *testing.T) {
|
|
// A missing, malformed-base64, or malformed-JSON token must reset to the zero
|
|
// value with ok=false so a tampered URL just pages from the start.
|
|
cases := map[string]string{
|
|
"empty": "",
|
|
"not base64": "!!!not base64!!!",
|
|
"base64 non-json": EncodeCursor([]byte("plain string, not this struct's JSON")),
|
|
}
|
|
for name, tok := range cases {
|
|
t.Run(name, func(t *testing.T) {
|
|
got, ok := DecodeCursor[testCursor](tok)
|
|
if ok {
|
|
t.Fatalf("ok=true for %s input %q", name, tok)
|
|
}
|
|
if got != (testCursor{}) {
|
|
t.Fatalf("non-zero cursor %+v for %s input", got, name)
|
|
}
|
|
})
|
|
}
|
|
}
|