1) 客服 Agent 四份交付文档 + 构建脚手架:品牌由包装占位 XX科技 / 旧名 南方财富 统一为南方基金(热线 400-889-8899 / 官网 nffund.com),系统名改为「智能服务系统」; 同步追加 §0.4 修订记录行,工程记录行保留原占位字面以支撑硬编码扫描验收。 2) 开发文档:清理 28 份已作废/残留文档(14 份移出归档 + 14 份仓库副本), 新增《文档规整方案与开发前待决事项-2026-09-17》。 3) 客服agent 四份交付文档首次纳入本分支。
100 lines
3.3 KiB
Python
100 lines
3.3 KiB
Python
from pathlib import Path
|
|
|
|
from PIL import Image, ImageDraw, ImageFont
|
|
|
|
from app.service.promotion_poster_renderer import PromotionPosterRenderer
|
|
|
|
|
|
def _draft(style_code: str) -> dict[str, object]:
|
|
return {
|
|
"style_code": style_code,
|
|
"title": "测试基金产品推介材料",
|
|
"chapters": [
|
|
{"title": "产品基本信息", "body": "基金类型:混合型\n运作方式:开放式"},
|
|
{"title": "投资范围、策略与限制", "body": "股票和债券,长期配置"},
|
|
{"title": "管理人及投研团队", "body": "管理人:测试基金管理有限公司"},
|
|
{"title": "收益与风险指标", "body": "产品收益 8%,最大回撤 -5%,夏普比率 0.8"},
|
|
],
|
|
}
|
|
|
|
|
|
def test_poster_renderer_creates_readable_dark_reference_style(tmp_path: Path) -> None:
|
|
output = tmp_path / "dark-poster.png"
|
|
|
|
result = PromotionPosterRenderer().render(
|
|
_draft("balanced_allocation"),
|
|
output,
|
|
)
|
|
|
|
assert result == str(output)
|
|
with Image.open(output) as image:
|
|
assert image.size == (1800, 2600)
|
|
assert image.getpixel((10, 10)) == (14, 59, 102)
|
|
|
|
|
|
def test_poster_renderer_creates_readable_warm_reference_style(tmp_path: Path) -> None:
|
|
output = tmp_path / "warm-poster.png"
|
|
|
|
PromotionPosterRenderer().render(
|
|
_draft("steady_professional"),
|
|
output,
|
|
)
|
|
|
|
with Image.open(output) as image:
|
|
assert image.size == (1800, 2600)
|
|
assert image.getpixel((10, 10)) == (201, 76, 47)
|
|
|
|
|
|
def test_poster_renderer_uses_theme_panels_instead_of_white(tmp_path: Path) -> None:
|
|
output = tmp_path / "theme-panel-poster.png"
|
|
|
|
PromotionPosterRenderer().render(
|
|
_draft("balanced_allocation"),
|
|
output,
|
|
)
|
|
|
|
with Image.open(output) as image:
|
|
assert image.getpixel((120, 620)) == (220, 234, 243)
|
|
assert image.getpixel((600, 1200)) == (220, 234, 243)
|
|
assert image.getpixel((120, 620)) != (255, 255, 255)
|
|
|
|
|
|
def test_poster_renderer_fills_ai_background_and_footer_without_white_bands(
|
|
tmp_path: Path,
|
|
) -> None:
|
|
background = tmp_path / "square-background.png"
|
|
output = tmp_path / "filled-poster.png"
|
|
Image.new("RGB", (1024, 1024), color=(80, 92, 106)).save(background)
|
|
|
|
PromotionPosterRenderer().render(
|
|
_draft("balanced_allocation"),
|
|
output,
|
|
background_path=str(background),
|
|
)
|
|
|
|
with Image.open(output) as image:
|
|
assert image.getpixel((900, 2450)) != (255, 255, 255)
|
|
assert image.getpixel((900, 2570)) != (255, 255, 255)
|
|
|
|
|
|
def test_long_strategy_text_changes_ai_50_50_ratio_and_fits_panel() -> None:
|
|
renderer = PromotionPosterRenderer()
|
|
image = Image.new("RGB", (1800, 2600), "white")
|
|
draw = ImageDraw.Draw(image)
|
|
font = ImageFont.truetype(r"C:\Windows\Fonts\msyh.ttc", 24)
|
|
strategy = "围绕宏观周期、估值水平和基本面趋势开展多资产配置," * 20
|
|
|
|
ratio, fitted_font = renderer._resolve_two_column_layout(
|
|
draw,
|
|
"基金类型:混合型",
|
|
strategy,
|
|
total_width=1620,
|
|
height=320,
|
|
requested_ratio=0.5,
|
|
font=font,
|
|
)
|
|
|
|
right_width = 1620 - 54 - int((1620 - 54) * ratio) - 68
|
|
assert ratio == 0.4
|
|
assert renderer._text_fits(draw, strategy, right_width, 260, fitted_font)
|