101 lines
3.0 KiB
Go
101 lines
3.0 KiB
Go
package api
|
|
|
|
import (
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// #33 sweep: the create API must enforce the same expiry window as the UI
|
|
// (1 minute .. 1 year). Previously -1h, 0s, 1ns and 30000h were all accepted,
|
|
// producing pastes that were born expired or effectively permanent.
|
|
func TestCreatePasteExpiryBounds(t *testing.T) {
|
|
s := testServer(t)
|
|
h := s.routes()
|
|
|
|
cases := []struct {
|
|
expiresIn string
|
|
wantCode int
|
|
}{
|
|
{"-1h", 400},
|
|
{"-0s", 400},
|
|
{"0s", 400},
|
|
{"1ns", 400},
|
|
{"59s", 400},
|
|
{"1m", 201},
|
|
{"90s", 201},
|
|
{"8760h", 201}, // exactly 1 year
|
|
{"8785h", 400}, // 1 year + 1 day: over the max
|
|
{"30000h", 400}, // ~3.4 years, over the max
|
|
}
|
|
globalLimiter = newLimiter() // one fresh bucket for the whole table
|
|
for _, c := range cases {
|
|
globalLimiter = newLimiter() // avoid create rate limit between cases
|
|
req := httptest.NewRequest("POST", "/api/pastes",
|
|
strings.NewReader(`{"content":"x","expires_in":"`+c.expiresIn+`"}`))
|
|
rec := httptest.NewRecorder()
|
|
h.ServeHTTP(rec, req)
|
|
if rec.Code != c.wantCode {
|
|
t.Errorf("expires_in %q: got %d want %d (%s)",
|
|
c.expiresIn, rec.Code, c.wantCode, rec.Body.String())
|
|
}
|
|
}
|
|
}
|
|
|
|
// #33 sweep: HTML paste views must increment view_count. The increment was
|
|
// missing from handlePasteView, so the counter only moved on /raw.
|
|
func TestPasteViewIncrementsViewCount(t *testing.T) {
|
|
s := testServer(t)
|
|
h := s.routes()
|
|
|
|
req := httptest.NewRequest("POST", "/api/pastes", strings.NewReader(`{"content":"vc"}`))
|
|
rec := httptest.NewRecorder()
|
|
h.ServeHTTP(rec, req)
|
|
id := jsonField(t, rec.Body.String(), "id")
|
|
|
|
// first render counts (no ?created=1 here: that's the just-created banner case)
|
|
req = httptest.NewRequest("GET", "/"+id, nil)
|
|
rec = httptest.NewRecorder()
|
|
h.ServeHTTP(rec, req)
|
|
if rec.Code != 200 {
|
|
t.Fatalf("view: got %d", rec.Code)
|
|
}
|
|
req = httptest.NewRequest("GET", "/"+id, nil)
|
|
rec = httptest.NewRecorder()
|
|
h.ServeHTTP(rec, req)
|
|
|
|
req = httptest.NewRequest("GET", "/api/pastes/"+id, nil)
|
|
rec = httptest.NewRecorder()
|
|
h.ServeHTTP(rec, req)
|
|
if rec.Code != 200 {
|
|
t.Fatalf("api get: got %d", rec.Code)
|
|
}
|
|
body := rec.Body.String()
|
|
if !strings.Contains(body, `"view_count":2`) {
|
|
t.Fatalf("expected view_count 2 after two HTML views, got: %s", body)
|
|
}
|
|
}
|
|
|
|
// #33 sweep: the just-created banner render (?created=1) must NOT count as a
|
|
// view for the creator.
|
|
func TestJustCreatedViewDoesNotCount(t *testing.T) {
|
|
s := testServer(t)
|
|
h := s.routes()
|
|
|
|
req := httptest.NewRequest("POST", "/api/pastes", strings.NewReader(`{"content":"jc"}`))
|
|
rec := httptest.NewRecorder()
|
|
h.ServeHTTP(rec, req)
|
|
id := jsonField(t, rec.Body.String(), "id")
|
|
|
|
req = httptest.NewRequest("GET", "/"+id+"?created=1&token=t", nil)
|
|
rec = httptest.NewRecorder()
|
|
h.ServeHTTP(rec, req)
|
|
|
|
req = httptest.NewRequest("GET", "/api/pastes/"+id, nil)
|
|
rec = httptest.NewRecorder()
|
|
h.ServeHTTP(rec, req)
|
|
if strings.Contains(rec.Body.String(), `"view_count":1`) {
|
|
t.Fatalf("just-created render counted as a view: %s", rec.Body.String())
|
|
}
|
|
}
|