From ab328b96ee49724e3f17c3ba4eab42b1e1505941 Mon Sep 17 00:00:00 2001 From: Meritoo Date: Fri, 29 Sep 2017 15:18:31 +0200 Subject: [PATCH] ParticipantService - getSurveyParticipants() method - catch and serve an exception while fetching participants of given survey --- src/Exception/CannotProcessDataException.php | 21 +++++- src/Service/ParticipantService.php | 26 +++++-- src/Type/ReasonType.php | 28 ++++++++ tests/Service/ParticipantServiceTest.php | 48 ++++++++++++- tests/Type/ReasonTypeTest.php | 71 ++++++++++++++++++++ 5 files changed, 188 insertions(+), 6 deletions(-) create mode 100644 src/Type/ReasonType.php create mode 100644 tests/Type/ReasonTypeTest.php diff --git a/src/Exception/CannotProcessDataException.php b/src/Exception/CannotProcessDataException.php index d79e556..3cc6980 100644 --- a/src/Exception/CannotProcessDataException.php +++ b/src/Exception/CannotProcessDataException.php @@ -16,6 +16,13 @@ namespace Meritoo\LimeSurvey\ApiClient\Exception; */ class CannotProcessDataException extends \Exception { + /** + * Reason why data cannot be processed, e.g. "Invalid user name or password" + * + * @var string + */ + private $reason; + /** * Class constructor * @@ -23,9 +30,21 @@ class CannotProcessDataException extends \Exception */ public function __construct($reason) { + $this->reason = $reason; + $template = 'Raw data returned by the LimeSurvey\'s API cannot be processed. Reason: \'%s\'.'; - $message = sprintf($template, $reason); + $message = sprintf($template, $this->reason); parent::__construct($message); } + + /** + * Returns reason why data cannot be processed, e.g. "Invalid user name or password" + * + * @return string + */ + public function getReason() + { + return $this->reason; + } } diff --git a/src/Service/ParticipantService.php b/src/Service/ParticipantService.php index 89a4342..df1f210 100644 --- a/src/Service/ParticipantService.php +++ b/src/Service/ParticipantService.php @@ -10,10 +10,12 @@ namespace Meritoo\LimeSurvey\ApiClient\Service; use Meritoo\Common\Collection\Collection; use Meritoo\LimeSurvey\ApiClient\Client\Client; +use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException; use Meritoo\LimeSurvey\ApiClient\Exception\MissingParticipantOfSurveyException; use Meritoo\LimeSurvey\ApiClient\Result\Collection\Participants; use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant; use Meritoo\LimeSurvey\ApiClient\Type\MethodType; +use Meritoo\LimeSurvey\ApiClient\Type\ReasonType; /** * Service that serves participants @@ -69,6 +71,8 @@ class ParticipantService * * @param int $surveyId ID of survey * @return Collection + * + * @throws CannotProcessDataException */ public function getSurveyParticipants($surveyId) { @@ -81,10 +85,24 @@ class ParticipantService $surveyId, ]; - $participants = $this - ->client - ->run(MethodType::LIST_PARTICIPANTS, $arguments) - ->getData(); + try { + $participants = $this + ->client + ->run(MethodType::LIST_PARTICIPANTS, $arguments) + ->getData(); + } catch (CannotProcessDataException $exception) { + $reason = $exception->getReason(); + + /* + * Reason of the exception is different than "Oops, there is no participants. Everything else is fine."? + * Let's throw the exception + */ + if (ReasonType::NO_PARTICIPANTS_FOUND !== $reason) { + throw $exception; + } + + $participants = new Collection(); + } $this ->allParticipants diff --git a/src/Type/ReasonType.php b/src/Type/ReasonType.php new file mode 100644 index 0000000..3bbc045 --- /dev/null +++ b/src/Type/ReasonType.php @@ -0,0 +1,28 @@ + + * @copyright Meritoo.pl + */ +class ReasonType extends BaseType +{ + /** + * Reason of exception when there is no participants of survey + * + * @var string + */ + const NO_PARTICIPANTS_FOUND = 'No survey participants found.'; + + /** + * Reason of exception when there is no table with tokens/participants of survey + * + * @var string + */ + const NO_TOKEN_TABLE = 'Error: No token table'; +} diff --git a/tests/Service/ParticipantServiceTest.php b/tests/Service/ParticipantServiceTest.php index eb73ecc..05f8332 100644 --- a/tests/Service/ParticipantServiceTest.php +++ b/tests/Service/ParticipantServiceTest.php @@ -8,17 +8,20 @@ namespace Meritoo\LimeSurvey\Test\ApiClient\Service; +use Exception; use Meritoo\Common\Collection\Collection; use Meritoo\Common\Test\Base\BaseTestCase; use Meritoo\Common\Type\OopVisibilityType; use Meritoo\LimeSurvey\ApiClient\Client\Client; use Meritoo\LimeSurvey\ApiClient\Configuration\ConnectionConfiguration; +use Meritoo\LimeSurvey\ApiClient\Exception\CannotProcessDataException; use Meritoo\LimeSurvey\ApiClient\Exception\MissingParticipantOfSurveyException; use Meritoo\LimeSurvey\ApiClient\Manager\JsonRpcClientManager; use Meritoo\LimeSurvey\ApiClient\Manager\SessionManager; use Meritoo\LimeSurvey\ApiClient\Result\Collection\Participants; use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant; use Meritoo\LimeSurvey\ApiClient\Service\ParticipantService; +use Meritoo\LimeSurvey\ApiClient\Type\ReasonType; use PHPUnit_Framework_MockObject_MockObject; /** @@ -68,7 +71,7 @@ class ParticipantServiceTest extends BaseTestCase static::assertEquals($client, $participantService->getClient()); } - public function testGetSurveyParticipantsFromEmptyParticipants() + public function testGetSurveyParticipants() { $rpcClientManager = $this->getJsonRpcClientManager(3); $sessionManager = $this->getSessionManager(); @@ -84,6 +87,29 @@ class ParticipantServiceTest extends BaseTestCase static::assertCount(0, $this->serviceWithParticipants->getSurveyParticipants(3)); } + public function testGetSurveyParticipantsWithImportantException() + { + $this->expectException(CannotProcessDataException::class); + $exception = new CannotProcessDataException(ReasonType::NO_TOKEN_TABLE); + + $rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception); + $sessionManager = $this->getSessionManager(); + + $this->createServiceWithParticipants($rpcClientManager, $sessionManager); + $this->serviceWithParticipants->getSurveyParticipants(3); + } + + public function testGetSurveyParticipantsWithNoParticipantsException() + { + $exception = new CannotProcessDataException(ReasonType::NO_PARTICIPANTS_FOUND); + + $rpcClientManager = $this->getJsonRpcClientManagerWithException(1, $exception); + $sessionManager = $this->getSessionManager(); + + $this->createServiceWithParticipants($rpcClientManager, $sessionManager); + static::assertCount(0, $this->serviceWithParticipants->getSurveyParticipants(3)); + } + public function testHasParticipant() { $rpcClientManager = $this->getJsonRpcClientManager(3); @@ -200,6 +226,26 @@ class ParticipantServiceTest extends BaseTestCase return $rpcClientManager; } + /** + * Returns manager of the JsonRPC client used while connecting to LimeSurvey's API with mocked method runMethod() + * that throws an exception + * + * @param int $runMethodCallCount Count of calls of the runMethod() method (who is mocked) + * @param Exception $exception The exception that should be thrown + * @return PHPUnit_Framework_MockObject_MockObject + */ + private function getJsonRpcClientManagerWithException($runMethodCallCount, Exception $exception) + { + $rpcClientManager = $this->createMock(JsonRpcClientManager::class); + + $rpcClientManager + ->expects(static::exactly($runMethodCallCount)) + ->method('runMethod') + ->willThrowException($exception); + + return $rpcClientManager; + } + /** * Creates instance of the tested service without participants * diff --git a/tests/Type/ReasonTypeTest.php b/tests/Type/ReasonTypeTest.php new file mode 100644 index 0000000..1755a8d --- /dev/null +++ b/tests/Type/ReasonTypeTest.php @@ -0,0 +1,71 @@ + + * @copyright Meritoo.pl + */ +class ReasonTypeTest extends BaseTypeTestCase +{ + public function testConstructorVisibilityAndArguments() + { + static::assertHasNoConstructor(ReasonType::class); + } + + /** + * {@inheritdoc} + */ + protected function getAllExpectedTypes() + { + return [ + 'NO_PARTICIPANTS_FOUND' => ReasonType::NO_PARTICIPANTS_FOUND, + 'NO_TOKEN_TABLE' => ReasonType::NO_TOKEN_TABLE, + ]; + } + + /** + * {@inheritdoc} + */ + protected function getTestedTypeInstance() + { + return new ReasonType(); + } + + /** + * {@inheritdoc} + */ + public function provideTypeToVerify() + { + yield[ + '', + false, + ]; + + yield[ + 'lorem', + false, + ]; + + yield[ + ReasonType::NO_PARTICIPANTS_FOUND, + true, + ]; + + yield[ + ReasonType::NO_TOKEN_TABLE, + true, + ]; + } +}