4de4b8dc08
CI/CD Pipeline / Check if frontend-only change (push) Has been skipped
CI/CD Pipeline / Frontend Lint (push) Has been skipped
CI/CD Pipeline / Check if frontend-only change (pull_request) Successful in 47s
CI/CD Pipeline / Validate - Migration (alembic) (push) Successful in 1m30s
CI/CD Pipeline / PR Build API Image (push) Has been skipped
CI/CD Pipeline / PR Build Web Image (push) Has been skipped
CI/CD Pipeline / PR Build Worker Image (push) Has been skipped
CI/CD Pipeline / Build Staging API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Validate - Type Check (mypy) (pull_request) Successful in 3m5s
CI/CD Pipeline / Build Staging Worker Image (push) Successful in 1m53s
CI/CD Pipeline / Validate - Type Check (mypy) (push) Successful in 3m25s
PR Automation / Auto Merge on CI Green + Approved (pull_request) Has been skipped
CI/CD Pipeline / Validate - Migration (alembic) (pull_request) Successful in 2m37s
CI/CD Pipeline / Frontend Lint (pull_request) Has been skipped
CI/CD Pipeline / Frontend Unit Tests (pull_request) Has been skipped
CI/CD Pipeline / Build Staging Web Image (push) Successful in 3m2s
CI/CD Pipeline / PR Build API Image (pull_request) Successful in 22s
CI/CD Pipeline / PR Build Web Image (pull_request) Has been skipped
CI/CD Pipeline / PR Build Worker Image (pull_request) Successful in 38s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (pull_request) Has been skipped
CI/CD Pipeline / Staging E2E Tests (pull_request) Has been skipped
CI/CD Pipeline / Staging API Integration Tests (pull_request) Has been skipped
CI/CD Pipeline / ACR Image Cleanup (pull_request) Has been skipped
AI Code Review / AI Code Review (pull_request) Successful in 3m23s
CI/CD Pipeline / Build Staging API Image (push) Successful in 5m27s
Preview Deploy / Deploy Preview Environment (pull_request) Successful in 2m14s
CI/CD Pipeline / Validate - Code Quality (push) Successful in 6m28s
PR Automation / Auto Approve on CI Green (pull_request) Successful in 3m24s
CI/CD Pipeline / Deploy Staging (Watchtower auto-deploy) (push) Successful in 1m5s
CI/CD Pipeline / ACR Image Cleanup (push) Successful in 1m18s
CI/CD Pipeline / Staging E2E Tests (push) Successful in 1m31s
CI/CD Pipeline / Frontend Unit Tests (push) Successful in 8m6s
CI/CD Pipeline / Validate - Code Quality (pull_request) Successful in 8m9s
CI/CD Pipeline / Integration Tests (push) Successful in 3m1s
CI/CD Pipeline / Staging API Integration Tests (push) Successful in 3m45s
CI/CD Pipeline / Integration Tests (pull_request) Successful in 2m28s
CI/CD Pipeline / Unit Tests (push) Successful in 14m12s
CI/CD Pipeline / CI Gate (push) Has been skipped
CI/CD Pipeline / Build Production API Image (push) Has been skipped
CI/CD Pipeline / Build Production Web Image (push) Has been skipped
CI/CD Pipeline / Build Production Worker Image (push) Has been skipped
CI/CD Pipeline / Canary Release to Production (push) Has been skipped
CI/CD Pipeline / Deploy Production (push) Has been skipped
CI/CD Pipeline / Production Browser E2E (push) Has been skipped
CI/CD Pipeline / Unit Tests (pull_request) Successful in 11m29s
CI/CD Pipeline / Build Production API Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Web Image (pull_request) Has been skipped
CI/CD Pipeline / Build Production Worker Image (pull_request) Has been skipped
CI/CD Pipeline / Deploy Production (pull_request) Has been skipped
CI/CD Pipeline / Canary Release to Production (pull_request) Has been skipped
CI/CD Pipeline / Production Browser E2E (pull_request) Has been skipped
CI/CD Pipeline / CI Gate (pull_request) Successful in 9s
90 lines
2.9 KiB
Python
90 lines
2.9 KiB
Python
"""packages.shared.title_overlay 单元测试。"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import tempfile
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from packages.shared.title_overlay import apply_title_to_image, wrap_title_text
|
|
|
|
|
|
@pytest.fixture
|
|
def sample_image():
|
|
"""生成一张 640x360 的纯黑测试图片。"""
|
|
from PIL import Image
|
|
|
|
tmp = tempfile.NamedTemporaryFile(suffix=".jpg", delete=False)
|
|
tmp.close()
|
|
img = Image.new("RGB", (640, 360), color=(0, 0, 0))
|
|
img.save(tmp.name, "JPEG")
|
|
yield tmp.name
|
|
Path(tmp.name).unlink(missing_ok=True)
|
|
|
|
|
|
def test_apply_title_to_image_empty_text_returns_none(sample_image):
|
|
assert apply_title_to_image(sample_image, "") is None
|
|
assert apply_title_to_image(sample_image, " ") is None
|
|
|
|
|
|
def test_apply_title_to_image_draws_title(sample_image):
|
|
result = apply_title_to_image(sample_image, "测试标题")
|
|
assert result == sample_image
|
|
assert Path(sample_image).exists()
|
|
assert Path(sample_image).stat().st_size > 0
|
|
|
|
|
|
def test_apply_title_to_image_respects_position(sample_image):
|
|
for pos in ("top", "center", "bottom"):
|
|
result = apply_title_to_image(sample_image, "位置测试", position=pos)
|
|
assert result == sample_image
|
|
|
|
|
|
def test_wrap_title_text_supports_long_text():
|
|
from PIL import ImageFont
|
|
|
|
font = ImageFont.load_default()
|
|
lines = wrap_title_text("这是一个比较长的标题需要自动换行处理ABC", font, max_width=40)
|
|
assert isinstance(lines, list)
|
|
assert len(lines) >= 1
|
|
|
|
|
|
def test_wrap_title_text_respects_explicit_newline():
|
|
from PIL import ImageFont
|
|
|
|
font = ImageFont.load_default()
|
|
lines = wrap_title_text("第一行\n第二行", font, max_width=10000)
|
|
assert lines == ["第一行", "第二行"]
|
|
|
|
|
|
def test_apply_title_to_image_custom_color(sample_image):
|
|
"""自定义颜色参数能正常生成图片。"""
|
|
result = apply_title_to_image(sample_image, "彩色标题", color="#ff0000")
|
|
assert result == sample_image
|
|
assert Path(sample_image).stat().st_size > 0
|
|
|
|
|
|
def test_apply_title_to_image_short_hex_color(sample_image):
|
|
"""3 位缩写 hex 颜色也能正常解析。"""
|
|
result = apply_title_to_image(sample_image, "短色", color="#f00")
|
|
assert result == sample_image
|
|
|
|
|
|
def test_apply_title_to_image_invalid_color_fallback(sample_image):
|
|
"""无效颜色字符串 fallback 到白色,不报错。"""
|
|
result = apply_title_to_image(sample_image, "异常色", color="not-a-color")
|
|
assert result == sample_image
|
|
|
|
|
|
def test_parse_hex_color():
|
|
from packages.shared.title_overlay import _parse_hex_color
|
|
|
|
assert _parse_hex_color("#ffffff") == (255, 255, 255)
|
|
assert _parse_hex_color("#000000") == (0, 0, 0)
|
|
assert _parse_hex_color("#ff0000") == (255, 0, 0)
|
|
assert _parse_hex_color("#f00") == (255, 0, 0)
|
|
assert _parse_hex_color("") == (255, 255, 255)
|
|
assert _parse_hex_color("invalid") == (255, 255, 255)
|
|
assert _parse_hex_color("#gggggg") == (255, 255, 255)
|