diff --git a/src/Base/Result/BaseItem.php b/src/Base/Result/BaseItem.php index 2389335..638e89b 100644 --- a/src/Base/Result/BaseItem.php +++ b/src/Base/Result/BaseItem.php @@ -16,13 +16,32 @@ namespace Meritoo\LimeSurvey\ApiClient\Base\Result; */ abstract class BaseItem { + /** + * Class constructor + * + * @param array $data (optional) Data to set in properties of the item + */ + public function __construct(array $data = []) + { + $this->setValues($data); + } + + /** + * Sets given value in given property + * + * @param string $property Name of property to set the value + * @param mixed $value Value to set in property + * @return mixed + */ + abstract public function setValue($property, $value); + /** * Sets values in each property of the item * * @param array $data Data to set in properties of the item * @return $this */ - public function setValues($data) + private function setValues(array $data) { /* * Oops, no data @@ -40,13 +59,4 @@ abstract class BaseItem return $this; } - - /** - * Sets given value in given property - * - * @param string $property Name of property to set the value - * @param mixed $value Value to set in property - * @return mixed - */ - abstract public function setValue($property, $value); } diff --git a/src/Exception/IncorrectClassOfResultItemException.php b/src/Exception/IncorrectClassOfResultItemException.php new file mode 100644 index 0000000..0851d10 --- /dev/null +++ b/src/Exception/IncorrectClassOfResultItemException.php @@ -0,0 +1,35 @@ + + * @copyright Meritoo.pl + */ +class IncorrectClassOfResultItemException extends \Exception +{ + /** + * Class constructor + * + * @param string $className Incorrect class name used to create instance of one item + */ + public function __construct($className) + { + $template = 'Class %s used to create instance of one item of the result should extend %s, but it does not. Did' + . ' you forget to use proper base class?'; + + $message = sprintf($template, $className, BaseItem::class); + parent::__construct($message); + } +} diff --git a/src/Exception/MissingParticipantOfSurveyException.php b/src/Exception/MissingParticipantOfSurveyException.php index db2424c..11d7dd1 100644 --- a/src/Exception/MissingParticipantOfSurveyException.php +++ b/src/Exception/MissingParticipantOfSurveyException.php @@ -1,5 +1,11 @@ * @copyright Meritoo.pl @@ -27,10 +28,10 @@ class UnknownInstanceOfResultItem extends Exception */ public function __construct($method) { - $template = 'Instance of one item used by result the of \'%s\' LimeSurvey API\'s method is unknown. Proper' - . ' class is not mapped in %s::%s() method. Did you forget about this?'; + $template = 'Class name used to create instance of one item used by result the of \'%s\' LimeSurvey API\'s' + . ' method is unknown. Proper class is not mapped in %s::%s() method. Did you forget about this?'; - $message = sprintf($template, $method, ResultProcessor::class, 'getItemInstance'); + $message = sprintf($template, $method, ResultProcessor::class, 'getItemClassName'); parent::__construct($message); } } diff --git a/src/Result/Processor/ResultProcessor.php b/src/Result/Processor/ResultProcessor.php index 1e32b61..563ebbc 100644 --- a/src/Result/Processor/ResultProcessor.php +++ b/src/Result/Processor/ResultProcessor.php @@ -8,7 +8,9 @@ namespace Meritoo\LimeSurvey\ApiClient\Result\Processor; +use Meritoo\Common\Utilities\Reflection; use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem; +use Meritoo\LimeSurvey\ApiClient\Exception\IncorrectClassOfResultItemException; use Meritoo\LimeSurvey\ApiClient\Exception\UnknownInstanceOfResultItem; use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant; use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort; @@ -31,7 +33,9 @@ class ResultProcessor * @param string $method Name of called method while talking to the LimeSurvey's API. One of the MethodType * class constants. * @param array $rawData Data returned by the LimeSurvey's API - * @return null|BaseItem|array + * @return array|BaseItem|null + * + * @throws IncorrectClassOfResultItemException */ public function process($method, array $rawData) { @@ -46,9 +50,9 @@ class ResultProcessor } /* - * Prepare instance of one item + * Prepare class name for instance of one item */ - $item = $this->getItemInstance($method); + $itemClassName = $this->getItemClassName($method); /* * The raw data is or, actually, should be iterable? @@ -57,49 +61,50 @@ class ResultProcessor $items = []; foreach ($rawData as $itemData) { - $emptyItem = clone $item; - $items[] = $emptyItem->setValues($itemData); + $items[] = new $itemClassName($itemData); } return $items; } - return $item->setValues($rawData); + return new $itemClassName($rawData); } /** - * Returns instance of one item of the result + * Returns class name used to create instance of one item of the result * * @param string $method Name of called method while talking to the LimeSurvey's API. One of the MethodType * class constants. - * @return BaseItem + * @return string + * + * @throws IncorrectClassOfResultItemException * @throws UnknownInstanceOfResultItem */ - private function getItemInstance($method) + private function getItemClassName($method) { - $item = null; + $className = null; $method = MethodType::getValidatedMethod($method); switch ($method) { case MethodType::ADD_PARTICIPANTS: case MethodType::GET_PARTICIPANT_PROPERTIES: - $item = new Participant(); + $className = Participant::class; break; case MethodType::GET_QUESTION_PROPERTIES: - $item = new Question(); + $className = Question::class; break; case MethodType::LIST_PARTICIPANTS: - $item = new ParticipantShort(); + $className = ParticipantShort::class; break; case MethodType::LIST_QUESTIONS: - $item = new QuestionShort(); + $className = QuestionShort::class; break; case MethodType::LIST_SURVEYS: - $item = new Survey(); + $className = Survey::class; break; /* @@ -108,12 +113,19 @@ class ResultProcessor } /* - * Instance of the item is unknown? + * Oops, class name for instance of the item is unknown */ - if (null === $item) { + if (null === $className) { throw new UnknownInstanceOfResultItem($method); } - return $item; + if (Reflection::isChildOfClass($className, BaseItem::class)) { + return $className; + } + + /* + * Oops, class is incorrect (should extend BaseItem) + */ + throw new IncorrectClassOfResultItemException($className); } } diff --git a/tests/Base/Result/BaseItemTest.php b/tests/Base/Result/BaseItemTest.php index 299209c..1efd5c0 100644 --- a/tests/Base/Result/BaseItemTest.php +++ b/tests/Base/Result/BaseItemTest.php @@ -9,6 +9,7 @@ namespace Meritoo\LimeSurvey\Test\ApiClient\Base\Result; use Meritoo\Common\Test\Base\BaseTestCase; +use Meritoo\Common\Type\OopVisibilityType; use Meritoo\LimeSurvey\ApiClient\Base\Result\BaseItem; /** @@ -21,31 +22,11 @@ class BaseItemTest extends BaseTestCase { public function testConstructorVisibilityAndArguments() { - static::assertHasNoConstructor(BaseItem::class); + static::assertConstructorVisibilityAndArguments(BaseItem::class, OopVisibilityType::IS_PUBLIC, 1, 0); } - public function testSetValues() + public function testSetValuesVisibilityAndArguments() { - $mock = $this->getBaseItemMock(); - - static::assertInstanceOf(BaseItem::class, $mock->setValues([])); - static::assertInstanceOf(BaseItem::class, $mock->setValues(['lorem'])); - } - - /** - * Returns mock of the tested class - * - * @return BaseItem - */ - private function getBaseItemMock() - { - $mock = $this->getMockForAbstractClass(BaseItem::class); - - $mock - ->expects(static::any()) - ->method('setValue') - ->willReturn(null); - - return $mock; + static::assertMethodVisibilityAndArguments(BaseItem::class, 'setValues', OopVisibilityType::IS_PRIVATE, 1, 1); } } diff --git a/tests/Exception/IncorrectClassOfResultItemExceptionTest.php b/tests/Exception/IncorrectClassOfResultItemExceptionTest.php new file mode 100644 index 0000000..6fa8189 --- /dev/null +++ b/tests/Exception/IncorrectClassOfResultItemExceptionTest.php @@ -0,0 +1,58 @@ + + * @copyright Meritoo.pl + */ +class IncorrectClassOfResultItemExceptionTest extends BaseTestCase +{ + public function testConstructorVisibilityAndArguments() + { + static::assertConstructorVisibilityAndArguments(IncorrectClassOfResultItemException::class, OopVisibilityType::IS_PUBLIC, 1, 1); + } + + /** + * @param string $className Incorrect class name used to create instance of one item + * @param string $expectedMessage Expected exception's message + * + * @dataProvider provideIncorrectClassName + */ + public function testConstructorMessage($className, $expectedMessage) + { + $exception = new IncorrectClassOfResultItemException($className); + static::assertEquals($expectedMessage, $exception->getMessage()); + } + + /** + * Provides incorrect class name used to create instance of one item + * + * @return Generator + */ + public function provideIncorrectClassName() + { + $template = 'Class %s used to create instance of one item of the result should extend %s, but it does not. Did' + . ' you forget to use proper base class?'; + + yield[ + stdClass::class, + sprintf($template, stdClass::class, BaseItem::class), + ]; + } +} diff --git a/tests/Exception/UnknownInstanceOfResultItemTest.php b/tests/Exception/UnknownInstanceOfResultItemTest.php index ae93f68..badf1e0 100644 --- a/tests/Exception/UnknownInstanceOfResultItemTest.php +++ b/tests/Exception/UnknownInstanceOfResultItemTest.php @@ -49,17 +49,17 @@ class UnknownInstanceOfResultItemTest extends BaseTestCase */ public function provideMethodName() { - $template = 'Instance of one item used by result the of \'%s\' LimeSurvey API\'s method is unknown. Proper' - . ' class is not mapped in %s::%s() method. Did you forget about this?'; + $template = 'Class name used to create instance of one item used by result the of \'%s\' LimeSurvey API\'s' + . ' method is unknown. Proper class is not mapped in %s::%s() method. Did you forget about this?'; yield[ MethodType::LIST_SURVEYS, - sprintf($template, MethodType::LIST_SURVEYS, ResultProcessor::class, 'getItemInstance'), + sprintf($template, MethodType::LIST_SURVEYS, ResultProcessor::class, 'getItemClassName'), ]; yield[ MethodType::ADD_PARTICIPANTS, - sprintf($template, MethodType::ADD_PARTICIPANTS, ResultProcessor::class, 'getItemInstance'), + sprintf($template, MethodType::ADD_PARTICIPANTS, ResultProcessor::class, 'getItemClassName'), ]; } } diff --git a/tests/Result/Collection/ParticipantsTest.php b/tests/Result/Collection/ParticipantsTest.php index 56a8fef..172c70a 100644 --- a/tests/Result/Collection/ParticipantsTest.php +++ b/tests/Result/Collection/ParticipantsTest.php @@ -125,9 +125,8 @@ class ParticipantsTest extends BaseTestCase { $surveyId = 1; $email = 'john@scott.com'; - $participant = new Participant(); - $participant->setValues([ + $participant = new Participant([ 'firstname' => 'John', 'lastname' => 'Scott', 'email' => $email, @@ -148,9 +147,8 @@ class ParticipantsTest extends BaseTestCase { $surveyId = 1; $email = 'john@scott.com'; - $participant = new Participant(); - $participant->setValues([ + $participant = new Participant([ 'firstname' => 'John', 'lastname' => 'Scott', 'email' => $email, diff --git a/tests/Result/Item/ParticipantShortTest.php b/tests/Result/Item/ParticipantShortTest.php index 80a2c75..fab697a 100644 --- a/tests/Result/Item/ParticipantShortTest.php +++ b/tests/Result/Item/ParticipantShortTest.php @@ -9,6 +9,7 @@ namespace Meritoo\LimeSurvey\Test\ApiClient\Result\Item; use Meritoo\Common\Test\Base\BaseTestCase; +use Meritoo\Common\Type\OopVisibilityType; use Meritoo\LimeSurvey\ApiClient\Result\Item\ParticipantShort; use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor; use Meritoo\LimeSurvey\ApiClient\Type\MethodType; @@ -44,7 +45,7 @@ class ParticipantShortTest extends BaseTestCase public function testConstructorVisibilityAndArguments() { - static::assertHasNoConstructor(ParticipantShort::class); + static::assertConstructorVisibilityAndArguments(ParticipantShort::class, OopVisibilityType::IS_PUBLIC, 1, 0); } public function testCreateOfTheParticipant() @@ -116,7 +117,7 @@ class ParticipantShortTest extends BaseTestCase parent::setUp(); $this->rawData = static::getParticipantsRawData(); - $this->participant1stInstance = (new ParticipantShort())->setValues($this->rawData[0]); - $this->participant2ndInstance = (new ParticipantShort())->setValues($this->rawData[1]); + $this->participant1stInstance = new ParticipantShort($this->rawData[0]); + $this->participant2ndInstance = new ParticipantShort($this->rawData[1]); } } diff --git a/tests/Result/Item/ParticipantTest.php b/tests/Result/Item/ParticipantTest.php index 7531cf8..eddd4e9 100644 --- a/tests/Result/Item/ParticipantTest.php +++ b/tests/Result/Item/ParticipantTest.php @@ -10,6 +10,7 @@ namespace Meritoo\LimeSurvey\Test\ApiClient\Result\Item; use DateTime; use Meritoo\Common\Test\Base\BaseTestCase; +use Meritoo\Common\Type\OopVisibilityType; use Meritoo\LimeSurvey\ApiClient\Result\Item\Participant; use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor; use Meritoo\LimeSurvey\ApiClient\Type\MethodType; @@ -45,7 +46,7 @@ class ParticipantTest extends BaseTestCase public function testConstructorVisibilityAndArguments() { - static::assertHasNoConstructor(Participant::class); + static::assertConstructorVisibilityAndArguments(Participant::class, OopVisibilityType::IS_PUBLIC, 1, 0); } public function testCreateOfTheParticipant() @@ -215,7 +216,7 @@ class ParticipantTest extends BaseTestCase parent::setUp(); $this->rawData = static::getParticipantsRawData(); - $this->participant1stInstance = (new Participant())->setValues($this->rawData[0]); - $this->participant2ndInstance = (new Participant())->setValues($this->rawData[1]); + $this->participant1stInstance = new Participant($this->rawData[0]); + $this->participant2ndInstance = new Participant($this->rawData[1]); } } diff --git a/tests/Result/Item/QuestionShortTest.php b/tests/Result/Item/QuestionShortTest.php index 2843627..fd056fc 100644 --- a/tests/Result/Item/QuestionShortTest.php +++ b/tests/Result/Item/QuestionShortTest.php @@ -9,6 +9,7 @@ namespace Meritoo\LimeSurvey\Test\ApiClient\Result\Item; use Meritoo\Common\Test\Base\BaseTestCase; +use Meritoo\Common\Type\OopVisibilityType; use Meritoo\LimeSurvey\ApiClient\Result\Item\QuestionShort; use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor; use Meritoo\LimeSurvey\ApiClient\Type\MethodType; @@ -44,7 +45,7 @@ class QuestionShortTest extends BaseTestCase public function testConstructorVisibilityAndArguments() { - static::assertHasNoConstructor(QuestionShort::class); + static::assertConstructorVisibilityAndArguments(QuestionShort::class, OopVisibilityType::IS_PUBLIC, 1, 0); } public function testCreateOfTheQuestionShort() @@ -222,7 +223,7 @@ class QuestionShortTest extends BaseTestCase parent::setUp(); $this->rawData = static::getQuestionsRawData(); - $this->question1stInstance = (new QuestionShort())->setValues($this->rawData[0]); - $this->question2ndInstance = (new QuestionShort())->setValues($this->rawData[1]); + $this->question1stInstance = new QuestionShort($this->rawData[0]); + $this->question2ndInstance = new QuestionShort($this->rawData[1]); } } diff --git a/tests/Result/Item/QuestionTest.php b/tests/Result/Item/QuestionTest.php index a03f965..1cf1e27 100644 --- a/tests/Result/Item/QuestionTest.php +++ b/tests/Result/Item/QuestionTest.php @@ -9,6 +9,7 @@ namespace Meritoo\LimeSurvey\Test\ApiClient\Result\Item; use Meritoo\Common\Test\Base\BaseTestCase; +use Meritoo\Common\Type\OopVisibilityType; use Meritoo\LimeSurvey\ApiClient\Result\Item\Question; use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor; use Meritoo\LimeSurvey\ApiClient\Type\MethodType; @@ -44,7 +45,7 @@ class QuestionTest extends BaseTestCase public function testConstructorVisibilityAndArguments() { - static::assertHasNoConstructor(Question::class); + static::assertConstructorVisibilityAndArguments(Question::class, OopVisibilityType::IS_PUBLIC, 1, 0); } public function testCreateOfTheQuestionShort() @@ -284,7 +285,7 @@ class QuestionTest extends BaseTestCase parent::setUp(); $this->rawData = static::getQuestionsRawData(); - $this->question1stInstance = (new Question())->setValues($this->rawData[0]); - $this->question2ndInstance = (new Question())->setValues($this->rawData[1]); + $this->question1stInstance = new Question($this->rawData[0]); + $this->question2ndInstance = new Question($this->rawData[1]); } } diff --git a/tests/Result/Item/SurveyTest.php b/tests/Result/Item/SurveyTest.php index cb84ff6..638cac9 100644 --- a/tests/Result/Item/SurveyTest.php +++ b/tests/Result/Item/SurveyTest.php @@ -10,6 +10,7 @@ namespace Meritoo\LimeSurvey\Test\ApiClient\Result\Item; use DateTime; use Meritoo\Common\Test\Base\BaseTestCase; +use Meritoo\Common\Type\OopVisibilityType; use Meritoo\LimeSurvey\ApiClient\Result\Item\Survey; use Meritoo\LimeSurvey\ApiClient\Result\Processor\ResultProcessor; use Meritoo\LimeSurvey\ApiClient\Type\MethodType; @@ -45,7 +46,7 @@ class SurveyTest extends BaseTestCase public function testConstructorVisibilityAndArguments() { - static::assertHasNoConstructor(Survey::class); + static::assertConstructorVisibilityAndArguments(Survey::class, OopVisibilityType::IS_PUBLIC, 1, 0); } public function testCreateOfTheSurvey() @@ -119,7 +120,7 @@ class SurveyTest extends BaseTestCase parent::setUp(); $this->rawData = static::getSurveysRawData(); - $this->survey1stInstance = (new Survey())->setValues($this->rawData[0]); - $this->survey2ndInstance = (new Survey())->setValues($this->rawData[1]); + $this->survey1stInstance = new Survey($this->rawData[0]); + $this->survey2ndInstance = new Survey($this->rawData[1]); } } diff --git a/tests/Result/Processor/ResultProcessorTest.php b/tests/Result/Processor/ResultProcessorTest.php index 6423010..2d98225 100644 --- a/tests/Result/Processor/ResultProcessorTest.php +++ b/tests/Result/Processor/ResultProcessorTest.php @@ -75,9 +75,9 @@ class ResultProcessorTest extends BaseTestCase static::assertInstanceOf(BaseItem::class, $processed); } - public function testGetItemInstanceVisibilityAndArguments() + public function testGetItemClassNameVisibilityAndArguments() { - static::assertMethodVisibilityAndArguments(ResultProcessor::class, 'getItemInstance', OopVisibilityType::IS_PRIVATE, 1, 1); + static::assertMethodVisibilityAndArguments(ResultProcessor::class, 'getItemClassName', OopVisibilityType::IS_PRIVATE, 1, 1); } public function testRunWithUnknownResultClass() diff --git a/tests/Service/ParticipantServiceTest.php b/tests/Service/ParticipantServiceTest.php index 0f02a8d..6a78d39 100644 --- a/tests/Service/ParticipantServiceTest.php +++ b/tests/Service/ParticipantServiceTest.php @@ -297,13 +297,13 @@ class ParticipantServiceTest extends BaseTestCase $allParticipants = new Participants([ 1 => new Collection([ - (new Participant())->setValues([ + new Participant([ 'firstname' => 'John', 'lastname' => 'Scott', 'email' => 'john@scott.com', 'completed' => 'Y', ]), - (new Participant())->setValues([ + new Participant([ 'firstname' => 'Mary', 'lastname' => 'Jane', 'email' => 'mary@jane.com', diff --git a/tests/Service/SurveyServiceTest.php b/tests/Service/SurveyServiceTest.php index a672972..fcef08f 100644 --- a/tests/Service/SurveyServiceTest.php +++ b/tests/Service/SurveyServiceTest.php @@ -204,11 +204,11 @@ class SurveyServiceTest extends BaseTestCase $client = new Client($configuration, $rpcClientManager, $sessionManager); $allSurveys = new Collection([ - (new Survey())->setValues([ + new Survey([ 'sid' => 1, 'surveyls_title' => 'Test', ]), - (new Survey())->setValues([ + new Survey([ 'sid' => 2, 'surveyls_title' => 'Another Test', ]),