| Server IP : 3.147.158.171 / Your IP : 216.73.216.216 Web Server : Apache/2.4.67 (Amazon Linux) OpenSSL/3.5.5 System : Linux ip-172-31-2-178.us-east-2.compute.internal 6.1.172-216.329.amzn2023.x86_64 #1 SMP PREEMPT_DYNAMIC Wed May 20 06:31:34 UTC 2026 x86_64 User : ec2-user ( 1000) PHP Version : 8.4.21 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /tsai/repo/api/tests/unit/ |
Upload File : |
"""Tests for image filename selection in ImageService.
The contract: every logical image owns one basename, and all format-variants
(png/jpeg/webp) of that image share the basename. A second logical image on
the same day takes `{date}-1` regardless of format, a third takes `{date}-2`,
etc. Transcoding a source to .webp yields `{base}.webp` and overwrites on
repeat (no `_N` siblings).
"""
import base64
from io import BytesIO
import pytest
from PIL import Image
from app.services.image import ImageService
def _tiny_png_b64() -> str:
buf = BytesIO()
Image.new("RGB", (1, 1), color=(0, 0, 0)).save(buf, format="PNG")
return base64.b64encode(buf.getvalue()).decode("utf-8")
@pytest.fixture
def service():
return ImageService()
@pytest.fixture
def png_b64():
return _tiny_png_b64()
def _stem(path: str) -> str:
import os
name = os.path.basename(path)
return os.path.splitext(name)[0]
def _ext(path: str) -> str:
import os
return os.path.splitext(path)[1]
def test_first_save_uses_bare_date(service, png_b64, tmp_path):
import datetime
today = datetime.date.today().strftime("%Y-%m-%d")
path = service.save_base64_image(str(tmp_path), png_b64, output_format="png")
assert _ext(path) == ".png"
assert _stem(path) == today
def test_second_save_different_format_takes_next_suffix(service, png_b64, tmp_path):
"""Bug before this change: a .jpeg save after a .png save lands on
{date}.jpeg alongside the png and gets visually merged with it.
"""
first = service.save_base64_image(str(tmp_path), png_b64, output_format="png")
second = service.save_base64_image(str(tmp_path), png_b64, output_format="jpeg")
first_stem = _stem(first)
second_stem = _stem(second)
assert _ext(first) == ".png"
assert _ext(second) == ".jpeg"
assert second_stem == f"{first_stem}-1"
def test_three_saves_mixed_formats_ladder_suffixes(service, png_b64, tmp_path):
a = service.save_base64_image(str(tmp_path), png_b64, output_format="png")
b = service.save_base64_image(str(tmp_path), png_b64, output_format="jpeg")
c = service.save_base64_image(str(tmp_path), png_b64, output_format="png")
base = _stem(a)
assert _stem(b) == f"{base}-1"
assert _stem(c) == f"{base}-2"
assert {_ext(a), _ext(b), _ext(c)} == {".png", ".jpeg"}
def test_get_unique_webp_path_just_swaps_extension(service, tmp_path):
source = tmp_path / "2026-04-16.png"
source.write_bytes(b"fake")
expected = str(tmp_path / "2026-04-16.webp")
assert service.get_unique_webp_path(str(source)) == expected
def test_get_unique_webp_path_does_not_add_underscore_when_webp_exists(service, tmp_path):
"""Legacy behavior was to return `{base}_1.webp` when `{base}.webp`
already existed. That broke variant grouping, so re-transcoding now
just overwrites.
"""
source = tmp_path / "2026-04-16.png"
source.write_bytes(b"fake")
existing_webp = tmp_path / "2026-04-16.webp"
existing_webp.write_bytes(b"prior transcode")
path = service.get_unique_webp_path(str(source))
assert path == str(existing_webp)
assert "_1" not in path
def test_basename_in_use_detects_any_allowed_extension(tmp_path):
(tmp_path / "2026-04-16.webp").write_bytes(b"x")
assert ImageService._basename_in_use(str(tmp_path), "2026-04-16") is True
assert ImageService._basename_in_use(str(tmp_path), "2026-04-17") is False
def test_save_then_transcode_groups_by_shared_basename(service, png_b64, tmp_path):
"""End-to-end: saving a png and transcoding to webp produces two files
that share a basename (so the browse endpoint's variant-collapse will
group them into a single entry).
"""
png_path = service.save_base64_image(str(tmp_path), png_b64, output_format="png")
webp_path = service.get_unique_webp_path(png_path)
assert _stem(png_path) == _stem(webp_path)
# A second image taken after the first + its transcode should get -1,
# not collide with the webp sibling.
next_png = service.save_base64_image(str(tmp_path), png_b64, output_format="png")
assert _stem(next_png) == f"{_stem(png_path)}-1"