package server import ( "bytes" "encoding/json" "io" "log/slog" "net/http" "net/http/httptest" "path/filepath" "testing" "github.com/wzray/dns/internal/resolv" ) func newTestServer(t *testing.T) (*Server, string) { t.Helper() path := filepath.Join(t.TempDir(), "resolv.conf") mgr := resolv.New(path) log := slog.New(slog.NewTextHandler(io.Discard, nil)) return New(mgr, log), path } func do(t *testing.T, h http.Handler, method, target string, body any) *httptest.ResponseRecorder { t.Helper() var rdr io.Reader if body != nil { b, err := json.Marshal(body) if err != nil { t.Fatalf("marshal: %v", err) } rdr = bytes.NewReader(b) } req := httptest.NewRequest(method, target, rdr) rec := httptest.NewRecorder() h.ServeHTTP(rec, req) return rec } func TestServer_AddListRemove(t *testing.T) { s, _ := newTestServer(t) h := s.Handler() rec := do(t, h, "GET", "/dns", nil) if rec.Code != http.StatusOK { t.Fatalf("list: status %d", rec.Code) } var lr listResponse if err := json.Unmarshal(rec.Body.Bytes(), &lr); err != nil { t.Fatalf("decode: %v", err) } if len(lr.Servers) != 0 { t.Fatalf("want empty, got %v", lr.Servers) } rec = do(t, h, "POST", "/dns", addRequest{Address: "1.1.1.1"}) if rec.Code != http.StatusCreated { t.Fatalf("add: status %d body %s", rec.Code, rec.Body.String()) } rec = do(t, h, "POST", "/dns", addRequest{Address: "1.1.1.1"}) if rec.Code != http.StatusConflict { t.Fatalf("dup: status %d", rec.Code) } rec = do(t, h, "POST", "/dns", addRequest{Address: "not-an-ip"}) if rec.Code != http.StatusBadRequest { t.Fatalf("invalid: status %d", rec.Code) } rec = do(t, h, "DELETE", "/dns/1.1.1.1", nil) if rec.Code != http.StatusNoContent { t.Fatalf("remove: status %d", rec.Code) } rec = do(t, h, "DELETE", "/dns/1.1.1.1", nil) if rec.Code != http.StatusNotFound { t.Fatalf("remove missing: status %d", rec.Code) } } func TestServer_BadJSON(t *testing.T) { s, _ := newTestServer(t) h := s.Handler() req := httptest.NewRequest("POST", "/dns", bytes.NewReader([]byte("{not json"))) rec := httptest.NewRecorder() h.ServeHTTP(rec, req) if rec.Code != http.StatusBadRequest { t.Fatalf("status %d", rec.Code) } } func TestServer_HealthAndUnknownRoute(t *testing.T) { s, _ := newTestServer(t) h := s.Handler() if rec := do(t, h, "GET", "/health", nil); rec.Code != http.StatusOK { t.Fatalf("health status %d", rec.Code) } if rec := do(t, h, "GET", "/unknown", nil); rec.Code != http.StatusNotFound { t.Fatalf("unknown route status %d", rec.Code) } }