package handlers import ( "encoding/json" "net/http" "net/http/httptest" "os" "path/filepath" "strings" "testing" ) func TestSetStaticCacheHeaders(t *testing.T) { tests := map[string]string{ "/static/css/00-base.css": "public, max-age=86400", "/static/js/00-utils.js": "public, max-age=86400", "/static/img/preview.webp": "public, max-age=31536000, immutable", "/static/fonts/ui.woff2": "public, max-age=31536000, immutable", "/static/videos/intro.mp4": "public, max-age=31536000, immutable", "/static/uploads/file.data": "public, max-age=3600", } for path, want := range tests { response := httptest.NewRecorder() setStaticCacheHeaders(response, path) if got := response.Header().Get("Cache-Control"); got != want { t.Fatalf("Cache-Control for %s = %q, want %q", path, got, want) } } } func TestHomeIncludesActiveUploadControls(t *testing.T) { app, cleanup := newTestApp(t) defer cleanup() request := httptest.NewRequest(http.MethodGet, "/", nil) response := httptest.NewRecorder() app.Home(response, request) if response.Code != http.StatusOK { t.Fatalf("status = %d, body = %s", response.Code, response.Body.String()) } for _, want := range []string{ `id="upload-active-actions"`, `id="cancel-upload"`, `id="pause-upload"`, `Cancel Upload`, `Pause Upload`, } { if !strings.Contains(response.Body.String(), want) { t.Fatalf("home page missing %q", want) } } } func TestWebManifestIncludesShareTarget(t *testing.T) { data, err := os.ReadFile(filepath.Join("..", "..", "static", "site.webmanifest")) if err != nil { t.Fatalf("ReadFile returned error: %v", err) } var manifest struct { ShareTarget struct { Action string `json:"action"` Method string `json:"method"` EncType string `json:"enctype"` Params struct { Title string `json:"title"` Text string `json:"text"` URL string `json:"url"` Files []struct { Name string `json:"name"` Accept []string `json:"accept"` } `json:"files"` } `json:"params"` } `json:"share_target"` } if err := json.Unmarshal(data, &manifest); err != nil { t.Fatalf("json.Unmarshal returned error: %v", err) } if manifest.ShareTarget.Action != "/share-target" || manifest.ShareTarget.Method != "POST" || manifest.ShareTarget.EncType != "multipart/form-data" { t.Fatalf("unexpected share_target config: %+v", manifest.ShareTarget) } if manifest.ShareTarget.Params.Title != "title" || manifest.ShareTarget.Params.Text != "text" || manifest.ShareTarget.Params.URL != "url" { t.Fatalf("unexpected share_target params: %+v", manifest.ShareTarget.Params) } if len(manifest.ShareTarget.Params.Files) != 1 || manifest.ShareTarget.Params.Files[0].Name != "files" || len(manifest.ShareTarget.Params.Files[0].Accept) != 1 || manifest.ShareTarget.Params.Files[0].Accept[0] != "*/*" { t.Fatalf("unexpected share_target files: %+v", manifest.ShareTarget.Params.Files) } } func TestServiceWorkerServedFromRootScope(t *testing.T) { app, cleanup := newTestApp(t) defer cleanup() request := httptest.NewRequest(http.MethodGet, "/service-worker.js", nil) response := httptest.NewRecorder() app.ServiceWorker(response, request) if response.Code != http.StatusOK { t.Fatalf("status = %d, body = %s", response.Code, response.Body.String()) } if got := response.Header().Get("Service-Worker-Allowed"); got != "/" { t.Fatalf("Service-Worker-Allowed = %q, want /", got) } if got := response.Header().Get("Content-Type"); got != "text/javascript; charset=utf-8" { t.Fatalf("Content-Type = %q", got) } if response.Body.Len() == 0 { t.Fatalf("service worker body missing") } } func TestShareTargetFallbackRedirectsHome(t *testing.T) { app, cleanup := newTestApp(t) defer cleanup() request := httptest.NewRequest(http.MethodPost, "/share-target", nil) response := httptest.NewRecorder() app.ShareTargetFallback(response, request) if response.Code != http.StatusSeeOther { t.Fatalf("status = %d, want %d", response.Code, http.StatusSeeOther) } if got := response.Header().Get("Location"); got != "/?share-target=unsupported" { t.Fatalf("Location = %q", got) } }