package api // #83 regression tests: `public` boolean in the create payload must map to // visibility (false -> unlisted, true -> public); string `visibility` still works. import ( "encoding/json" "net/http/httptest" "strings" "testing" ) func createPasteBody(t *testing.T, h *apiServer, body string) map[string]any { req := httptest.NewRequest("POST", "/api/pastes", strings.NewReader(body)) rec := httptest.NewRecorder() h.routes().ServeHTTP(rec, req) if rec.Code != 201 { t.Fatalf("create: got %d: %s", rec.Code, rec.Body.String()) } var resp map[string]any if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil { t.Fatalf("bad json: %v", err) } return resp } func getVis(t *testing.T, h *apiServer, id string) string { req := httptest.NewRequest("GET", "/api/pastes/"+id, nil) rec := httptest.NewRecorder() h.routes().ServeHTTP(rec, req) if rec.Code != 200 { t.Fatalf("get %s: got %d", id, rec.Code) } var resp struct { Visibility string `json:"visibility"` } if err := json.Unmarshal(rec.Body.Bytes(), &resp); err != nil { t.Fatalf("bad json: %v", err) } return resp.Visibility } // TestPublicBooleanFalseMapsToUnlisted: {"public": false} must create an unlisted paste. func TestPublicBooleanFalseMapsToUnlisted(t *testing.T) { s := testServer(t) resp := createPasteBody(t, s, `{"content":"x","public":false}`) if v := getVis(t, s, resp["id"].(string)); v != "unlisted" { t.Fatalf("public:false -> got visibility %q, want unlisted", v) } } // TestPublicBooleanTrueMapsToPublic: {"public": true} must create a public paste. func TestPublicBooleanTrueMapsToPublic(t *testing.T) { s := testServer(t) resp := createPasteBody(t, s, `{"content":"x","public":true}`) if v := getVis(t, s, resp["id"].(string)); v != "public" { t.Fatalf("public:true -> got visibility %q, want public", v) } } // TestPublicBooleanOverridesString: boolean wins when both fields are sent. func TestPublicBooleanOverridesString(t *testing.T) { s := testServer(t) resp := createPasteBody(t, s, `{"content":"x","visibility":"public","public":false}`) if v := getVis(t, s, resp["id"].(string)); v != "unlisted" { t.Fatalf("boolean override -> got %q, want unlisted", v) } } // TestVisibilityStringStillWorks: existing string contract unchanged. func TestVisibilityStringStillWorks(t *testing.T) { s := testServer(t) resp := createPasteBody(t, s, `{"content":"x","visibility":"unlisted"}`) if v := getVis(t, s, resp["id"].(string)); v != "unlisted" { t.Fatalf("string field -> got %q, want unlisted", v) } resp = createPasteBody(t, s, `{"content":"y","visibility":"public"}`) if v := getVis(t, s, resp["id"].(string)); v != "public" { t.Fatalf("string field -> got %q, want public", v) } } // TestPublicListExcludesPublicFalse: {"public":false} pastes stay out of /api/public. func TestPublicListExcludesPublicFalse(t *testing.T) { s := testServer(t) createPasteBody(t, s, `{"content":"hidden","public":false}`) req := httptest.NewRequest("GET", "/api/public", nil) rec := httptest.NewRecorder() s.routes().ServeHTTP(rec, req) var resp struct { Total int `json:"total"` } json.Unmarshal(rec.Body.Bytes(), &resp) if resp.Total != 0 { t.Fatalf("public:false paste leaked into /api/public: total=%d", resp.Total) } }