"""Tests for the transparency audit rule. The rule mirrors `Importer._transparency_pct` semantics for retroactive enforcement: returns True iff the fraction of fully-transparent pixels exceeds the threshold. Animated images short-circuit to False to avoid the multi-frame PIL decode that triggered SoftTimeLimitExceeded 2026-05-26 against animated WebPs. """ from PIL import Image from backend.app.services.audits import transparency def test_transparency_evaluate_true_when_fully_transparent(): im = Image.new("RGBA", (10, 10), (0, 0, 0, 0)) assert transparency.evaluate(im, threshold=0.5) is True def test_transparency_evaluate_false_when_fully_opaque(): im = Image.new("RGBA", (10, 10), (200, 100, 50, 255)) assert transparency.evaluate(im, threshold=0.5) is False def test_transparency_evaluate_respects_threshold_boundary(): # Half-transparent image: 50% alpha=0 pixels, 50% alpha=255. im = Image.new("RGBA", (10, 10), (0, 0, 0, 0)) for x in range(5): for y in range(10): im.putpixel((x, y), (0, 0, 0, 255)) # 50% transparent. threshold=0.4 → True; threshold=0.6 → False. assert transparency.evaluate(im, threshold=0.4) is True assert transparency.evaluate(im, threshold=0.6) is False def test_transparency_evaluate_false_for_rgb_image_without_alpha(): im = Image.new("RGB", (10, 10), (128, 128, 128)) assert transparency.evaluate(im, threshold=0.5) is False def test_transparency_evaluate_false_for_animated_image(): im = Image.new("RGBA", (10, 10), (0, 0, 0, 0)) # Mark as animated (mimics PIL's WebP/GIF multi-frame attribute). im.is_animated = True # type: ignore[attr-defined] im.n_frames = 5 # type: ignore[attr-defined] assert transparency.evaluate(im, threshold=0.5) is False