From 96005c82aff3da3e3ef9cb0ba2f589d5347635f0 Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Sat, 1 Jul 2023 16:40:41 +0200 Subject: [PATCH 1/7] WIP --- composer.json | 3 +- src/Dto/Tickets/AllTicketsDTO.php | 2 +- src/Dto/Tickets/Attachments/AttachmentDTO.php | 2 +- src/Dto/Tickets/Attachments/ThumbnailDTO.php | 2 +- src/Dto/Tickets/Attachments/UploadDTO.php | 2 +- src/Dto/Tickets/Comments/CommentDTO.php | 2 +- src/Dto/Tickets/CountTicketsDTO.php | 2 +- src/Dto/Tickets/SingleTicketDTO.php | 2 +- src/ZendeskConnector.php | 94 +++++++++---------- 9 files changed, 56 insertions(+), 55 deletions(-) diff --git a/composer.json b/composer.json index e3b0ff8..6a50ef4 100644 --- a/composer.json +++ b/composer.json @@ -60,7 +60,8 @@ "allow-plugins": { "composer/package-versions-deprecated": false, "pestphp/pest-plugin": true, - "phpstan/extension-installer": true + "phpstan/extension-installer": true, + "dealerdirect/phpcodesniffer-composer-installer": true } }, "extra": { diff --git a/src/Dto/Tickets/AllTicketsDTO.php b/src/Dto/Tickets/AllTicketsDTO.php index 2015dc9..f493422 100644 --- a/src/Dto/Tickets/AllTicketsDTO.php +++ b/src/Dto/Tickets/AllTicketsDTO.php @@ -6,7 +6,7 @@ use Saloon\Http\Response; use Spatie\LaravelData\Data; -class AllTicketsDTO extends Data +final class AllTicketsDTO extends Data { public function __construct( public array $tickets, diff --git a/src/Dto/Tickets/Attachments/AttachmentDTO.php b/src/Dto/Tickets/Attachments/AttachmentDTO.php index c4adc65..7fe10c5 100644 --- a/src/Dto/Tickets/Attachments/AttachmentDTO.php +++ b/src/Dto/Tickets/Attachments/AttachmentDTO.php @@ -7,7 +7,7 @@ use Saloon\Http\Response; use Spatie\LaravelData\Data; -class AttachmentDTO extends Data +final class AttachmentDTO extends Data { public function __construct( public ?string $content_type, diff --git a/src/Dto/Tickets/Attachments/ThumbnailDTO.php b/src/Dto/Tickets/Attachments/ThumbnailDTO.php index 91b8b9f..18e10c1 100644 --- a/src/Dto/Tickets/Attachments/ThumbnailDTO.php +++ b/src/Dto/Tickets/Attachments/ThumbnailDTO.php @@ -5,7 +5,7 @@ use CodebarAg\Zendesk\Enums\MalwareScanResult; use Spatie\LaravelData\Data; -class ThumbnailDTO extends Data +final class ThumbnailDTO extends Data { public function __construct( public ?string $content_type, diff --git a/src/Dto/Tickets/Attachments/UploadDTO.php b/src/Dto/Tickets/Attachments/UploadDTO.php index e25a736..0fffb15 100644 --- a/src/Dto/Tickets/Attachments/UploadDTO.php +++ b/src/Dto/Tickets/Attachments/UploadDTO.php @@ -7,7 +7,7 @@ use Saloon\Http\Response; use Spatie\LaravelData\Data; -class UploadDTO extends Data +final class UploadDTO extends Data { public function __construct( public string $token, diff --git a/src/Dto/Tickets/Comments/CommentDTO.php b/src/Dto/Tickets/Comments/CommentDTO.php index 9c0a82a..8910682 100644 --- a/src/Dto/Tickets/Comments/CommentDTO.php +++ b/src/Dto/Tickets/Comments/CommentDTO.php @@ -7,7 +7,7 @@ use Illuminate\Support\Carbon; use Spatie\LaravelData\Data; -class CommentDTO extends Data +final class CommentDTO extends Data { public function __construct( public ?array $attachments, diff --git a/src/Dto/Tickets/CountTicketsDTO.php b/src/Dto/Tickets/CountTicketsDTO.php index 547e3ba..2257567 100644 --- a/src/Dto/Tickets/CountTicketsDTO.php +++ b/src/Dto/Tickets/CountTicketsDTO.php @@ -6,7 +6,7 @@ use Saloon\Http\Response; use Spatie\LaravelData\Data; -class CountTicketsDTO extends Data +final class CountTicketsDTO extends Data { public function __construct( public ?int $value, diff --git a/src/Dto/Tickets/SingleTicketDTO.php b/src/Dto/Tickets/SingleTicketDTO.php index 0f3ee8b..0d5ce64 100644 --- a/src/Dto/Tickets/SingleTicketDTO.php +++ b/src/Dto/Tickets/SingleTicketDTO.php @@ -10,7 +10,7 @@ use Spatie\LaravelData\Data; use function Pest\Laravel\instance; -class SingleTicketDTO extends Data +final class SingleTicketDTO extends Data { public function __construct( public ?bool $allow_attachments, diff --git a/src/ZendeskConnector.php b/src/ZendeskConnector.php index 4face32..4fa139e 100644 --- a/src/ZendeskConnector.php +++ b/src/ZendeskConnector.php @@ -8,51 +8,51 @@ class ZendeskConnector extends Connector { - public function resolveBaseUrl(): string - { - if (! config('zendesk.subdomain')) { - throw new \Exception('No subdomain provided.', 500); - } - - return 'https://'.config('zendesk.subdomain').'.zendesk.com/api/v2'; - } - - protected function defaultHeaders(): array - { - return [ - 'Content-Type' => 'application/json', - 'Accept' => 'application/json', - ]; - } - - protected function defaultAuth(): ?Authenticator - { - if (! config('zendesk.auth.method')) { - throw new \Exception('No authentication method provided.', 500); - } - - if (! config('zendesk.auth.email_address')) { - throw new \Exception('No email address provided.', 500); - } - - if (config('zendesk.auth.method') === 'basic' && ! config('zendesk.auth.password')) { - throw new \Exception('No password provided for basic authentication.', 500); - } - - if (config('zendesk.auth.method') === 'basic' && ! config('zendesk.auth.password')) { - throw new \Exception('No password provided for basic authentication.', 500); - } - - if (config('zendesk.auth.method') === 'token' && ! config('zendesk.auth.api_token')) { - throw new \Exception('No API token provided for token authentication.', 500); - } - - $authenticationString = match (config('zendesk.auth.method')) { - 'basic' => $authenticationString = config('zendesk.auth.email_address').':'.config('zendesk.auth.password'), - 'token' => $authenticationString = config('zendesk.auth.email_address').'/token:'.config('zendesk.auth.api_token'), - default => throw new \Exception('Invalid authentication method provided.', 500), - }; - - return new TokenAuthenticator(base64_encode($authenticationString), 'Basic'); - } + public function resolveBaseUrl(): string + { + if (!config('zendesk.subdomain')) { + throw new \Exception('No subdomain provided.', 500); + } + + return 'https://' . config('zendesk.subdomain') . '.zendesk.com/api/v2'; + } + + protected function defaultHeaders(): array + { + return [ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + ]; + } + + protected function defaultAuth(): ?Authenticator + { + if (!config('zendesk.auth.method')) { + throw new \Exception('No authentication method provided.', 500); + } + + if (!config('zendesk.auth.email_address')) { + throw new \Exception('No email address provided.', 500); + } + + if (config('zendesk.auth.method') === 'basic' && !config('zendesk.auth.password')) { + throw new \Exception('No password provided for basic authentication.', 500); + } + + if (config('zendesk.auth.method') === 'basic' && !config('zendesk.auth.password')) { + throw new \Exception('No password provided for basic authentication.', 500); + } + + if (config('zendesk.auth.method') === 'token' && !config('zendesk.auth.api_token')) { + throw new \Exception('No API token provided for token authentication.', 500); + } + + $authenticationString = match (config('zendesk.auth.method')) { + 'basic' => $authenticationString = config('zendesk.auth.email_address') . ':' . config('zendesk.auth.password'), + 'token' => $authenticationString = config('zendesk.auth.email_address') . '/token:' . config('zendesk.auth.api_token'), + default => throw new \Exception('Invalid authentication method provided.', 500), + }; + + return new TokenAuthenticator(base64_encode($authenticationString), 'Basic'); + } } From 5a4a1261c735fe826640a93cdc4738e35c16232a Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Sat, 1 Jul 2023 16:40:53 +0200 Subject: [PATCH 2/7] WIP --- src/Dto/Tickets/AllTicketsDTO.php | 3 +- src/Dto/Tickets/Attachments/AttachmentDTO.php | 4 +- src/Dto/Tickets/Attachments/ThumbnailDTO.php | 2 +- src/Dto/Tickets/Attachments/UploadDTO.php | 3 +- src/Dto/Tickets/Comments/CommentDTO.php | 4 +- src/Dto/Tickets/CountTicketsDTO.php | 2 +- src/Dto/Tickets/SingleTicketDTO.php | 7 +- src/Requests/CreateAttachmentRequest.php | 4 +- src/Requests/CreateSingleTicketRequest.php | 1 - src/ZendeskConnector.php | 94 +++++++++---------- 10 files changed, 58 insertions(+), 66 deletions(-) diff --git a/src/Dto/Tickets/AllTicketsDTO.php b/src/Dto/Tickets/AllTicketsDTO.php index f493422..4b2094e 100644 --- a/src/Dto/Tickets/AllTicketsDTO.php +++ b/src/Dto/Tickets/AllTicketsDTO.php @@ -2,7 +2,6 @@ namespace CodebarAg\Zendesk\Dto\Tickets; -use Illuminate\Support\Collection; use Saloon\Http\Response; use Spatie\LaravelData\Data; @@ -20,7 +19,7 @@ public static function fromResponse(Response $response): self { $data = $response->json(); - return new static( + return new self( tickets: collect($data['tickets'])->map(function (array $ticket) { return SingleTicketDTO::fromArray($ticket); })->toArray(), diff --git a/src/Dto/Tickets/Attachments/AttachmentDTO.php b/src/Dto/Tickets/Attachments/AttachmentDTO.php index 7fe10c5..ecf9ff3 100644 --- a/src/Dto/Tickets/Attachments/AttachmentDTO.php +++ b/src/Dto/Tickets/Attachments/AttachmentDTO.php @@ -3,8 +3,6 @@ namespace CodebarAg\Zendesk\Dto\Tickets\Attachments; use CodebarAg\Zendesk\Enums\MalwareScanResult; -use Illuminate\Support\Carbon; -use Saloon\Http\Response; use Spatie\LaravelData\Data; final class AttachmentDTO extends Data @@ -37,7 +35,7 @@ public static function fromArray(array $data): self } } - return new static( + return new self( content_type: $data['content_type'] ?? null, content_url: $data['content_url'] ?? null, deleted: $data['deleted'] ?? null, diff --git a/src/Dto/Tickets/Attachments/ThumbnailDTO.php b/src/Dto/Tickets/Attachments/ThumbnailDTO.php index 18e10c1..14b249c 100644 --- a/src/Dto/Tickets/Attachments/ThumbnailDTO.php +++ b/src/Dto/Tickets/Attachments/ThumbnailDTO.php @@ -26,7 +26,7 @@ public function __construct( public static function fromArray(array $data): self { - return new static( + return new self( content_type: $data['content_type'] ?? null, content_url: $data['content_url'] ?? null, deleted: $data['deleted'] ?? null, diff --git a/src/Dto/Tickets/Attachments/UploadDTO.php b/src/Dto/Tickets/Attachments/UploadDTO.php index 0fffb15..f446d49 100644 --- a/src/Dto/Tickets/Attachments/UploadDTO.php +++ b/src/Dto/Tickets/Attachments/UploadDTO.php @@ -2,7 +2,6 @@ namespace CodebarAg\Zendesk\Dto\Tickets\Attachments; -use CodebarAg\Zendesk\Enums\MalwareScanResult; use Illuminate\Support\Carbon; use Saloon\Http\Response; use Spatie\LaravelData\Data; @@ -34,7 +33,7 @@ public static function fromArray(array $data): self } } - return new static( + return new self( token: $data['token'] ?? null, expires_at: Carbon::parse($data['expires_at'] ?? null), attachments: $attachments, diff --git a/src/Dto/Tickets/Comments/CommentDTO.php b/src/Dto/Tickets/Comments/CommentDTO.php index 8910682..a70c5af 100644 --- a/src/Dto/Tickets/Comments/CommentDTO.php +++ b/src/Dto/Tickets/Comments/CommentDTO.php @@ -2,8 +2,6 @@ namespace CodebarAg\Zendesk\Dto\Tickets\Comments; -use CodebarAg\Zendesk\Dto\Tickets\Attachments\AttachmentDTO; -use CodebarAg\Zendesk\Dto\Tickets\SingleTicketDTO; use Illuminate\Support\Carbon; use Spatie\LaravelData\Data; @@ -28,7 +26,7 @@ public function __construct( public static function fromArray(array $data): self { - return new static( + return new self( attachments: $data['attachments'] ?? null, audit_id: $data['audit_id'] ?? null, author_id: $data['author_id'] ?? null, diff --git a/src/Dto/Tickets/CountTicketsDTO.php b/src/Dto/Tickets/CountTicketsDTO.php index 2257567..90b569d 100644 --- a/src/Dto/Tickets/CountTicketsDTO.php +++ b/src/Dto/Tickets/CountTicketsDTO.php @@ -18,7 +18,7 @@ public static function fromResponse(Response $response): self { $data = $response->json()['count']; - return new static( + return new self( value: $data['value'], refreshed_at: Carbon::parse($data['refreshed_at']), ); diff --git a/src/Dto/Tickets/SingleTicketDTO.php b/src/Dto/Tickets/SingleTicketDTO.php index 0d5ce64..40ad9a4 100644 --- a/src/Dto/Tickets/SingleTicketDTO.php +++ b/src/Dto/Tickets/SingleTicketDTO.php @@ -8,7 +8,6 @@ use Illuminate\Support\Carbon; use Saloon\Http\Response; use Spatie\LaravelData\Data; -use function Pest\Laravel\instance; final class SingleTicketDTO extends Data { @@ -82,19 +81,19 @@ public static function fromArray(array $data): self $comment = CommentDTO::fromArray($comment); } - $priority = array_key_exists('priority', $data) ? $data['priority'] : null; + $priority = array_key_exists('priority', $data) ? $data['priority'] : null; if ($priority && ! $priority instanceof TicketPriority) { $priority = TicketPriority::tryFrom($priority); } - $type = array_key_exists('type', $data) ? $data['type'] : null; + $type = array_key_exists('type', $data) ? $data['type'] : null; if ($type && ! $type instanceof TicketType) { $type = TicketType::tryFrom($type); } - return new static( + return new self( allow_attachments: $data['allow_attachments'] ?? null, allow_channelback: $data['allow_channelback'] ?? null, assignee_email: $data['assignee_email'] ?? null, diff --git a/src/Requests/CreateAttachmentRequest.php b/src/Requests/CreateAttachmentRequest.php index b7a7912..75622ed 100644 --- a/src/Requests/CreateAttachmentRequest.php +++ b/src/Requests/CreateAttachmentRequest.php @@ -2,7 +2,6 @@ namespace CodebarAg\Zendesk\Requests; -use CodebarAg\Zendesk\Dto\Tickets\Attachments\AttachmentDTO; use CodebarAg\Zendesk\Dto\Tickets\Attachments\UploadDTO; use Saloon\Contracts\Body\HasBody; use Saloon\Contracts\Response; @@ -25,7 +24,8 @@ public function __construct( protected string $fileName, protected string $mimeType, protected mixed $stream, - ) { } + ) { + } protected function defaultHeaders(): array { diff --git a/src/Requests/CreateSingleTicketRequest.php b/src/Requests/CreateSingleTicketRequest.php index 15fe5e4..23621ef 100644 --- a/src/Requests/CreateSingleTicketRequest.php +++ b/src/Requests/CreateSingleTicketRequest.php @@ -2,7 +2,6 @@ namespace CodebarAg\Zendesk\Requests; -use CodebarAg\Zendesk\Dto\Tickets\CreateTicketDTO; use CodebarAg\Zendesk\Dto\Tickets\SingleTicketDTO; use Saloon\Contracts\Body\HasBody; use Saloon\Contracts\Response; diff --git a/src/ZendeskConnector.php b/src/ZendeskConnector.php index 4fa139e..4face32 100644 --- a/src/ZendeskConnector.php +++ b/src/ZendeskConnector.php @@ -8,51 +8,51 @@ class ZendeskConnector extends Connector { - public function resolveBaseUrl(): string - { - if (!config('zendesk.subdomain')) { - throw new \Exception('No subdomain provided.', 500); - } - - return 'https://' . config('zendesk.subdomain') . '.zendesk.com/api/v2'; - } - - protected function defaultHeaders(): array - { - return [ - 'Content-Type' => 'application/json', - 'Accept' => 'application/json', - ]; - } - - protected function defaultAuth(): ?Authenticator - { - if (!config('zendesk.auth.method')) { - throw new \Exception('No authentication method provided.', 500); - } - - if (!config('zendesk.auth.email_address')) { - throw new \Exception('No email address provided.', 500); - } - - if (config('zendesk.auth.method') === 'basic' && !config('zendesk.auth.password')) { - throw new \Exception('No password provided for basic authentication.', 500); - } - - if (config('zendesk.auth.method') === 'basic' && !config('zendesk.auth.password')) { - throw new \Exception('No password provided for basic authentication.', 500); - } - - if (config('zendesk.auth.method') === 'token' && !config('zendesk.auth.api_token')) { - throw new \Exception('No API token provided for token authentication.', 500); - } - - $authenticationString = match (config('zendesk.auth.method')) { - 'basic' => $authenticationString = config('zendesk.auth.email_address') . ':' . config('zendesk.auth.password'), - 'token' => $authenticationString = config('zendesk.auth.email_address') . '/token:' . config('zendesk.auth.api_token'), - default => throw new \Exception('Invalid authentication method provided.', 500), - }; - - return new TokenAuthenticator(base64_encode($authenticationString), 'Basic'); - } + public function resolveBaseUrl(): string + { + if (! config('zendesk.subdomain')) { + throw new \Exception('No subdomain provided.', 500); + } + + return 'https://'.config('zendesk.subdomain').'.zendesk.com/api/v2'; + } + + protected function defaultHeaders(): array + { + return [ + 'Content-Type' => 'application/json', + 'Accept' => 'application/json', + ]; + } + + protected function defaultAuth(): ?Authenticator + { + if (! config('zendesk.auth.method')) { + throw new \Exception('No authentication method provided.', 500); + } + + if (! config('zendesk.auth.email_address')) { + throw new \Exception('No email address provided.', 500); + } + + if (config('zendesk.auth.method') === 'basic' && ! config('zendesk.auth.password')) { + throw new \Exception('No password provided for basic authentication.', 500); + } + + if (config('zendesk.auth.method') === 'basic' && ! config('zendesk.auth.password')) { + throw new \Exception('No password provided for basic authentication.', 500); + } + + if (config('zendesk.auth.method') === 'token' && ! config('zendesk.auth.api_token')) { + throw new \Exception('No API token provided for token authentication.', 500); + } + + $authenticationString = match (config('zendesk.auth.method')) { + 'basic' => $authenticationString = config('zendesk.auth.email_address').':'.config('zendesk.auth.password'), + 'token' => $authenticationString = config('zendesk.auth.email_address').'/token:'.config('zendesk.auth.api_token'), + default => throw new \Exception('Invalid authentication method provided.', 500), + }; + + return new TokenAuthenticator(base64_encode($authenticationString), 'Basic'); + } } From 8124c81dc407c898ba00cd0ffc6bc3ccfe0a46fa Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Sat, 1 Jul 2023 16:46:05 +0200 Subject: [PATCH 3/7] WIP --- src/Dto/Tickets/AllTicketsDTO.php | 2 +- src/Dto/Tickets/Attachments/AttachmentDTO.php | 2 +- src/Dto/Tickets/Attachments/ThumbnailDTO.php | 2 +- src/Dto/Tickets/Attachments/UploadDTO.php | 2 +- src/Dto/Tickets/Comments/CommentDTO.php | 2 +- src/Dto/Tickets/CountTicketsDTO.php | 2 +- src/Dto/Tickets/SingleTicketDTO.php | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/Dto/Tickets/AllTicketsDTO.php b/src/Dto/Tickets/AllTicketsDTO.php index 4b2094e..3c6eb85 100644 --- a/src/Dto/Tickets/AllTicketsDTO.php +++ b/src/Dto/Tickets/AllTicketsDTO.php @@ -5,7 +5,7 @@ use Saloon\Http\Response; use Spatie\LaravelData\Data; -final class AllTicketsDTO extends Data +class AllTicketsDTO extends Data { public function __construct( public array $tickets, diff --git a/src/Dto/Tickets/Attachments/AttachmentDTO.php b/src/Dto/Tickets/Attachments/AttachmentDTO.php index ecf9ff3..23324ed 100644 --- a/src/Dto/Tickets/Attachments/AttachmentDTO.php +++ b/src/Dto/Tickets/Attachments/AttachmentDTO.php @@ -5,7 +5,7 @@ use CodebarAg\Zendesk\Enums\MalwareScanResult; use Spatie\LaravelData\Data; -final class AttachmentDTO extends Data +class AttachmentDTO extends Data { public function __construct( public ?string $content_type, diff --git a/src/Dto/Tickets/Attachments/ThumbnailDTO.php b/src/Dto/Tickets/Attachments/ThumbnailDTO.php index 14b249c..d4930fd 100644 --- a/src/Dto/Tickets/Attachments/ThumbnailDTO.php +++ b/src/Dto/Tickets/Attachments/ThumbnailDTO.php @@ -5,7 +5,7 @@ use CodebarAg\Zendesk\Enums\MalwareScanResult; use Spatie\LaravelData\Data; -final class ThumbnailDTO extends Data +class ThumbnailDTO extends Data { public function __construct( public ?string $content_type, diff --git a/src/Dto/Tickets/Attachments/UploadDTO.php b/src/Dto/Tickets/Attachments/UploadDTO.php index f446d49..809065d 100644 --- a/src/Dto/Tickets/Attachments/UploadDTO.php +++ b/src/Dto/Tickets/Attachments/UploadDTO.php @@ -6,7 +6,7 @@ use Saloon\Http\Response; use Spatie\LaravelData\Data; -final class UploadDTO extends Data +class UploadDTO extends Data { public function __construct( public string $token, diff --git a/src/Dto/Tickets/Comments/CommentDTO.php b/src/Dto/Tickets/Comments/CommentDTO.php index a70c5af..789c7bf 100644 --- a/src/Dto/Tickets/Comments/CommentDTO.php +++ b/src/Dto/Tickets/Comments/CommentDTO.php @@ -5,7 +5,7 @@ use Illuminate\Support\Carbon; use Spatie\LaravelData\Data; -final class CommentDTO extends Data +class CommentDTO extends Data { public function __construct( public ?array $attachments, diff --git a/src/Dto/Tickets/CountTicketsDTO.php b/src/Dto/Tickets/CountTicketsDTO.php index 90b569d..f6ee4b2 100644 --- a/src/Dto/Tickets/CountTicketsDTO.php +++ b/src/Dto/Tickets/CountTicketsDTO.php @@ -6,7 +6,7 @@ use Saloon\Http\Response; use Spatie\LaravelData\Data; -final class CountTicketsDTO extends Data +class CountTicketsDTO extends Data { public function __construct( public ?int $value, diff --git a/src/Dto/Tickets/SingleTicketDTO.php b/src/Dto/Tickets/SingleTicketDTO.php index 40ad9a4..c559373 100644 --- a/src/Dto/Tickets/SingleTicketDTO.php +++ b/src/Dto/Tickets/SingleTicketDTO.php @@ -9,7 +9,7 @@ use Saloon\Http\Response; use Spatie\LaravelData\Data; -final class SingleTicketDTO extends Data +class SingleTicketDTO extends Data { public function __construct( public ?bool $allow_attachments, From d5c051381a10b5f8e4b47edb7fd08defbbb08ace Mon Sep 17 00:00:00 2001 From: Sebastian Fix Date: Mon, 3 Jul 2023 10:44:05 +0200 Subject: [PATCH 4/7] WIP --- .github/ISSUE_TEMPLATE/config.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 646bb9c..81e7423 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,10 +1,10 @@ blank_issues_enabled: false contact_links: - name: Ask a question - url: https://github.com/codebar-ag/laravel-zendesk/discussions/new?category=q-a + url: https://github.com/codebar-ag/laravel-zendesk/issues/new about: Ask the community for help - name: Request a feature - url: https://github.com/codebar-ag/laravel-zendesk/discussions/new?category=ideas + url: https://github.com/codebar-ag/laravel-zendesk/issues/new about: Share ideas for new features - name: Report a bug url: https://github.com/codebar-ag/laravel-zendesk/issues/new From 5b7a66b2ae02d712e6d1da5cd280109c7d45dc3d Mon Sep 17 00:00:00 2001 From: Rhys Lees <43909932+RhysLees@users.noreply.github.com> Date: Mon, 3 Jul 2023 15:41:27 +0100 Subject: [PATCH 5/7] WIP --- README.md | 2 + src/ZendeskConnector.php | 14 +- tests/Connectors/ZendeskConnectorTest.php | 169 ++++++++++++++++++ tests/Fixtures/Files/test.png | Bin 0 -> 26271 bytes .../Fixtures/Saloon/all-tickets-request.json | 38 ++++ .../Saloon/count-tickets-request.json | 1 + .../Saloon/create-attachment-request.json | 40 +++++ .../Saloon/create-single-ticket-request.json | 1 + .../Saloon/single-ticket-request.json | 37 ++++ tests/Pest.php | 9 + tests/Requests/AllTicketsRequestTest.php | 42 +++++ tests/Requests/CountTicketsRequestTest.php | 22 +++ .../Requests/CreateAttachmentRequestTest.php | 33 ++++ .../CreateSingleTicketRequestTest.php | 46 +++++ tests/Requests/SingleTicketRequestTest.php | 30 ++++ tests/TestCase.php | 6 + 16 files changed, 485 insertions(+), 5 deletions(-) create mode 100644 tests/Connectors/ZendeskConnectorTest.php create mode 100644 tests/Fixtures/Files/test.png create mode 100644 tests/Fixtures/Saloon/all-tickets-request.json create mode 100644 tests/Fixtures/Saloon/count-tickets-request.json create mode 100644 tests/Fixtures/Saloon/create-attachment-request.json create mode 100644 tests/Fixtures/Saloon/create-single-ticket-request.json create mode 100644 tests/Fixtures/Saloon/single-ticket-request.json create mode 100644 tests/Requests/AllTicketsRequestTest.php create mode 100644 tests/Requests/CountTicketsRequestTest.php create mode 100644 tests/Requests/CreateAttachmentRequestTest.php create mode 100644 tests/Requests/CreateSingleTicketRequestTest.php create mode 100644 tests/Requests/SingleTicketRequestTest.php diff --git a/README.md b/README.md index 0b82b81..bfa9f87 100644 --- a/README.md +++ b/README.md @@ -207,6 +207,8 @@ $uploadResponse = $connector->send( $token = $uploadResponse->dto()->token; +// And to pass to your ticket request + $ticketResponse = $connector->send( new CreateSingleTicketRequest( SingleTicketDTO::fromArray([ diff --git a/src/ZendeskConnector.php b/src/ZendeskConnector.php index 4face32..04e5da1 100644 --- a/src/ZendeskConnector.php +++ b/src/ZendeskConnector.php @@ -26,6 +26,12 @@ protected function defaultHeaders(): array } protected function defaultAuth(): ?Authenticator + { + $authenticationString = $this->setAuth(); + return new TokenAuthenticator(base64_encode($authenticationString), 'Basic'); + } + + public function setAuth(): string { if (! config('zendesk.auth.method')) { throw new \Exception('No authentication method provided.', 500); @@ -47,12 +53,10 @@ protected function defaultAuth(): ?Authenticator throw new \Exception('No API token provided for token authentication.', 500); } - $authenticationString = match (config('zendesk.auth.method')) { - 'basic' => $authenticationString = config('zendesk.auth.email_address').':'.config('zendesk.auth.password'), - 'token' => $authenticationString = config('zendesk.auth.email_address').'/token:'.config('zendesk.auth.api_token'), + return match (config('zendesk.auth.method')) { + 'basic' => config('zendesk.auth.email_address').':'.config('zendesk.auth.password'), + 'token' => config('zendesk.auth.email_address').'/token:'.config('zendesk.auth.api_token'), default => throw new \Exception('Invalid authentication method provided.', 500), }; - - return new TokenAuthenticator(base64_encode($authenticationString), 'Basic'); } } diff --git a/tests/Connectors/ZendeskConnectorTest.php b/tests/Connectors/ZendeskConnectorTest.php new file mode 100644 index 0000000..0d5b5f6 --- /dev/null +++ b/tests/Connectors/ZendeskConnectorTest.php @@ -0,0 +1,169 @@ +resolveBaseUrl(); + +})->throws('No subdomain provided.', 500); + +it('will not throw an exception if a subdomain is set', closure: function () { + config([ + 'zendesk.subdomain' => 'codebarsolutionsag' + ]); + + $connector = new ZendeskConnector; + $connector->resolveBaseUrl(); + +})->expectNotToPerformAssertions(); + +it('will return the base path', closure: function () { + config([ + 'zendesk.subdomain' => 'codebarsolutionsag' + ]); + + $connector = new ZendeskConnector; + $path = $connector->resolveBaseUrl(); + + expect($path)->toBe('https://codebarsolutionsag.zendesk.com/api/v2'); + +}); + + +it('will throw an exception if an auth method is not set', closure: function () { + config([ + 'zendesk.auth.method' => null, + ]); + + $connector = new ZendeskConnector; + $connector->setAuth(); + +})->throws('No authentication method provided.', 500); + +it('will throw an exception if an auth method invalid', closure: function () { + config([ + 'zendesk.auth.method' => 'not-a-valid-method', + ]); + + $connector = new ZendeskConnector; + $connector->setAuth(); + +})->throws('Invalid authentication method provided.', 500); + +it('will not throw an exception if an auth method valid', closure: function () { + config([ + 'zendesk.subdomain' => 'codebarsolutionsag', + 'zendesk.auth.email_address' => 'test@example.com', + 'zendesk.auth.api_token' => 'test-token', + 'zendesk.auth.password' => 'test-password', + ]); + + + config([ + 'zendesk.auth.method' => 'token', + ]); + + $connector = new ZendeskConnector; + $connector->setAuth(); + + config([ + 'zendesk.auth.method' => 'basic', + ]); + + $connector = new ZendeskConnector; + $connector->setAuth(); + +})->expectNotToPerformAssertions(); + +it('will throw an exception if a token is not provided when using the token method', closure: function () { + config([ + 'zendesk.subdomain' => 'codebarsolutionsag', + 'zendesk.auth.method' => 'token', + 'zendesk.auth.email_address' => 'test@example.com', + 'zendesk.auth.api_token' => null, + 'zendesk.auth.password' => null, + ]); + + $connector = new ZendeskConnector; + $connector->setAuth(); + +})->throws('No API token provided for token authentication.', 500); + +it('will not throw an exception if a token is provided when using the token method', closure: function () { + config([ + 'zendesk.subdomain' => 'codebarsolutionsag', + 'zendesk.auth.method' => 'token', + 'zendesk.auth.email_address' => 'test@example.com', + 'zendesk.auth.api_token' => 'test-token', + 'zendesk.auth.password' => null, + ]); + + $connector = new ZendeskConnector; + $connector->setAuth(); + +})->expectNotToPerformAssertions(); + +it('will throw an exception if a password is not provided when using the basic method', closure: function () { + config([ + 'zendesk.subdomain' => 'codebarsolutionsag', + 'zendesk.auth.method' => 'basic', + 'zendesk.auth.email_address' => 'test@example.com', + 'zendesk.auth.api_token' => null, + 'zendesk.auth.password' => null, + ]); + + $connector = new ZendeskConnector; + $connector->setAuth(); + +})->throws('No password provided for basic authentication.', 500); + +it('will not throw an exception if a password is provided when using the password method', closure: function () { + config([ + 'zendesk.subdomain' => 'codebarsolutionsag', + 'zendesk.auth.method' => 'basic', + 'zendesk.auth.email_address' => 'test@example.com', + 'zendesk.auth.api_token' => null, + 'zendesk.auth.password' => 'test-password', + ]); + + $connector = new ZendeskConnector; + $connector->setAuth(); + +})->expectNotToPerformAssertions(); + +it('will compile the correct authentication string for token method', function () { + config([ + 'zendesk.subdomain' => 'codebarsolutionsag', + 'zendesk.auth.method' => 'token', + 'zendesk.auth.email_address' => 'test@example.com', + 'zendesk.auth.api_token' => 'test-token', + 'zendesk.auth.password' => null, + ]); + + $connector = new ZendeskConnector; + + $token = $connector->setAuth(); + + expect($token)->toBe('test@example.com/token:test-token'); +}); + +it('will compile the correct authentication string for basic method', function () { + config([ + 'zendesk.subdomain' => 'codebarsolutionsag', + 'zendesk.auth.method' => 'basic', + 'zendesk.auth.email_address' => 'test@example.com', + 'zendesk.auth.api_token' => null, + 'zendesk.auth.password' => 'test-password', + ]); + + $connector = new ZendeskConnector; + + $token = $connector->setAuth(); + + expect($token)->toBe('test@example.com:test-password'); +}); diff --git a/tests/Fixtures/Files/test.png b/tests/Fixtures/Files/test.png new file mode 100644 index 0000000000000000000000000000000000000000..372c2a2777d2b4e3074d64e82a7a19b9ab85976f GIT binary patch literal 26271 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 WXbNsFwl@H{myv{:controller=>\"tickets\", :action=>\"create\", :unpermitted_keys=>[\"ticket.allow_attachments\", \"ticket.allow_channelback\", \"ticket.comment.attachments\", \"ticket.comment.audit_id\", \"ticket.comment.created_at\", \"ticket.comment.id\", \"ticket.comment.metadata\", \"ticket.comment.plain_body\", \"ticket.comment.type\", \"ticket.comment.via\", \"ticket.created_at\", \"ticket.email_cc_ids\", \"ticket.follower_ids\", \"ticket.followup_ids\", \"ticket.from_messaging_channel\", \"ticket.has_incidents\", \"ticket.id\", \"ticket.is_public\", \"ticket.self_update\", \"ticket.satisfaction_rating\", \"ticket.updated_at\"], :invalid_values=>[]}}","x-frame-options":"SAMEORIGIN","zendesk-ep":"-22","location":"https:\/\/codebarsolutionsag.zendesk.com\/api\/v2\/tickets\/83.json","x-rate-limit":"400","rate-limit":"400","x-rate-limit-remaining":"399","rate-limit-remaining":"399","rate-limit-reset":"25","strict-transport-security":"max-age=31536000;","etag":"W\/\"3f19ce42212521a313aba3506dabd849\"","cache-control":"max-age=0, private, must-revalidate","x-zendesk-origin-server":"classic-app-server-6fc8db697c-vp95d","set-cookie":["_zendesk_cookie=BAhJIhl7ImRldmljZV90b2tlbnMiOnt9fQY6BkVU--0bf2100788cb010d0183feca16aaf88ccaf719ca; path=\/; expires=Wed, 03 Jul 2024 07:05:25 GMT; secure; HttpOnly; SameSite=None","__cfruid=212285535bde6012c576e4f7e5897005b752ea29-1688390195; path=\/; domain=.codebarsolutionsag.zendesk.com; HttpOnly; Secure; SameSite=None"],"x-request-id":["7e0f675b4829d168-LHR","7e0f675b4829d168-LHR"],"x-runtime":"0.490684","X-Zendesk-Zorg":"yes","CF-Cache-Status":"DYNAMIC","Report-To":"{\"endpoints\":[{\"url\":\"https:\\\/\\\/a.nel.cloudflare.com\\\/report\\\/v3?s=WhPNGryN2lnTT63PGIv4jkoAL%2BCJfcUd9U1L%2B%2F6RBPPdiAz7EXz0y4Oj84xA9dyzvnJHh4SVHLzJ9asKpj7DJczwb9mXhXY5Q8BverBn44Bu9RmF8gitXsMkSpAbWkL9gBwsgUTzlEcW4sPwEYwwSw%3D%3D\"}],\"group\":\"cf-nel\",\"max_age\":604800}","NEL":"{\"success_fraction\":0.01,\"report_to\":\"cf-nel\",\"max_age\":604800}","Server":"cloudflare","CF-RAY":"7e0f675b4829d168-LHR"},"data":"{\"ticket\":{\"url\":\"https:\/\/codebarsolutionsag.zendesk.com\/api\/v2\/tickets\/83.json\",\"id\":83,\"external_id\":null,\"via\":{\"channel\":\"api\",\"source\":{\"from\":{},\"to\":{},\"rel\":null}},\"created_at\":\"2023-07-03T13:16:35Z\",\"updated_at\":\"2023-07-03T13:16:35Z\",\"type\":null,\"subject\":\"My printer is on fire!\",\"raw_subject\":\"My printer is on fire!\",\"description\":\"The smoke is very colorful.\",\"priority\":\"urgent\",\"status\":\"open\",\"recipient\":null,\"requester_id\":17145664265741,\"submitter_id\":17145664265741,\"assignee_id\":17145664265741,\"organization_id\":17145651654157,\"group_id\":17145664762125,\"collaborator_ids\":[],\"follower_ids\":[],\"email_cc_ids\":[],\"forum_topic_id\":null,\"problem_id\":null,\"has_incidents\":false,\"is_public\":true,\"due_at\":null,\"tags\":[],\"custom_fields\":[{\"id\":17146061349901,\"value\":null},{\"id\":17195718961677,\"value\":\"Check field works\"},{\"id\":17195752153741,\"value\":\"Check field works number 2\"}],\"satisfaction_rating\":null,\"sharing_agreement_ids\":[],\"custom_status_id\":17145678334989,\"fields\":[{\"id\":17146061349901,\"value\":null},{\"id\":17195718961677,\"value\":\"Check field works\"},{\"id\":17195752153741,\"value\":\"Check field works number 2\"}],\"followup_ids\":[],\"ticket_form_id\":17145664563725,\"brand_id\":17145651602957,\"allow_channelback\":false,\"allow_attachments\":true,\"from_messaging_channel\":false},\"audit\":{\"id\":17278400133517,\"ticket_id\":83,\"created_at\":\"2023-07-03T13:16:35Z\",\"author_id\":17145664265741,\"metadata\":{\"system\":{\"client\":\"GuzzleHttp\/7\",\"ip_address\":\"94.101.151.181\",\"location\":\"Herne Bay, ENG, United Kingdom\",\"latitude\":51.3724,\"longitude\":1.1561},\"custom\":{}},\"events\":[{\"id\":17278400133645,\"type\":\"Comment\",\"author_id\":17145664265741,\"body\":\"The smoke is very colorful.\",\"html_body\":\"

The smoke is very colorful.<\/p><\/div>\",\"plain_body\":\"The smoke is very colorful.\",\"public\":true,\"attachments\":[],\"audit_id\":17278400133517},{\"id\":17278400133773,\"type\":\"Create\",\"value\":\"urgent\",\"field_name\":\"priority\"},{\"id\":17278400133901,\"type\":\"Create\",\"value\":\"My printer is on fire!\",\"field_name\":\"subject\"},{\"id\":17278400134029,\"type\":\"Create\",\"value\":\"17145664265741\",\"field_name\":\"requester_id\"},{\"id\":17278400134157,\"type\":\"Create\",\"value\":\"Check field works\",\"field_name\":\"17195718961677\"},{\"id\":17278400134285,\"type\":\"Create\",\"value\":\"Check field works number 2\",\"field_name\":\"17195752153741\"},{\"id\":17278400134413,\"type\":\"Create\",\"value\":null,\"field_name\":\"type\"},{\"id\":17278400134541,\"type\":\"Create\",\"value\":\"open\",\"field_name\":\"status\"},{\"id\":17278400134669,\"type\":\"Create\",\"value\":\"17145664265741\",\"field_name\":\"assignee_id\"},{\"id\":17278400134797,\"type\":\"Create\",\"value\":\"17145664762125\",\"field_name\":\"group_id\"},{\"id\":17278400134925,\"type\":\"Create\",\"value\":\"17145651654157\",\"field_name\":\"organization_id\"},{\"id\":17278400135053,\"type\":\"Create\",\"value\":\"17145651602957\",\"field_name\":\"brand_id\"},{\"id\":17278400135181,\"type\":\"Create\",\"value\":\"17145664563725\",\"field_name\":\"ticket_form_id\"},{\"id\":17278400135309,\"type\":\"Create\",\"value\":\"17145678334989\",\"field_name\":\"custom_status_id\"},{\"id\":17278414083597,\"type\":\"AssociateAttValsEvent\",\"attribute_values\":[]}],\"via\":{\"channel\":\"api\",\"source\":{\"from\":{},\"to\":{},\"rel\":null}}}}"} \ No newline at end of file diff --git a/tests/Fixtures/Saloon/single-ticket-request.json b/tests/Fixtures/Saloon/single-ticket-request.json new file mode 100644 index 0000000..7ec8913 --- /dev/null +++ b/tests/Fixtures/Saloon/single-ticket-request.json @@ -0,0 +1,37 @@ +{ + "statusCode": 200, + "headers": { + "Date": "Mon, 03 Jul 2023 11:31:04 GMT", + "Content-Type": "application\/json; charset=utf-8", + "Transfer-Encoding": "chunked", + "Connection": "keep-alive", + "x-zendesk-api-version": "v2", + "x-zendesk-application-version": "v17438", + "x-frame-options": "SAMEORIGIN", + "x-rate-limit": "400", + "rate-limit": "400", + "x-rate-limit-remaining": "398", + "rate-limit-remaining": "398", + "rate-limit-reset": "56", + "strict-transport-security": "max-age=31536000;", + "etag": "W\/\"f6a375c66420a3a7c52a087aa0f3bb47\"", + "cache-control": "max-age=0, private, must-revalidate", + "x-zendesk-origin-server": "classic-app-server-6fc8db697c-js56h", + "set-cookie": [ + "_zendesk_cookie=BAhJIhl7ImRldmljZV90b2tlbnMiOnt9fQY6BkVU--0bf2100788cb010d0183feca16aaf88ccaf719ca; path=\/; expires=Wed, 03 Jul 2024 07:05:41 GMT; secure; HttpOnly; SameSite=None", + "__cfruid=b15e262f7b806ba2db1221699a831cc39e74cd44-1688383864; path=\/; domain=.codebarsolutionsag.zendesk.com; HttpOnly; Secure; SameSite=None" + ], + "x-request-id": [ + "7e0ecccb0ef7414d-LHR", + "7e0ecccb0ef7414d-LHR" + ], + "x-runtime": "0.086786", + "X-Zendesk-Zorg": "yes", + "CF-Cache-Status": "DYNAMIC", + "Report-To": "{\"endpoints\":[{\"url\":\"https:\\\/\\\/a.nel.cloudflare.com\\\/report\\\/v3?s=7lMEsubYh03mZhbyhOB7legoUvkomiPxbsQOg0HD6GL0OxkjWkOR0%2BYeSVdaW9J2uI%2FTZdGSdesx8628LQHv%2BSSghfw776Er2QMrCaswrMMD6WyL4RTiVF5m%2F20KZSDfwoR4VeTsATquzrBuUeD0Gg%3D%3D\"}],\"group\":\"cf-nel\",\"max_age\":604800}", + "NEL": "{\"success_fraction\":0.01,\"report_to\":\"cf-nel\",\"max_age\":604800}", + "Server": "cloudflare", + "CF-RAY": "7e0ecccb0ef7414d-LHR" + }, + "data": "{\"ticket\":{\"url\":\"https:\/\/codebarsolutionsag.zendesk.com\/api\/v2\/tickets\/81.json\",\"id\":81,\"external_id\":null,\"via\":{\"channel\":\"api\",\"source\":{\"from\":{},\"to\":{},\"rel\":null}},\"created_at\":\"2023-07-03T11:16:03Z\",\"updated_at\":\"2023-07-03T11:16:05Z\",\"type\":null,\"subject\":\"My printer is on fire!\",\"raw_subject\":\"My printer is on fire!\",\"description\":\"The smoke is very colorful.\",\"priority\":\"urgent\",\"status\":\"open\",\"recipient\":null,\"requester_id\":17145664265741,\"submitter_id\":17145664265741,\"assignee_id\":17145664265741,\"organization_id\":17145651654157,\"group_id\":17145664762125,\"collaborator_ids\":[],\"follower_ids\":[],\"email_cc_ids\":[],\"forum_topic_id\":null,\"problem_id\":null,\"has_incidents\":false,\"is_public\":true,\"due_at\":null,\"tags\":[],\"custom_fields\":[{\"id\":17146061349901,\"value\":null},{\"id\":17195718961677,\"value\":\"Check field works\"},{\"id\":17195752153741,\"value\":\"Check field works number 2\"}],\"satisfaction_rating\":null,\"sharing_agreement_ids\":[],\"custom_status_id\":17145678334989,\"fields\":[{\"id\":17146061349901,\"value\":null},{\"id\":17195718961677,\"value\":\"Check field works\"},{\"id\":17195752153741,\"value\":\"Check field works number 2\"}],\"followup_ids\":[],\"ticket_form_id\":17145664563725,\"brand_id\":17145651602957,\"allow_channelback\":false,\"allow_attachments\":true,\"from_messaging_channel\":false}}" +} diff --git a/tests/Pest.php b/tests/Pest.php index cc8b9d4..1cb836f 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -8,3 +8,12 @@ uses()->beforeEach(function () { Event::fake(); })->in(__DIR__); + +uses()->beforeEach(function () { + config([ + 'zendesk.subdomain' => 'codebarsolutionsag', + 'zendesk.auth.method' => 'token', + 'zendesk.auth.email_address' => 'invoice@codebar.ch', + 'zendesk.auth.api_token' => 'TqxDOhfFVseETyvdQ0ISV6JKaXuXtmoFRX67gKnZ', + ]); +})->in(__DIR__.'/Requests'); diff --git a/tests/Requests/AllTicketsRequestTest.php b/tests/Requests/AllTicketsRequestTest.php new file mode 100644 index 0000000..c64683f --- /dev/null +++ b/tests/Requests/AllTicketsRequestTest.php @@ -0,0 +1,42 @@ + MockResponse::fixture('all-tickets-request'), + ]); + + $connector = new ZendeskConnector; + $connector->withMockClient($mockClient); + + $response = $connector->send(new AllTicketsRequest()); + + $mockClient->assertSent(AllTicketsRequest::class); + + expect($response->dto()->count)->toBe(2) + ->and($response->dto()->tickets[1]['id'])->toBe(81) + ->and($response->dto()->tickets[1]['subject'])->toBe('My printer is on fire!') + ->and($response->dto()->tickets[1]['raw_subject'])->toBe('My printer is on fire!') + ->and($response->dto()->tickets[1]['description'])->toBe('The smoke is very colorful.') + ->and($response->dto()->tickets[1]['priority'])->toBe(TicketPriority::URGENT) + ->and($response->dto()->tickets[1]['custom_fields'][1]['id'])->toBe(17195718961677) + ->and($response->dto()->tickets[1]['custom_fields'][1]['value'])->toBe('Check field works') + ->and($response->dto()->tickets[1]['custom_fields'][2]['id'])->toBe(17195752153741) + ->and($response->dto()->tickets[1]['custom_fields'][2]['value'])->toBe('Check field works number 2') + ->and($response->dto()->tickets[0]['id'])->toBe(79) + ->and($response->dto()->tickets[0]['subject'])->toBe('Eine neue Anfrage der Bärtschi ist eingetroffen: Projekt #1.') + ->and($response->dto()->tickets[0]['raw_subject'])->toBe('Eine neue Anfrage der Bärtschi ist eingetroffen: Projekt #1.') + ->and($response->dto()->tickets[0]['description']) + ->toBe("Eine neue Anfrage der Bärtschi ist eingetroffen.\n\nAnfrage\nIdentifikation 1\nBemerkung asdasd\nURL https://app.pv.test/nova/resources/inquiries/1\nErstellt am 01.07.2023 14:21 Uhr\n**Kunde**\nKunden Bärtschi\nKunden ID 437046\nBenutzer ID 437046_ralph\nBenutzername Ralph Senn\n**Konfiguration**\nName Projekt #1\nDachform Sattel-/Pultdach\nMontage Aufdach\nHerkunft Asiatisch\nWechselrichter Typ String\n**Adresse**\nStrasse Mühlematten 12\nPLZ 4455\nOrt Zunzgen\nLand CH") + ->and($response->dto()->tickets[0]['priority'])->toBe(TicketPriority::URGENT) + ->and($response->dto()->tickets[0]['custom_fields'][1]['id'])->toBe(17195718961677) + ->and($response->dto()->tickets[0]['custom_fields'][1]['value'])->toBe(null) + ->and($response->dto()->tickets[0]['custom_fields'][2]['id'])->toBe(17195752153741) + ->and($response->dto()->tickets[0]['custom_fields'][2]['value'])->toBe(null); + +}); diff --git a/tests/Requests/CountTicketsRequestTest.php b/tests/Requests/CountTicketsRequestTest.php new file mode 100644 index 0000000..86feb66 --- /dev/null +++ b/tests/Requests/CountTicketsRequestTest.php @@ -0,0 +1,22 @@ + MockResponse::fixture('count-tickets-request'), + ]); + + $connector = new ZendeskConnector; + $connector->withMockClient($mockClient); + + $response = $connector->send(new CountTicketsRequest()); + + $mockClient->assertSent(CountTicketsRequest::class); + + expect($response->dto()->value)->toBe(4) + ->and($response->dto()->refreshed_at->toDateTimeString())->toBe('2023-07-03 13:19:53'); +}); diff --git a/tests/Requests/CreateAttachmentRequestTest.php b/tests/Requests/CreateAttachmentRequestTest.php new file mode 100644 index 0000000..0c7a590 --- /dev/null +++ b/tests/Requests/CreateAttachmentRequestTest.php @@ -0,0 +1,33 @@ + MockResponse::fixture('create-attachment-request'), + ]); + + $connector = new ZendeskConnector; + $connector->withMockClient($mockClient); + + $response = $connector->send( + new CreateAttachmentRequest( + fileName: 'test.png', + mimeType: 'image/png', + stream: fopen(__DIR__.'/../Fixtures/Files/test.png', 'r') + ) + ); + + $mockClient->assertSent(CreateAttachmentRequest::class); + + expect($response->dto()->token)->toBe('OPvgMbfg5Der4DYn66hTC31in') + ->and($response->dto()->attachment->content_type)->toBe('image/png') + ->and($response->dto()->attachment->size)->toBe(26271) + ->and($response->dto()->attachment->file_name)->toBe('test.png') + ->and($response->dto()->attachment->width)->toBe('640') + ->and($response->dto()->attachment->height)->toBe('360') + ->and($response->dto()->attachment->content_url)->toBe('https://codebarsolutionsag.zendesk.com/attachments/token/52HCaRgRZM38MvaUuUQsYzhUA/?name=test.png'); +}); diff --git a/tests/Requests/CreateSingleTicketRequestTest.php b/tests/Requests/CreateSingleTicketRequestTest.php new file mode 100644 index 0000000..22e8c43 --- /dev/null +++ b/tests/Requests/CreateSingleTicketRequestTest.php @@ -0,0 +1,46 @@ + MockResponse::fixture('create-single-ticket-request'), + ]); + + $connector = new ZendeskConnector; + $connector->withMockClient($mockClient); + + $response = $connector->send(new CreateSingleTicketRequest([ + 'comment' => CommentDTO::fromArray([ + 'body' => 'The smoke is very colorful.', + ]), + 'priority' => TicketPriority::URGENT, + 'subject' => 'My printer is on fire!', + 'custom_fields' => [ + [ + 'id' => 17195718961677, + 'value' => 'Check field works', + ], + [ + 'id' => 17195752153741, + 'value' => 'Check field works number 2', + ], + ], + ])); + + $mockClient->assertSent(CreateSingleTicketRequest::class); + + expect($response->dto()->subject)->toBe('My printer is on fire!') + ->and($response->dto()->raw_subject)->toBe('My printer is on fire!') + ->and($response->dto()->description)->toBe('The smoke is very colorful.') + ->and($response->dto()->priority)->toBe(TicketPriority::URGENT) + ->and($response->dto()->custom_fields[1]['id'])->toBe(17195718961677) + ->and($response->dto()->custom_fields[1]['value'])->toBe('Check field works') + ->and($response->dto()->custom_fields[2]['id'])->toBe(17195752153741) + ->and($response->dto()->custom_fields[2]['value'])->toBe('Check field works number 2'); +}); diff --git a/tests/Requests/SingleTicketRequestTest.php b/tests/Requests/SingleTicketRequestTest.php new file mode 100644 index 0000000..23c32f7 --- /dev/null +++ b/tests/Requests/SingleTicketRequestTest.php @@ -0,0 +1,30 @@ + MockResponse::fixture('single-ticket-request'), + ]); + + $connector = new ZendeskConnector; + $connector->withMockClient($mockClient); + + $response = $connector->send(new SingleTicketRequest(81)); + + $mockClient->assertSent(SingleTicketRequest::class); + + expect($response->dto()->id)->toBe(81) + ->and($response->dto()->subject)->toBe('My printer is on fire!') + ->and($response->dto()->raw_subject)->toBe('My printer is on fire!') + ->and($response->dto()->description)->toBe('The smoke is very colorful.') + ->and($response->dto()->priority)->toBe(TicketPriority::URGENT) + ->and($response->dto()->custom_fields[1]['id'])->toBe(17195718961677) + ->and($response->dto()->custom_fields[1]['value'])->toBe('Check field works') + ->and($response->dto()->custom_fields[2]['id'])->toBe(17195752153741) + ->and($response->dto()->custom_fields[2]['value'])->toBe('Check field works number 2'); +}); diff --git a/tests/TestCase.php b/tests/TestCase.php index 6b100a4..a4319ac 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -5,6 +5,7 @@ use CodebarAg\Zendesk\ZendeskServiceProvider; use Illuminate\Database\Eloquent\Factories\Factory; use Orchestra\Testbench\TestCase as Orchestra; +use Spatie\LaravelData\Support\DataConfig; class TestCase extends Orchestra { @@ -15,6 +16,11 @@ protected function setUp(): void Factory::guessFactoryNamesUsing( fn (string $modelName) => 'CodebarAg\\Zendesk\\Database\\Factories\\'.class_basename($modelName).'Factory' ); + + // Provide a config array to DataConfig + $this->app->when(DataConfig::class) + ->needs('$config') + ->give([]); } protected function getPackageProviders($app): array From 9e7ba86fc23db701677e9c401a2787ee530bfcd8 Mon Sep 17 00:00:00 2001 From: Rhys Lees <43909932+RhysLees@users.noreply.github.com> Date: Mon, 3 Jul 2023 15:41:44 +0100 Subject: [PATCH 6/7] WIP --- src/ZendeskConnector.php | 1 + tests/Connectors/ZendeskConnectorTest.php | 10 ++-------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/src/ZendeskConnector.php b/src/ZendeskConnector.php index 04e5da1..ca8d8c0 100644 --- a/src/ZendeskConnector.php +++ b/src/ZendeskConnector.php @@ -28,6 +28,7 @@ protected function defaultHeaders(): array protected function defaultAuth(): ?Authenticator { $authenticationString = $this->setAuth(); + return new TokenAuthenticator(base64_encode($authenticationString), 'Basic'); } diff --git a/tests/Connectors/ZendeskConnectorTest.php b/tests/Connectors/ZendeskConnectorTest.php index 0d5b5f6..6c6d9fb 100644 --- a/tests/Connectors/ZendeskConnectorTest.php +++ b/tests/Connectors/ZendeskConnectorTest.php @@ -1,10 +1,6 @@ 'codebarsolutionsag' + 'zendesk.subdomain' => 'codebarsolutionsag', ]); $connector = new ZendeskConnector; @@ -24,7 +20,7 @@ it('will return the base path', closure: function () { config([ - 'zendesk.subdomain' => 'codebarsolutionsag' + 'zendesk.subdomain' => 'codebarsolutionsag', ]); $connector = new ZendeskConnector; @@ -34,7 +30,6 @@ }); - it('will throw an exception if an auth method is not set', closure: function () { config([ 'zendesk.auth.method' => null, @@ -63,7 +58,6 @@ 'zendesk.auth.password' => 'test-password', ]); - config([ 'zendesk.auth.method' => 'token', ]); From ff6c98d7bda8a944ad43d9da49ed0585c587649c Mon Sep 17 00:00:00 2001 From: Rhys Lees <43909932+RhysLees@users.noreply.github.com> Date: Mon, 3 Jul 2023 15:43:05 +0100 Subject: [PATCH 7/7] WIP --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bfa9f87..d4c24e4 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ composer require codebar-ag/laravel-zendesk Optionally, you can publish the config file with: ```bash -php artisan vendor:publish --provider="CodebarAg\Zendesk\ZendeskServiceProvider" --tag="config" +php artisan vendor:publish --provider="CodebarAg\Zendesk\ZendeskServiceProvider" ``` You can add the following env variables to your `.env` file: