package server import ( "io" "net/http" "net/http/httptest" "net/url" "strings" "testing" ) // postForm posts an application/x-www-form-urlencoded body to the router. func postForm(router http.Handler, path string, form url.Values) *httptest.ResponseRecorder { req := httptest.NewRequest("POST", path, strings.NewReader(form.Encode())) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") w := httptest.NewRecorder() router.ServeHTTP(w, req) return w } func TestSubscriptionsPageRenders(t *testing.T) { srv, _, cleanup := setupTestServer(t) defer cleanup() req := httptest.NewRequest("GET", "/subscriptions", nil) w := httptest.NewRecorder() srv.Router().ServeHTTP(w, req) if w.Code != http.StatusOK { body, _ := io.ReadAll(w.Body) t.Fatalf("expected 200, got %d: %s", w.Code, body) } if !strings.Contains(w.Body.String(), "Create Subscription") { t.Error("subscriptions page missing create form") } } func TestCreateSubscriptionLifecycle(t *testing.T) { srv, _, cleanup := setupTestServer(t) defer cleanup() router := srv.Router() // Valid create redirects (303) and persists. w := postForm(router, "/subscriptions", url.Values{ "name": {"My Sub"}, "url": {"https://example.com/playlist"}, "output_dir": {"subscriptions/mine"}, "refresh_mode": {"overwrite"}, "schedule_kind": {"daily"}, }) if w.Code != http.StatusSeeOther { t.Fatalf("create: expected 303, got %d", w.Code) } // It now appears on the listing with its details. req := httptest.NewRequest("GET", "/subscriptions", nil) lw := httptest.NewRecorder() router.ServeHTTP(lw, req) body := lw.Body.String() for _, want := range []string{"My Sub", "subscriptions/mine", "Next run:"} { if !strings.Contains(body, want) { t.Errorf("listing missing %q", want) } } } func TestCreateSubscriptionValidation(t *testing.T) { srv, _, cleanup := setupTestServer(t) defer cleanup() router := srv.Router() // Missing output_dir is rejected. w := postForm(router, "/subscriptions", url.Values{ "url": {"https://example.com/x"}, "schedule_kind": {"daily"}, "output_dir": {""}, }) if w.Code != http.StatusBadRequest { t.Errorf("empty output_dir: expected 400, got %d", w.Code) } // Invalid custom cron is rejected. w = postForm(router, "/subscriptions", url.Values{ "url": {"https://example.com/x"}, "output_dir": {"foo"}, "schedule_kind": {"cron"}, "cron_expr": {"definitely not cron"}, }) if w.Code != http.StatusBadRequest { t.Errorf("bad cron: expected 400, got %d", w.Code) } }