marky

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

non_html_archive_test.go (2957B)


      1 package internal
      2 
      3 import (
      4 	"net/http"
      5 	"net/http/cookiejar"
      6 	"net/http/httptest"
      7 	"testing"
      8 )
      9 
     10 // Ensure that non-HTML URLs (e.g., PDFs) do not create archives and listings
     11 // show has_archive=false. Also verify archive endpoint returns 404 even with fetch=1.
     12 func TestNonHTML_NoArchiveAndNoLink(t *testing.T) {
     13 	t.Parallel()
     14 
     15 	// Content server that reports application/pdf for HEAD.
     16 	pdf := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
     17 		w.Header().Set("Content-Type", "application/pdf")
     18 		// No body needed.
     19 		if r.Method == http.MethodHead {
     20 			w.WriteHeader(http.StatusOK)
     21 			return
     22 		}
     23 		w.WriteHeader(http.StatusOK)
     24 	}))
     25 	defer pdf.Close()
     26 
     27 	// API server
     28 	db, err := OpenAtPath(t.Context(), t.TempDir()+"/nonhtml.db")
     29 	if err != nil {
     30 		t.Fatalf("open db: %v", err)
     31 	}
     32 	t.Cleanup(func() { _ = db.Close() })
     33 	h, err := NewHandler(db)
     34 	if err != nil {
     35 		t.Fatalf("handler: %v", err)
     36 	}
     37 	srv := httptest.NewServer(h)
     38 	defer srv.Close()
     39 
     40 	// Auth: sign up and retain cookie
     41 	jar, _ := cookiejar.New(nil)
     42 	client := &http.Client{Jar: jar}
     43 	signupPayload := map[string]string{"username": "pdfuser", "password": "pw"}
     44 	_ = postJSONWithClient[map[string]any](t, client, srv.URL+"/signup", signupPayload, 200)
     45 
     46 	// Create a public bookmark pointing to the PDF URL
     47 	body := map[string]any{"url": pdf.URL + "/doc.pdf", "public": true}
     48 	b := postJSONWithClient[map[string]any](t, client, srv.URL+"/bookmarks", body, 201)
     49 	idFloat, _ := b["id"].(float64)
     50 	if idFloat <= 0 {
     51 		t.Fatalf("expected id > 0, got %v", idFloat)
     52 	}
     53 	if ha, ok := b["has_archive"].(bool); !ok || ha {
     54 		t.Fatalf("expected has_archive=false at creation, got %v", b["has_archive"])
     55 	}
     56 
     57 	// DB must report no archive
     58 	has, err := db.HasArchive(t.Context(), int64(idFloat))
     59 	if err != nil {
     60 		t.Fatalf("has archive: %v", err)
     61 	}
     62 	if has {
     63 		t.Fatalf("expected no archive row for non-HTML URL")
     64 	}
     65 
     66 	// Logged-in listing includes has_archive=false
     67 	list := getJSONWithClient[[]map[string]any](t, client, srv.URL+"/bookmarks", 200)
     68 	if len(list) != 1 {
     69 		t.Fatalf("expected 1 bookmark, got %d", len(list))
     70 	}
     71 	if ha, ok := list[0]["has_archive"].(bool); !ok || ha {
     72 		t.Fatalf("expected has_archive=false in listing, got %v", list[0]["has_archive"])
     73 	}
     74 
     75 	// Public listing for user via JSON feed under /u:{username}.json shows same
     76 	pub := getJSONWithClient[[]map[string]any](t, client, srv.URL+"/u:pdfuser.json", 200)
     77 	if len(pub) != 1 {
     78 		t.Fatalf("expected 1 public bookmark, got %d", len(pub))
     79 	}
     80 	if ha, ok := pub[0]["has_archive"].(bool); !ok || ha {
     81 		t.Fatalf("expected has_archive=false in public listing, got %v", pub[0]["has_archive"])
     82 	}
     83 
     84 	// Archive endpoint returns 404, even with fetch=1 as owner
     85 	arch := getWithClient(t, client, srv.URL+"/bookmarks/"+itoa(int(idFloat))+"/archive", 404)
     86 	_ = arch.Body.Close()
     87 
     88 	arch2 := getWithClient(t, client, srv.URL+"/bookmarks/"+itoa(int(idFloat))+"/archive?fetch=1", 404)
     89 	_ = arch2.Body.Close()
     90 }