116 lines
3.2 KiB
Go
116 lines
3.2 KiB
Go
package api
|
|
|
|
import (
|
|
"palette/internal/store"
|
|
"palette/internal/web"
|
|
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// doReq performs a request against the router, carrying the given cookies,
|
|
// and returns the recorder (so Set-Cookie from the viewer middleware is visible).
|
|
func doReq(t *testing.T, h http.Handler, method, path, cookie string, body string) *httptest.ResponseRecorder {
|
|
t.Helper()
|
|
req := httptest.NewRequest(method, path, strings.NewReader(body))
|
|
if body != "" {
|
|
req.Header.Set("Content-Type", "application/json")
|
|
}
|
|
if cookie != "" {
|
|
req.AddCookie(&http.Cookie{Name: "vwr", Value: cookie})
|
|
}
|
|
rec := httptest.NewRecorder()
|
|
h.ServeHTTP(rec, req)
|
|
return rec
|
|
}
|
|
|
|
// viewerCookieFor performs a request without the vwr cookie and extracts the
|
|
// one the viewer middleware sets in the response.
|
|
func viewerCookieFor(t *testing.T, h http.Handler, path string) string {
|
|
t.Helper()
|
|
rec := doReq(t, h, "GET", path, "", "")
|
|
for _, c := range rec.Result().Cookies() {
|
|
if c.Name == "vwr" {
|
|
return c.Value
|
|
}
|
|
}
|
|
t.Fatal("vwr cookie not set")
|
|
return ""
|
|
}
|
|
|
|
func TestMineCreateListDelete(t *testing.T) {
|
|
globalLimiter = newLimiter() // fresh rate-limit buckets
|
|
st, err := store.OpenStore(":memory:")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ui, err := web.New()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
cfg := Config{MaxTextBytes: 5 * 1024 * 1024}
|
|
ss := NewTestSettingsStore(t, cfg)
|
|
globalSettingsFn = ss.get
|
|
t.Cleanup(func() { globalSettingsFn = nil })
|
|
a := &apiServer{store: st, cfg: cfg, ui: ui, settings: ss, adminKey: "test-admin-key"}
|
|
h := a.routes()
|
|
|
|
alice := viewerCookieFor(t, h, "/public")
|
|
if alice == "" {
|
|
t.Fatal("no viewer cookie issued")
|
|
}
|
|
|
|
// create with alice's cookie -> stored viewer id
|
|
rec := doReq(t, h, "POST", "/api/pastes", alice, `{"content":"hello mine"}`)
|
|
if rec.Code != 201 {
|
|
t.Fatalf("create: %d %s", rec.Code, rec.Body.String())
|
|
}
|
|
var created struct{ ID string }
|
|
json.Unmarshal(rec.Body.Bytes(), &created)
|
|
if created.ID == "" {
|
|
t.Fatal("no id returned")
|
|
}
|
|
|
|
// owner sees it in /api/mine
|
|
rec = doReq(t, h, "GET", "/api/mine", alice, "")
|
|
if rec.Code != 200 {
|
|
t.Fatalf("mine: %d", rec.Code)
|
|
}
|
|
var list struct {
|
|
Total int `json:"total"`
|
|
Items []struct{ ID string `json:"id"` } `json:"items"`
|
|
}
|
|
json.Unmarshal(rec.Body.Bytes(), &list)
|
|
if list.Total != 1 || len(list.Items) != 1 || list.Items[0].ID != created.ID {
|
|
t.Fatalf("mine list: total=%d items=%v", list.Total, list.Items)
|
|
}
|
|
|
|
// a different browser's cookie does NOT see it
|
|
bob := viewerCookieFor(t, h, "/public")
|
|
rec = doReq(t, h, "GET", "/api/mine", bob, "")
|
|
json.Unmarshal(rec.Body.Bytes(), &list)
|
|
if list.Total != 0 {
|
|
t.Fatalf("other browser sees %d pastes, want 0", list.Total)
|
|
}
|
|
|
|
// delete enforcement: bob cannot delete alice's paste
|
|
rec = doReq(t, h, "DELETE", "/api/pastes/"+created.ID, bob, "")
|
|
if rec.Code != 403 {
|
|
t.Fatalf("bob delete: %d, want 403", rec.Code)
|
|
}
|
|
|
|
// owner can delete
|
|
rec = doReq(t, h, "DELETE", "/api/pastes/"+created.ID, alice, "")
|
|
if rec.Code != 200 {
|
|
t.Fatalf("alice delete: %d", rec.Code)
|
|
}
|
|
rec = doReq(t, h, "GET", "/api/mine", alice, "")
|
|
json.Unmarshal(rec.Body.Bytes(), &list)
|
|
if list.Total != 0 {
|
|
t.Fatalf("after delete, mine total=%d, want 0", list.Total)
|
|
}
|
|
}
|