Files
rond-with-you/internal/web/templates_test.go
T
tamakyi d5f6dfa381 审计修复:前端(模板 / CSS / JS 与无障碍)
- 地图脚本:localStorage 读写走 lsGet/lsSet 兜底(隐私模式下裸访问会打断整段脚本);
  preview() 在 /api/map-config 还没回来时不丢点(previewQueue 在 if (live) 之前排队);
  异步回包一律发序号作废,取消后回来的包不再画
- photo-exif.js:EXIF 时间全 0 不再变成 1899-11-30 写进到访时间;读 count 前先按版本卡宽度
- 数据编辑页:三个筛选表单都把其余条件用隐藏域原样带上,提交不再把别的列表的筛选清掉
- 补全页:sessionStorage 的读写一律包 try(脏数据/隐私模式都会抛)
- 窄屏:删掉被后面同特异性规则盖掉的死内边距;宽表堆叠类名成对、判据扩到所有 tb 表
- 无障碍:图片删除按钮补 aria-label,访客画廊图片补 alt
- report.html 补上漏掉的 </tr>,fog-mask 的宽表带 tb-stack

本批不碰数据库与导出路径:往返包 823/323/8/30/791/557/2246 全等、
坐标偏差 0.000000000、时间偏差 0s、迷雾 8701 块一致。
2026-09-24 20:37:57 +08:00

68 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package web
import (
"bytes"
"html/template"
"path/filepath"
"strings"
"testing"
"time"
)
// TestPageTemplatesParse 把每个页面模板都解析一遍。
// 模板是启动时编译的(见 New),语法错会让整个服务起不来;
// 这个测试把它提前到 go test 阶段,不用真起一次服务才发现。
func TestPageTemplatesParse(t *testing.T) {
for key, def := range pageFiles {
if _, err := template.New(filepath.Base(def.files[0])).Funcs(templateFuncs()).
ParseFS(tmplFS, def.files...); err != nil {
t.Errorf("解析模板 %s 失败: %v", key, err)
}
}
}
// TestLayoutFooterToleratesMissingLastVisit 钉住页脚在「数据集一条到访都没有」时也渲染得完。
//
// last_visit_at 可以为 NULL(refreshDatasetAgg 用 LEFT JOIN 求 max,零到访就写 NULL),
// 而 d 的形参是 time.Time、实参是 *time.Time:非 nil 时模板会自动解一层指针,**nil 时报
// "dereference of nil pointer" 并中断渲染**。render() 只把错误记进日志,客户端拿到的是
// HTTP 200 加一个「页脚之后整段不存在」的页面——滚动恢复、地图脚本引入全丢,
// 服务端一点动静都没有。所以这里断言「有收尾的 </html>」,而不只是断言没报错。
func TestLayoutFooterToleratesMissingLastVisit(t *testing.T) {
base, err := template.New("layout.html").Funcs(templateFuncs()).ParseFS(tmplFS, "templates/layout.html")
if err != nil {
t.Fatalf("解析 layout.html: %v", err)
}
tpl, err := base.Parse(`{{define "content"}}正文{{end}}`)
if err != nil {
t.Fatalf("补 content 块: %v", err)
}
last := time.Date(2026, 9, 21, 12, 0, 0, 0, time.Local)
cases := []struct {
name string
ds *Dataset
want string
}{
{"没有数据集", nil, ""},
{"数据集里一条到访都没有", &Dataset{Name: "空数据集"}, ""},
{"正常", &Dataset{Name: "有数据", Last: &last}, "数据截至 2026-09-21"},
}
for _, c := range cases {
var buf bytes.Buffer
if err := tpl.ExecuteTemplate(&buf, "layout", Page{Nav: "home", Title: "测", Dataset: c.ds}); err != nil {
t.Fatalf("%s: 渲染失败: %v", c.name, err)
}
got := buf.String()
if !strings.Contains(got, "</html>") {
t.Errorf("%s: 页面被截断(没有收尾的 </html>)", c.name)
}
if c.want == "" {
if strings.Contains(got, "数据截至") {
t.Errorf("%s: 没有可信的截止时间时不该渲染「数据截至」", c.name)
}
} else if !strings.Contains(got, c.want) {
t.Errorf("%s: 页脚应含 %q", c.name, c.want)
}
}
}