Skip to content

Type webhook action/resource as enums + encode the relationship - #9

Merged
loevgaard merged 1 commit into
2.xfrom
webhook-enums-fail-fast
Jun 23, 2026
Merged

loevgaard merged 1 commit into
2.xfrom
webhook-enums-fail-fast

Conversation

@loevgaard

Copy link
Copy Markdown
Member

What

Two related changes around the webhook enums, both in the fail-fast direction.

1. Encode the resource ↔ action relationship

Shipmondo only allows certain actions per resource. That mapping is now on the enum:

WebhookResourceName::Orders->actions();   // list<WebhookAction>
WebhookResourceName::Orders->supports(WebhookAction::Delete); // true

And WebhooksEndpoint::create() rejects an invalid pair before sending (only when both resourceName and action are set — null fields stay server-authoritative):

$client->webhooks()->create(new WebhookRequest(
    resourceName: WebhookResourceName::Shipments,
    action: WebhookAction::Delete, // not valid for Shipments
));
// throws \InvalidArgumentException before the HTTP call (instead of a server 422)

2. Strict enums on the read paths (fail-fast)

action / resourceType were lenient strings. They're now the WebhookAction / WebhookResourceName enums on both webhook DTOs, and an unexpected value blows up rather than slipping through:

  • Inbound — WebhookEvent::$action / $resourceType are enums; WebhookParser resolves the SMD-Action / SMD-Resource-Type headers via tryFrom() and throws MalformedWebhookException (a ShipmondoException) if a header is missing or unknown.
  • Read — the response Webhook::$action / $resourceName are enums; an unknown value now fails mapping with a MappingException. The original strings remain reachable via Resource::$raw.

This reverses the earlier deliberate "lenient reads" choice — at the maintainer's request (preference for things to blow up when something is unexpected). Since 2.x is still in alpha, there's no stable BC to worry about.

⚠️ Behavior change: webhooks()->getPage() / paginate() will now throw if any single webhook subscription carries an action/resource the SDK doesn't model yet (the agreed trade-off for consistency with the inbound path).

Tests

  • New WebhookResourceNameTest: actions() per resource, supports() truth table, and an invariant that every WebhookAction is mapped to at least one resource (guards against forgetting to map a new action).
  • WebhooksEndpointTest: invalid resource/action combo throws before sending.
  • WebhookParserTest: unknown action, missing action, and unknown resource each throw MalformedWebhookException; happy-path assertions updated to enums.

Verification

  • PHPUnit: 106 tests / 248 assertions (3 live-API skipped); line coverage 97.57%
  • PHPStan max: clean
  • ECS: clean

Makes the webhook action and resource strict enums that fail fast on an
unexpected value, and adds the resource -> actions relationship.

- WebhookResourceName::actions(): list<WebhookAction> and
  supports(WebhookAction): bool encode which actions Shipmondo allows for
  each resource.
- WebhooksEndpoint::create() rejects an unsupported resource/action pair
  (when both are set) before sending, instead of a server 422.
- The response Webhook and the inbound WebhookEvent now type action /
  resourceName (resourceType) as WebhookAction / WebhookResourceName.
  An unknown value fails fast: a MappingException on the read path and a
  MalformedWebhookException in the parser (the raw strings remain reachable
  via Resource::$raw on the response). This reverses the earlier
  lenient-strings choice.
@codecov

codecov Bot commented Jun 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.07%. Comparing base (ffb41ba) to head (64412c1).

Additional details and impacted files
@@             Coverage Diff              @@
##                2.x       #9      +/-   ##
============================================
+ Coverage     97.89%   98.07%   +0.17%     
- Complexity      179      186       +7     
============================================
  Files            32       33       +1     
  Lines           476      520      +44     
============================================
+ Hits            466      510      +44     
  Misses           10       10              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@loevgaard
loevgaard merged commit 0bf7a00 into 2.x Jun 23, 2026
23 checks passed
@loevgaard
loevgaard deleted the webhook-enums-fail-fast branch June 23, 2026 11:09
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