Files
dtf-system/tests/test_grade_check.py
Cauê Faleiros 37715ef223
All checks were successful
Build and deploy / Validate source (push) Successful in 1m23s
Build and deploy / Integration suite on a real stack (push) Successful in 3m13s
Build and deploy / Secret scan and release gate (push) Successful in 10s
Build and deploy / Publish images (push) Successful in 1m25s
feat: the server checks the grade against the files before approving
The price depends on the grade, which the browser worked out and the API
took on trust. Before a cart is approved at checkout the API now recomputes
it from the uploaded files by the Site's own rules: the pixel size in a
PNG, JPG or WebP header across the printed width (rotation included), and
the area-weighted DPI of the images placed in a PDF of up to 150 MB, 300
for vectors. Sheets take the worst grade, artworks the average. A claim more
than 2 points above the file's grade, or a discount on a file the server
cannot grade, waits for an operator, with the reason on the Kanban.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-30 12:24:37 -03:00

87 lines
3.9 KiB
Python

"""The server's grade against real image and PDF files.
Runs where Pillow and pikepdf are installed (the API image).
"""
import io
import tempfile
import unittest
import pikepdf
from PIL import Image
from app import grade_check
class FakeFiles:
def __init__(self, blobs):
self.blobs = blobs
def head(self, row):
return self.blobs[row['name']][:grade_check.HEAD_BYTES]
def pdf_dpi(self, row):
with tempfile.NamedTemporaryFile(suffix='.pdf') as handle:
handle.write(self.blobs[row['name']])
handle.flush()
return grade_check.pdf_dpi(handle.name)
def encoded(fmt, size, **options):
out = io.BytesIO()
Image.new('RGBA' if fmt in ('PNG', 'WEBP') else 'RGB', size, (200, 30, 30)).save(out, fmt, **options)
return out.getvalue()
def item(kind, grade, sources):
return {'grade': grade, 'production': {'sources': [
{'upload_id': name, 'kind': kind, 'width_cm': width, 'rotation_degrees': rotation}
for name, width, rotation in sources]}}
class GradeCheckTests(unittest.TestCase):
def test_image_sizes_from_the_first_bytes(self):
for fmt, options in (('PNG', {}), ('JPEG', {'quality': 80}), ('JPEG', {'progressive': True}),
('WEBP', {'lossless': True}), ('WEBP', {'quality': 80})):
self.assertEqual(grade_check.image_size(encoded(fmt, (1234, 567), **options)), (1234, 567), (fmt, options))
# A JPEG with a large metadata block before the frame header.
exif = Image.Exif()
exif[0x010E] = 'x' * 60000
self.assertEqual(grade_check.image_size(encoded('JPEG', (800, 600), exif=exif)), (800, 600))
self.assertIsNone(grade_check.image_size(b'not an image at all'))
def test_pdf_dpi_is_the_images_area_weighted(self):
out = io.BytesIO()
Image.new('RGB', (1500, 750), 'white').save(out, 'PDF', resolution=150)
with tempfile.NamedTemporaryFile(suffix='.pdf') as handle:
handle.write(out.getvalue()); handle.flush()
self.assertEqual(grade_check.pdf_dpi(handle.name), 150)
vector = pikepdf.new()
vector.add_blank_page(page_size=(1615, 850))
with tempfile.NamedTemporaryFile(suffix='.pdf') as handle:
vector.save(handle.name)
self.assertEqual(grade_check.pdf_dpi(handle.name), 300)
def test_grades_follow_the_site(self):
# 57 cm is 22.44 in: 6059 px is 270 DPI, grade 90; 3366 px is 150 DPI, grade 50.
files = FakeFiles({'a.png': encoded('PNG', (6059, 100)), 'b.jpg': encoded('JPEG', (3366, 100)),
'tall.png': encoded('PNG', (100, 2362)), 'x.cdr': b'CDR'})
rows = {n: {'name': n, 'size': 1} for n in files.blobs}
# A sheet takes the worst sheet's grade.
self.assertEqual(grade_check.item_grade(files, item('sheet', 0, [('a.png', 57, 0)]), rows), 90)
self.assertEqual(grade_check.item_grade(files, item('sheet', 0, [('a.png', 57, 0), ('b.jpg', 57, 0)]), rows), 50)
# Artworks average; a rotated one is measured along its height.
self.assertEqual(grade_check.item_grade(files, item('artwork', 0, [('a.png', 57, 0), ('b.jpg', 57, 0)]), rows), 70)
self.assertEqual(grade_check.item_grade(files, item('artwork', 0, [('tall.png', 20, 90)]), rows), 100)
self.assertIsNone(grade_check.item_grade(files, item('sheet', 0, [('x.cdr', 57, 0)]), rows))
# What the cart claims is checked, with a point or two of rounding.
claim = lambda g, src: grade_check.mismatch(files, [item('sheet', g, src)], rows)
self.assertIsNone(claim(90, [('a.png', 57, 0)]))
self.assertIsNone(claim(92, [('a.png', 57, 0)]))
self.assertEqual(claim(100, [('a.png', 57, 0)]), 'Nota 100 maior que a do arquivo (90)')
self.assertEqual(claim(40, [('x.cdr', 57, 0)]), 'Nota não conferida no servidor')
self.assertIsNone(claim(0, [('x.cdr', 57, 0)]))
if __name__ == '__main__':
unittest.main()