diff --git a/src/AppBundle/Form/DataTransformer/TagArrayToStringTransformer.php b/src/AppBundle/Form/DataTransformer/TagArrayToStringTransformer.php index 835a61907..6ed04b40e 100644 --- a/src/AppBundle/Form/DataTransformer/TagArrayToStringTransformer.php +++ b/src/AppBundle/Form/DataTransformer/TagArrayToStringTransformer.php @@ -22,6 +22,7 @@ * See http://symfony.com/doc/current/form/data_transformers.html * * @author Yonel Ceruto + * @author Jonathan Boyer */ class TagArrayToStringTransformer implements DataTransformerInterface { @@ -54,7 +55,7 @@ public function reverseTransform($string) return []; } - $names = explode(',', $string); + $names = array_filter(array_unique(array_map('trim', explode(',', $string)))); // Get the current tags and find the new ones that should be created. $tags = $this->manager->getRepository(Tag::class)->findBy([ diff --git a/tests/AppBundle/Form/DataTransformer/TagArrayToStringTransformerTest.php b/tests/AppBundle/Form/DataTransformer/TagArrayToStringTransformerTest.php new file mode 100644 index 000000000..f77b5986c --- /dev/null +++ b/tests/AppBundle/Form/DataTransformer/TagArrayToStringTransformerTest.php @@ -0,0 +1,142 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Tests\AppBundle\Form\DataTransformer; + +use AppBundle\Entity\Tag; +use AppBundle\Form\DataTransformer\TagArrayToStringTransformer; +use Doctrine\Common\Persistence\ObjectManager; +use Doctrine\ORM\EntityRepository; + +/** + * Tests that tags are transformed correctly using the data transformer. + * + * See http://symfony.com/doc/current/testing/database.html + */ +class TagArrayToStringTransformerTest extends \PHPUnit\Framework\TestCase +{ + /** + * Ensures that tags are created correctly. + */ + public function testCreateTheRightAmountOfTags() + { + $tags = $this->getMockedTransformer()->reverseTransform('Hello, Demo, How'); + + $this->assertCount(3, $tags); + $this->assertSame('Hello', $tags[0]->getName()); + } + + /** + * Ensures that empty tags and errors in the number of commas are + * dealed correctly. + */ + public function testCreateTheRightAmountOfTagsWithTooManyCommas() + { + $transformer = $this->getMockedTransformer(); + + $this->assertCount(3, $transformer->reverseTransform('Hello, Demo,, How')); + $this->assertCount(3, $transformer->reverseTransform('Hello, Demo, How,')); + } + + /** + * Ensures that leading/trailing spaces are ignored for tag names. + */ + public function testTrimNames() + { + $tags = $this->getMockedTransformer()->reverseTransform(' Hello '); + + $this->assertSame('Hello', $tags[0]->getName()); + } + + /** + * Ensures that duplicated tag names are ignored. + */ + public function testDuplicateNames() + { + $tags = $this->getMockedTransformer()->reverseTransform('Hello, Hello, Hello'); + + $this->assertCount(1, $tags); + } + + /** + * Ensures that the transformer uses tags already persisted in the database. + */ + public function testUsesAlreadyDefinedTags() + { + $persistedTags = [ + $this->createTag('Hello'), + $this->createTag('World'), + ]; + $tags = $this->getMockedTransformer($persistedTags)->reverseTransform('Hello, World, How, Are, You'); + + $this->assertCount(5, $tags); + $this->assertSame($persistedTags[0], $tags[0]); + $this->assertSame($persistedTags[1], $tags[1]); + } + + /** + * Ensures that the transformation from Tag instances to a simple string + * works as expected. + */ + public function testTransform() + { + $persistedTags = [ + $this->createTag('Hello'), + $this->createTag('World'), + ]; + $transformed = $this->getMockedTransformer()->transform($persistedTags); + + $this->assertSame('Hello,World', $transformed); + } + + /** + * This helper method mocks the real TagArrayToStringTransformer class to + * simplify the tests. See https://phpunit.de/manual/current/en/test-doubles.html. + * + * @param array $findByReturnValues The values returned when calling to the findBy() method + * + * @return TagArrayToStringTransformer + */ + private function getMockedTransformer($findByReturnValues = []) + { + $tagRepository = $this->getMockBuilder(EntityRepository::class) + ->disableOriginalConstructor() + ->getMock(); + $tagRepository->expects($this->any()) + ->method('findBy') + ->will($this->returnValue($findByReturnValues)); + + $entityManager = $this + ->getMockBuilder(ObjectManager::class) + ->disableOriginalConstructor() + ->getMock(); + $entityManager->expects($this->any()) + ->method('getRepository') + ->will($this->returnValue($tagRepository)); + + return new TagArrayToStringTransformer($entityManager); + } + + /** + * This helper method creates a Tag instance for the given tag name. + * + * @param string $name + * + * @return Tag + */ + private function createTag($name) + { + $tag = new Tag(); + $tag->setName($name); + + return $tag; + } +}