marky

Lightweight bookmarking + plaintext archive
Log | Files | Refs | README | LICENSE

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 }