test(api): cover WebP/JPEG negotiation, which nothing exercised
from_accept returns JPEG unless Accept contains image/webp, and no thumbnail test sent the header — curl defaults to */*, which does not match. So the whole suite ran on JPEG and the WebP path was never exercised over HTTP, despite being what background generation writes and what the derived tier was built around. The gap was invisible because the JPEG results were all correct. Three assertions, one property each. Content-Type proves negotiation happened: thumbnail_content_type sniffs the body with `infer` rather than echoing the request, so image/webp cannot be right by accident — serve JPEG bytes down the WebP path and it reads image/jpeg and fails. Differing bytes prove they are genuinely two artifacts rather than one served twice. Differing ETags prove the validators are separate. `variant` has carried the format only since 20261022000000; before that a JPEG request could match the WebP row and be served the wrong codec, and a shared validator is exactly how a cache would then hand either to either. A final conditional request confirms each codec revalidates against its own. Together these also cover the per-format variant keying that lets one source hold both codecs — the prerequisite for JPEG clients ever leaving the sidecar, and therefore for step 10e. Note on placement: thumb_etag stays in step 4's capture block, beside thumb_bytes. Every later request omits Accept and so negotiates JPEG, so the validator must be the JPEG one — captured after the new block it would describe a different codec than the bytes next to it, and the copy assertions compare against both.
This commit is contained in:
@@ -140,9 +140,68 @@ Authorization: Bearer {{token}}
|
||||
HTTP 200
|
||||
[Captures]
|
||||
thumb_bytes: bytes
|
||||
# The JPEG validator, since every later request omits `Accept` and so
|
||||
# negotiates JPEG too. Captured here rather than after step 4b, or it
|
||||
# would belong to a different codec than the bytes beside it.
|
||||
thumb_etag: header "ETag"
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# Step 4b – Codec negotiation: WebP and JPEG are separate artifacts.
|
||||
#
|
||||
# Every other request in the suite omits `Accept`, and curl defaults to
|
||||
# `*/*`, which `ThumbnailFormat::from_accept` maps to JPEG — so without
|
||||
# this case the WebP path is never exercised at all, despite being what
|
||||
# background generation writes and what the derived tier was built
|
||||
# around.
|
||||
#
|
||||
# The three assertions are one property each:
|
||||
#
|
||||
# Content-Type — negotiation actually happened (it is byte-sniffed
|
||||
# from the body, so it cannot be right by accident).
|
||||
# bytes — the two really are different artifacts.
|
||||
# ETag — the validators are distinct. `variant` carries the
|
||||
# format since migration 20261022000000; before that a
|
||||
# JPEG request could match the WebP row and be served
|
||||
# the wrong codec, and a shared validator is how a
|
||||
# cache would then hand either to either.
|
||||
#
|
||||
# Together they also cover the per-format variant keying that lets one
|
||||
# source hold both codecs — the prerequisite for JPEG clients ever
|
||||
# leaving the sidecar.
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
GET {{base_url}}/api/files/{{orig_file_id}}/thumbnail/preview
|
||||
Authorization: Bearer {{token}}
|
||||
Accept: image/webp
|
||||
|
||||
HTTP 200
|
||||
[Captures]
|
||||
webp_bytes: bytes
|
||||
webp_etag: header "ETag"
|
||||
[Asserts]
|
||||
header "Content-Type" == "image/webp"
|
||||
|
||||
|
||||
GET {{base_url}}/api/files/{{orig_file_id}}/thumbnail/preview
|
||||
Authorization: Bearer {{token}}
|
||||
Accept: image/jpeg
|
||||
|
||||
HTTP 200
|
||||
[Asserts]
|
||||
header "Content-Type" == "image/jpeg"
|
||||
bytes != {{webp_bytes}}
|
||||
header "ETag" != "{{webp_etag}}"
|
||||
|
||||
|
||||
# Each codec revalidates against its OWN validator.
|
||||
GET {{base_url}}/api/files/{{orig_file_id}}/thumbnail/preview
|
||||
Authorization: Bearer {{token}}
|
||||
Accept: image/webp
|
||||
If-None-Match: {{webp_etag}}
|
||||
|
||||
HTTP 304
|
||||
|
||||
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
# Step 5 – Single-file copy into the destination folder
|
||||
# ─────────────────────────────────────────────────────────────
|
||||
|
||||
Reference in New Issue
Block a user