feat: 工资查询助手首版 v1.0.105

基于 skill-template 脚手架开发,包含:
- payroll_config(费率配置,可编辑)+ payslip_snapshots(解析历史,只读)2 张业务表
- 全国默认 + 北上广 4 套费率(社保/公积金/个税起征点/7 级税率表)
- 5 个业务 Action:calculate-payslip-simple / calculate-payslip-full / explain-term / view-config / edit-config
- 个税累计预扣法计算,支持多月历史累加
- 20 个薪资名词库(社保/公积金/个税/全勤/加班费等)
- 完整市场文档(README/TUTORIAL/DEMO/CHANGELOG)
- 296 测试全部通过
This commit is contained in:
skill-dev
2026-09-07 17:02:05 +08:00
commit 3db196e49d
205 changed files with 29927 additions and 0 deletions

View File

@@ -0,0 +1,75 @@
# -*- coding: utf-8 -*-
"""HTML 报告页薄写入 helper。"""
from __future__ import annotations
import os
import unittest
from _support import IsolatedDataRoot
from service.html_page_service import (
HOST_HTML_RENDER_ACTION_ID,
load_html_template,
render_html_placeholders,
write_html_page,
)
class TestHtmlPageService(unittest.TestCase):
def test_host_action_id_is_stable(self) -> None:
self.assertEqual(HOST_HTML_RENDER_ACTION_ID, "render-html")
def test_write_html_page_atomic_under_html_dir(self) -> None:
with IsolatedDataRoot() as tmp:
path = write_html_page(
"example-report.html",
"<!DOCTYPE html><html><head><title>示例</title></head><body>ok</body></html>",
)
self.assertTrue(os.path.isfile(path))
norm = path.replace("\\", "/")
self.assertIn("/html/example-report.html", norm)
self.assertTrue(os.path.normcase(os.path.normpath(path)).startswith(
os.path.normcase(os.path.normpath(tmp)),
))
self.assertFalse(os.path.isfile(path + ".tmp"))
with open(path, encoding="utf-8") as f:
self.assertIn("<title>示例</title>", f.read())
def test_load_and_fill_example_template(self) -> None:
with IsolatedDataRoot():
template = load_html_template("assets/html/example-report.html")
page = render_html_placeholders(
template,
{
"TITLE": "示例报告",
"GENERATED_AT": "2026-08-14 15:49:00",
"BODY": "<p>hello</p>",
},
)
self.assertIn("<title>示例报告</title>", page)
self.assertIn("报告生成于 · 2026-08-14 15:49:00", page)
self.assertIn("<p>hello</p>", page)
self.assertNotIn("{{TITLE}}", page)
dest = write_html_page("example-report.html", page)
self.assertTrue(os.path.isfile(dest))
def test_rejects_unsafe_filename(self) -> None:
with IsolatedDataRoot():
with self.assertRaises(ValueError):
write_html_page("../x.html", "<html></html>")
with self.assertRaises(ValueError):
write_html_page("note.txt", "<html></html>")
def test_example_report_shell_embedded_preview_layout(self) -> None:
"""守护 example-report.html:数据管理 iframe 预览布局基线不退化。"""
template = load_html_template("assets/html/example-report.html")
self.assertIn("overflow-x: hidden", template)
self.assertIn("min-width: 0", template)
self.assertIn("table-layout: fixed", template)
self.assertIn("overflow-wrap: anywhere", template)
self.assertNotIn("max-width:", template)
if __name__ == "__main__":
unittest.main()