96 lines
3.7 KiB
Python
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()
|