From 2e11cb55bf12d1667998e11b2d2fcbd905ce3099 Mon Sep 17 00:00:00 2001 From: Martial Saunois Date: Tue, 8 Mar 2016 17:39:48 +0100 Subject: [PATCH] Fix #6 : Throw a DuplicateTorrentException when Transmission returns this error --- src/DuplicateTorrentException.php | 61 +++++++++++++++++++++++++++++++ src/RpcClient.php | 23 ++++++++++-- src/TransmissionException.php | 21 +++++++++++ tests/RpcClientTest.php | 35 ++++++++++++++++++ 4 files changed, 136 insertions(+), 4 deletions(-) diff --git a/src/DuplicateTorrentException.php b/src/DuplicateTorrentException.php index 7bcf931..05947ee 100644 --- a/src/DuplicateTorrentException.php +++ b/src/DuplicateTorrentException.php @@ -4,5 +4,66 @@ class DuplicateTorrentException extends \Exception { + /** + * @var int + */ + private $torrentId; + /** + * @var string + */ + private $torrentName; + + /** + * @var string + */ + private $torrentHashString; + + /** + * @return int + */ + public function getTorrentId() + { + return $this->torrentId; + } + + /** + * @param int $torrentId + */ + public function setTorrentId($torrentId) + { + $this->torrentId = $torrentId; + } + + /** + * @return string + */ + public function getTorrentName() + { + return $this->torrentName; + } + + /** + * @param string $torrentName + */ + public function setTorrentName($torrentName) + { + $this->torrentName = $torrentName; + } + + /** + * @return string + */ + public function getTorrentHashString() + { + return $this->torrentHashString; + } + + /** + * @param string $torrentHashString + */ + public function setTorrentHashString($torrentHashString) + { + $this->torrentHashString = $torrentHashString; + } } diff --git a/src/RpcClient.php b/src/RpcClient.php index e2962f2..8d8ceb4 100644 --- a/src/RpcClient.php +++ b/src/RpcClient.php @@ -215,10 +215,24 @@ public function torrentAdd($sessionId, array $argumentsWithValues) )); } - $response = $this->sendRequest($sessionId, $this->buildRequestBody( - 'torrent-add', - $argumentsWithValues - )); + try { + $response = $this->sendRequest($sessionId, $this->buildRequestBody( + 'torrent-add', + $argumentsWithValues + )); + } catch (TransmissionException $e) { + if ($e->getResult() === 'duplicate torrent') { + $responseArguments = $e->getArguments(); + $duplicateTorrentException = new DuplicateTorrentException(); + $duplicateTorrentException->setTorrentId($responseArguments['torrent-duplicate']['id']); + $duplicateTorrentException->setTorrentName($responseArguments['torrent-duplicate']['name']); + $duplicateTorrentException->setTorrentHashString($responseArguments['torrent-duplicate']['hashString']); + + throw $duplicateTorrentException; + } + + throw $e; + } return $response['arguments']['torrent-added']; } @@ -567,6 +581,7 @@ private function sendRequest($sessionId, $requestBody) if ($responseBody['result'] !== 'success') { $e = new TransmissionException('The Transmission RPC API returned an error: ' . $responseBody['result']); $e->setResult($responseBody['result']); + $e->setArguments($responseBody['arguments']); if (!is_null($this->logger)) { $this->logger->error( diff --git a/src/TransmissionException.php b/src/TransmissionException.php index 80f2493..31f6a62 100644 --- a/src/TransmissionException.php +++ b/src/TransmissionException.php @@ -9,6 +9,11 @@ class TransmissionException extends \Exception */ private $result; + /** + * @var array + */ + private $arguments; + /** * @return string */ @@ -24,4 +29,20 @@ public function setResult($result) { $this->result = $result; } + + /** + * @return array + */ + public function getArguments() + { + return $this->arguments; + } + + /** + * @param array $arguments + */ + public function setArguments(array $arguments) + { + $this->arguments = $arguments; + } } diff --git a/tests/RpcClientTest.php b/tests/RpcClientTest.php index 90c2a86..f3b497d 100644 --- a/tests/RpcClientTest.php +++ b/tests/RpcClientTest.php @@ -4,6 +4,7 @@ use GuzzleHttp\Exception\ClientException; use Martial\Transmission\API\CSRFException; +use Martial\Transmission\API\DuplicateTorrentException; use Martial\Transmission\API\RpcClient; use Martial\Transmission\API\TransmissionException; use Mockery as m; @@ -701,6 +702,40 @@ public function testTorrentAddShouldThrowAnExceptionWithAnInvalidSessionId() } } + public function testTorrentAddShouldThrowAnExceptionWithDuplicateTorrent() + { + $success = false; + $arguments = ['filename' => '/path/to/Fedora.torrent']; + $requestBody = '{"method":"torrent-add","arguments":{"filename":"/path/to/Fedora.torrent"}}'; + $hashString = md5('Fedora.iso'); + $torrentId = 42; + $torrentName = 'Fedora.iso'; + + $this + ->sendRequest($requestBody) + ->andReturn($this->guzzleResponse); + + $this->setResponseBody(sprintf( + '{"arguments":{"torrent-duplicate":{"id":%d,"name":"%s","hashString":"%s"}},"result":"duplicate torrent"}', + $torrentId, + $torrentName, + $hashString + )); + + try { + $this->rpcClient->torrentAdd($this->sessionId, $arguments); + } catch (DuplicateTorrentException $e) { + $this->assertSame($torrentId, $e->getTorrentId()); + $this->assertSame($torrentName, $e->getTorrentName()); + $this->assertSame($hashString, $e->getTorrentHashString()); + $success = true; + } + + if (!$success) { + $this->fail('DuplicateTorrentException was not thrown.'); + } + } + public function testTorrentRemoveWithLocalDataWithSuccess() { $requestBody = '{"method":"torrent-remove","arguments":{"ids":[42,1337],"delete-local-data":true}}';