@@ -0,0 +1,121 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"palette/internal/store"
|
||||
)
|
||||
|
||||
// #95: HTML paste views dedupe per viewer (vwr cookie) within the burn viewer
|
||||
// window, reusing the paste_views table. Repeated views by the same viewer do
|
||||
// not inflate view_count; a different viewer counts.
|
||||
func TestHTMLViewsDedupedPerViewer(t *testing.T) {
|
||||
s := testServer(t)
|
||||
h := s.routes()
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/pastes", strings.NewReader(`{"content":"vd"}`))
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeHTTP(rec, req)
|
||||
id := jsonField(t, rec.Body.String(), "id")
|
||||
|
||||
view := func(vwr string) {
|
||||
req := httptest.NewRequest("GET", "/"+id, nil)
|
||||
if vwr != "" {
|
||||
req.AddCookie(&http.Cookie{Name: "vwr", Value: vwr})
|
||||
}
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeHTTP(rec, req)
|
||||
if rec.Code != 200 {
|
||||
t.Fatalf("view: got %d", rec.Code)
|
||||
}
|
||||
}
|
||||
count := func() string {
|
||||
req := httptest.NewRequest("GET", "/api/pastes/"+id, nil)
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeHTTP(rec, req)
|
||||
return rec.Body.String()
|
||||
}
|
||||
|
||||
// same viewer (same cookie) renders twice: still 1 view
|
||||
view("v-a")
|
||||
view("v-a")
|
||||
if got := count(); !strings.Contains(got, `"view_count":1`) {
|
||||
t.Fatalf("expected view_count 1 after duplicate viewer views, got: %s", got)
|
||||
}
|
||||
// a different viewer counts
|
||||
view("v-b")
|
||||
if got := count(); !strings.Contains(got, `"view_count":2`) {
|
||||
t.Fatalf("expected view_count 2 after second viewer, got: %s", got)
|
||||
}
|
||||
// viewer without cookie counts every time (plain API clients, #49 decision)
|
||||
view("")
|
||||
view("")
|
||||
if got := count(); !strings.Contains(got, `"view_count":4`) {
|
||||
t.Fatalf("expected view_count 4 after uncoookied views, got: %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
// #95: raw views always count, even from a cookie-holding viewer (#49 decision).
|
||||
func TestRawViewsAlwaysCount(t *testing.T) {
|
||||
s := testServer(t)
|
||||
h := s.routes()
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/pastes", strings.NewReader(`{"content":"rv"}`))
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeHTTP(rec, req)
|
||||
id := jsonField(t, rec.Body.String(), "id")
|
||||
|
||||
for i := 0; i < 3; i++ {
|
||||
req := httptest.NewRequest("GET", "/raw/"+id, nil)
|
||||
req.AddCookie(&http.Cookie{Name: "vwr", Value: "same-viewer"})
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeHTTP(rec, req)
|
||||
if rec.Code != 200 {
|
||||
t.Fatalf("raw view: got %d", rec.Code)
|
||||
}
|
||||
}
|
||||
req = httptest.NewRequest("GET", "/api/pastes/"+id, nil)
|
||||
rec = httptest.NewRecorder()
|
||||
h.ServeHTTP(rec, req)
|
||||
if got := rec.Body.String(); !strings.Contains(got, `"view_count":3`) {
|
||||
t.Fatalf("expected view_count 3 after 3 raw views by one viewer, got: %s", got)
|
||||
}
|
||||
}
|
||||
|
||||
// #95: after the dedupe window passes, the same viewer counts again.
|
||||
func TestViewDedupeWindowExpires(t *testing.T) {
|
||||
s := testServer(t)
|
||||
h := s.routes()
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/pastes", strings.NewReader(`{"content":"we"}`))
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeHTTP(rec, req)
|
||||
id := jsonField(t, rec.Body.String(), "id")
|
||||
|
||||
view := func() {
|
||||
req := httptest.NewRequest("GET", "/"+id, nil)
|
||||
req.AddCookie(&http.Cookie{Name: "vwr", Value: "v-w"})
|
||||
rec := httptest.NewRecorder()
|
||||
h.ServeHTTP(rec, req)
|
||||
if rec.Code != 200 {
|
||||
t.Fatalf("view: got %d", rec.Code)
|
||||
}
|
||||
}
|
||||
view()
|
||||
view()
|
||||
// jump past the 15-minute window
|
||||
realNow := store.TimeNow
|
||||
store.TimeNow = func() time.Time { return realNow().Add(16 * time.Minute) }
|
||||
defer func() { store.TimeNow = realNow }()
|
||||
view()
|
||||
req = httptest.NewRequest("GET", "/api/pastes/"+id, nil)
|
||||
rec = httptest.NewRecorder()
|
||||
h.ServeHTTP(rec, req)
|
||||
if got := rec.Body.String(); !strings.Contains(got, `"view_count":2`) {
|
||||
t.Fatalf("expected view_count 2 after window expiry, got: %s", got)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user