archiver_test.go (1730B)
1 package internal 2 3 import ( 4 "context" 5 "net/http" 6 "net/http/httptest" 7 "testing" 8 ) 9 10 func TestTitleAndText(t *testing.T) { 11 t.Parallel() 12 mux := http.NewServeMux() 13 mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { 14 w.Header().Set("Content-Type", "text/html") 15 _, _ = w.Write([]byte(`<!doctype html><html><head><title>Test Page</title></head><body><p>Hello <a href="https://example.org">there</a>!</p></body></html>`)) 16 }) 17 srv := httptest.NewServer(mux) 18 defer srv.Close() 19 20 title, txt, err := TitleAndText(context.Background(), srv.URL) 21 if err != nil { 22 t.Fatalf("TitleAndText: %v", err) 23 } 24 if title != "Test Page" { 25 t.Fatalf("expected title 'Test Page', got %q", title) 26 } 27 if want := "Hello"; txt == "" || !containsFold(txt, want) { 28 t.Fatalf("expected text to contain %q, got: %q", want, txt) 29 } 30 } 31 32 func TestIsHTMLURL_ErrorHEADResponseIsInconclusive(t *testing.T) { 33 t.Parallel() 34 35 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 36 if r.Method == http.MethodHead { 37 w.Header().Set("Content-Type", "text/plain") 38 w.WriteHeader(http.StatusForbidden) 39 return 40 } 41 t.Fatalf("unexpected %s request", r.Method) 42 })) 43 defer srv.Close() 44 45 if !IsHTMLURL(t.Context(), srv.URL) { 46 t.Fatal("expected a failed HEAD request to be treated as inconclusive") 47 } 48 } 49 50 func containsFold(s, sub string) bool { 51 return len(s) >= len(sub) && (stringFold(s, sub) || containsFold(s[1:], sub)) 52 } 53 54 func stringFold(s, sub string) bool { 55 if len(sub) > len(s) { 56 return false 57 } 58 for i := 0; i < len(sub); i++ { 59 a, b := s[i], sub[i] 60 if 'A' <= a && a <= 'Z' { 61 a = a + 32 62 } 63 if 'A' <= b && b <= 'Z' { 64 b = b + 32 65 } 66 if a != b { 67 return false 68 } 69 } 70 return true 71 }