Files
zyt/app/tests/test_packaging_brand_icons.py
T
2026-08-22 10:46:13 +08:00

96 lines
3.7 KiB
Python

from __future__ import annotations
import hashlib
import struct
from pathlib import Path
PROJECT_ROOT = Path(__file__).resolve().parents[1]
BRANDING_ROOT = PROJECT_ROOT / "resources" / "branding"
MASTER_SHA256 = "c76f19b9a1c89c23d9923a0903c673dc5127acecc640272e4974241021f1100e"
def _png_info(path: Path) -> tuple[int, int, int]:
data = path.read_bytes()
assert data.startswith(b"\x89PNG\r\n\x1a\n")
assert data[12:16] == b"IHDR"
width, height = struct.unpack(">II", data[16:24])
color_type = data[25]
return width, height, color_type
def _ico_sizes(path: Path) -> set[tuple[int, int]]:
data = path.read_bytes()
reserved, image_type, count = struct.unpack_from("<HHH", data)
assert reserved == 0
assert image_type == 1
sizes: set[tuple[int, int]] = set()
for index in range(count):
width, height = struct.unpack_from("BB", data, 6 + index * 16)
sizes.add((width or 256, height or 256))
return sizes
def test_brand_assets_are_complete_and_derived_from_the_approved_master() -> None:
master = BRANDING_ROOT / "brand-master.png"
lockup = BRANDING_ROOT / "brand-lockup.png"
icon_png = BRANDING_ROOT / "app-icon.png"
icon_ico = BRANDING_ROOT / "app-icon.ico"
icon_icns = BRANDING_ROOT / "app-icon.icns"
favicon = PROJECT_ROOT / "video_companion" / "public" / "favicon.png"
assert hashlib.sha256(master.read_bytes()).hexdigest() == MASTER_SHA256
assert _png_info(master)[:2] == (1254, 1254)
assert _png_info(lockup)[0] >= 800
assert _png_info(lockup)[1] >= 900
assert _png_info(icon_png) == (1024, 1024, 6)
assert _png_info(favicon)[:2] == (64, 64)
assert {(16, 16), (32, 32), (48, 48), (64, 64), (256, 256)} <= _ico_sizes(
icon_ico
)
icns = icon_icns.read_bytes()
assert icns.startswith(b"icns")
assert struct.unpack(">I", icns[4:8])[0] == len(icns)
def test_runtime_and_packaging_use_the_same_brand_icon() -> None:
app_source = (PROJECT_ROOT / "src" / "doctor_workstation" / "app.py").read_text(
encoding="utf-8"
)
resources_source = (
PROJECT_ROOT / "src" / "doctor_workstation" / "resources.py"
).read_text(encoding="utf-8")
login_source = (
PROJECT_ROOT / "src" / "doctor_workstation" / "ui" / "login.py"
).read_text(encoding="utf-8")
shell_source = (
PROJECT_ROOT / "src" / "doctor_workstation" / "ui" / "shell.py"
).read_text(encoding="utf-8")
spec = (PROJECT_ROOT / "packaging" / "doctor_workstation.spec").read_text(
encoding="utf-8"
)
installer = (
PROJECT_ROOT / "packaging" / "windows" / "doctor_workstation.iss"
).read_text(encoding="utf-8")
package_script = (PROJECT_ROOT / "scripts" / "package_windows.ps1").read_text(
encoding="utf-8"
)
companion_html = (PROJECT_ROOT / "video_companion" / "index.html").read_text(
encoding="utf-8"
)
assert 'resource_path("branding", "app-icon.png")' in resources_source
assert "app_icon_path()" in app_source
assert "brand_lockup_path()" in login_source
assert "return QIcon(str(app_icon_path()))" in login_source
assert "QPixmap(str(app_icon_path()))" in shell_source
assert 'icon=str(WINDOWS_ICON) if sys.platform == "win32" else None' in spec
assert "icon=str(MACOS_ICON)" in spec
assert "SetupIconFile={#AppIconFile}" in installer
assert installer.count('IconFilename: "{app}\\{#AppExecutableName}"') == 2
assert '"/DAppIconFile=$WindowsIcon"' in package_script
assert '<link rel="icon" type="image/png" href="/favicon.png" />' in companion_html
assert "icon.svg" not in app_source
assert "_draw_mark" not in login_source
assert not (PROJECT_ROOT / "resources" / "icon.svg").exists()