package rules import ( "context" "net/http" "net/http/httptest" "testing" ) func TestAnalyzeURL(t *testing.T) { tests := []struct { name string serverResponse func(w http.ResponseWriter) url string wantErr bool check func(t *testing.T, metadata *URLMetadata) }{ { name: "successful HEAD request", serverResponse: func(w http.ResponseWriter) { w.Header().Set("Content-Type", "text/html; charset=utf-8") w.WriteHeader(http.StatusOK) }, url: "", // Will be replaced with server URL wantErr: false, check: func(t *testing.T, metadata *URLMetadata) { // Domain will be from test server (127.0.0.1), so just check it's not empty if metadata.Domain == "" { t.Error("Domain is empty") } if metadata.MimeType != "text/html" { t.Errorf("MimeType = %q, want %q", metadata.MimeType, "text/html") } }, }, { name: "content type without charset", serverResponse: func(w http.ResponseWriter) { w.Header().Set("Content-Type", "application/pdf") w.WriteHeader(http.StatusOK) }, url: "http://example.com/file.pdf", wantErr: false, check: func(t *testing.T, metadata *URLMetadata) { if metadata.MimeType != "application/pdf" { t.Errorf("MimeType = %q, want %q", metadata.MimeType, "application/pdf") } }, }, { name: "domain with port", serverResponse: func(w http.ResponseWriter) { w.Header().Set("Content-Type", "text/html") w.WriteHeader(http.StatusOK) }, url: "", // Will be replaced with server URL wantErr: false, check: func(t *testing.T, metadata *URLMetadata) { // Domain will be from test server, so just check it's not empty if metadata.Domain == "" { t.Error("Domain is empty") } }, }, { name: "no content type header", serverResponse: func(w http.ResponseWriter) { w.WriteHeader(http.StatusOK) }, url: "http://example.com/page", wantErr: false, check: func(t *testing.T, metadata *URLMetadata) { if metadata.MimeType != "" { t.Errorf("MimeType = %q, want empty", metadata.MimeType) } }, }, { name: "invalid URL", serverResponse: func(w http.ResponseWriter) { w.WriteHeader(http.StatusOK) }, url: "not-a-valid-url", wantErr: true, }, { name: "server error", serverResponse: func(w http.ResponseWriter) { w.WriteHeader(http.StatusInternalServerError) }, url: "http://example.com/page", wantErr: false, // HEAD request succeeds even with error status check: func(t *testing.T, metadata *URLMetadata) { // Should still get metadata even if server returns error if metadata == nil { t.Fatal("metadata is nil") } }, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Create test server server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.Method != http.MethodHead { t.Errorf("Expected HEAD request, got %s", r.Method) } tt.serverResponse(w) })) defer server.Close() // Use server URL if url is not explicitly invalid testURL := tt.url if tt.url != "not-a-valid-url" { testURL = server.URL + "/test" } ctx := context.Background() metadata, err := AnalyzeURL(ctx, testURL) if (err != nil) != tt.wantErr { t.Errorf("AnalyzeURL() error = %v, wantErr %v", err, tt.wantErr) return } if tt.wantErr { return } if metadata == nil { t.Fatal("AnalyzeURL() returned nil metadata") } if tt.check != nil { tt.check(t, metadata) } }) } } func TestAnalyzeURL_DomainExtraction(t *testing.T) { tests := []struct { name string url string wantDomain string }{ { name: "simple domain", url: "http://example.com", wantDomain: "example.com", }, { name: "domain with port", url: "http://example.com:8080", wantDomain: "example.com", }, { name: "subdomain", url: "http://api.example.com", wantDomain: "api.example.com", }, { name: "https", url: "https://example.com", wantDomain: "example.com", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { // Create test server server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) })) defer server.Close() // Replace server URL with our test URL ctx := context.Background() metadata, err := AnalyzeURL(ctx, tt.url) if err != nil { // If URL parsing fails, that's expected for some test cases // We'll test domain extraction separately return } if metadata.Domain != tt.wantDomain { t.Errorf("Domain = %q, want %q", metadata.Domain, tt.wantDomain) } }) } }