Files
cv-site/internal/handlers/cv_text_test.go
T

244 lines
6.0 KiB
Go
Raw Normal View History

package handlers
import (
"net/http"
"net/http/httptest"
"strings"
"testing"
)
// TestPlainText tests the PlainText handler
// NOTE: This test requires running from project root due to template path resolution
// Run with: go test ./internal/handlers/ -run TestPlainText -v
// Or skip in CI: go test ./internal/handlers/ -run TestPlainText -short
func TestPlainText(t *testing.T) {
// Skip if running in short mode (CI) - requires project root
if testing.Short() {
t.Skip("Skipping PlainText test - requires running from project root")
}
handler := newTestCVHandler(t, "localhost:8080", nil)
tests := []struct {
name string
lang string
icons string
download string
expectStatus int
expectHeader string
expectContains string
}{
{
name: "Default language (English)",
lang: "",
expectStatus: http.StatusOK,
expectContains: "Juan",
},
{
name: "English language",
lang: "en",
expectStatus: http.StatusOK,
expectContains: "Juan",
},
{
name: "Spanish language",
lang: "es",
expectStatus: http.StatusOK,
expectContains: "Juan",
},
{
name: "Invalid language",
lang: "fr",
expectStatus: http.StatusBadRequest,
},
{
name: "With icons disabled",
lang: "en",
icons: "false",
expectStatus: http.StatusOK,
expectContains: "Juan",
},
{
name: "Download mode",
lang: "en",
download: "true",
expectStatus: http.StatusOK,
expectHeader: "attachment",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Build query string
query := "/text"
params := []string{}
if tt.lang != "" {
params = append(params, "lang="+tt.lang)
}
if tt.icons != "" {
params = append(params, "icons="+tt.icons)
}
if tt.download != "" {
params = append(params, "download="+tt.download)
}
if len(params) > 0 {
query += "?" + strings.Join(params, "&")
}
req := httptest.NewRequest(http.MethodGet, query, nil)
w := httptest.NewRecorder()
handler.PlainText(w, req)
if w.Code != tt.expectStatus {
t.Errorf("Expected status %d, got %d", tt.expectStatus, w.Code)
}
// Check Content-Type for successful requests
if tt.expectStatus == http.StatusOK {
contentType := w.Header().Get("Content-Type")
if !strings.HasPrefix(contentType, "text/plain") {
t.Errorf("Expected text/plain content type, got %s", contentType)
}
}
// Check Content-Disposition header for download mode
if tt.expectHeader != "" {
disposition := w.Header().Get("Content-Disposition")
if !strings.Contains(disposition, tt.expectHeader) {
t.Errorf("Expected Content-Disposition containing '%s', got '%s'", tt.expectHeader, disposition)
}
}
// Check response body contains expected content (if success)
if tt.expectStatus == http.StatusOK && tt.expectContains != "" {
body := w.Body.String()
if !strings.Contains(body, tt.expectContains) {
t.Errorf("Expected body to contain '%s'", tt.expectContains)
}
}
})
}
}
// TestPlainTextDownloadFilename tests that download filename is correctly formatted
// NOTE: This test requires running from project root due to template path resolution
func TestPlainTextDownloadFilename(t *testing.T) {
// Skip if running in short mode (CI) - requires project root
if testing.Short() {
t.Skip("Skipping PlainTextDownloadFilename test - requires running from project root")
}
handler := newTestCVHandler(t, "localhost:8080", nil)
tests := []struct {
name string
lang string
expectPrefix string
}{
{
name: "English download filename",
lang: "en",
expectPrefix: "cv-jamr-",
},
{
name: "Spanish download filename",
lang: "es",
expectPrefix: "cv-jamr-",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/text?lang="+tt.lang+"&download=true", nil)
w := httptest.NewRecorder()
handler.PlainText(w, req)
if w.Code != http.StatusOK {
t.Fatalf("Expected status OK, got %d", w.Code)
}
disposition := w.Header().Get("Content-Disposition")
if !strings.Contains(disposition, tt.expectPrefix) {
t.Errorf("Expected filename to contain '%s', got '%s'", tt.expectPrefix, disposition)
}
// Verify language suffix is in filename
if !strings.Contains(disposition, "-"+tt.lang+".txt") {
t.Errorf("Expected filename to end with '-%s.txt', got '%s'", tt.lang, disposition)
}
})
}
}
// TestIsTextBrowser tests the text browser detection
func TestIsTextBrowser(t *testing.T) {
tests := []struct {
name string
userAgent string
accept string
expect bool
}{
{
name: "Regular browser",
userAgent: "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36",
expect: false,
},
{
name: "curl",
userAgent: "curl/7.79.1",
expect: true,
},
{
name: "wget",
userAgent: "Wget/1.21",
expect: true,
},
{
name: "httpie",
userAgent: "HTTPie/2.6.0",
expect: true,
},
{
name: "lynx",
userAgent: "Lynx/2.9.0dev.10",
expect: true,
},
{
name: "w3m",
userAgent: "w3m/0.5.3",
expect: true,
},
{
name: "Accept text/plain",
userAgent: "Mozilla/5.0",
accept: "text/plain",
expect: true,
},
{
name: "Accept text/html",
userAgent: "Mozilla/5.0",
accept: "text/html",
expect: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/", nil)
if tt.userAgent != "" {
req.Header.Set("User-Agent", tt.userAgent)
}
if tt.accept != "" {
req.Header.Set("Accept", tt.accept)
}
result := isTextBrowser(req)
if result != tt.expect {
t.Errorf("isTextBrowser() = %v, expected %v for User-Agent: %s", result, tt.expect, tt.userAgent)
}
})
}
}