// Package handler 提供 HTTP 请求处理功能。 package handler import ( "os" "path/filepath" "testing" "time" "github.com/valyala/fasthttp" ) func TestGenerateAutoIndex_HTML(t *testing.T) { // 创建临时目录 tmpDir, err := os.MkdirTemp("", "autoindex_test") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpDir) // 创建测试文件和目录 if err := os.WriteFile(filepath.Join(tmpDir, "file1.txt"), []byte("content1"), 0o644); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(tmpDir, "file2.html"), []byte("content2"), 0o644); err != nil { t.Fatal(err) } if err := os.Mkdir(filepath.Join(tmpDir, "subdir"), 0o755); err != nil { t.Fatal(err) } if err := os.WriteFile(filepath.Join(tmpDir, ".hidden"), []byte("hidden"), 0o644); err != nil { t.Fatal(err) } // 测试 HTML 格式 ctx := &fasthttp.RequestCtx{} ctx.Request.SetRequestURI("/test/") config := AutoIndexConfig{ Format: "html", Localtime: false, ExactSize: false, } if !GenerateAutoIndex(ctx, tmpDir, "/test/", config) { t.Fatal("GenerateAutoIndex returned false") } if ct := string(ctx.Response.Header.ContentType()); ct != "text/html; charset=utf-8" { t.Errorf("Content-Type = %s, want text/html; charset=utf-8", ct) } body := string(ctx.Response.Body()) // 检查包含文件名 if !containsAll(body, "file1.txt", "file2.html", "subdir") { t.Errorf("HTML body missing expected files: %s", body) } // 检查隐藏文件不显示 if containsAll(body, ".hidden") { t.Errorf("HTML body should not contain hidden file: %s", body) } // 检查目录有斜杠后缀 if !containsAll(body, "subdir/") { t.Errorf("HTML body directory should have / suffix: %s", body) } } func TestGenerateAutoIndex_JSON(t *testing.T) { // 创建临时目录 tmpDir, err := os.MkdirTemp("", "autoindex_test") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpDir) // 创建测试文件 if err := os.WriteFile(filepath.Join(tmpDir, "test.json"), []byte("{}"), 0o644); err != nil { t.Fatal(err) } // 测试 JSON 格式 ctx := &fasthttp.RequestCtx{} ctx.Request.SetRequestURI("/api/") config := AutoIndexConfig{ Format: "json", } if !GenerateAutoIndex(ctx, tmpDir, "/api/", config) { t.Fatal("GenerateAutoIndex returned false") } if ct := string(ctx.Response.Header.ContentType()); ct != "application/json" { t.Errorf("Content-Type = %s, want application/json", ct) } body := string(ctx.Response.Body()) // 检查 JSON 格式 if !containsAll(body, `"name"`, `"type"`, `"mtime"`, "test.json") { t.Errorf("JSON body missing expected fields: %s", body) } } func TestGenerateAutoIndex_XML(t *testing.T) { // 创建临时目录 tmpDir, err := os.MkdirTemp("", "autoindex_test") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpDir) // 创建测试文件 if err := os.WriteFile(filepath.Join(tmpDir, "data.xml"), []byte(""), 0o644); err != nil { t.Fatal(err) } // 测试 XML 格式 ctx := &fasthttp.RequestCtx{} ctx.Request.SetRequestURI("/xml/") config := AutoIndexConfig{ Format: "xml", } if !GenerateAutoIndex(ctx, tmpDir, "/xml/", config) { t.Fatal("GenerateAutoIndex returned false") } if ct := string(ctx.Response.Header.ContentType()); ct != "text/xml; charset=utf-8" { t.Errorf("Content-Type = %s, want text/xml; charset=utf-8", ct) } body := string(ctx.Response.Body()) // 检查 XML 格式 if !containsAll(body, ` zFileIdx || dirIdx > mFileIdx { t.Errorf("Directories should come first: dirIdx=%d, zFileIdx=%d, mFileIdx=%d", dirIdx, zFileIdx, mFileIdx) } } func TestGenerateAutoIndex_SizeFormatting(t *testing.T) { // 创建临时目录 tmpDir, err := os.MkdirTemp("", "autoindex_test") if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpDir) // 创建不同大小的文件 smallFile := filepath.Join(tmpDir, "small.txt") if err := os.WriteFile(smallFile, make([]byte, 100), 0o644); err != nil { t.Fatal(err) } // 测试人类可读格式 ctx := &fasthttp.RequestCtx{} config := AutoIndexConfig{ Format: "html", ExactSize: false, } if !GenerateAutoIndex(ctx, tmpDir, "/", config) { t.Fatal("GenerateAutoIndex returned false") } body := string(ctx.Response.Body()) if !containsAll(body, "small.txt") { t.Errorf("Missing file in output: %s", body) } } func TestFormatSize(t *testing.T) { tests := []struct { size int64 expected string }{ {0, "0"}, {100, "100"}, {1024, "1.0K"}, {1536, "1.5K"}, {1048576, "1.0M"}, {1572864, "1.5M"}, {1073741824, "1.0G"}, {1610612736, "1.5G"}, } for _, tt := range tests { result := formatSize(tt.size) if result != tt.expected { t.Errorf("formatSize(%d) = %s, want %s", tt.size, result, tt.expected) } } } func TestEscapeHTML(t *testing.T) { tests := []struct { input string expected string }{ {"normal", "normal"}, {"