diff --git a/README.md b/README.md index 677f7ea..ea3f39e 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ with PHPUnit and as close as possible from the original RPC interface. With composer: ```sh -composer require 'martial/transmission-api:~1.0' +composer require 'martial/transmission-api:~2.0' ``` ## Usage @@ -34,7 +34,7 @@ You may want to use a logger: $logger = new \Monolog\Logger('transmission'); $logger->pushHandler(new \Monolog\Handler\StreamHandler('php://stdout')); -$api->setLogger($logger); +$api = new \Martial\Transmission\API\RpcClient($httpClient, 'rpc-username', 'rpc-password', $logger); ``` ### Session ID diff --git a/UPGRADE-2.0.md b/UPGRADE-2.0.md new file mode 100644 index 0000000..3ba040e --- /dev/null +++ b/UPGRADE-2.0.md @@ -0,0 +1,56 @@ +# UPGRADE FROM 1.x TO 2.0 + +## Torrent IDs + +The array of torrent IDs provided as an argument of almost all the client's methods is replaced by a new class +\Martial\Transmission\API\TorrentIdList. This class has been created to ensure that the request to the +Transmission RPC API is well formatted. +The constructor of this class has one argument, your array of IDs. + +Before: + +```php +$api = new \Martial\Transmission\API\RpcClient($guzzle, $rpcUsername, $rpcPassword); +$sessionId = // Fetch a new session ID +$torrentIds = [42, 43, 44]; +$api->torrentGet($sessionId, $torrentIds, [ + \Martial\Transmission\API\Argument\Torrent\Get::ID, + \Martial\Transmission\API\Argument\Torrent\Get::NAME, + \Martial\Transmission\API\Argument\Torrent\Get::STATUS +]); +``` + +Now: + +```php +$api = new \Martial\Transmission\API\RpcClient($guzzle, $rpcUsername, $rpcPassword); +$sessionId = // Fetch a new session ID +$torrentIds = new \Martial\Transmission\API\TorrentIdList([42, 43, 44]); +$api->torrentGet($sessionId, $torrentIds, [ + \Martial\Transmission\API\Argument\Torrent\Get::ID, + \Martial\Transmission\API\Argument\Torrent\Get::NAME, + \Martial\Transmission\API\Argument\Torrent\Get::STATUS +]); +``` + +## Logger + +The method \Martial\Transmission\API\TransmissionAPI::setLogger() has been removed because it violated the SRP +principle. The logger can now be injected as fourth argument of the client's controller. + +Before: + +```php +$api = new \Martial\Transmission\API\RpcClient($guzzle, $rpcUsername, $rpcPassword); +$logger = new \Monolog\Logger('transmission'); +$logger->pushHandler(new \Monolog\Handler\StreamHandler('php://stdout')); +$api->setLogger($logger); +``` + +Now: + +```php +$logger = new \Monolog\Logger('transmission'); +$logger->pushHandler(new \Monolog\Handler\StreamHandler('php://stdout')); +$api = new \Martial\Transmission\API\RpcClient($guzzle, $rpcUsername, $rpcPassword, $logger); +``` diff --git a/doc/examples.php b/doc/examples.php index 14d5b68..28c88c8 100644 --- a/doc/examples.php +++ b/doc/examples.php @@ -2,18 +2,26 @@ // Load composer +use GuzzleHttp\Client; +use Martial\Transmission\API\Argument\Torrent\Add; +use Martial\Transmission\API\Argument\Torrent\Get; +use Martial\Transmission\API\CSRFException; +use Martial\Transmission\API\RpcClient; +use Martial\Transmission\API\TorrentIdList; +use Martial\Transmission\API\TransmissionAPI; +use Monolog\Handler\StreamHandler; +use Monolog\Logger; + $rpcUri = 'http://42.42.42.42:9091/transmission/rpc'; $rpcUsername = 'transmission'; $rpcPassword = 'transmission'; $newTorrentFile = '/tmp/debian-8.2.0-amd64-CD-1.iso.torrent'; -$guzzle = new GuzzleHttp\Client(['base_uri' => $rpcUri]); -$api = new \Martial\Transmission\API\RpcClient($guzzle, $rpcUsername, $rpcPassword); - -$logger = new \Monolog\Logger('transmission'); -$logger->pushHandler(new \Monolog\Handler\StreamHandler('php://stdout')); +$guzzle = new Client(['base_uri' => $rpcUri]); +$logger = new Logger('transmission'); +$logger->pushHandler(new StreamHandler('php://stdout')); -$api->setLogger($logger); +$api = new RpcClient($guzzle, $rpcUsername, $rpcPassword, $logger); /** * @param array $torrentList @@ -23,9 +31,9 @@ function printTorrentData(array $torrentList) foreach ($torrentList as $torrentData) { printf( 'The status of the torrent "%s" with the ID %d is "%s".', - $torrentData[\Martial\Transmission\API\Argument\Torrent\Get::NAME], - $torrentData[\Martial\Transmission\API\Argument\Torrent\Get::ID], - $torrentData[\Martial\Transmission\API\Argument\Torrent\Get::STATUS] + $torrentData[Get::NAME], + $torrentData[Get::ID], + $torrentData[Get::STATUS] ); echo PHP_EOL; @@ -33,17 +41,17 @@ function printTorrentData(array $torrentList) } /** - * @param \Martial\Transmission\API\TransmissionAPI $api + * @param TransmissionAPI $api * @param $sessionId * @param array $ids * @return array */ -function getTorrentData(\Martial\Transmission\API\TransmissionAPI $api, $sessionId, array $ids) +function getTorrentData(TransmissionAPI $api, $sessionId, array $ids) { - $torrentList = $api->torrentGet($sessionId, $ids, [ - \Martial\Transmission\API\Argument\Torrent\Get::ID, - \Martial\Transmission\API\Argument\Torrent\Get::NAME, - \Martial\Transmission\API\Argument\Torrent\Get::STATUS + $torrentList = $api->torrentGet($sessionId, new TorrentIdList($ids), [ + Get::ID, + Get::NAME, + Get::STATUS ]); @@ -66,19 +74,19 @@ function checkNotEmptyList(array $torrentList) // Fetching a new session ID try { $api->sessionGet($sessionId); -} catch (\Martial\Transmission\API\CSRFException $e) { +} catch (CSRFException $e) { $sessionId = $e->getSessionId(); } // Adding a new torrent to the download queue $torrentData = $api->torrentAdd($sessionId, [ - \Martial\Transmission\API\Argument\Torrent\Add::FILENAME => $newTorrentFile + Add::FILENAME => $newTorrentFile ]); printf( 'New torrent "%s" with ID %d added:', - $torrentData[\Martial\Transmission\API\Argument\Torrent\Get::NAME], - $torrentData[\Martial\Transmission\API\Argument\Torrent\Get::ID] + $torrentData[Get::NAME], + $torrentData[Get::ID] ); echo PHP_EOL; @@ -88,9 +96,11 @@ function checkNotEmptyList(array $torrentList) printTorrentData($torrentList); // Stopping the first torrent -$api->torrentStop($sessionId, [$torrentList[0][\Martial\Transmission\API\Argument\Torrent\Get::ID]]); +$api->torrentStop($sessionId, new TorrentIdList( + [$torrentList[0][Get::ID]] +)); -sleep(1); +sleep(1); // The transmission API is not real time $torrentList = getTorrentData($api, $sessionId, []); checkNotEmptyList($torrentList); @@ -98,17 +108,17 @@ function checkNotEmptyList(array $torrentList) printTorrentData($torrentList); // Starting the first torrent -$api->torrentStart($sessionId, [$torrentList[0][\Martial\Transmission\API\Argument\Torrent\Get::ID]]); +$api->torrentStart($sessionId, new TorrentIdList([$torrentList[0][Get::ID]])); -sleep(1); // The transmission API is not real time +sleep(1); -$torrentList = getTorrentData($api, $sessionId, [$torrentList[0][\Martial\Transmission\API\Argument\Torrent\Get::ID]]); +$torrentList = getTorrentData($api, $sessionId, [$torrentList[0][Get::ID]]); checkNotEmptyList($torrentList); echo 'Torrent list:' . PHP_EOL; printTorrentData($torrentList); // Removing the first torrent -$api->torrentRemove($sessionId, [$torrentList[0][\Martial\Transmission\API\Argument\Torrent\Get::ID]], true); +$api->torrentRemove($sessionId, new TorrentIdList([$torrentList[0][Get::ID]]), true); sleep(1); diff --git a/src/RpcClient.php b/src/RpcClient.php index 26e890f..cba6607 100644 --- a/src/RpcClient.php +++ b/src/RpcClient.php @@ -36,146 +36,76 @@ class RpcClient implements TransmissionAPI * @param ClientInterface $httpClient * @param string $rpcUsername * @param string $rpcPassword + * @param LoggerInterface $logger */ - public function __construct(ClientInterface $httpClient, $rpcUsername, $rpcPassword) + public function __construct(ClientInterface $httpClient, $rpcUsername, $rpcPassword, LoggerInterface $logger = null) { $this->httpClient = $httpClient; $this->rpcUsername = $rpcUsername; $this->rpcPassword = $rpcPassword; - } - - /** - * Injects a logger. - * - * @param LoggerInterface $logger - */ - public function setLogger(LoggerInterface $logger) - { $this->logger = $logger; } /** - * Starts the given torrents (all the torrents if no IDs are provided). - * - * @param string $sessionId - * @param int[] $ids - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ - public function torrentStart($sessionId, array $ids) + public function torrentStart($sessionId, TorrentIdList $ids) { - $this->sendRequest($sessionId, $this->buildRequestBody('torrent-start', ['ids' => $ids])); + $this->sendRequest($sessionId, $this->buildRequestBody('torrent-start', ['ids' => $ids->getList()])); } /** - * Starts now the given torrents (all the torrents if no IDs are provided). - * - * @param string $sessionId - * @param int[] $ids - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ - public function torrentStartNow($sessionId, array $ids) + public function torrentStartNow($sessionId, TorrentIdList $ids) { - $this->sendRequest($sessionId, $this->buildRequestBody('torrent-start-now', ['ids' => $ids])); + $this->sendRequest($sessionId, $this->buildRequestBody('torrent-start-now', ['ids' => $ids->getList()])); } /** - * Stops the given torrents (all the torrents if no IDs are provided). - * - * @param string $sessionId - * @param int[] $ids - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ - public function torrentStop($sessionId, array $ids) + public function torrentStop($sessionId, TorrentIdList $ids) { - $this->sendRequest($sessionId, $this->buildRequestBody('torrent-stop', ['ids' => $ids])); + $this->sendRequest($sessionId, $this->buildRequestBody('torrent-stop', ['ids' => $ids->getList()])); } /** - * Verifies the given torrents (all the torrents if no IDs are provided). - * - * @param string $sessionId - * @param int[] $ids - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ - public function torrentVerify($sessionId, array $ids) + public function torrentVerify($sessionId, TorrentIdList $ids) { - $this->sendRequest($sessionId, $this->buildRequestBody('torrent-verify', ['ids' => $ids])); + $this->sendRequest($sessionId, $this->buildRequestBody('torrent-verify', ['ids' => $ids->getList()])); } /** - * Reannonces the given torrents (all the torrents if no IDs are provided). - * - * @param string $sessionId - * @param int[] $ids - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ - public function torrentReannounce($sessionId, array $ids) + public function torrentReannounce($sessionId, TorrentIdList $ids) { - $this->sendRequest($sessionId, $this->buildRequestBody('torrent-reannounce', ['ids' => $ids])); + $this->sendRequest($sessionId, $this->buildRequestBody('torrent-reannounce', ['ids' => $ids->getList()])); } /** - * Applies the given arguments with their values to the given torrent IDs. - * The available methods are defined in the constants of the interface Martial\Transmission\Argument\Torrent\Set. - * Each of them has a block of documentation to know the accepted value type. - * Using an empty array for "files-wanted", "files-unwanted", "priority-high", "priority-low", or - * "priority-normal" is shorthand for saying "all files". Ex: - * - * $client->torrentSet('iefjzo234fez', [42, 1337], ['downloadLimit' => 200]); - * - * - * @param string $sessionId - * @param array $ids - * @param array $argumentsWithValues - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ - public function torrentSet($sessionId, array $ids, array $argumentsWithValues) + public function torrentSet($sessionId, TorrentIdList $ids, array $argumentsWithValues) { $this->sendRequest($sessionId, $this->buildRequestBody( 'torrent-set', - array_merge(['ids' => $ids], $argumentsWithValues) + array_merge(['ids' => $ids->getList()], $argumentsWithValues) )); } /** - * Retrieves the data of the given fields for the given torrent IDs. - * The available fields are defined in the constants of the interface \Martial\Transmission\Argument\Torrent\Get. - * All torrents are used if the "ids" array is empty. - * Returns an array of torrents data. Ex: - * - * [ - * [ - * 'id' => 42, - * 'name' => 'Fedora x86_64 DVD', - * 'totalSize' => 34983493932, - * ], - * [ - * 'id' => 1337, - * 'name' => 'Ubuntu x86_64 DVD', - * 'totalSize' => 9923890123, - * ], - * ]; - * - * - * @param string $sessionId - * @param array $ids - * @param array $fields - * @return array - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ - public function torrentGet($sessionId, array $ids, array $fields = []) + public function torrentGet($sessionId, TorrentIdList $ids, array $fields = []) { - if (empty($ids)) { + if (empty($ids->getList())) { $arguments = ['fields' => $fields]; } else { - $arguments = array_merge(['ids' => $ids], ['fields' => $fields]); + $arguments = array_merge(['ids' => $ids->getList()], ['fields' => $fields]); } $response = $this->sendRequest($sessionId, $this->buildRequestBody('torrent-get', $arguments)); @@ -184,25 +114,7 @@ public function torrentGet($sessionId, array $ids, array $fields = []) } /** - * Adds a torrent to the download queue. - * The available arguments are defined in the constants of the interface \Martial\Transmission\Argument\Torrent\Add. - * You MUST provide the filename or the metainfo argument in order to add a torrent. - * Returns an array with the torrent ID, name and hashString fields. Ex: - * - * [ - * 'id' => 42, - * 'name' => 'Fedora x86_64 DVD', - * 'hashString' => 'fb7bd58d695990c5a8cb4ac04de9a34ad27a5259' - * ] - * - * - * @param string $sessionId - * @param array $argumentsWithValues - * @return array - * @throws DuplicateTorrentException - * @throws TransmissionException - * @throws CSRFException - * @throws MissingArgumentException + * @inheritdoc */ public function torrentAdd($sessionId, array $argumentsWithValues) { @@ -215,41 +127,20 @@ public function torrentAdd($sessionId, array $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; - } + $response = $this->sendRequest($sessionId, $this->buildRequestBody( + 'torrent-add', + $argumentsWithValues + )); return $response['arguments']['torrent-added']; } /** - * Removes the given torrent IDs from the download queue. - * All torrents are used if the "ids" array is empty. - * - * @param string $sessionId - * @param array $ids - * @param bool $deleteLocalData - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ - public function torrentRemove($sessionId, array $ids, $deleteLocalData = false) + public function torrentRemove($sessionId, TorrentIdList $ids, $deleteLocalData = false) { - $arguments = ['ids' => $ids]; + $arguments = ['ids' => $ids->getList()]; if ($deleteLocalData) { $arguments['delete-local-data'] = true; @@ -259,45 +150,19 @@ public function torrentRemove($sessionId, array $ids, $deleteLocalData = false) } /** - * Moves the given torrent IDs. - * If $move is set to true, move from previous location. Otherwise, search "location" for files. - * All torrents are used if the "ids" array is empty. - * - * @param string $sessionId - * @param array $ids - * @param string $location - * @param bool $move - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ - public function torrentSetLocation($sessionId, array $ids, $location, $move = false) + public function torrentSetLocation($sessionId, TorrentIdList $ids, $location, $move = false) { $this->sendRequest($sessionId, $this->buildRequestBody('torrent-set-location', [ - 'ids' => $ids, + 'ids' => $ids->getList(), 'location' => $location, 'move' => $move ])); } /** - * Renames a torrent path. - * The old and new paths are relative to the download directory of your Transmission settings. - * Returns an array of torrent data. Ex: - * - * [ - * 'id' => 42, - * 'name' => 'Fedora x86_64 DVD', - * 'path' => '/path/to/torrent' - * ] - * - * - * @param string $sessionId - * @param int $id - * @param string $oldPath - * @param string $newPath - * @return array - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ public function torrentRenamePath($sessionId, $id, $oldPath, $newPath) { @@ -311,14 +176,7 @@ public function torrentRenamePath($sessionId, $id, $oldPath, $newPath) } /** - * Defines session settings. - * The settings are listed in the constants of the interface \Martial\Transmission\Argument\Session\Set. - * Each of them has a block of documentation to know the accepted value type. - * - * @param string $sessionId - * @param array $argumentsWithValues - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ public function sessionSet($sessionId, array $argumentsWithValues) { @@ -343,13 +201,7 @@ public function sessionSet($sessionId, array $argumentsWithValues) } /** - * Retrieves the session settings. - * Returns an array of all the settings listed in the interface \Martial\Transmission\Argument\Session\Get. - * - * @param string $sessionId - * @return array - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ public function sessionGet($sessionId) { @@ -359,13 +211,7 @@ public function sessionGet($sessionId) } /** - * Retrieves an array of stats. - * The keys of the array are listed in the interface \Martial\Transmission\Argument\Session\Stats. - * - * @param string $sessionId - * @return array - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ public function sessionStats($sessionId) { @@ -375,14 +221,7 @@ public function sessionStats($sessionId) } /** - * Updates the blocklist. - * Returns the blocklist size. - * - * @param string $sessionId - * @return int - * @throws TransmissionException - * @throws CSRFException - * @throws BlocklistNotFoundException + * @inheritdoc */ public function blocklistUpdate($sessionId) { @@ -400,12 +239,7 @@ public function blocklistUpdate($sessionId) } /** - * Checks if the incoming peer port is accessible from the outside world. - * - * @param string $sessionId - * @return bool - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ public function portTest($sessionId) { @@ -415,11 +249,7 @@ public function portTest($sessionId) } /** - * Closes the transmission session. - * - * @param string $sessionId - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ public function sessionClose($sessionId) { @@ -427,67 +257,39 @@ public function sessionClose($sessionId) } /** - * Moves the given IDs to the top of the queue. - * - * @param string $sessionId - * @param array $ids - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ - public function queueMoveTop($sessionId, array $ids) + public function queueMoveTop($sessionId, TorrentIdList $ids) { - $this->sendRequest($sessionId, $this->buildRequestBody('queue-move-top', ['ids' => $ids])); + $this->sendRequest($sessionId, $this->buildRequestBody('queue-move-top', ['ids' => $ids->getList()])); } /** - * Moves the given IDs to previous position in the queue. - * - * @param string $sessionId - * @param array $ids - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ - public function queueMoveDown($sessionId, array $ids) + public function queueMoveDown($sessionId, TorrentIdList $ids) { - $this->sendRequest($sessionId, $this->buildRequestBody('queue-move-down', ['ids' => $ids])); + $this->sendRequest($sessionId, $this->buildRequestBody('queue-move-down', ['ids' => $ids->getList()])); } /** - * Moves the given IDs to the next potision in the queue. - * - * @param string $sessionId - * @param array $ids - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ - public function queueMoveUp($sessionId, array $ids) + public function queueMoveUp($sessionId, TorrentIdList $ids) { - $this->sendRequest($sessionId, $this->buildRequestBody('queue-move-up', ['ids' => $ids])); + $this->sendRequest($sessionId, $this->buildRequestBody('queue-move-up', ['ids' => $ids->getList()])); } /** - * Moves the given IDs to the bottom of the queue. - * - * @param string $sessionId - * @param array $ids - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ - public function queueMoveBottom($sessionId, array $ids) + public function queueMoveBottom($sessionId, TorrentIdList $ids) { - $this->sendRequest($sessionId, $this->buildRequestBody('queue-move-bottom', ['ids' => $ids])); + $this->sendRequest($sessionId, $this->buildRequestBody('queue-move-bottom', ['ids' => $ids->getList()])); } /** - * Tests how much free space is available in a client-specified folder. - * Returns an array of data whose the keys are defined in the interface - * \Martial\Transmission\Argument\Session\FreeSpace - * - * @param string $sessionId - * @param string $path - * @return array - * @throws TransmissionException - * @throws CSRFException + * @inheritdoc */ public function freeSpace($sessionId, $path) { @@ -509,10 +311,6 @@ private function buildRequestBody($method, array $arguments = []) $body->method = $method; if (!empty($arguments)) { - if (isset($arguments['ids']) && is_array($arguments['ids'])) { - $arguments['ids'] = array_values($arguments['ids']); - } - $body->arguments = new \StdClass(); foreach ($arguments as $argument => $value) { @@ -536,11 +334,7 @@ private function buildRequestBody($method, array $arguments = []) private function sendRequest($sessionId, $requestBody) { try { - if (!is_null($this->logger)) { - $this->logger->debug('Request sent to the Transmission RPC API.', [ - 'request' => $requestBody - ]); - } + $this->log('debug', 'Request sent to the Transmission RPC API.', ['request' => $requestBody]); $response = $this ->httpClient @@ -559,22 +353,16 @@ private function sendRequest($sessionId, $requestBody) $e->getResponse()->getHeader('X-Transmission-Session-Id')[0] ); - if (!is_null($this->logger)) { - $this->logger->info('Invalid Transmission session ID. A new ID has been generated.', [ - 'session_id' => $csrfException->getSessionId() - ]); - } + $this->log('info', 'Invalid Transmission session ID. A new ID has been generated.', [ + 'session_id' => $csrfException->getSessionId() + ]); throw $csrfException; } throw $e; } catch (RequestException $e) { - if (!is_null($this->logger)) { - $this->logger->error('The Transmission RPC API returned a 500 error.', [ - 'exception' => $e - ]); - } + $this->log('error', 'The Transmission RPC API returned a 500 error.', ['exception' => $e]); throw new TransmissionException('Transmission request error.', 0, $e); } @@ -586,16 +374,11 @@ private function sendRequest($sessionId, $requestBody) $e->setResult($responseBody['result']); $e->setArguments($responseBody['arguments']); - if (!is_null($this->logger)) { - $this->logger->error( - 'The Transmission RPC API returned an error with this request.', - [ - 'request' => $requestBody, - 'response' => $responseBody['result'], - 'exception' => $e - ] - ); - } + $this->log('error', 'The Transmission RPC API returned an error with this request.', [ + 'request' => $requestBody, + 'response' => $responseBody['result'], + 'exception' => $e + ]); throw $e; } @@ -612,4 +395,11 @@ private function sendRequest($sessionId, $requestBody) return $responseBody; } + + private function log($level, $message, array $context = []) + { + if (!is_null($this->logger)) { + $this->logger->log($level, $message, $context); + } + } } diff --git a/src/TorrentIdList.php b/src/TorrentIdList.php new file mode 100644 index 0000000..6ae3b6b --- /dev/null +++ b/src/TorrentIdList.php @@ -0,0 +1,42 @@ + $id) { + $type = gettype($id); + + if ('integer' !== $type) { + throw new \InvalidArgumentException(sprintf( + 'The array of IDs can only contain integers. Item of type %s given at the offset %s', + $type, + $key + )); + } + } + + $this->list = \SplFixedArray::fromArray($ids, false); + } + + /** + * @return array + */ + public function getList() + { + return $this->list->toArray(); + } +} diff --git a/src/TransmissionAPI.php b/src/TransmissionAPI.php index 470cfe3..0ccd937 100644 --- a/src/TransmissionAPI.php +++ b/src/TransmissionAPI.php @@ -2,8 +2,6 @@ namespace Martial\Transmission\API; -use Psr\Log\LoggerInterface; - /** * The interface of the Transmission PHP client. Its behavior is as close to the original RPC API as possible. So, for more information about methods or arguments, * read the official API documentation. @@ -29,51 +27,51 @@ interface TransmissionAPI * Starts the given torrents (all the torrents if no IDs are provided). * * @param string $sessionId - * @param int[] $ids + * @param TorrentIdList $ids * @throws TransmissionException * @throws CSRFException */ - public function torrentStart($sessionId, array $ids); + public function torrentStart($sessionId, TorrentIdList $ids); /** * Starts now the given torrents (all the torrents if no IDs are provided). * * @param string $sessionId - * @param int[] $ids + * @param TorrentIdList $ids * @throws TransmissionException * @throws CSRFException */ - public function torrentStartNow($sessionId, array $ids); + public function torrentStartNow($sessionId, TorrentIdList $ids); /** * Stops the given torrents (all the torrents if no IDs are provided). * * @param string $sessionId - * @param int[] $ids + * @param TorrentIdList $ids * @throws TransmissionException * @throws CSRFException */ - public function torrentStop($sessionId, array $ids); + public function torrentStop($sessionId, TorrentIdList $ids); /** * Verifies the given torrents (all the torrents if no IDs are provided). * * @param string $sessionId - * @param int[] $ids + * @param TorrentIdList $ids * @throws TransmissionException * @throws CSRFException */ - public function torrentVerify($sessionId, array $ids); + public function torrentVerify($sessionId, TorrentIdList $ids); /** * Reannonces the given torrents (all the torrents if no IDs are provided). * * @param string $sessionId - * @param int[] $ids + * @param TorrentIdList $ids * @throws TransmissionException * @throws CSRFException */ - public function torrentReannounce($sessionId, array $ids); + public function torrentReannounce($sessionId, TorrentIdList $ids); /** * Applies the given arguments with their values to the given torrent IDs. @@ -86,12 +84,12 @@ public function torrentReannounce($sessionId, array $ids); * * * @param string $sessionId - * @param array $ids + * @param TorrentIdList $ids * @param array $argumentsWithValues * @throws TransmissionException * @throws CSRFException */ - public function torrentSet($sessionId, array $ids, array $argumentsWithValues); + public function torrentSet($sessionId, TorrentIdList $ids, array $argumentsWithValues); /** * Retrieves the data of the given fields for the given torrent IDs. @@ -114,13 +112,13 @@ public function torrentSet($sessionId, array $ids, array $argumentsWithValues); * * * @param string $sessionId - * @param array $ids + * @param TorrentIdList $ids * @param array $fields * @return array * @throws TransmissionException * @throws CSRFException */ - public function torrentGet($sessionId, array $ids, array $fields = []); + public function torrentGet($sessionId, TorrentIdList $ids, array $fields = []); /** * Adds a torrent to the download queue. @@ -150,12 +148,12 @@ public function torrentAdd($sessionId, array $argumentsWithValues); * All torrents are used if the "ids" array is empty. * * @param string $sessionId - * @param array $ids + * @param TorrentIdList $ids * @param bool $deleteLocalData * @throws TransmissionException * @throws CSRFException */ - public function torrentRemove($sessionId, array $ids, $deleteLocalData = false); + public function torrentRemove($sessionId, TorrentIdList $ids, $deleteLocalData = false); /** * Moves the given torrent IDs. @@ -163,13 +161,13 @@ public function torrentRemove($sessionId, array $ids, $deleteLocalData = false); * All torrents are used if the "ids" array is empty. * * @param string $sessionId - * @param array $ids + * @param TorrentIdList $ids * @param string $location * @param bool $move * @throws TransmissionException * @throws CSRFException */ - public function torrentSetLocation($sessionId, array $ids, $location, $move = false); + public function torrentSetLocation($sessionId, TorrentIdList $ids, $location, $move = false); /** * Renames a torrent path. @@ -262,41 +260,41 @@ public function sessionClose($sessionId); * Moves the given IDs to the top of the queue. * * @param string $sessionId - * @param array $ids + * @param TorrentIdList $ids * @throws TransmissionException * @throws CSRFException */ - public function queueMoveTop($sessionId, array $ids); + public function queueMoveTop($sessionId, TorrentIdList $ids); /** * Moves the given IDs to previous position in the queue. * * @param string $sessionId - * @param array $ids + * @param TorrentIdList $ids * @throws TransmissionException * @throws CSRFException */ - public function queueMoveDown($sessionId, array $ids); + public function queueMoveDown($sessionId, TorrentIdList $ids); /** * Moves the given IDs to the next potision in the queue. * * @param string $sessionId - * @param array $ids + * @param TorrentIdList $ids * @throws TransmissionException * @throws CSRFException */ - public function queueMoveUp($sessionId, array $ids); + public function queueMoveUp($sessionId, TorrentIdList $ids); /** * Moves the given IDs to the bottom of the queue. * * @param string $sessionId - * @param array $ids + * @param TorrentIdList $ids * @throws TransmissionException * @throws CSRFException */ - public function queueMoveBottom($sessionId, array $ids); + public function queueMoveBottom($sessionId, TorrentIdList $ids); /** * Tests how much free space is available in a client-specified folder. @@ -310,11 +308,4 @@ public function queueMoveBottom($sessionId, array $ids); * @throws CSRFException */ public function freeSpace($sessionId, $path); - - /** - * Injects a logger. - * - * @param LoggerInterface $logger - */ - public function setLogger(LoggerInterface $logger); } diff --git a/tests/RpcClientTest.php b/tests/RpcClientTest.php index 429c210..70f6c93 100644 --- a/tests/RpcClientTest.php +++ b/tests/RpcClientTest.php @@ -6,6 +6,7 @@ use Martial\Transmission\API\CSRFException; use Martial\Transmission\API\DuplicateTorrentException; use Martial\Transmission\API\RpcClient; +use Martial\Transmission\API\TorrentIdList; use Martial\Transmission\API\TransmissionException; use Mockery as m; @@ -40,14 +41,19 @@ class RpcClientTest extends \PHPUnit_Framework_TestCase */ private $sessionId; + /** + * @var TorrentIdList + */ + private $torrentIdList; + protected function setUp() { $this->guzzle = m::mock('\GuzzleHttp\ClientInterface'); $this->guzzleResponse = m::mock('\Psr\Http\Message\ResponseInterface'); $this->logger = m::mock('\Psr\Log\LoggerInterface'); $this->sessionId = uniqid(); - $this->rpcClient = new RpcClient($this->guzzle, self::RPC_USERNAME, self::RPC_PASSWORD); - $this->rpcClient->setLogger($this->logger); + $this->torrentIdList = new TorrentIdList(self::TORRENT_IDS); + $this->rpcClient = new RpcClient($this->guzzle, self::RPC_USERNAME, self::RPC_PASSWORD, $this->logger); } public function testTorrentStartWithSuccess() @@ -60,7 +66,7 @@ public function testTorrentStartWithSuccess() $this->setResponseBody('{"arguments":{},"result":"success"}'); - $this->rpcClient->torrentStart($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStart($this->sessionId, $this->torrentIdList); } /** @@ -76,7 +82,7 @@ public function testTorrentStartShouldThrowAnExceptionWhenTheServerReturnsAnErro ->sendRequest($requestBody) ->andThrow($requestException); - $this->rpcClient->torrentStart($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStart($this->sessionId, $this->torrentIdList); } /** @@ -92,7 +98,7 @@ public function testTorrentStartShouldThrowAnExceptionWhenTheRpcApiReturnsAnErro $this->setResponseBody('{"arguments":{},"result":"error"}'); - $this->rpcClient->torrentStart($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStart($this->sessionId, $this->torrentIdList); } public function testTorrentStartShouldThrowAnExceptionWithAnInvalidSessionId() @@ -105,7 +111,7 @@ public function testTorrentStartShouldThrowAnExceptionWithAnInvalidSessionId() ->andThrow($this->generateCSRFException()); try { - $this->rpcClient->torrentStart($invalidSessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStart($invalidSessionId, $this->torrentIdList); } catch (CSRFException $e) { $this->assertSame($this->sessionId, $e->getSessionId()); } @@ -122,7 +128,7 @@ public function testTorrentStartShouldThrowAnExceptionWhenTheRequestFails() ->sendRequest($requestBody) ->andThrow(m::mock('\GuzzleHttp\Exception\ClientException')); - $this->rpcClient->torrentStart($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStart($this->sessionId, $this->torrentIdList); } public function testTorrentStartNowWithSuccess() @@ -135,7 +141,7 @@ public function testTorrentStartNowWithSuccess() $this->setResponseBody('{"arguments":{},"result":"success"}'); - $this->rpcClient->torrentStartNow($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStartNow($this->sessionId, $this->torrentIdList); } /** @@ -151,7 +157,7 @@ public function testTorrentStartNowShouldThrowAnExceptionWhenTheServerReturnsAnE ->sendRequest($requestBody) ->andThrow($requestException); - $this->rpcClient->torrentStartNow($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStartNow($this->sessionId, $this->torrentIdList); } /** @@ -165,7 +171,7 @@ public function testTorrentStartNowShouldThrowAnExceptionWhenTheRequestFails() ->sendRequest($requestBody) ->andThrow(m::mock('\GuzzleHttp\Exception\ClientException')); - $this->rpcClient->torrentStartNow($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStartNow($this->sessionId, $this->torrentIdList); } /** @@ -181,7 +187,7 @@ public function testTorrentStartNowShouldThrowAnExceptionWhenTheRpcApiReturnsAnE $this->setResponseBody('{"arguments":{},"result":"error"}'); - $this->rpcClient->torrentStartNow($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStartNow($this->sessionId, $this->torrentIdList); } public function testTorrentStartNowShouldThrowAnExceptionWithAnInvalidSessionId() @@ -194,7 +200,7 @@ public function testTorrentStartNowShouldThrowAnExceptionWithAnInvalidSessionId( ->andThrow($this->generateCSRFException()); try { - $this->rpcClient->torrentStartNow($invalidSessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStartNow($invalidSessionId, $this->torrentIdList); } catch (CSRFException $e) { $this->assertSame($this->sessionId, $e->getSessionId()); } @@ -210,7 +216,7 @@ public function testTorrentStopWithSuccess() $this->setResponseBody('{"arguments":{},"result":"success"}'); - $this->rpcClient->torrentStop($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStop($this->sessionId, $this->torrentIdList); } /** @@ -226,7 +232,7 @@ public function testTorrentStopShouldThrowAnExceptionWhenTheServerReturnsAnError ->sendRequest($requestBody) ->andThrow($requestException); - $this->rpcClient->torrentStop($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStop($this->sessionId, $this->torrentIdList); } /** @@ -240,7 +246,7 @@ public function testTorrentStopShouldThrowAnExceptionWhenTheRequestFails() ->sendRequest($requestBody) ->andThrow(m::mock('\GuzzleHttp\Exception\ClientException')); - $this->rpcClient->torrentStop($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStop($this->sessionId, $this->torrentIdList); } /** @@ -256,7 +262,7 @@ public function testTorrentStopShouldThrowAnExceptionWhenTheRpcApiReturnsAnError $this->setResponseBody('{"arguments":{},"result":"error"}'); - $this->rpcClient->torrentStop($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStop($this->sessionId, $this->torrentIdList); } public function testTorrentStopShouldThrowAnExceptionWithAnInvalidSessionId() @@ -269,7 +275,7 @@ public function testTorrentStopShouldThrowAnExceptionWithAnInvalidSessionId() ->andThrow($this->generateCSRFException()); try { - $this->rpcClient->torrentStop($invalidSessionId, self::TORRENT_IDS); + $this->rpcClient->torrentStop($invalidSessionId, $this->torrentIdList); } catch (CSRFException $e) { $this->assertSame($this->sessionId, $e->getSessionId()); } @@ -285,7 +291,7 @@ public function testTorrentVerifyWithSuccess() $this->setResponseBody('{"arguments":{},"result":"success"}'); - $this->rpcClient->torrentVerify($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentVerify($this->sessionId, $this->torrentIdList); } /** @@ -301,7 +307,7 @@ public function testTorrentVerifyShouldThrowAnExceptionWhenTheServerReturnsAnErr ->sendRequest($requestBody) ->andThrow($requestException); - $this->rpcClient->torrentVerify($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentVerify($this->sessionId, $this->torrentIdList); } /** @@ -317,7 +323,7 @@ public function testTorrentVerifyShouldThrowAnExceptionWhenTheRpcApiReturnsAnErr $this->setResponseBody('{"arguments":{},"result":"error"}'); - $this->rpcClient->torrentVerify($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentVerify($this->sessionId, $this->torrentIdList); } /** @@ -331,7 +337,7 @@ public function testVerifyStopShouldThrowAnExceptionWhenTheRequestFails() ->sendRequest($requestBody) ->andThrow(m::mock('\GuzzleHttp\Exception\ClientException')); - $this->rpcClient->torrentVerify($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentVerify($this->sessionId, $this->torrentIdList); } public function testTorrentVerifyShouldThrowAnExceptionWithAnInvalidSessionId() @@ -344,7 +350,7 @@ public function testTorrentVerifyShouldThrowAnExceptionWithAnInvalidSessionId() ->andThrow($this->generateCSRFException()); try { - $this->rpcClient->torrentVerify($invalidSessionId, self::TORRENT_IDS); + $this->rpcClient->torrentVerify($invalidSessionId, $this->torrentIdList); } catch (CSRFException $e) { $this->assertSame($this->sessionId, $e->getSessionId()); } @@ -360,7 +366,7 @@ public function testTorrentReannounceWithSuccess() $this->setResponseBody('{"arguments":{},"result":"success"}'); - $this->rpcClient->torrentReannounce($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentReannounce($this->sessionId, $this->torrentIdList); } /** @@ -376,7 +382,7 @@ public function testTorrentReannounceShouldThrowAnExceptionWhenTheServerReturnsA ->sendRequest($requestBody) ->andThrow($requestException); - $this->rpcClient->torrentReannounce($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentReannounce($this->sessionId, $this->torrentIdList); } /** @@ -390,7 +396,7 @@ public function testTorrentReannounceShouldThrowAnExceptionWhenTheRequestFails() ->sendRequest($requestBody) ->andThrow(m::mock('\GuzzleHttp\Exception\ClientException')); - $this->rpcClient->torrentReannounce($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentReannounce($this->sessionId, $this->torrentIdList); } /** @@ -406,7 +412,7 @@ public function testTorrentReannounceShouldThrowAnExceptionWhenTheRpcApiReturnsA $this->setResponseBody('{"arguments":{},"result":"error"}'); - $this->rpcClient->torrentReannounce($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentReannounce($this->sessionId, $this->torrentIdList); } public function testTorrentReannounceShouldThrowAnExceptionWithAnInvalidSessionId() @@ -419,7 +425,7 @@ public function testTorrentReannounceShouldThrowAnExceptionWithAnInvalidSessionI ->andThrow($this->generateCSRFException()); try { - $this->rpcClient->torrentReannounce($invalidSessionId, self::TORRENT_IDS); + $this->rpcClient->torrentReannounce($invalidSessionId, $this->torrentIdList); } catch (CSRFException $e) { $this->assertSame($this->sessionId, $e->getSessionId()); } @@ -436,7 +442,7 @@ public function testTorrentSetWithSuccess() $this->setResponseBody('{"arguments":{},"result":"success"}'); - $this->rpcClient->torrentSet($this->sessionId, self::TORRENT_IDS, $arguments); + $this->rpcClient->torrentSet($this->sessionId, $this->torrentIdList, $arguments); } @@ -454,7 +460,7 @@ public function testTorrentSetShouldThrowAnExceptionWhenTheServerReturnsAnError5 ->sendRequest($requestBody) ->andThrow($requestException); - $this->rpcClient->torrentSet($this->sessionId, self::TORRENT_IDS, $arguments); + $this->rpcClient->torrentSet($this->sessionId, $this->torrentIdList, $arguments); } /** @@ -469,7 +475,7 @@ public function testTorrentSetShouldThrowAnExceptionWhenTheRequestFails() ->sendRequest($requestBody) ->andThrow(m::mock('\GuzzleHttp\Exception\ClientException')); - $this->rpcClient->torrentSet($this->sessionId, self::TORRENT_IDS, $arguments); + $this->rpcClient->torrentSet($this->sessionId, $this->torrentIdList, $arguments); } /** @@ -486,7 +492,7 @@ public function testTorrentSetShouldThrowAnExceptionWhenTheRpcApiReturnsAnError( $this->setResponseBody('{"arguments":{},"result":"error"}'); - $this->rpcClient->torrentSet($this->sessionId, self::TORRENT_IDS, $arguments); + $this->rpcClient->torrentSet($this->sessionId, $this->torrentIdList, $arguments); } public function testTorrentSetShouldThrowAnExceptionWithAnInvalidSessionId() @@ -500,7 +506,7 @@ public function testTorrentSetShouldThrowAnExceptionWithAnInvalidSessionId() ->andThrow($this->generateCSRFException()); try { - $this->rpcClient->torrentSet($invalidSessionId, self::TORRENT_IDS, $arguments); + $this->rpcClient->torrentSet($invalidSessionId, $this->torrentIdList, $arguments); } catch (CSRFException $e) { $this->assertSame($this->sessionId, $e->getSessionId()); } @@ -521,7 +527,7 @@ public function testTorrentGetWithSuccess() $this->assertSame([ ['name' => 'Fedora', 'totalSize' => 12345] - ], $this->rpcClient->torrentGet($this->sessionId, self::TORRENT_IDS, $fields)); + ], $this->rpcClient->torrentGet($this->sessionId, $this->torrentIdList, $fields)); } public function testTorrentGetAllWithSuccess() @@ -539,7 +545,7 @@ public function testTorrentGetAllWithSuccess() $this->assertSame([ ['name' => 'Fedora', 'totalSize' => 12345] - ], $this->rpcClient->torrentGet($this->sessionId, [], $fields)); + ], $this->rpcClient->torrentGet($this->sessionId, new TorrentIdList([]), $fields)); } /** @@ -556,7 +562,7 @@ public function testTorrentGetShouldThrowAnExceptionWhenTheServerReturnsAnError5 ->sendRequest($requestBody) ->andThrow($requestException); - $this->rpcClient->torrentGet($this->sessionId, self::TORRENT_IDS, $fields); + $this->rpcClient->torrentGet($this->sessionId, $this->torrentIdList, $fields); } /** @@ -571,7 +577,7 @@ public function testTorrentGetShouldThrowAnExceptionWhenTheRequestFails() ->sendRequest($requestBody) ->andThrow(m::mock('\GuzzleHttp\Exception\ClientException')); - $this->rpcClient->torrentGet($this->sessionId, self::TORRENT_IDS, $fields); + $this->rpcClient->torrentGet($this->sessionId, $this->torrentIdList, $fields); } /** @@ -588,7 +594,7 @@ public function testTorrentGetShouldThrowAnExceptionWhenTheRpcApiReturnsAnError( $this->setResponseBody('{"arguments":{},"result":"error"}'); - $this->rpcClient->torrentGet($this->sessionId, self::TORRENT_IDS, $fields); + $this->rpcClient->torrentGet($this->sessionId, $this->torrentIdList, $fields); } public function testTorrentGetShouldThrowAnExceptionWithAnInvalidSessionId() @@ -602,7 +608,7 @@ public function testTorrentGetShouldThrowAnExceptionWithAnInvalidSessionId() ->andThrow($this->generateCSRFException()); try { - $this->rpcClient->torrentGet($invalidSessionId, self::TORRENT_IDS, $fields); + $this->rpcClient->torrentGet($invalidSessionId, $this->torrentIdList, $fields); } catch (CSRFException $e) { $this->assertSame($this->sessionId, $e->getSessionId()); } @@ -746,7 +752,7 @@ public function testTorrentRemoveWithLocalDataWithSuccess() $this->setResponseBody('{"arguments":{},"result":"success"}'); - $this->rpcClient->torrentRemove($this->sessionId, self::TORRENT_IDS, true); + $this->rpcClient->torrentRemove($this->sessionId, $this->torrentIdList, true); } public function testTorrentRemoveWithSuccess() @@ -759,7 +765,7 @@ public function testTorrentRemoveWithSuccess() $this->setResponseBody('{"arguments":{},"result":"success"}'); - $this->rpcClient->torrentRemove($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentRemove($this->sessionId, $this->torrentIdList); } /** @@ -775,7 +781,7 @@ public function testTorrentRemoveShouldThrowAnExceptionWhenTheServerReturnsAnErr ->sendRequest($requestBody) ->andThrow($requestException); - $this->rpcClient->torrentRemove($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentRemove($this->sessionId, $this->torrentIdList); } /** @@ -789,7 +795,7 @@ public function testTorrentRemoveShouldThrowAnExceptionWhenTheRequestFails() ->sendRequest($requestBody) ->andThrow(m::mock('\GuzzleHttp\Exception\ClientException')); - $this->rpcClient->torrentRemove($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentRemove($this->sessionId, $this->torrentIdList); } /** @@ -805,7 +811,7 @@ public function testTorrentRemoveShouldThrowAnExceptionWhenTheRpcApiReturnsAnErr $this->setResponseBody('{"arguments":{},"result":"error"}'); - $this->rpcClient->torrentRemove($this->sessionId, self::TORRENT_IDS); + $this->rpcClient->torrentRemove($this->sessionId, $this->torrentIdList); } public function testTorrentRemoveShouldThrowAnExceptionWithAnInvalidSessionId() @@ -818,7 +824,7 @@ public function testTorrentRemoveShouldThrowAnExceptionWithAnInvalidSessionId() ->andThrow($this->generateCSRFException()); try { - $this->rpcClient->torrentRemove($invalidSessionId, self::TORRENT_IDS); + $this->rpcClient->torrentRemove($invalidSessionId, $this->torrentIdList); } catch (CSRFException $e) { $this->assertSame($this->sessionId, $e->getSessionId()); } @@ -836,7 +842,7 @@ public function testTorrentSetLocationWithSuccess() $this->setResponseBody('{"arguments":{},"result":"success"}'); - $this->rpcClient->torrentSetLocation($this->sessionId, self::TORRENT_IDS, $location); + $this->rpcClient->torrentSetLocation($this->sessionId, $this->torrentIdList, $location); } public function testTorrentSetLocationWithMoveWithSuccess() @@ -851,7 +857,7 @@ public function testTorrentSetLocationWithMoveWithSuccess() $this->setResponseBody('{"arguments":{},"result":"success"}'); - $this->rpcClient->torrentSetLocation($this->sessionId, self::TORRENT_IDS, $location, true); + $this->rpcClient->torrentSetLocation($this->sessionId, $this->torrentIdList, $location, true); } /** @@ -869,7 +875,7 @@ public function testTorrentSetLocationShouldThrowAnExceptionWhenTheServerReturns ->sendRequest($requestBody) ->andThrow($requestException); - $this->rpcClient->torrentSetLocation($this->sessionId, self::TORRENT_IDS, $location); + $this->rpcClient->torrentSetLocation($this->sessionId, $this->torrentIdList, $location); } /** @@ -885,7 +891,7 @@ public function testTorrentSetLocationShouldThrowAnExceptionWhenTheRequestFails( ->sendRequest($requestBody) ->andThrow(m::mock('\GuzzleHttp\Exception\ClientException')); - $this->rpcClient->torrentSetLocation($this->sessionId, self::TORRENT_IDS, $location); + $this->rpcClient->torrentSetLocation($this->sessionId, $this->torrentIdList, $location); } /** @@ -903,7 +909,7 @@ public function testTorrentSetLocationShouldThrowAnExceptionWhenTheRpcApiReturns $this->setResponseBody('{"arguments":{},"result":"error"}'); - $this->rpcClient->torrentSetLocation($this->sessionId, self::TORRENT_IDS, $location); + $this->rpcClient->torrentSetLocation($this->sessionId, $this->torrentIdList, $location); } public function testTorrentSetLocationShouldThrowAnExceptionWithAnInvalidSessionId() @@ -918,7 +924,7 @@ public function testTorrentSetLocationShouldThrowAnExceptionWithAnInvalidSession ->andThrow($this->generateCSRFException()); try { - $this->rpcClient->torrentSetLocation($invalidSessionId, self::TORRENT_IDS, $location); + $this->rpcClient->torrentSetLocation($invalidSessionId, $this->torrentIdList, $location); } catch (CSRFException $e) { $this->assertSame($this->sessionId, $e->getSessionId()); } @@ -1519,7 +1525,7 @@ public function testQueueMoveTopWithSuccess() $jsonResponse = '{"arguments":{},"result":"success"}'; $this->setResponseBody($jsonResponse); - $this->rpcClient->queueMoveTop($this->sessionId, [42, 1337]); + $this->rpcClient->queueMoveTop($this->sessionId, $this->torrentIdList); } /** @@ -1535,7 +1541,7 @@ public function testQueueMoveTopShouldThrowAnExceptionWhenTheServerReturnsAnErro ->sendRequest($requestBody) ->andThrow($requestException); - $this->rpcClient->queueMoveTop($this->sessionId, [42, 1337]); + $this->rpcClient->queueMoveTop($this->sessionId, $this->torrentIdList); } /** @@ -1549,7 +1555,7 @@ public function testQueueMoveTopShouldThrowAnExceptionWhenTheRequestFails() ->sendRequest($requestBody) ->andThrow(m::mock('\GuzzleHttp\Exception\ClientException')); - $this->rpcClient->queueMoveTop($this->sessionId, [42, 1337]); + $this->rpcClient->queueMoveTop($this->sessionId, $this->torrentIdList); } public function testQueueMoveTopShouldThrowAnExceptionWithAnInvalidSessionId() @@ -1562,7 +1568,7 @@ public function testQueueMoveTopShouldThrowAnExceptionWithAnInvalidSessionId() ->andThrow($this->generateCSRFException()); try { - $this->rpcClient->queueMoveTop($invalidSessionId, [42, 1337]); + $this->rpcClient->queueMoveTop($invalidSessionId, $this->torrentIdList); } catch (CSRFException $e) { $this->assertSame($this->sessionId, $e->getSessionId()); } @@ -1578,7 +1584,7 @@ public function testQueueMoveDownWithSuccess() $jsonResponse = '{"arguments":{},"result":"success"}'; $this->setResponseBody($jsonResponse); - $this->rpcClient->queueMoveDown($this->sessionId, [42, 1337]); + $this->rpcClient->queueMoveDown($this->sessionId, $this->torrentIdList); } /** @@ -1594,7 +1600,7 @@ public function testQueueMoveDownShouldThrowAnExceptionWhenTheServerReturnsAnErr ->sendRequest($requestBody) ->andThrow($requestException); - $this->rpcClient->queueMoveDown($this->sessionId, [42, 1337]); + $this->rpcClient->queueMoveDown($this->sessionId, $this->torrentIdList); } /** @@ -1608,7 +1614,7 @@ public function testQueueMoveDownShouldThrowAnExceptionWhenTheRequestFails() ->sendRequest($requestBody) ->andThrow(m::mock('\GuzzleHttp\Exception\ClientException')); - $this->rpcClient->queueMoveDown($this->sessionId, [42, 1337]); + $this->rpcClient->queueMoveDown($this->sessionId, $this->torrentIdList); } public function testQueueMoveDownShouldThrowAnExceptionWithAnInvalidSessionId() @@ -1621,7 +1627,7 @@ public function testQueueMoveDownShouldThrowAnExceptionWithAnInvalidSessionId() ->andThrow($this->generateCSRFException()); try { - $this->rpcClient->queueMoveDown($invalidSessionId, [42, 1337]); + $this->rpcClient->queueMoveDown($invalidSessionId, $this->torrentIdList); } catch (CSRFException $e) { $this->assertSame($this->sessionId, $e->getSessionId()); } @@ -1637,7 +1643,7 @@ public function testQueueMoveUpWithSuccess() $jsonResponse = '{"arguments":{},"result":"success"}'; $this->setResponseBody($jsonResponse); - $this->rpcClient->queueMoveUp($this->sessionId, [42, 1337]); + $this->rpcClient->queueMoveUp($this->sessionId, $this->torrentIdList); } /** @@ -1653,7 +1659,7 @@ public function testQueueMoveUpShouldThrowAnExceptionWhenTheServerReturnsAnError ->sendRequest($requestBody) ->andThrow($requestException); - $this->rpcClient->queueMoveUp($this->sessionId, [42, 1337]); + $this->rpcClient->queueMoveUp($this->sessionId, $this->torrentIdList); } /** @@ -1667,7 +1673,7 @@ public function testQueueMoveUpShouldThrowAnExceptionWhenTheRequestFails() ->sendRequest($requestBody) ->andThrow(m::mock('\GuzzleHttp\Exception\ClientException')); - $this->rpcClient->queueMoveUp($this->sessionId, [42, 1337]); + $this->rpcClient->queueMoveUp($this->sessionId, $this->torrentIdList); } public function testQueueMoveUpShouldThrowAnExceptionWithAnInvalidSessionId() @@ -1680,7 +1686,7 @@ public function testQueueMoveUpShouldThrowAnExceptionWithAnInvalidSessionId() ->andThrow($this->generateCSRFException()); try { - $this->rpcClient->queueMoveUp($invalidSessionId, [42, 1337]); + $this->rpcClient->queueMoveUp($invalidSessionId, $this->torrentIdList); } catch (CSRFException $e) { $this->assertSame($this->sessionId, $e->getSessionId()); } @@ -1696,7 +1702,7 @@ public function testQueueMoveBottomWithSuccess() $jsonResponse = '{"arguments":{},"result":"success"}'; $this->setResponseBody($jsonResponse); - $this->rpcClient->queueMoveBottom($this->sessionId, [42, 1337]); + $this->rpcClient->queueMoveBottom($this->sessionId, $this->torrentIdList); } /** @@ -1712,7 +1718,7 @@ public function testQueueMoveBottomShouldThrowAnExceptionWhenTheServerReturnsAnE ->sendRequest($requestBody) ->andThrow($requestException); - $this->rpcClient->queueMoveBottom($this->sessionId, [42, 1337]); + $this->rpcClient->queueMoveBottom($this->sessionId, $this->torrentIdList); } /** @@ -1726,7 +1732,7 @@ public function testQueueMoveBottomShouldThrowAnExceptionWhenTheRequestFails() ->sendRequest($requestBody) ->andThrow(m::mock('\GuzzleHttp\Exception\ClientException')); - $this->rpcClient->queueMoveBottom($this->sessionId, [42, 1337]); + $this->rpcClient->queueMoveBottom($this->sessionId, $this->torrentIdList); } public function testQueueMoveBottomShouldThrowAnExceptionWithAnInvalidSessionId() @@ -1739,7 +1745,7 @@ public function testQueueMoveBottomShouldThrowAnExceptionWithAnInvalidSessionId( ->andThrow($this->generateCSRFException()); try { - $this->rpcClient->queueMoveBottom($invalidSessionId, [42, 1337]); + $this->rpcClient->queueMoveBottom($invalidSessionId, $this->torrentIdList); } catch (CSRFException $e) { $this->assertSame($this->sessionId, $e->getSessionId()); } @@ -1858,9 +1864,9 @@ private function generateCSRFException() $this ->logger - ->shouldReceive('info') + ->shouldReceive('log') ->once() - ->withArgs(['Invalid Transmission session ID. A new ID has been generated.', [ + ->withArgs(['info', 'Invalid Transmission session ID. A new ID has been generated.', [ 'session_id' => $this->sessionId ]]); @@ -1903,7 +1909,7 @@ private function setResponseBody($responseBody) if ($responseToArray['result'] !== 'success') { $this ->logger - ->shouldReceive('error') + ->shouldReceive('log') ->once(); } @@ -1921,9 +1927,10 @@ private function debugRequest($requestBody) { $this ->logger - ->shouldReceive('debug') + ->shouldReceive('log') ->once() ->withArgs([ + 'debug', 'Request sent to the Transmission RPC API.', ['request' => $requestBody] ]); @@ -1933,9 +1940,9 @@ private function logRequestError($requestException) { $this ->logger - ->shouldReceive('error') + ->shouldReceive('log') ->once() - ->withArgs(['The Transmission RPC API returned a 500 error.', [ + ->withArgs(['error', 'The Transmission RPC API returned a 500 error.', [ 'exception' => $requestException ]]); } diff --git a/tests/TorrentIdListTest.php b/tests/TorrentIdListTest.php new file mode 100644 index 0000000..e39b174 --- /dev/null +++ b/tests/TorrentIdListTest.php @@ -0,0 +1,40 @@ + 42, + 4 => 43, + 5 => 44, + 'string' => 45, + 12 => 46 + ]; + + $list = (new TorrentIdList($ids))->getList(); + + $this->assertSame($ids[2], $list[0]); + $this->assertSame($ids[4], $list[1]); + $this->assertSame($ids[5], $list[2]); + $this->assertSame($ids['string'], $list[3]); + $this->assertSame($ids[12], $list[4]); + } + + /** + * @expectedException \InvalidArgumentException + * @expectedExceptionMessage The array of IDs can only contain integers. Item of type string given at the offset 2 + */ + public function testListShouldThrowAnExceptionWhenTheArrayOfIdsDoesNotContainOnlyIntegers() + { + new TorrentIdList([ + 42, + 54, + '74' + ]); + } +}