package main import ( "context" "net/http" "net/http/httptest" "net/url" "os" "path/filepath" "strings" "testing" ) func TestGenerateSlug(t *testing.T) { tests := []struct { name string input string expected string }{ {"Normal title", "The Ultimate Guide to Go", "the-ultimate-guide-to-go"}, {"Long title truncation", "This is a very long title that should be cut off", "this-is-a-very-long"}, {"Punctuation removal", "Wow! This is: awesome (really).", "wow-this-is-awesome-really"}, {"Multiple spaces", "Title with spaces", "title-with-spaces"}, {"Empty string", "", ""}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { got := generateSlug(tt.input) if got != tt.expected { t.Errorf("generateSlug(%q) = %q; want %q", tt.input, got, tt.expected) } }) } } func TestProcessHTML(t *testing.T) { inputHTML := `

Capo Notation

Here is an image:

` targetURL, _ := url.Parse("https://example.com/blog/post") outDir := "/tmp/output" modifiedHTML, jobs, err := processHTML(inputHTML, targetURL, outDir) if err != nil { t.Fatalf("processHTML failed: %v", err) } if len(jobs) != 2 { t.Fatalf("expected 2 image jobs, got %d", len(jobs)) } // Test first image (CDN hash fallback to nearest preceding heading) job1 := jobs[0] if !strings.HasPrefix(filepath.Base(job1.LocalPath), "capo-notation-") { t.Errorf("expected job1 filename to fallback to 'capo-notation-', got %q", filepath.Base(job1.LocalPath)) } // Test second image (Original filename) job2 := jobs[1] if !strings.HasPrefix(filepath.Base(job2.LocalPath), "cat-") { t.Errorf("expected job2 filename to fallback to 'cat-', got %q", filepath.Base(job2.LocalPath)) } // Ensure modified HTML has rewritten srcs and alts. if !strings.Contains(modifiedHTML, `alt="Capo Notation"`) { t.Errorf("modified HTML missing injected fallback alt text for job1.") } } func TestDownloadImage(t *testing.T) { expectedContent := []byte("fake image content") server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == "/notfound.jpg" { http.NotFound(w, r) return } w.Write(expectedContent) })) defer server.Close() tmpFile, err := os.CreateTemp("", "test_img_*.jpg") if err != nil { t.Fatalf("failed to create temp file: %v", err) } tmpPath := tmpFile.Name() tmpFile.Close() defer os.Remove(tmpPath) ctx := context.Background() client := server.Client() err = downloadImage(ctx, client, server.URL+"/test.jpg", tmpPath) if err != nil { t.Fatalf("downloadImage failed on valid URL: %v", err) } content, err := os.ReadFile(tmpPath) if err != nil { t.Fatalf("failed to read written file: %v", err) } if string(content) != string(expectedContent) { t.Errorf("expected content %q, got %q", expectedContent, content) } err = downloadImage(ctx, client, server.URL+"/notfound.jpg", tmpPath) if err == nil { t.Errorf("expected error on 404 response, got nil") } else if !strings.Contains(err.Error(), "bad status 404") { t.Errorf("expected 404 error message, got %q", err) } }