116 lines
3.6 KiB
Go
116 lines
3.6 KiB
Go
package routers
|
|
|
|
import (
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"server/pkg/verifyfiles"
|
|
|
|
beego "github.com/beego/beego/v2/server/web"
|
|
)
|
|
|
|
// TestVerifyFilesEndToEnd 走真实 HTTP 链路验证:
|
|
// 根路径下的验证文件能被吐出来,且不带白名单的路径仍然 404。
|
|
func TestVerifyFilesEndToEnd(t *testing.T) {
|
|
dir := t.TempDir()
|
|
if err := os.WriteFile(filepath.Join(dir, "1XXl8fPHr9.txt"), []byte("1XXl8fPHr9"), 0o644); err != nil {
|
|
t.Fatalf("准备测试文件失败: %v", err)
|
|
}
|
|
// 注册到全局 beego(与线上 router.go 的注册方式一致)
|
|
RegisterVerifyFiles(dir, "")
|
|
|
|
beego.BeeApp.Handlers.Init()
|
|
|
|
// 1) 验证文件正常返回
|
|
req := httptest.NewRequest(http.MethodGet, "/1XXl8fPHr9.txt", nil)
|
|
req.Host = "api.yunzer.cn"
|
|
rec := httptest.NewRecorder()
|
|
beego.BeeApp.Handlers.ServeHTTP(rec, req)
|
|
|
|
if rec.Code != http.StatusOK {
|
|
t.Fatalf("验证文件应返回 200,实际 %d", rec.Code)
|
|
}
|
|
if got := rec.Body.String(); got != "1XXl8fPHr9" {
|
|
t.Fatalf("验证文件内容不对,实际 %q", got)
|
|
}
|
|
if ct := rec.Header().Get("Content-Type"); ct == "" || ct[:len("text/plain")] != "text/plain" {
|
|
t.Logf("Content-Type: %s", ct)
|
|
}
|
|
|
|
// 2) 不存在的验证文件仍走正常路由(404),行为不变
|
|
req2 := httptest.NewRequest(http.MethodGet, "/not-exist-verify.txt", nil)
|
|
req2.Host = "api.yunzer.cn"
|
|
rec2 := httptest.NewRecorder()
|
|
beego.BeeApp.Handlers.ServeHTTP(rec2, req2)
|
|
|
|
if rec2.Code != http.StatusNotFound {
|
|
t.Fatalf("不存在的验证文件应返回 404,实际 %d", rec2.Code)
|
|
}
|
|
}
|
|
|
|
// TestAppRootFrom 确认服务根目录按「含 conf/app.conf 的目录」定位。
|
|
func TestAppRootFrom(t *testing.T) {
|
|
root := t.TempDir()
|
|
if err := os.MkdirAll(filepath.Join(root, "conf"), 0o755); err != nil {
|
|
t.Fatalf("准备测试目录失败: %v", err)
|
|
}
|
|
if err := os.WriteFile(filepath.Join(root, "conf", "app.conf"), []byte("appname = server"), 0o644); err != nil {
|
|
t.Fatalf("准备测试文件失败: %v", err)
|
|
}
|
|
|
|
other := t.TempDir()
|
|
|
|
if got := appRootFrom([]string{other, root}); got != root {
|
|
t.Fatalf("应定位到 %s,实际 %s", root, got)
|
|
}
|
|
if got := appRootFrom([]string{other, ""}); got != "" {
|
|
t.Fatalf("没有 conf/app.conf 时应返回空串,实际 %s", got)
|
|
}
|
|
if got := appRootFrom([]string{""}); got != "" {
|
|
t.Fatalf("空候选应返回空串,实际 %s", got)
|
|
}
|
|
}
|
|
|
|
// TestDefaultDirResolvesToRepoVerifyDir 确认默认目录落在「服务根目录/verify」下,
|
|
// 且仓库里的验证文件能被解析出来、内容正确。
|
|
// 线上等价:服务根目录 /www/wwwroot/api.yunzer.cn → verify/1XXl8fPHr9.txt。
|
|
func TestDefaultDirResolvesToRepoVerifyDir(t *testing.T) {
|
|
orig, err := os.Getwd()
|
|
if err != nil {
|
|
t.Fatalf("取当前工作目录失败: %v", err)
|
|
}
|
|
defer os.Chdir(orig)
|
|
|
|
// 切到 go/ 目录:这里有 conf/app.conf,等价于线上服务根目录
|
|
goRoot := filepath.Dir(orig)
|
|
if err := os.Chdir(goRoot); err != nil {
|
|
t.Fatalf("切换工作目录失败: %v", err)
|
|
}
|
|
|
|
root := appRoot()
|
|
if root == "" {
|
|
t.Fatalf("应能从 conf/app.conf 定位服务根目录(工作目录 %s)", goRoot)
|
|
}
|
|
|
|
dir := filepath.Join(root, verifyfiles.DefaultDir)
|
|
resolver, err := verifyfiles.New(verifyfiles.Config{Dir: dir})
|
|
if err != nil || resolver == nil {
|
|
t.Fatalf("创建 Resolver 失败: %v", err)
|
|
}
|
|
|
|
full, ok := resolver.Resolve("/1XXl8fPHr9.txt")
|
|
if !ok {
|
|
t.Fatalf("默认目录 %s 下应能解析出验证文件", dir)
|
|
}
|
|
b, err := os.ReadFile(full)
|
|
if err != nil {
|
|
t.Fatalf("读取验证文件失败: %v", err)
|
|
}
|
|
if string(b) != "1XXl8fPHr9" {
|
|
t.Fatalf("验证文件内容不对,实际 %q", string(b))
|
|
}
|
|
}
|