Merge minor fixes: #92-#98, #100 theme switcher + cans work
This commit is contained in:
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
package web
|
||||||
|
|
||||||
|
// Version is the display version, set at build time via
|
||||||
|
// -ldflags "-X palette/internal/web.Version=v0.2.1" (#93). Falls back to
|
||||||
|
// "dev" for bare `go build` runs.
|
||||||
|
var Version = "dev"
|
||||||
Reference in New Issue
Block a user