fix(server): v2入口加固——page_id孤代理/NaN区间值拒绝,共享ISO解析
Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
@@ -350,3 +350,37 @@ def test_dirty_intervals_soft_skipped(db):
|
||||
e2 = Event.objects.get(event_id="e-page_stay-2")
|
||||
assert e2.active_from_ms is None # 非数值 int 化为 None
|
||||
assert VisitSession.objects.get(session_id="s1").stay_ms == 10000 # 仅 p1 有效区间
|
||||
|
||||
# 27. NaN/Infinity/超量纲区间值:NaN/Inf 是非法 JSON 数值(json.loads 默认收,但 SQLite
|
||||
# JSON 有效性校验拒 + bulk_create(ignore_conflicts) 静默丢行而 accepted 已计数——幽灵
|
||||
# 事件),入口 properties_invalid 拒;有限超量纲值(1e308)合法入库但区间列降级 None
|
||||
def test_nonfinite_interval_values_rejected_or_degraded(db):
|
||||
site = Site.objects.create(name="s", domains=["a.com"], site_id=SITE_ID)
|
||||
evs = [_v2_event("page_stay", "p1", "s1", seq=1, active_from=0, active_to=10000, flush_reason="periodic"),
|
||||
_v2_event("page_stay", "p2", "s1", seq=2,
|
||||
active_from=float("nan"), active_to=float("inf"), flush_reason="periodic"),
|
||||
_v2_event("page_stay", "p3", "s1", seq=3,
|
||||
active_from=-1e308, active_to=1e308, flush_reason="periodic")]
|
||||
r = ingest_batch(site, _v2_batch(evs, sid="s1"))
|
||||
assert (r["accepted"], r["duplicated"]) == (2, 0)
|
||||
assert r["rejected"] == [{"index": 1, "event_id": "e-page_stay-2",
|
||||
"reason": "properties_invalid"}]
|
||||
e3 = Event.objects.get(event_id="e-page_stay-3")
|
||||
assert e3.active_from_ms is None and e3.active_to_ms is None # 超 ±2^63 量纲 → None
|
||||
assert VisitSession.objects.get(session_id="s1").stay_ms == 10000
|
||||
|
||||
# 28. page_id 校验(invalid_page_id):session_resume 仅豁免"空值",非空值一律完整校验
|
||||
# (孤代理 "\ud800" 是合规 JSON,跳过 _utf8_ok 会在存储时炸整批)
|
||||
def test_v2_page_id_validation(db):
|
||||
site = Site.objects.create(name="s", domains=["a.com"], site_id=SITE_ID)
|
||||
bad_surrogate = _v2_event("session_resume", "", "s1", seq=1,
|
||||
prev_session_id="s0", reason="idle_timeout")
|
||||
bad_surrogate["page_id"] = "p\ud800" # session_resume 的非空 page_id 也不豁免孤代理
|
||||
bad_long = _v2_event("page_view", "L" * 65, "s1", seq=2)
|
||||
bad_type = _v2_event("page_view", 123, "s1", seq=3)
|
||||
ok_resume = _v2_event("session_resume", "", "s1", seq=4,
|
||||
prev_session_id="s0", reason="idle_timeout")
|
||||
r = ingest_batch(site, _v2_batch([bad_surrogate, bad_long, bad_type, ok_resume], sid="s1"))
|
||||
assert r["accepted"] == 1 # 空 page_id 的 session_resume 通过
|
||||
assert [x["reason"] for x in r["rejected"]] == ["invalid_page_id"] * 3
|
||||
assert {x["index"] for x in r["rejected"]} == {0, 1, 2}
|
||||
|
||||
Reference in New Issue
Block a user