feat(print): AirPrint queue detection + Stage 2 warning badge (#202 Phase 5) #207

Merged
gronod merged 1 commits from feat/202-airprint-detection into milestone/m12-native-spool 2026-09-17 17:31:10 +01:00
Owner

Summary

Phase 5 of the M12 megaplan: AirPrint queue detection during enumeration plus a persistent Stage 2 warning badge (#202, docs/14 §10.2).

  • CupsParsers — new lpstatDeviceURIs(output:), lpoptionsMakeAndModel(output:), and detectAirPrint(deviceURI:makeAndModel:ppd:) implementing the six rules: apple-airprint:// URI; *APAirPrint: True; make-and-model with "Apple"+"AirPrint"; ipps:// + PPD "airprint" mention; local ipp:// resolved via the _universal._sub._ipp._tcp mDNS subtype; *cupsFilter2 destination image/urf.
  • CupsService.listPrinters — one extra lpstat -v spawn (cupsLpstat("v"), tolerateFailure: true, no fallback respawn); lpoptions -p now yields display name and make-and-model from a single spawn per queue; Printer.isAirPrint populated from URI + make-and-model + loaded PPD.
  • Printer.isAirPrint: Bool = false — tolerant decoder so pre-#202 payloads still decode; PrintOptions.cupsOptions doc updated to "Stage 2 mirror, not an lp payload".
  • Stage2View — live airPrintWarningBadge: "AirPrint queue — unmanaged colour cannot be guaranteed." shown only while the selected queue is AirPrint.
  • Fixtures — lpstat -v marks Mock_Canon_Pro via the _universal mDNS subtype; lpoptions emits printer-make-and-model='EPSON XP-55 Series'.

Tests

  • CupsParserTests: fixture-driven case per rule (6 true), USB Epson negative, plus testListPrintersToleratesLpstatVFailure asserting enumeration proceeds with isAirPrint == false and exactly one -v spawn.
  • Milestone12AirPrintUITests: badge appears for the AirPrint fixture queue and disappears for the USB queue, both directions.

Verification

xcodebuild test -scheme ICCery -destination 'platform=macOS' ARCHS=x86_64 — 515 unit + 69 UI tests; sole failure was the new test's label-vs-value assertion, fixed and re-run green (70 UI tests total).

Part of #202.

## Summary Phase 5 of the M12 megaplan: AirPrint queue detection during enumeration plus a persistent Stage 2 warning badge (#202, docs/14 §10.2). - `CupsParsers` — new `lpstatDeviceURIs(output:)`, `lpoptionsMakeAndModel(output:)`, and `detectAirPrint(deviceURI:makeAndModel:ppd:)` implementing the six rules: `apple-airprint://` URI; `*APAirPrint: True`; make-and-model with "Apple"+"AirPrint"; `ipps://` + PPD "airprint" mention; local `ipp://` resolved via the `_universal._sub._ipp._tcp` mDNS subtype; `*cupsFilter2` destination `image/urf`. - `CupsService.listPrinters` — one extra `lpstat -v` spawn (`cupsLpstat("v")`, `tolerateFailure: true`, **no fallback respawn**); `lpoptions -p` now yields display name and make-and-model from a single spawn per queue; `Printer.isAirPrint` populated from URI + make-and-model + loaded PPD. - `Printer.isAirPrint: Bool = false` — tolerant decoder so pre-#202 payloads still decode; `PrintOptions.cupsOptions` doc updated to "Stage 2 mirror, not an `lp` payload". - `Stage2View` — live `airPrintWarningBadge`: "AirPrint queue — unmanaged colour cannot be guaranteed." shown only while the selected queue is AirPrint. - Fixtures — `lpstat -v` marks `Mock_Canon_Pro` via the `_universal` mDNS subtype; `lpoptions` emits `printer-make-and-model='EPSON XP-55 Series'`. ## Tests - `CupsParserTests`: fixture-driven case per rule (6 true), USB Epson negative, plus `testListPrintersToleratesLpstatVFailure` asserting enumeration proceeds with `isAirPrint == false` and exactly **one** `-v` spawn. - `Milestone12AirPrintUITests`: badge appears for the AirPrint fixture queue and disappears for the USB queue, both directions. ## Verification `xcodebuild test -scheme ICCery -destination 'platform=macOS' ARCHS=x86_64` — 515 unit + 69 UI tests; sole failure was the new test's label-vs-value assertion, fixed and re-run green (70 UI tests total). Part of #202.
gronod added 1 commit 2026-09-17 17:20:52 +01:00
- CupsParsers: lpstatDeviceURIs / lpoptionsMakeAndModel /
  detectAirPrint — the six docs/14 §10.2 rules (apple-airprint:// URI,
  *APAirPrint: True, Apple+AirPrint make-and-model, ipps://+PPD
  mention, ipp:// + _universal mDNS subtype, cupsFilter2→image/urf).
- CupsService.listPrinters: one tolerated lpstat -v spawn feeds
  detection; lpoptions -p yields displayName + makeAndModel in a
  single spawn; Printer.isAirPrint populated per queue.
- Printer.isAirPrint defaults false with a tolerant decoder.
- Stage2View: live airPrintWarningBadge — "AirPrint queue —
  unmanaged colour cannot be guaranteed."
- Fixtures: lpstat -v marks Mock_Canon_Pro via _universal subtype;
  lpoptions emits printer-make-and-model.
- Tests: six rule fixtures + USB negative + a no-fallback-respawn
  listPrinters case; Milestone12AirPrintUITests tracks the badge
  across queue selection.

Gate: full xcodebuild test green (515 unit + 70 UI).
gronod merged commit 7a3a0886be into milestone/m12-native-spool 2026-09-17 17:31:10 +01:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: gronod/iccery-v2-mac#207