Files
palette/customslug_test.go
T
poslop 3facff3d1e
CI / test (push) Successful in 19s
CI / docker (push) Skipped
Syntax highlighting, rate limiting, creator auto-unlock (#1, #2, #26)
#1: server-side regex highlighter (highlight.go) for go/python/js/json/bash/sql;
token span classes styled in app.css; per-line so gutter stays aligned.
#2: in-memory token-bucket rate limiter (ratelimit.go) on POST /api/pastes,
/api/guess-language and unlock POST; 429 + Retry-After + X-RateLimit headers.
#26: new-page JS POSTs the password to /{id} with ?next= after creation; the
unlock handler honors same-origin ?next= redirect so the creator lands on the
unlocked paste. POST /{id} route added.

Tests: ratelimit_test.go (burst/429, refill, unlock limit, highlight, auto-
unlock e2e); existing tests updated for per-test limiter isolation.
2026-09-08 21:09:25 -05:00

72 lines
2.0 KiB
Go

package main
import (
"encoding/json"
"net/http/httptest"
"strings"
"testing"
)
func TestCustomSlugCreateAndFetch(t *testing.T) {
s := testServer(t)
h := s.routes()
req := httptest.NewRequest("POST", "/api/pastes", strings.NewReader(`{"content":"x","custom_slug":"release-notes"}`))
rec := httptest.NewRecorder()
h.ServeHTTP(rec, req)
if rec.Code != 201 {
t.Fatalf("create: %d %s", rec.Code, rec.Body.String())
}
// fetch by custom slug
req = httptest.NewRequest("GET", "/api/pastes/release-notes", nil)
rec = httptest.NewRecorder()
h.ServeHTTP(rec, req)
if rec.Code != 200 {
t.Fatalf("fetch by slug: %d", rec.Code)
}
var got map[string]any
json.Unmarshal(rec.Body.Bytes(), &got)
if got["content"] != "x" {
t.Fatal("content mismatch via custom slug")
}
}
func TestCustomSlugValidation(t *testing.T) {
s := testServer(t)
h := s.routes()
cases := []struct {
slug, body string
wantCode int
}{
{"dup", `{"content":"first","custom_slug":"dup"}`, 201},
{"dup", `{"content":"second","custom_slug":"dup"}`, 400},
{"api", `{"content":"x","custom_slug":"api"}`, 400},
{"raw", `{"content":"x","custom_slug":"raw"}`, 400},
{"bad slug", `{"content":"x","custom_slug":"has space"}`, 400},
{"", `{"content":"x","custom_slug":""}`, 201}, // empty = no custom slug, fine
}
for i, c := range cases {
req := httptest.NewRequest("POST", "/api/pastes", strings.NewReader(c.body))
req.RemoteAddr = "10.7.1." + string(rune('1'+i)) + ":1000" // avoid rate-limit bucket sharing
rec := httptest.NewRecorder()
h.ServeHTTP(rec, req)
if rec.Code != c.wantCode {
t.Fatalf("slug %q: got %d want %d: %s", c.slug, rec.Code, c.wantCode, rec.Body.String())
}
}
}
func TestSlugCollisionWithAutoID(t *testing.T) {
s := testServer(t)
// manually insert a paste, then try to claim its auto ID as a custom slug
p, err := s.store.CreatePaste(&Paste{Content: "auto"})
if err != nil {
t.Fatal(err)
}
if taken, _ := s.store.SlugTaken(p.ID); !taken {
t.Fatal("auto id should be claimed")
}
}