From 78c31dae0fe077c7a774d822d77bdf11682918f1 Mon Sep 17 00:00:00 2001 From: Rolf Timmermans Date: Mon, 30 May 2016 11:49:55 +0200 Subject: [PATCH 01/13] Offer createKey() to register a new API key. --- lib/Tinify.php | 22 ++++++++++++++++++ lib/Tinify/Client.php | 49 +++++++++++++++++++++++++-------------- lib/Tinify/Exception.php | 2 +- lib/Tinify/Source.php | 8 +++---- test/TinifyClientTest.php | 41 ++++++++++++++++++++++++++++++++ test/TinifyTest.php | 39 +++++++++++++++++++++++++++++++ 6 files changed, 138 insertions(+), 23 deletions(-) diff --git a/lib/Tinify.php b/lib/Tinify.php index 39c62d8..c5b77c7 100644 --- a/lib/Tinify.php +++ b/lib/Tinify.php @@ -15,6 +15,16 @@ public static function setKey($key) { self::$client = NULL; } + public static function getKey() { + return self::$key; + } + + public static function createKey($email, $options) { + $body = array_merge(array("email" => $email), $options); + $response = self::getAnonymousClient()->request("post", "/keys", $body); + self::setKey($response->body->key); + } + public static function setAppIdentifier($appIdentifier) { self::$appIdentifier = $appIdentifier; self::$client = NULL; @@ -28,6 +38,10 @@ public static function setCompressionCount($compressionCount) { self::$compressionCount = $compressionCount; } + public static function getAnonymousClient() { + return new Client(NULL, self::$appIdentifier); + } + public static function getClient() { if (!self::$key) { throw new AccountException("Provide an API key with Tinify\setKey(...)"); @@ -45,6 +59,14 @@ function setKey($key) { return Tinify::setKey($key); } +function getKey() { + return Tinify::getKey(); +} + +function createKey($email, $options) { + return Tinify::createKey($email, $options); +} + function setAppIdentifier($appIdentifier) { return Tinify::setAppIdentifier($appIdentifier); } diff --git a/lib/Tinify/Client.php b/lib/Tinify/Client.php index 1b4a59a..1d0db9b 100644 --- a/lib/Tinify/Client.php +++ b/lib/Tinify/Client.php @@ -16,15 +16,16 @@ private static function caBundle() { return __DIR__ . "/../data/cacert.pem"; } - function __construct($key, $app_identifier = NULL) { + function __construct($key, $appIdentifier = NULL) { + $userAgent = join(" ", array_filter(array(self::userAgent(), $appIdentifier))); $this->options = array( CURLOPT_BINARYTRANSFER => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HEADER => true, - CURLOPT_USERPWD => "api:" . $key, + CURLOPT_USERPWD => $key ? ("api:" . $key) : NULL, CURLOPT_CAINFO => self::caBundle(), CURLOPT_SSL_VERIFYPEER => true, - CURLOPT_USERAGENT => join(" ", array_filter(array(self::userAgent(), $app_identifier))), + CURLOPT_USERAGENT => $userAgent, ); } @@ -64,22 +65,34 @@ function request($method, $url, $body = NULL, $header = array()) { Tinify::setCompressionCount(intval($headers["compression-count"])); } - if ($status >= 200 && $status <= 299) { - return array("body" => $body, "headers" => $headers); + $isJson = false; + if (isset($headers["content-type"])) { + /* Parse JSON response bodies. */ + list($contentType) = explode(";", $headers["content-type"], 2); + if (strtolower(trim($contentType)) == "application/json") { + $isJson = true; + } } - $details = json_decode($body); - if (!$details) { - $message = sprintf("Error while parsing response: %s (#%d)", - PHP_VERSION_ID >= 50500 ? json_last_error_msg() : "Error", - json_last_error()); - $details = (object) array( - "message" => $message, - "error" => "ParseError" - ); + /* 1xx and 3xx are unexpected and will be treated as error. */ + $isError = $status <= 199 || $status >= 300; + + if ($isJson || $isError) { + /* Parse JSON bodies, always interpret errors as JSON. */ + $body = json_decode($body); + if (!$body) { + $message = sprintf("Error while parsing response: %s (#%d)", + PHP_VERSION_ID >= 50500 ? json_last_error_msg() : "Error", + json_last_error()); + throw Exception::create($message, "ParseError", $status); + } } - throw Exception::create($details->message, $details->error, $status); + if ($isError) { + throw Exception::create($body->message, $body->error, $status); + } + + return (object) array("body" => $body, "headers" => $headers); } else { $message = sprintf("%s (#%d)", curl_error($request), curl_errno($request)); curl_close($request); @@ -92,14 +105,14 @@ protected static function parseHeaders($headers) { $headers = explode("\r\n", $headers); } - $res = array(); + $result = array(); foreach ($headers as $header) { if (empty($header)) continue; $split = explode(":", $header, 2); if (count($split) === 2) { - $res[strtolower($split[0])] = trim($split[1]); + $result[strtolower($split[0])] = trim($split[1]); } } - return $res; + return $result; } } diff --git a/lib/Tinify/Exception.php b/lib/Tinify/Exception.php index 1fc49de..e0c4578 100644 --- a/lib/Tinify/Exception.php +++ b/lib/Tinify/Exception.php @@ -4,7 +4,7 @@ class Exception extends \Exception { public static function create($message, $type, $status) { - if ($status == 401 || $status == 429) { + if ($status == 401 || $status == 403 || $status == 429) { $klass = "Tinify\AccountException"; } else if($status >= 400 && $status <= 499) { $klass = "Tinify\ClientException"; diff --git a/lib/Tinify/Source.php b/lib/Tinify/Source.php index fe27a9d..01c013f 100644 --- a/lib/Tinify/Source.php +++ b/lib/Tinify/Source.php @@ -11,13 +11,13 @@ public static function fromFile($path) { public static function fromBuffer($string) { $response = Tinify::getClient()->request("post", "/shrink", $string); - return new self($response["headers"]["location"]); + return new self($response->headers["location"]); } public static function fromUrl($url) { $body = array("source" => array("url" => $url)); $response = Tinify::getClient()->request("post", "/shrink", $body); - return new self($response["headers"]["location"]); + return new self($response->headers["location"]); } public function __construct($url, $commands = array()) { @@ -39,12 +39,12 @@ public function resize($options) { public function store($options) { $response = Tinify::getClient()->request("post", $this->url, array_merge($this->commands, array("store" => $options))); - return new Result($response["headers"], $response["body"]); + return new Result($response->headers, $response->body); } public function result() { $response = Tinify::getClient()->request("get", $this->url, $this->commands); - return new Result($response["headers"], $response["body"]); + return new Result($response->headers, $response->body); } public function toFile($path) { diff --git a/test/TinifyClientTest.php b/test/TinifyClientTest.php index 7183456..8636dbe 100644 --- a/test/TinifyClientTest.php +++ b/test/TinifyClientTest.php @@ -65,6 +65,47 @@ public function testRequestWhenValidWithAppIdShouldIssueRequestWithUserAgent() { $this->assertSame(Tinify\Client::userAgent() . " TestApp/0.1", CurlMock::last(CURLOPT_USERAGENT)); } + public function testRequestWhenValidShouldParseJSONBody() { + CurlMock::register("https://api.tinify.com/", array( + "status" => 200, + "body" => '{"hello":"world"}', + "headers" => array("Content-Type" => "application/JSON; charset=utf-8") + )); + $client = new Tinify\Client("key"); + $response = $client->request("post", "/"); + + $this->assertEquals((object) array("hello" => "world"), $response->body); + } + + public function testRequestWhenValidShouldNotParseBinaryBody() { + CurlMock::register("https://api.tinify.com/", array( + "status" => 200, + "body" => "binary body", + "headers" => array("Content-Type" => "image/png") + )); + $client = new Tinify\Client("key"); + $response = $client->request("post", "/"); + + $this->assertSame("binary body", $response->body); + } + + public function testRequestWithBadJSONBodyThrowExceptionWithMessage() { + CurlMock::register("https://api.tinify.com/", array( + "status" => 200, + "body" => '', + "headers" => array("Content-Type" => "application/JSON"), + )); + if (PHP_VERSION_ID >= 50500) { + $this->setExpectedExceptionRegExp("Tinify\Exception", + "/Error while parsing response: Syntax error \(#4\) \(HTTP 200\/ParseError\)/"); + } else { + $this->setExpectedExceptionRegExp("Tinify\Exception", + "/Error while parsing response: Error \(#4\) \(HTTP 200\/ParseError\)/"); + } + $client = new Tinify\Client("key"); + $client->request("get", "/"); + } + public function testRequestWithUnexpectedErrorShouldThrowConnectionException() { CurlMock::register("https://api.tinify.com/", array( "error" => "Failed!", "errno" => 2 diff --git a/test/TinifyTest.php b/test/TinifyTest.php index a002989..c6e3b20 100644 --- a/test/TinifyTest.php +++ b/test/TinifyTest.php @@ -10,6 +10,45 @@ public function setUp() { $this->dummyFile = __DIR__ . "/examples/dummy.png"; } + public function testGetKeyWithoutKeyShouldReturnNull() { + $this->assertSame(NULL, Tinify\getKey()); + } + + public function testGetKeyWithKeyShouldReturnKey() { + Tinify\setKey("abcde"); + $this->assertSame("abcde", Tinify\getKey()); + } + + public function testCreateKeyWithNewEmailShouldSetKey() { + CurlMock::register("https://api.tinify.com/keys", array( + "status" => 202, + "body" => '{"key":"abcdefg123"}', + "headers" => array("Content-Type" => "application/json"), + )); + + Tinify\createKey("user@example.com", array( + "name" => "John", + "identifier" => "My Tinify plugin", + "link" => "https://mywebsite.example.com/admin/settings", + )); + + $this->assertSame("abcdefg123", Tinify\getKey()); + } + + public function testCreateKeyWithDuplicateEmailShouldThrowClientException() { + CurlMock::register("https://api.tinify.com/keys", array( + "status" => 403, + "body" => '{"error":"Duplicate registration","message":"This email address has already been used"}', + )); + + $this->setExpectedException("Tinify\AccountException"); + Tinify\createKey("user@example.com", array( + "name" => "John", + "identifier" => "My Tinify plugin", + "link" => "https://mywebsite.example.com/admin/settings", + )); + } + public function testKeyShouldResetClientWithNewKey() { CurlMock::register("https://api.tinify.com/", array("status" => 200)); Tinify\setKey("abcde"); From d8abbc00d36de88c60b107ae5b79342cf7872c91 Mon Sep 17 00:00:00 2001 From: Rolf Timmermans Date: Mon, 30 May 2016 15:17:19 +0200 Subject: [PATCH 02/13] Reuse anonymous client. --- lib/Tinify.php | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/Tinify.php b/lib/Tinify.php index c5b77c7..0c9cf13 100644 --- a/lib/Tinify.php +++ b/lib/Tinify.php @@ -8,7 +8,9 @@ class Tinify { private static $key = NULL; private static $appIdentifier = NULL; private static $compressionCount = NULL; + private static $client = NULL; + private static $anonymousClient = NULL; public static function setKey($key) { self::$key = $key; @@ -28,6 +30,7 @@ public static function createKey($email, $options) { public static function setAppIdentifier($appIdentifier) { self::$appIdentifier = $appIdentifier; self::$client = NULL; + self::$anonymousClient = NULL; } public static function getCompressionCount() { @@ -38,10 +41,6 @@ public static function setCompressionCount($compressionCount) { self::$compressionCount = $compressionCount; } - public static function getAnonymousClient() { - return new Client(NULL, self::$appIdentifier); - } - public static function getClient() { if (!self::$key) { throw new AccountException("Provide an API key with Tinify\setKey(...)"); @@ -53,6 +52,14 @@ public static function getClient() { return self::$client; } + + private static function getAnonymousClient() { + if (!self::$anonymousClient) { + self::$anonymousClient = new Client(NULL, self::$appIdentifier); + } + + return self::$anonymousClient; + } } function setKey($key) { From e7d975e80a2bef474b2fe8a08f3d68991a37eb45 Mon Sep 17 00:00:00 2001 From: Rolf Timmermans Date: Mon, 30 May 2016 15:17:55 +0200 Subject: [PATCH 03/13] Make method public. --- lib/Tinify.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Tinify.php b/lib/Tinify.php index 0c9cf13..12dc777 100644 --- a/lib/Tinify.php +++ b/lib/Tinify.php @@ -53,7 +53,7 @@ public static function getClient() { return self::$client; } - private static function getAnonymousClient() { + public static function getAnonymousClient() { if (!self::$anonymousClient) { self::$anonymousClient = new Client(NULL, self::$appIdentifier); } From 94280d155ca64761cc697f0d34725f35810f3a78 Mon Sep 17 00:00:00 2001 From: Rolf Timmermans Date: Tue, 31 May 2016 15:22:14 +0200 Subject: [PATCH 04/13] Use self. [ci skip] --- lib/Tinify/Client.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Tinify/Client.php b/lib/Tinify/Client.php index 1d0db9b..f150951 100644 --- a/lib/Tinify/Client.php +++ b/lib/Tinify/Client.php @@ -42,7 +42,7 @@ function request($method, $url, $body = NULL, $header = array()) { $request = curl_init(); curl_setopt_array($request, $this->options); - $url = strtolower(substr($url, 0, 6)) == "https:" ? $url : Client::API_ENDPOINT . $url; + $url = strtolower(substr($url, 0, 6)) == "https:" ? $url : self::API_ENDPOINT . $url; curl_setopt($request, CURLOPT_URL, $url); curl_setopt($request, CURLOPT_HTTPHEADER, $header); curl_setopt($request, CURLOPT_CUSTOMREQUEST, strtoupper($method)); From 769d98a93ef084769a95f796d1def0066149cd2d Mon Sep 17 00:00:00 2001 From: Rolf Timmermans Date: Thu, 2 Jun 2016 13:28:58 +0200 Subject: [PATCH 05/13] Make status public. --- lib/Tinify/Exception.php | 4 +++- test/TinifyExceptionTest.php | 13 +++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 test/TinifyExceptionTest.php diff --git a/lib/Tinify/Exception.php b/lib/Tinify/Exception.php index e0c4578..580b24b 100644 --- a/lib/Tinify/Exception.php +++ b/lib/Tinify/Exception.php @@ -3,6 +3,8 @@ namespace Tinify; class Exception extends \Exception { + public $status; + public static function create($message, $type, $status) { if ($status == 401 || $status == 403 || $status == 429) { $klass = "Tinify\AccountException"; @@ -19,8 +21,8 @@ public static function create($message, $type, $status) { } function __construct($message, $type = NULL, $status = NULL) { + $this->status = $status; if ($status) { - $this->status = $status; parent::__construct($message . " (HTTP " . $status . "/" . $type . ")"); } else { parent::__construct($message); diff --git a/test/TinifyExceptionTest.php b/test/TinifyExceptionTest.php new file mode 100644 index 0000000..2329e72 --- /dev/null +++ b/test/TinifyExceptionTest.php @@ -0,0 +1,13 @@ +assertSame(401, $err->status); + } + + public function testStatusShouldReturnNullIfUnset() { + $err = new Tinify\Exception("Message", "Error"); + $this->assertSame(null, $err->status); + } +} From c369f9fd8ea1bae4654bac6f4d3ed4070fb75f03 Mon Sep 17 00:00:00 2001 From: Rolf Timmermans Date: Wed, 22 Jun 2016 13:58:28 +0200 Subject: [PATCH 06/13] Make options protected. --- lib/Tinify/Client.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Tinify/Client.php b/lib/Tinify/Client.php index f150951..4237700 100644 --- a/lib/Tinify/Client.php +++ b/lib/Tinify/Client.php @@ -5,7 +5,7 @@ class Client { const API_ENDPOINT = "https://api.tinify.com"; - private $options; + protected $options; public static function userAgent() { $curl = curl_version(); From ce0b3fe4b7490604604294992f41d8ccd91f6cf6 Mon Sep 17 00:00:00 2001 From: Rolf Timmermans Date: Wed, 19 Jul 2017 14:34:08 +0200 Subject: [PATCH 07/13] Change ordering and naming. --- lib/Tinify/Client.php | 4 ++-- test/curl_mock.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/Tinify/Client.php b/lib/Tinify/Client.php index b669700..142edfc 100644 --- a/lib/Tinify/Client.php +++ b/lib/Tinify/Client.php @@ -20,8 +20,6 @@ private static function caBundle() { } function __construct($key, $appIdentifier = NULL, $proxy = NULL) { - $userAgent = join(" ", array_filter(array(self::userAgent(), $appIdentifier))); - $curl = curl_version(); if (!($curl["features"] & CURL_VERSION_SSL)) { @@ -33,6 +31,8 @@ function __construct($key, $appIdentifier = NULL, $proxy = NULL) { throw new ClientException("Your curl version ${version} is outdated; please upgrade to 7.18.1 or higher"); } + $userAgent = join(" ", array_filter(array(self::userAgent(), $appIdentifier))); + $this->options = array( CURLOPT_BINARYTRANSFER => true, CURLOPT_RETURNTRANSFER => true, diff --git a/test/curl_mock.php b/test/curl_mock.php index 6d344bc..9008924 100644 --- a/test/curl_mock.php +++ b/test/curl_mock.php @@ -6,7 +6,7 @@ class CurlMockException extends Exception { } class CurlMock { - private static $default_version = array( + private static $defaultVersion = array( "version_number" => 471808, "version" => "7.51.0", "features" => 951197, @@ -44,7 +44,7 @@ public static function register($url, $request, $response = NULL) { public static function reset() { self::$requests = array(); self::$urls = array(); - self::$version = self::$default_version; + self::$version = self::$defaultVersion; } public static function last_has($key) { From c6b617c7d507f6c8aa518da4366f5e719d7348f7 Mon Sep 17 00:00:00 2001 From: Mattijs van Druenen Date: Wed, 7 Nov 2018 11:17:13 +0100 Subject: [PATCH 08/13] Use keys endpoint for key validation, and added retrieving remaining compression count, paying state and email address when they are returned from validate() calls. --- lib/Tinify.php | 54 ++++++++++++++++++++++++++++++++++++++- lib/Tinify/Client.php | 19 +++++++++++++- lib/Tinify/Exception.php | 2 +- test/TinifyClientTest.php | 30 ++++++++++++++++++++++ test/TinifyTest.php | 14 +++++----- 5 files changed, 109 insertions(+), 10 deletions(-) diff --git a/lib/Tinify.php b/lib/Tinify.php index 8157f4b..07d158a 100644 --- a/lib/Tinify.php +++ b/lib/Tinify.php @@ -13,6 +13,9 @@ class Tinify { private static $proxy = NULL; private static $compressionCount = NULL; + private static $remainingCredits = NULL; + private static $payingState = NULL; + private static $emailAddress = NULL; private static $client = NULL; @@ -49,6 +52,30 @@ public static function setCompressionCount($compressionCount) { self::$compressionCount = $compressionCount; } + public static function getRemainingCredits() { + return self::$remainingCredits; + } + + public static function setRemainingCredits($remainingCredits) { + self::$remainingCredits = $remainingCredits; + } + + public static function getPayingState() { + return self::$payingState; + } + + public static function setPayingState($payingState) { + self::$payingState = $payingState; + } + + public static function getEmailAddress() { + return self::$emailAddress; + } + + public static function setEmailAddress($emailAddress) { + self::$emailAddress = $emailAddress; + } + public static function getClient($mode = self::AUTHENTICATED) { if ($mode == self::AUTHENTICATED && !self::$key) { throw new AccountException("Provide an API key with Tinify\setKey(...)"); @@ -94,6 +121,30 @@ function compressionCount() { return Tinify::getCompressionCount(); } +function getRemainingCredits() { + return Tinify::getRemainingCredits(); +} + +function remainingCredits() { + return Tinify::getRemainingCredits(); +} + +function getPayingState() { + return Tinify::getPayingState(); +} + +function payingState() { + return Tinify::getPayingState(); +} + +function getEmailAddress() { + return Tinify::getEmailAddress(); +} + +function emailAddress() { + return Tinify::getEmailAddress(); +} + function fromFile($path) { return Source::fromFile($path); } @@ -108,7 +159,8 @@ function fromUrl($string) { function validate() { try { - Tinify::getClient()->request("post", "/shrink"); + Tinify::getClient()->request("get", "/keys/" . Tinify::getKey()); + return true; } catch (AccountException $err) { if ($err->status == 429) return true; throw $err; diff --git a/lib/Tinify/Client.php b/lib/Tinify/Client.php index 142edfc..bfdfe9f 100644 --- a/lib/Tinify/Client.php +++ b/lib/Tinify/Client.php @@ -118,6 +118,18 @@ function request($method, $url, $body = NULL) { Tinify::setCompressionCount(intval($headers["compression-count"])); } + if ( isset( $headers["compression-count-remaining"] ) ) { + Tinify::setRemainingCredits( intval( $headers["compression-count-remaining"] ) ); + } + + if ( isset( $headers["paying-state"] ) ) { + Tinify::setPayingState( $headers["paying-state"] ); + } + + if ( isset( $headers["email-address"] ) ) { + Tinify::setEmailAddress( $headers["email-address"] ); + } + $isJson = false; if (isset($headers["content-type"])) { /* Parse JSON response bodies. */ @@ -144,7 +156,12 @@ function request($method, $url, $body = NULL) { if ($isError) { if ($retries > 0 && $status >= 500) continue; - throw Exception::create($body->message, $body->error, $status); + /* When the key doesn't exist a 404 response is given. */ + if ($status == 404) { + throw Exception::create(null, null, $status); + } else { + throw Exception::create($body->message, $body->error, $status); + } } return (object) array("body" => $body, "headers" => $headers); diff --git a/lib/Tinify/Exception.php b/lib/Tinify/Exception.php index 580b24b..2eb2a8c 100644 --- a/lib/Tinify/Exception.php +++ b/lib/Tinify/Exception.php @@ -6,7 +6,7 @@ class Exception extends \Exception { public $status; public static function create($message, $type, $status) { - if ($status == 401 || $status == 403 || $status == 429) { + if ($status == 401 || $status == 403 || $status == 404 || $status == 429) { $klass = "Tinify\AccountException"; } else if($status >= 400 && $status <= 499) { $klass = "Tinify\ClientException"; diff --git a/test/TinifyClientTest.php b/test/TinifyClientTest.php index 9f25c7d..28960c6 100644 --- a/test/TinifyClientTest.php +++ b/test/TinifyClientTest.php @@ -55,6 +55,36 @@ public function testRequestWhenValidShouldUpdateCompressionCount() { $this->assertSame(12, Tinify\getCompressionCount()); } + public function testRequestWhenValidShouldUpdateRemainingCredits() { + CurlMock::register("https://api.tinify.com/", array( + "status" => 200, "headers" => array("Compression-Count-Remaining" => "488") + )); + $client = new Tinify\Client("key"); + $client->request("get", "/"); + + $this->assertSame(488, Tinify\getRemainingCredits()); + } + + public function testRequestWhenValidShouldUpdatePayingState() { + CurlMock::register("https://api.tinify.com/", array( + "status" => 200, "headers" => array("Paying-State" => "free") + )); + $client = new Tinify\Client("key"); + $client->request("get", "/"); + + $this->assertSame("free", Tinify\getPayingState()); + } + + public function testRequestWhenValidShouldUpdateEmailAddress() { + CurlMock::register("https://api.tinify.com/", array( + "status" => 200, "headers" => array("Email-Address" => "test@example.com") + )); + $client = new Tinify\Client("key"); + $client->request("get", "/"); + + $this->assertSame("test@example.com", Tinify\getEmailAddress()); + } + public function testRequestWhenValidWithAppIdShouldIssueRequestWithUserAgent() { CurlMock::register("https://api.tinify.com/", array("status" => 200)); $client = new Tinify\Client("key", "TestApp/0.1"); diff --git a/test/TinifyTest.php b/test/TinifyTest.php index 598b6a4..889df26 100644 --- a/test/TinifyTest.php +++ b/test/TinifyTest.php @@ -109,24 +109,24 @@ public function testSetClientShouldReplaceClient() { public function testValidateWithValidKeyShouldReturnTrue() { Tinify\setKey("valid"); - CurlMock::register("https://api.tinify.com/shrink", array( - "status" => 400, "body" => '{"error":"Input missing","message":"No input"}' + CurlMock::register("https://api.tinify.com/keys/valid", array( + "status" => 200, "body" => '{}' )); $this->assertTrue(Tinify\validate()); } public function testValidateWithLimitedKeyShouldReturnTrue() { - Tinify\setKey("invalid"); - CurlMock::register("https://api.tinify.com/shrink", array( - "status" => 429, "body" => '{"error":"Too many requests","message":"Your monthly limit has been exceeded"}' + Tinify\setKey("limited"); + CurlMock::register("https://api.tinify.com/keys/limited", array( + "status" => 200, "body" => '{}' )); $this->assertTrue(Tinify\validate()); } public function testValidateWithErrorShouldThrowException() { Tinify\setKey("invalid"); - CurlMock::register("https://api.tinify.com/shrink", array( - "status" => 401, "body" => '{"error":"Unauthorized","message":"Credentials are invalid"}' + CurlMock::register("https://api.tinify.com/keys/invalid", array( + "status" => 404, "body" => '{}' )); $this->setExpectedException("Tinify\AccountException"); Tinify\validate(); From b21ccb567f3923b80660658416ee134dbe0ae0d4 Mon Sep 17 00:00:00 2001 From: Mattijs van Druenen Date: Wed, 7 Nov 2018 11:58:12 +0100 Subject: [PATCH 09/13] Use assertSame instead so that tests also succeed on PHP 7.2. --- test/TinifyClientTest.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/test/TinifyClientTest.php b/test/TinifyClientTest.php index 28960c6..1df1131 100644 --- a/test/TinifyClientTest.php +++ b/test/TinifyClientTest.php @@ -101,8 +101,7 @@ public function testRequestWhenValidShouldParseJSONBody() { )); $client = new Tinify\Client("key"); $response = $client->request("post", "/"); - - $this->assertEquals((object) array("hello" => "world"), $response->body); + $this->assertSame("world", $response->body->hello); } public function testRequestWhenValidShouldNotParseBinaryBody() { From cb76e97b93ef7646c9a24a461687defe1a4d212e Mon Sep 17 00:00:00 2001 From: Mattijs van Druenen Date: Wed, 7 Nov 2018 12:13:32 +0100 Subject: [PATCH 10/13] Lets indeed not introduce extra alias getters for the new information returned from the /keys endpoint. --- lib/Tinify.php | 12 ------------ test/TinifyClientTest.php | 6 +++--- 2 files changed, 3 insertions(+), 15 deletions(-) diff --git a/lib/Tinify.php b/lib/Tinify.php index 07d158a..32d10f1 100644 --- a/lib/Tinify.php +++ b/lib/Tinify.php @@ -121,26 +121,14 @@ function compressionCount() { return Tinify::getCompressionCount(); } -function getRemainingCredits() { - return Tinify::getRemainingCredits(); -} - function remainingCredits() { return Tinify::getRemainingCredits(); } -function getPayingState() { - return Tinify::getPayingState(); -} - function payingState() { return Tinify::getPayingState(); } -function getEmailAddress() { - return Tinify::getEmailAddress(); -} - function emailAddress() { return Tinify::getEmailAddress(); } diff --git a/test/TinifyClientTest.php b/test/TinifyClientTest.php index 1df1131..1ad0c92 100644 --- a/test/TinifyClientTest.php +++ b/test/TinifyClientTest.php @@ -62,7 +62,7 @@ public function testRequestWhenValidShouldUpdateRemainingCredits() { $client = new Tinify\Client("key"); $client->request("get", "/"); - $this->assertSame(488, Tinify\getRemainingCredits()); + $this->assertSame(488, Tinify\remainingCredits()); } public function testRequestWhenValidShouldUpdatePayingState() { @@ -72,7 +72,7 @@ public function testRequestWhenValidShouldUpdatePayingState() { $client = new Tinify\Client("key"); $client->request("get", "/"); - $this->assertSame("free", Tinify\getPayingState()); + $this->assertSame("free", Tinify\payingState()); } public function testRequestWhenValidShouldUpdateEmailAddress() { @@ -82,7 +82,7 @@ public function testRequestWhenValidShouldUpdateEmailAddress() { $client = new Tinify\Client("key"); $client->request("get", "/"); - $this->assertSame("test@example.com", Tinify\getEmailAddress()); + $this->assertSame("test@example.com", Tinify\emailAddress()); } public function testRequestWhenValidWithAppIdShouldIssueRequestWithUserAgent() { From 58652f928c14647a8bd4e7dc1e732f6a589afcdb Mon Sep 17 00:00:00 2001 From: Yekta Turan Date: Thu, 1 Sep 2022 12:29:52 +0200 Subject: [PATCH 11/13] Updated request func not to overwrite request body and created test. --- lib/Tinify/Client.php | 10 +++++----- test/TinifyClientTest.php | 13 +++++++++++++ 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/lib/Tinify/Client.php b/lib/Tinify/Client.php index bfdfe9f..115c672 100644 --- a/lib/Tinify/Client.php +++ b/lib/Tinify/Client.php @@ -112,7 +112,7 @@ function request($method, $url, $body = NULL) { curl_close($request); $headers = self::parseHeaders(substr($response, 0, $headerSize)); - $body = substr($response, $headerSize); + $responseBody = substr($response, $headerSize); if (isset($headers["compression-count"])) { Tinify::setCompressionCount(intval($headers["compression-count"])); @@ -144,8 +144,8 @@ function request($method, $url, $body = NULL) { if ($isJson || $isError) { /* Parse JSON bodies, always interpret errors as JSON. */ - $body = json_decode($body); - if (!$body) { + $responseBody = json_decode($responseBody); + if (!$responseBody) { $message = sprintf("Error while parsing response: %s (#%d)", PHP_VERSION_ID >= 50500 ? json_last_error_msg() : "Error", json_last_error()); @@ -160,11 +160,11 @@ function request($method, $url, $body = NULL) { if ($status == 404) { throw Exception::create(null, null, $status); } else { - throw Exception::create($body->message, $body->error, $status); + throw Exception::create($responseBody->message, $responseBody->error, $status); } } - return (object) array("body" => $body, "headers" => $headers); + return (object) array("body" => $responseBody, "headers" => $headers); } else { $message = sprintf("%s (#%d)", curl_error($request), curl_errno($request)); curl_close($request); diff --git a/test/TinifyClientTest.php b/test/TinifyClientTest.php index 1ad0c92..a09e8b7 100644 --- a/test/TinifyClientTest.php +++ b/test/TinifyClientTest.php @@ -231,6 +231,19 @@ public function testRequestWithServerErrorRepeatedlyShouldThrowServerException() $client->request("get", "/"); } + public function testRequestWithBodyAndServerErrorRepeatedlyShouldThrowServerException() { + CurlMock::register("https://api.tinify.com/", array( + "body" => '{"email":"user@gmail.com"}' + ), array( + "status" => 500, "body" => '{"error":"InternalServerError","message":"Oops!"}' + )); + + $this->setExpectedException("Tinify\ServerException"); + $client = new Tinify\Client("key"); + $response = $client->request("post", "/", array("email"=> "user@gmail.com")); + $this->assertEquals("", $response->body); + } + public function testRequestWithServerErrorRepeatedlyShouldThrowExceptionWithMessage() { CurlMock::register("https://api.tinify.com/", array( "status" => 584, "body" => '{"error":"InternalServerError","message":"Oops!"}' From d71421ecce9e034524eacccb83bae710d8386cbe Mon Sep 17 00:00:00 2001 From: tijmen Date: Sat, 1 Feb 2025 14:04:16 +0100 Subject: [PATCH 12/13] Remove setup --- test/TinifyTest.php | 7 ------- 1 file changed, 7 deletions(-) diff --git a/test/TinifyTest.php b/test/TinifyTest.php index 3d3a63f..39348da 100644 --- a/test/TinifyTest.php +++ b/test/TinifyTest.php @@ -3,13 +3,6 @@ use Tinify\CurlMock; class ClientTest extends TestCase { - private $dummyFile; - - public function setUp() { - parent::setUp(); - $this->dummyFile = __DIR__ . "/examples/dummy.png"; - } - public function testGetKeyWithoutKeyShouldReturnNull() { $this->assertSame(NULL, Tinify\getKey()); } From a2117ceb3e1bcc49a9c712ab13f4055f32202606 Mon Sep 17 00:00:00 2001 From: tijmen Date: Tue, 4 Feb 2025 20:56:24 +0100 Subject: [PATCH 13/13] Remove status check --- lib/Tinify/Client.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/lib/Tinify/Client.php b/lib/Tinify/Client.php index f67dc96..7c2bc03 100644 --- a/lib/Tinify/Client.php +++ b/lib/Tinify/Client.php @@ -113,7 +113,7 @@ function request($method, $url, $body = NULL) { $headers = self::parseHeaders(substr($response, 0, $headerSize)); $responseBody = substr($response, $headerSize); - if (isset($headers["compression-count"])) { + if ( isset($headers["compression-count"] ) ) { Tinify::setCompressionCount(intval($headers["compression-count"])); } @@ -124,10 +124,6 @@ function request($method, $url, $body = NULL) { if ( isset( $headers["paying-state"] ) ) { Tinify::setPayingState( $headers["paying-state"] ); } - - if ($status >= 200 && $status <= 299) { - return (object) array("body" => $responseBody, "headers" => $headers); - } $details = json_decode($responseBody); if (!$details) {