- Entry 增加 DeviceVisits:同一 URL 多次/多设备上报取各设备最大值再求和,
不再平方级放大(30 次访问曾被计成 465 次)
- handleGet 不再截断 100 条,返回 {items,total},后台显示当前条数
- 清理死代码(hostVisits/hostOf/visitCount/isCodeHostVal/dashySection)
- 守门测试:重复上报、多设备求和、陈旧数据、持久化、统计、门户文案、第 101 条可见性
68 lines
2.0 KiB
Go
68 lines
2.0 KiB
Go
package main
|
||
|
||
import (
|
||
"encoding/json"
|
||
"fmt"
|
||
"net/http"
|
||
"net/http/httptest"
|
||
"testing"
|
||
)
|
||
|
||
// 守门:读取侧不得再截断到 100 条。
|
||
// 此前 handleGet 硬砍 100 条,而门户「历史访问」已不限条数 —— 后台因此
|
||
// 看不见也删不掉第 101 条之后的记录。
|
||
func TestHandleGetReturnsAllEntries(t *testing.T) {
|
||
withTempHistory(t)
|
||
const n = 250
|
||
for i := 0; i < n; i++ {
|
||
history[fmt.Sprintf("https://ex.com/%03d", i)] = &Entry{
|
||
URL: fmt.Sprintf("https://ex.com/%03d", i),
|
||
TotalVisits: n - i, // 降序
|
||
}
|
||
}
|
||
req := httptest.NewRequest(http.MethodGet, "/", nil)
|
||
w := httptest.NewRecorder()
|
||
handleGet(w, req)
|
||
|
||
var out struct {
|
||
Items []Entry `json:"items"`
|
||
Total int `json:"total"`
|
||
}
|
||
if err := json.Unmarshal(w.Body.Bytes(), &out); err != nil {
|
||
t.Fatalf("解析失败: %v", err)
|
||
}
|
||
if len(out.Items) != n {
|
||
t.Errorf("返回 %d 条,期望 %d 条(后台必须能删到每一条)", len(out.Items), n)
|
||
}
|
||
if out.Total != n {
|
||
t.Errorf("total = %d,期望 %d", out.Total, n)
|
||
}
|
||
// 顺序:按访问次数降序
|
||
for i := 1; i < len(out.Items); i++ {
|
||
if out.Items[i-1].TotalVisits < out.Items[i].TotalVisits {
|
||
t.Fatalf("第 %d/%d 条顺序错乱:%d < %d", i, len(out.Items), out.Items[i-1].TotalVisits, out.Items[i].TotalVisits)
|
||
}
|
||
}
|
||
}
|
||
|
||
// 超过 100 条时,第 101 条仍可被逐条删除(后台删除按钮按 URL 定位)。
|
||
func TestEntryBeyondOldCapIsDeletable(t *testing.T) {
|
||
withTempHistory(t)
|
||
const n = 150
|
||
for i := 0; i < n; i++ {
|
||
history[fmt.Sprintf("https://ex.com/%03d", i)] = &Entry{
|
||
URL: fmt.Sprintf("https://ex.com/%03d", i), TotalVisits: 1,
|
||
}
|
||
}
|
||
target := "https://ex.com/149" // 旧截断下后台永远看不到这条
|
||
req := httptest.NewRequest(http.MethodDelete, "/item?url="+target, nil)
|
||
w := httptest.NewRecorder()
|
||
handleDeleteItem(w, req)
|
||
if w.Code == http.StatusNotFound {
|
||
t.Fatalf("第 150 条无法删除:%s", w.Body.String())
|
||
}
|
||
if _, ok := history[target]; ok {
|
||
t.Error("删除后仍存在于 history")
|
||
}
|
||
}
|