From d789117592436bbe00b4797fda3ce357a6583c7f Mon Sep 17 00:00:00 2001 From: Bjarn Bronsveld Date: Tue, 7 Jul 2026 22:41:28 +0200 Subject: [PATCH] Add latest Team API support --- src/Client/ApiClient.php | 12 ++++++++++ src/Objects/MessageEventData.php | 2 +- src/Objects/ProjectData.php | 1 + src/Objects/StoreProjectData.php | 1 + src/Objects/StoreSuppressionData.php | 2 +- src/Objects/StoreWebhookData.php | 2 +- src/Objects/TeamData.php | 2 +- src/Objects/UpdateProjectData.php | 1 + src/Objects/UpdateRouteData.php | 4 ++-- .../UpdateRouteInboundSettingsData.php | 15 +++++++++++++ src/Objects/UpdateRouteSettingsData.php | 17 ++++++++++++++ src/Objects/UpdateWebhookData.php | 2 +- src/Objects/WebhookDeliveryData.php | 2 +- src/Objects/WebhookDeliveryListData.php | 2 +- src/Objects/WebhookListData.php | 2 +- src/Responses/BlockedFileTypesResponse.php | 14 ++++++++++++ src/Responses/ProjectResponse.php | 1 + src/Responses/TeamResponse.php | 2 +- src/Responses/WebhookDeliveryResponse.php | 2 +- src/Types/ApiTypes.php | 19 +++++++++------- tests/Client/ApiClientTest.php | 20 +++++++++++++++++ tests/SdkCoverageTest.php | 22 ++++++++++++++++++- 22 files changed, 126 insertions(+), 21 deletions(-) create mode 100644 src/Objects/UpdateRouteInboundSettingsData.php create mode 100644 src/Objects/UpdateRouteSettingsData.php create mode 100644 src/Responses/BlockedFileTypesResponse.php diff --git a/src/Client/ApiClient.php b/src/Client/ApiClient.php index c0e51cc..3876ffc 100644 --- a/src/Client/ApiClient.php +++ b/src/Client/ApiClient.php @@ -11,6 +11,7 @@ use Lettermint\Endpoints\SuppressionsEndpoint; use Lettermint\Endpoints\TeamEndpoint; use Lettermint\Endpoints\WebhooksEndpoint; +use Lettermint\Responses\BlockedFileTypesResponse; /** * @property-read DomainsEndpoint $domains Access domain operations. @@ -68,4 +69,15 @@ public function ping(): string { return trim($this->httpClient->getRaw('/v1/ping')); } + + public function blockedFileTypes(): BlockedFileTypesResponse + { + $response = $this->httpClient->get('/v1/blocked-file-types'); + + if (! is_array($response)) { + throw new \UnexpectedValueException('Expected API response to be an array.'); + } + + return new BlockedFileTypesResponse($response); + } } diff --git a/src/Objects/MessageEventData.php b/src/Objects/MessageEventData.php index 4055874..fa42513 100644 --- a/src/Objects/MessageEventData.php +++ b/src/Objects/MessageEventData.php @@ -6,7 +6,7 @@ /** * @property string $message_id - * @property 'queued'|'processed'|'suppressed'|'delivered'|'soft_bounced'|'hard_bounced'|'spam_complaint'|'failed'|'blocked'|'policy_rejected'|'unsubscribed'|'opened'|'clicked'|'inbound_received'|'inbound_queued'|'inbound_spam_blocked'|'inbound_processed'|'inbound_retry' $event + * @property 'queued'|'processed'|'suppressed'|'delivered'|'auto_replied'|'soft_bounced'|'hard_bounced'|'spam_complaint'|'failed'|'blocked'|'policy_rejected'|'unsubscribed'|'opened'|'clicked'|'inbound_received'|'inbound_queued'|'inbound_spam_blocked'|'inbound_processed'|'inbound_retry' $event * @property array|null $metadata * @property string $timestamp */ diff --git a/src/Objects/ProjectData.php b/src/Objects/ProjectData.php index 61acffd..059783c 100644 --- a/src/Objects/ProjectData.php +++ b/src/Objects/ProjectData.php @@ -8,6 +8,7 @@ * @property string $id * @property string $name * @property bool $smtp_enabled + * @property bool $redact_email_content * @property string|null $default_route_id * @property string|null $token_generated_at * @property string|null $token_last_used_at diff --git a/src/Objects/StoreProjectData.php b/src/Objects/StoreProjectData.php index b1042d2..92f1378 100644 --- a/src/Objects/StoreProjectData.php +++ b/src/Objects/StoreProjectData.php @@ -8,6 +8,7 @@ * @property string $name * @property bool $smtp_enabled * @property 'both'|'transactional'|'broadcast' $initial_routes + * @property bool $short_token */ final class StoreProjectData extends Resource { diff --git a/src/Objects/StoreSuppressionData.php b/src/Objects/StoreSuppressionData.php index 97f9b35..a67d6d7 100644 --- a/src/Objects/StoreSuppressionData.php +++ b/src/Objects/StoreSuppressionData.php @@ -7,7 +7,7 @@ /** * @property string|null $email * @property 'spam_complaint'|'hard_bounce'|'unsubscribe'|'manual' $reason - * @property 'team'|'project'|'route' $scope + * @property 'global'|'team'|'project'|'route' $scope * @property string|null $route_id * @property string|null $project_id * @property list|null $emails diff --git a/src/Objects/StoreWebhookData.php b/src/Objects/StoreWebhookData.php index ae0222e..e25046b 100644 --- a/src/Objects/StoreWebhookData.php +++ b/src/Objects/StoreWebhookData.php @@ -10,7 +10,7 @@ * @property string $url * @property bool|null $enabled * @property bool|null $include_machine_events - * @property list<'message.created'|'message.sent'|'message.delivered'|'message.hard_bounced'|'message.soft_bounced'|'message.spam_complaint'|'message.failed'|'message.suppressed'|'message.unsubscribed'|'message.opened'|'message.clicked'|'message.inbound'|'message.policy_rejected'|'webhook.test'> $events + * @property list<'message.created'|'message.sent'|'message.delivered'|'message.auto_replied'|'message.hard_bounced'|'message.soft_bounced'|'message.spam_complaint'|'message.failed'|'message.suppressed'|'message.unsubscribed'|'message.opened'|'message.clicked'|'message.inbound'|'message.policy_rejected'|'webhook.test'> $events */ final class StoreWebhookData extends Resource { diff --git a/src/Objects/TeamData.php b/src/Objects/TeamData.php index 44d0321..9d930e7 100644 --- a/src/Objects/TeamData.php +++ b/src/Objects/TeamData.php @@ -9,7 +9,7 @@ * @property string $name * @property 'personal'|'business' $type * @property 'free'|'starter'|'growth'|'pro' $plan - * @property 300|10000|50000|125000|500000|750000|1000000|1500000 $tier + * @property 300|10000|50000|125000|300000|500000|750000|1000000|1500000 $tier * @property string|null $verified_at * @property list $features * @property list<\Lettermint\Objects\TeamAddonData> $addons diff --git a/src/Objects/UpdateProjectData.php b/src/Objects/UpdateProjectData.php index 6fda7b3..9126d5a 100644 --- a/src/Objects/UpdateProjectData.php +++ b/src/Objects/UpdateProjectData.php @@ -7,6 +7,7 @@ /** * @property string|null $name * @property bool|null $smtp_enabled + * @property bool|null $redact_email_content * @property string|null $default_route_id */ final class UpdateProjectData extends Resource diff --git a/src/Objects/UpdateRouteData.php b/src/Objects/UpdateRouteData.php index da9b204..08b5799 100644 --- a/src/Objects/UpdateRouteData.php +++ b/src/Objects/UpdateRouteData.php @@ -6,8 +6,8 @@ /** * @property string|null $name - * @property array $settings - * @property array $inbound_settings + * @property \Lettermint\Objects\UpdateRouteSettingsData|mixed $settings + * @property \Lettermint\Objects\UpdateRouteInboundSettingsData|mixed $inbound_settings */ final class UpdateRouteData extends Resource { diff --git a/src/Objects/UpdateRouteInboundSettingsData.php b/src/Objects/UpdateRouteInboundSettingsData.php new file mode 100644 index 0000000..00930b7 --- /dev/null +++ b/src/Objects/UpdateRouteInboundSettingsData.php @@ -0,0 +1,15 @@ + $events + * @property list<'message.created'|'message.sent'|'message.delivered'|'message.auto_replied'|'message.hard_bounced'|'message.soft_bounced'|'message.spam_complaint'|'message.failed'|'message.suppressed'|'message.unsubscribed'|'message.opened'|'message.clicked'|'message.inbound'|'message.policy_rejected'|'webhook.test'> $events */ final class UpdateWebhookData extends Resource { diff --git a/src/Objects/WebhookDeliveryData.php b/src/Objects/WebhookDeliveryData.php index 303a84e..617ff31 100644 --- a/src/Objects/WebhookDeliveryData.php +++ b/src/Objects/WebhookDeliveryData.php @@ -7,7 +7,7 @@ /** * @property string $id * @property string $webhook_id - * @property 'message.created'|'message.sent'|'message.delivered'|'message.hard_bounced'|'message.soft_bounced'|'message.spam_complaint'|'message.failed'|'message.suppressed'|'message.unsubscribed'|'message.opened'|'message.clicked'|'message.inbound'|'message.policy_rejected'|'webhook.test' $event_type + * @property 'message.created'|'message.sent'|'message.delivered'|'message.auto_replied'|'message.hard_bounced'|'message.soft_bounced'|'message.spam_complaint'|'message.failed'|'message.suppressed'|'message.unsubscribed'|'message.opened'|'message.clicked'|'message.inbound'|'message.policy_rejected'|'webhook.test' $event_type * @property 'pending'|'success'|'failed'|'client_error'|'server_error'|'timeout' $status * @property int $attempt_number * @property int|null $http_status_code diff --git a/src/Objects/WebhookDeliveryListData.php b/src/Objects/WebhookDeliveryListData.php index 0422a2a..4198101 100644 --- a/src/Objects/WebhookDeliveryListData.php +++ b/src/Objects/WebhookDeliveryListData.php @@ -7,7 +7,7 @@ /** * @property string $id * @property string $webhook_id - * @property 'message.created'|'message.sent'|'message.delivered'|'message.hard_bounced'|'message.soft_bounced'|'message.spam_complaint'|'message.failed'|'message.suppressed'|'message.unsubscribed'|'message.opened'|'message.clicked'|'message.inbound'|'message.policy_rejected'|'webhook.test' $event_type + * @property 'message.created'|'message.sent'|'message.delivered'|'message.auto_replied'|'message.hard_bounced'|'message.soft_bounced'|'message.spam_complaint'|'message.failed'|'message.suppressed'|'message.unsubscribed'|'message.opened'|'message.clicked'|'message.inbound'|'message.policy_rejected'|'webhook.test' $event_type * @property 'pending'|'success'|'failed'|'client_error'|'server_error'|'timeout' $status * @property int $attempt_number * @property int|null $http_status_code diff --git a/src/Objects/WebhookListData.php b/src/Objects/WebhookListData.php index c601915..b753411 100644 --- a/src/Objects/WebhookListData.php +++ b/src/Objects/WebhookListData.php @@ -9,7 +9,7 @@ * @property string $route_id * @property string $name * @property string $url - * @property list<'message.created'|'message.sent'|'message.delivered'|'message.hard_bounced'|'message.soft_bounced'|'message.spam_complaint'|'message.failed'|'message.suppressed'|'message.unsubscribed'|'message.opened'|'message.clicked'|'message.inbound'|'message.policy_rejected'|'webhook.test'> $events + * @property list<'message.created'|'message.sent'|'message.delivered'|'message.auto_replied'|'message.hard_bounced'|'message.soft_bounced'|'message.spam_complaint'|'message.failed'|'message.suppressed'|'message.unsubscribed'|'message.opened'|'message.clicked'|'message.inbound'|'message.policy_rejected'|'webhook.test'> $events * @property bool $enabled * @property string|null $last_called_at * @property string $created_at diff --git a/src/Responses/BlockedFileTypesResponse.php b/src/Responses/BlockedFileTypesResponse.php new file mode 100644 index 0000000..1f63a2f --- /dev/null +++ b/src/Responses/BlockedFileTypesResponse.php @@ -0,0 +1,14 @@ + $extensions + * @property list $mime_types + */ +final class BlockedFileTypesResponse extends Resource +{ + // +} diff --git a/src/Responses/ProjectResponse.php b/src/Responses/ProjectResponse.php index 5ea0469..5807d31 100644 --- a/src/Responses/ProjectResponse.php +++ b/src/Responses/ProjectResponse.php @@ -8,6 +8,7 @@ * @property string $id * @property string $name * @property bool $smtp_enabled + * @property bool $redact_email_content * @property string|null $default_route_id * @property string|null $token_generated_at * @property string|null $token_last_used_at diff --git a/src/Responses/TeamResponse.php b/src/Responses/TeamResponse.php index fc827cb..1ebc825 100644 --- a/src/Responses/TeamResponse.php +++ b/src/Responses/TeamResponse.php @@ -9,7 +9,7 @@ * @property string $name * @property 'personal'|'business' $type * @property 'free'|'starter'|'growth'|'pro' $plan - * @property 300|10000|50000|125000|500000|750000|1000000|1500000 $tier + * @property 300|10000|50000|125000|300000|500000|750000|1000000|1500000 $tier * @property string|null $verified_at * @property list $features * @property list<\Lettermint\Objects\TeamAddonData> $addons diff --git a/src/Responses/WebhookDeliveryResponse.php b/src/Responses/WebhookDeliveryResponse.php index d929312..43081ac 100644 --- a/src/Responses/WebhookDeliveryResponse.php +++ b/src/Responses/WebhookDeliveryResponse.php @@ -7,7 +7,7 @@ /** * @property string $id * @property string $webhook_id - * @property 'message.created'|'message.sent'|'message.delivered'|'message.hard_bounced'|'message.soft_bounced'|'message.spam_complaint'|'message.failed'|'message.suppressed'|'message.unsubscribed'|'message.opened'|'message.clicked'|'message.inbound'|'message.policy_rejected'|'webhook.test' $event_type + * @property 'message.created'|'message.sent'|'message.delivered'|'message.auto_replied'|'message.hard_bounced'|'message.soft_bounced'|'message.spam_complaint'|'message.failed'|'message.suppressed'|'message.unsubscribed'|'message.opened'|'message.clicked'|'message.inbound'|'message.policy_rejected'|'webhook.test' $event_type * @property 'pending'|'success'|'failed'|'client_error'|'server_error'|'timeout' $status * @property int $attempt_number * @property int|null $http_status_code diff --git a/src/Types/ApiTypes.php b/src/Types/ApiTypes.php index 193b98c..7097ef6 100644 --- a/src/Types/ApiTypes.php +++ b/src/Types/ApiTypes.php @@ -20,13 +20,13 @@ * @phpstan-type MessageAttachmentData array{size: int, filename: string, content_id: string|null, content_type: string} * @phpstan-type MessageData array{id: string, type: MessageType, status: MessageStatus, status_changed_at: string|null, tag: string|null, from_email: string, from_name: string|null, reply_to: list|null, subject: string|null, to: list|null, cc: list|null, bcc: list|null, attachments: list|null, metadata: array|null, spam_score?: float|int|null, spam_symbols?: list, route_id: string, created_at: string} * @phpstan-type MessageEventData array{message_id: string, event: MessageEventType, metadata: array|null, timestamp: string} - * @phpstan-type MessageEventType 'queued'|'processed'|'suppressed'|'delivered'|'soft_bounced'|'hard_bounced'|'spam_complaint'|'failed'|'blocked'|'policy_rejected'|'unsubscribed'|'opened'|'clicked'|'inbound_received'|'inbound_queued'|'inbound_spam_blocked'|'inbound_processed'|'inbound_retry' + * @phpstan-type MessageEventType 'queued'|'processed'|'suppressed'|'delivered'|'auto_replied'|'soft_bounced'|'hard_bounced'|'spam_complaint'|'failed'|'blocked'|'policy_rejected'|'unsubscribed'|'opened'|'clicked'|'inbound_received'|'inbound_queued'|'inbound_spam_blocked'|'inbound_processed'|'inbound_retry' * @phpstan-type MessageListData array{id: string, type: MessageType, status: MessageStatus, from_email: string, from_name: string|null, subject: string|null, to: list|null, cc: list|null, bcc: list|null, reply_to: list|null, tag: string|null, created_at: string} * @phpstan-type MessageRecipientData array{email: string, name: string|null} * @phpstan-type MessageStatsData array{messages_transactional: int, messages_broadcast: int, messages_inbound: int, deliverability: float|int} * @phpstan-type MessageType 'inbound'|'outbound' * @phpstan-type Plan 'free'|'starter'|'growth'|'pro' - * @phpstan-type ProjectData array{id: string, name: string, smtp_enabled: bool, default_route_id: string|null, token_generated_at: string|null, token_last_used_at: string|null, token_last_used_ip: string|null, routes?: list, routes_count?: int, domains?: list, domains_count?: int, team_members?: list, team_members_count?: int, last_28_days?: MessageStatsData|null, created_at: string, updated_at: string} + * @phpstan-type ProjectData array{id: string, name: string, smtp_enabled: bool, redact_email_content: bool, default_route_id: string|null, token_generated_at: string|null, token_last_used_at: string|null, token_last_used_ip: string|null, routes?: list, routes_count?: int, domains?: list, domains_count?: int, team_members?: list, team_members_count?: int, last_28_days?: MessageStatsData|null, created_at: string, updated_at: string} * @phpstan-type ProjectListData array{id: string, name: string, smtp_enabled: bool, routes_count: int, domains_count: int, team_members_count: int, last_28_days: MessageStatsData, created_at: string, updated_at: string} * @phpstan-type RecordType 'TXT'|'CNAME'|'MX' * @phpstan-type RouteData array{id: string, project_id: string, slug: string, name: string, route_type: RouteType, is_default: bool, inbound_address?: string, inbound_domain?: string, inbound_domain_verified_at?: string, inbound_spam_threshold?: float|int, attachment_delivery?: AttachmentDelivery, project?: ProjectListData, webhooks_count?: int, suppressed_recipients_count?: int, statistics?: array|list, created_at: string, updated_at: string} @@ -41,9 +41,9 @@ * @phpstan-type StatsTotalsData array{sent: int, delivered: int, hard_bounced: int, spam_complaints: int, opened: int|null, clicked: int|null, inbound: StatsInboundData, transactional: StatsTypeData|null, broadcast: StatsTypeData|null, effective_opened: int|null, machine_opened: int|null, machine_clicked: int|null} * @phpstan-type StatsTypeData array{sent: int, hard_bounced: int, spam_complaints: int} * @phpstan-type StoreDomainData array{domain: string} - * @phpstan-type StoreProjectData array{name: string, smtp_enabled?: bool, initial_routes?: InitialRoutes} + * @phpstan-type StoreProjectData array{name: string, smtp_enabled?: bool, initial_routes?: InitialRoutes, short_token?: bool} * @phpstan-type StoreRouteData array{name: string, route_type: RouteType, slug?: string|null} - * @phpstan-type StoreSuppressionData array{email?: string|null, reason: SuppressionReason, scope: 'team'|'project'|'route', route_id?: string|null, project_id?: string|null, emails?: non-empty-list|null} + * @phpstan-type StoreSuppressionData array{email?: string|null, reason: SuppressionReason, scope: SuppressionScope, route_id?: string|null, project_id?: string|null, emails?: non-empty-list|null} * @phpstan-type StoreWebhookData array{route_id: string, name: string, url: string, enabled?: bool|null, include_machine_events?: bool|null, events: non-empty-list} * @phpstan-type SuppressedRecipientData array{id: string, type: SuppressionType, value: string, reason: SuppressionReason, scope: SuppressionScope, project_id: string|null, route_id: string|null, created_at: string, updated_at: string} * @phpstan-type SuppressionReason 'spam_complaint'|'hard_bounce'|'unsubscribe'|'manual' @@ -56,18 +56,20 @@ * @phpstan-type TeamUsageDetailData array{current_period: TeamUsagePeriodData, historical_usage: list} * @phpstan-type TeamUsagePeriodData array{usage: int, last_incremented_at: string|null, period_start: string, period_end: string} * @phpstan-type UpdateDomainProjectsData array{project_ids: non-empty-list} - * @phpstan-type UpdateProjectData array{name?: string|null, smtp_enabled?: bool|null, default_route_id?: string|null} + * @phpstan-type UpdateProjectData array{name?: string|null, smtp_enabled?: bool|null, redact_email_content?: bool|null, default_route_id?: string|null} * @phpstan-type UpdateProjectMembersData array{team_member_ids: non-empty-list} - * @phpstan-type UpdateRouteData array{name?: string|null, settings?: array{track_opens?: bool|null, track_clicks?: bool|null, disable_hosted_unsubscribe?: bool|null}, inbound_settings?: array{inbound_domain?: string|null, inbound_spam_threshold?: float|int|null, attachment_delivery?: AttachmentDelivery}} + * @phpstan-type UpdateRouteData array{name?: string|null, settings?: UpdateRouteSettingsData|null, inbound_settings?: UpdateRouteInboundSettingsData|null} + * @phpstan-type UpdateRouteInboundSettingsData array{inbound_domain?: string|null, inbound_spam_threshold?: float|int|null, attachment_delivery?: AttachmentDelivery|null} + * @phpstan-type UpdateRouteSettingsData array{track_opens?: bool|null, track_clicks?: bool|null, disable_plaintext_generation?: bool|null, disable_hosted_unsubscribe?: bool|null, redact_email_content?: bool|null} * @phpstan-type UpdateTeamData array{name?: string|null} * @phpstan-type UpdateWebhookData array{name?: string, url?: string, enabled?: bool, include_machine_events?: bool, events?: non-empty-list} * @phpstan-type UserData array{id: string, name: string, email: string, avatar: string|null} - * @phpstan-type VolumeTier 300|10000|50000|125000|500000|750000|1000000|1500000 + * @phpstan-type VolumeTier 300|10000|50000|125000|300000|500000|750000|1000000|1500000 * @phpstan-type WebhookData array{id: string, route_id: string, name: string, url: string, events: non-empty-list, enabled: bool, include_machine_events: bool, secret?: string, last_called_at: string|null, created_at: string, updated_at: string} * @phpstan-type WebhookDeliveryData array{id: string, webhook_id: string, event_type: WebhookEvent, status: WebhookDeliveryStatus, attempt_number: int, http_status_code: int|null, duration_ms: int|null, payload: non-empty-list, response_body: string|null, response_headers: list|null, error_message: string|null, delivered_at: string|null, timestamp: string} * @phpstan-type WebhookDeliveryListData array{id: string, webhook_id: string, event_type: WebhookEvent, status: WebhookDeliveryStatus, attempt_number: int, http_status_code: int|null, duration_ms: int|null, delivered_at: string|null, created_at: string} * @phpstan-type WebhookDeliveryStatus 'pending'|'success'|'failed'|'client_error'|'server_error'|'timeout' - * @phpstan-type WebhookEvent 'message.created'|'message.sent'|'message.delivered'|'message.hard_bounced'|'message.soft_bounced'|'message.spam_complaint'|'message.failed'|'message.suppressed'|'message.unsubscribed'|'message.opened'|'message.clicked'|'message.inbound'|'message.policy_rejected'|'webhook.test' + * @phpstan-type WebhookEvent 'message.created'|'message.sent'|'message.delivered'|'message.auto_replied'|'message.hard_bounced'|'message.soft_bounced'|'message.spam_complaint'|'message.failed'|'message.suppressed'|'message.unsubscribed'|'message.opened'|'message.clicked'|'message.inbound'|'message.policy_rejected'|'webhook.test' * @phpstan-type WebhookListData array{id: string, route_id: string, name: string, url: string, events: list, enabled: bool, last_called_at: string|null, created_at: string, updated_at: string} * @phpstan-type StatsQuery StatsRequestData * @phpstan-type SendMailResponse array{message_id: string, status: MessageStatus} @@ -78,6 +80,7 @@ * @phpstan-type VerifyDnsRecordsResponse array{message: string} * @phpstan-type VerifyDnsRecordResponse array{message: string} * @phpstan-type UpdateDomainProjectsResponse array{data: DomainData, message: string} + * @phpstan-type BlockedFileTypesResponse array{extensions: list, mime_types: list} * @phpstan-type MessageListResponse array{data: list, path: string|null, per_page: int, next_cursor: string|null, next_page_url: string|null, prev_cursor: string|null, prev_page_url: string|null}|list * @phpstan-type MessageResponse MessageData * @phpstan-type MessageEventsResponse array{data: list, path: string|null, per_page: int, next_cursor: string|null, next_page_url: string|null, prev_cursor: string|null, prev_page_url: string|null} diff --git a/tests/Client/ApiClientTest.php b/tests/Client/ApiClientTest.php index ba76f6e..e808343 100644 --- a/tests/Client/ApiClientTest.php +++ b/tests/Client/ApiClientTest.php @@ -10,6 +10,7 @@ use Lettermint\Endpoints\SuppressionsEndpoint; use Lettermint\Endpoints\TeamEndpoint; use Lettermint\Endpoints\WebhooksEndpoint; +use Lettermint\Responses\BlockedFileTypesResponse; test('it exposes api endpoints', function () { $client = new ApiClient('api-token', 'http://api.example.com'); @@ -50,3 +51,22 @@ expect($client->ping())->toBe('pong'); }); + +test('it lists blocked file types', function () { + $client = new ApiClient('api-token', 'http://api.example.com'); + $reflection = new ReflectionClass($client); + $property = $reflection->getProperty('httpClient'); + $property->setAccessible(true); + $httpClient = Mockery::mock(HttpClient::class); + $httpClient->shouldReceive('get') + ->once() + ->with('/v1/blocked-file-types') + ->andReturn(['extensions' => ['exe'], 'mime_types' => ['application/x-msdownload']]); + $property->setValue($client, $httpClient); + + $response = $client->blockedFileTypes(); + + expect($response)->toBeInstanceOf(BlockedFileTypesResponse::class) + ->and($response->extensions)->toBe(['exe']) + ->and($response->mime_types)->toBe(['application/x-msdownload']); +}); diff --git a/tests/SdkCoverageTest.php b/tests/SdkCoverageTest.php index 2067da4..dab6c24 100644 --- a/tests/SdkCoverageTest.php +++ b/tests/SdkCoverageTest.php @@ -24,6 +24,7 @@ ['team', 'domain.verifySpecificDnsRecord', DomainsEndpoint::class, 'verifyDnsRecord'], ['team', 'domain.updateProjects', DomainsEndpoint::class, 'updateProjects'], ['team', 'v1.ping', ApiClient::class, 'ping'], + ['team', 'v1.blockedFileTypes', ApiClient::class, 'blockedFileTypes'], ['team', 'message.index', MessagesEndpoint::class, 'list'], ['team', 'message.show', MessagesEndpoint::class, 'retrieve'], ['team', 'message.events', MessagesEndpoint::class, 'events'], @@ -64,7 +65,7 @@ ['team', 'webhook.showDelivery', WebhooksEndpoint::class, 'delivery'], ]; - expect($operations)->toHaveCount(49); + expect($operations)->toHaveCount(50); $missing = []; @@ -81,6 +82,7 @@ $typesSource = file_get_contents(__DIR__.'/../src/Types/ApiTypes.php'); $endpointFiles = [ + __DIR__.'/../src/Client/ApiClient.php', __DIR__.'/../src/Endpoints/EmailEndpoint.php', __DIR__.'/../src/Endpoints/DomainsEndpoint.php', __DIR__.'/../src/Endpoints/MessagesEndpoint.php', @@ -97,6 +99,7 @@ $expectedTypes = [ 'SendMailResponse', 'SendBatchMailResponse', + 'BlockedFileTypesResponse', 'DomainListResponse', 'DomainResponse', 'DeleteDomainResponse', @@ -175,3 +178,20 @@ expect($typesSource)->not->toContain("@phpstan-type {$responseType} CursorPage"); } }); + +test('generated php api types include current team schema additions', function () { + $typesSource = file_get_contents(__DIR__.'/../src/Types/ApiTypes.php'); + + expect($typesSource) + ->toContain("'auto_replied'") + ->toContain("'message.auto_replied'") + ->toContain('redact_email_content: bool') + ->toContain('redact_email_content?: bool|null') + ->toContain('@phpstan-type UpdateRouteSettingsData array{') + ->toContain('@phpstan-type UpdateRouteInboundSettingsData array{') + ->toContain('disable_plaintext_generation?: bool|null') + ->toContain('short_token?: bool') + ->toContain('@phpstan-type BlockedFileTypesResponse array{extensions: list, mime_types: list}') + ->toContain('300000') + ->toContain("scope: SuppressionScope"); +});