Browse Source

fix(tests): check label text in the content stream, not the whole PDF

maziggy 1 day ago
parent
commit
bc649befc3
1 changed files with 19 additions and 3 deletions
  1. 19 3
      backend/tests/unit/services/test_label_renderer_fields.py

+ 19 - 3
backend/tests/unit/services/test_label_renderer_fields.py

@@ -1,12 +1,13 @@
 """Choosing what a spool label shows, and PNG output (#2981).
 
-Text is checked in an uncompressed PDF, where ReportLab writes each string as
-it was drawn.
+Text is checked in the content stream of an uncompressed PDF, where ReportLab
+writes each string as it was drawn.
 """
 
 from __future__ import annotations
 
 import io
+import re
 from datetime import date
 from unittest.mock import patch
 
@@ -51,13 +52,28 @@ def _data(**overrides) -> LabelData:
 
 
 def _text(template: str, data: LabelData, fields=DEFAULT_LABEL_FIELDS) -> bytes:
+    """The page's content stream, i.e. only the text and shapes drawn.
+
+    Not the whole file: its creation timestamp, document ID and xref offsets
+    change from run to run, so a "not in" check against them fails whenever
+    they happen to contain the digits (a run at 14:32:30 writes ``143230``).
+    The QR code's image stream is left out for the same reason.
+    """
     w_mm, h_mm = label_size_mm(template)
     buf = io.BytesIO()
     c = rl_canvas.Canvas(buf, pagesize=(w_mm * mm, h_mm * mm), pageCompression=0)
     _draw_label(c, 0, 0, w_mm * mm, h_mm * mm, data, False, fields)
     c.showPage()
     c.save()
-    return buf.getvalue()
+    pdf = buf.getvalue()
+    streams = []
+    for m in re.finditer(rb"stream\r?\n(.*?)endstream", pdf, re.S):
+        # The object's own dictionary sits between its "N 0 obj" and "stream".
+        head = pdf[pdf.rfind(b" obj", 0, m.start()) : m.start()]
+        if b"/Subtype /Image" not in head:
+            streams.append(m.group(1))
+    assert len(streams) == 1, f"expected one page content stream, got {len(streams)}"
+    return streams[0]
 
 
 def test_default_fields_are_what_labels_always_carried():