From f93db8c38b4de5cc1e964198e5a99afc36039135 Mon Sep 17 00:00:00 2001 From: Andrew McIntosh Date: Thu, 12 Oct 2023 09:56:15 -0400 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Handle=20webhook=20callback=20verif?= =?UTF-8?q?ication,=20resend?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit See Issue#44 --- README.md | 6 ++++ src/FreshBooksClient.php | 2 +- src/Resource/AccountingResource.php | 2 +- src/Resource/EventsResource.php | 32 ++++++++++++++++++++ tests/Resource/EventsResourceTest.php | 42 +++++++++++++++++++++++++++ 5 files changed, 82 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9b914e1..23178bc 100644 --- a/README.md +++ b/README.md @@ -472,6 +472,12 @@ To run all tests: make test ``` +Run a specific test: + +```shell + ./vendor/bin/phpunit --filter testCreateValidationError +``` + ### Documentations You can generate the documentation via: diff --git a/src/FreshBooksClient.php b/src/FreshBooksClient.php index eb21edf..c7ec428 100644 --- a/src/FreshBooksClient.php +++ b/src/FreshBooksClient.php @@ -307,7 +307,7 @@ public function taxes(): AccountingResource /** * FreshBooks callbacks (webhook callbacks) resource with calls to - * get, list, create, update, delete, resend_verification, verify + * get, list, create, update, delete, verify, resendVerification * * @return EventsResource */ diff --git a/src/Resource/AccountingResource.php b/src/Resource/AccountingResource.php index bc51162..d17860d 100644 --- a/src/Resource/AccountingResource.php +++ b/src/Resource/AccountingResource.php @@ -62,7 +62,7 @@ protected function getUrl(string $accountId, int $resourceId = null): string * @param array $data * @return array */ - private function makeRequest(string $method, string $url, array $data = null): array + protected function makeRequest(string $method, string $url, array $data = null): array { if (!is_null($data)) { $data = json_encode($data); diff --git a/src/Resource/EventsResource.php b/src/Resource/EventsResource.php index 0597773..4ec4399 100644 --- a/src/Resource/EventsResource.php +++ b/src/Resource/EventsResource.php @@ -64,4 +64,36 @@ protected function handleError(int $statusCode, array $responseData, string $raw var_dump($details); throw new FreshBooksException($message, $statusCode, null, $rawRespone, $errorCode, $details); } + + /** + * Tell FreshBooks to resend the verification webhook for the callback + * + * @param string $accountId The alpha-numeric account id + * @param int $resourceId Id of the resource to update + * @return DataTransferObject Model of the updated resource's response data. + */ + public function resendVerification(string $accountId, int $resourceId): DataTransferObject + { + $data = array($this->singleModel::RESPONSE_FIELD => array("resend" => true)); + $result = $this->makeRequest(self::PUT, $this->getUrl($accountId, $resourceId), $data); + return new $this->singleModel($result[$this->singleModel::RESPONSE_FIELD]); + } + + /** + * Verify webhook callback by making a put request + * + * @param string $accountId The alpha-numeric account id + * @param int $resourceId Id of the resource to update + * @param string The string verifier received by the webhook callback URI + * @return DataTransferObject Model of the updated resource's response data. + */ + public function verify( + string $accountId, + int $resourceId, + string $verifier, + ): DataTransferObject { + $data = array($this->singleModel::RESPONSE_FIELD => array("verifier" => $verifier)); + $result = $this->makeRequest(self::PUT, $this->getUrl($accountId, $resourceId), $data); + return new $this->singleModel($result[$this->singleModel::RESPONSE_FIELD]); + } } diff --git a/tests/Resource/EventsResourceTest.php b/tests/Resource/EventsResourceTest.php index e713ee6..fbca632 100644 --- a/tests/Resource/EventsResourceTest.php +++ b/tests/Resource/EventsResourceTest.php @@ -117,4 +117,46 @@ public function testCreateValidationError(): void ]], $e->getErrorDetails()); } } + + public function testVerify(): void + { + $callbackId = 12345; + $mockHttpClient = $this->getMockHttpClient( + 200, + ['response' => ['result' => ['callback' => [ + 'callbackid' => $callbackId, + 'verified' => true + ]]]] + ); + + $resource = new EventsResource($mockHttpClient, 'events/callbacks', Callback::class, CallbackList::class); + $callback = $resource->verify($this->accountId, $callbackId, 'some_verifier'); + + $this->assertSame($callbackId, $callback->callbackId); + + $request = $mockHttpClient->getLastRequest(); + $this->assertSame('PUT', $request->getMethod()); + $this->assertSame('/events/account/ACM123/events/callbacks/12345', $request->getRequestTarget()); + } + + public function testResend(): void + { + $callbackId = 12345; + $mockHttpClient = $this->getMockHttpClient( + 200, + ['response' => ['result' => ['callback' => [ + 'callbackid' => $callbackId, + 'verified' => true + ]]]] + ); + + $resource = new EventsResource($mockHttpClient, 'events/callbacks', Callback::class, CallbackList::class); + $callback = $resource->resendVerification($this->accountId, $callbackId); + + $this->assertSame($callbackId, $callback->callbackId); + + $request = $mockHttpClient->getLastRequest(); + $this->assertSame('PUT', $request->getMethod()); + $this->assertSame('/events/account/ACM123/events/callbacks/12345', $request->getRequestTarget()); + } }