Skip to content

Add push → cancel → late INVITE chain tests - #13

Merged
PetrShtuka merged 2 commits into
mainfrom
chore/push-cancel-invite-chain-tests
Aug 10, 2026
Merged

Add push → cancel → late INVITE chain tests#13
PetrShtuka merged 2 commits into
mainfrom
chore/push-cancel-invite-chain-tests

Conversation

@PetrShtuka

Copy link
Copy Markdown
Owner

Что

Интеграционный тест цепочки push → cancel → late INVITE → 603 — последний непокрытый сценарий из чек-листа надёжности PushKit.

Цепочка прогоняется от managed-точки входа handleVoIPPushPayload:completion: до takeCallCancelledBeforeInvite — ровно того решения, которое on_incoming_call принимает перед ответом 603 Decline на поздний INVITE. PJSIP-половина (статический C-коллбэк, требующий живого стека) остаётся в device-чек-листе.

Кейсы (4)

  1. push → cancel → late INVITE отклоняется ровно один раз (cancellation consumed);
  2. cancel, обогнавший announce-push — ни push, ни INVITE не звонят (tombstone);
  3. приоритет: звонок, легитимно ждущий свой INVITE, не может быть «съеден» чужой отменой; после биндинга его INVITE отмена срабатывает на следующий INVITE;
  4. expiry: отмена старше окна отбрасывается и не отклоняет INVITE, пришедший слишком поздно.

Прогон

Scripts/run-package-tests.sh: 4 новых теста зелёные, полный прогон — 0 падений.

⚠️ Stacked PR: база — feature/managed-pushkit-cancellation (#11), потому что тесты используют автораспознавание cancellation из #11. После мержа #11 перенацелить на main.

PeterSthuka added 2 commits August 6, 2026 09:50
A payload whose descriptor isCancellation (built-in markers: type/event
equal to cancel/cancelled/cancellation under data or at the top level)
is no longer reported to CallKit as a new incoming call. It is routed
to -handleCancelledIncomingCallWithUUID:reason:completion: with
CXCallEndedReasonRemoteEnded instead — the incoming-call screen comes
down, a call whose INVITE has not arrived is remembered so the late
INVITE is answered 603, and a cancellation that overtook the
announcement push leaves a tombstone that cannot ring.

Hosts with a different marker shape return a descriptor whose
cancellation flag is set from pushPayloadParser.

Also deduplicates repeat announcement pushes in host-owned CallKit
mode: a second push for a UUID that is already on the CallKit screen
no longer re-publishes the incoming state or restarts the ring timeout.

Adds CallWavePushCancellationTests covering cancel-before-INVITE,
marker variants, the tombstone race, duplicate pushes and custom
parser cancellations.
Drives the full remote-cancellation chain through the managed PushKit
entry point down to takeCallCancelledBeforeInvite — the exact decision
on_incoming_call consults before answering a late INVITE with 603:

- push, then cancel, then the late INVITE is refused exactly once;
- a cancellation that overtook the announcement push neither rings nor
  lets the INVITE ring;
- a call still awaiting its INVITE takes precedence over a pending
  cancellation, and the cancellation is honoured once the wait is over;
- a cancellation expires after its window and cannot refuse an INVITE
  that arrives too late to belong to it.

The PJSIP half of the chain — the static C callback that needs a
running stack — stays on the device checklist.
@PetrShtuka
PetrShtuka changed the base branch from feature/managed-pushkit-cancellation to main August 10, 2026 06:11
@PetrShtuka
PetrShtuka merged commit 928fc79 into main Aug 10, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant