| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354 | <?phpnamespace JMS\Serializer\Tests\Serializer\Doctrine;use Doctrine\Common\Annotations\AnnotationReader;use Doctrine\Common\Annotations\Reader;use Doctrine\Common\Persistence\AbstractManagerRegistry;use Doctrine\Common\Persistence\ManagerRegistry;use Doctrine\DBAL\Connection;use Doctrine\DBAL\DriverManager;use Doctrine\ORM\Configuration;use Doctrine\ORM\EntityManager;use Doctrine\ORM\Mapping\Driver\AnnotationDriver;use Doctrine\ORM\ORMException;use Doctrine\ORM\Tools\SchemaTool;use Doctrine\ORM\UnitOfWork;use JMS\Serializer\Builder\CallbackDriverFactory;use JMS\Serializer\Builder\DefaultDriverFactory;use JMS\Serializer\Construction\DoctrineObjectConstructor;use JMS\Serializer\Construction\ObjectConstructorInterface;use JMS\Serializer\Construction\UnserializeObjectConstructor;use JMS\Serializer\DeserializationContext;use JMS\Serializer\Metadata\ClassMetadata;use JMS\Serializer\Metadata\Driver\DoctrineTypeDriver;use JMS\Serializer\Serializer;use JMS\Serializer\SerializerBuilder;use JMS\Serializer\Tests\Fixtures\Doctrine\Author;use JMS\Serializer\Tests\Fixtures\Doctrine\IdentityFields\Server;use JMS\Serializer\Tests\Fixtures\Doctrine\SingleTableInheritance\Excursion;use JMS\Serializer\VisitorInterface;class ObjectConstructorTest extends \PHPUnit_Framework_TestCase{    /** @var ManagerRegistry */    private $registry;    /** @var Serializer */    private $serializer;    /** @var VisitorInterface */    private $visitor;    /** @var DeserializationContext */    private $context;    public function testFindEntity()    {        $em = $this->registry->getManager();        $author = new Author('John', 5);        $em->persist($author);        $em->flush();        $em->clear();        $fallback = $this->getMockBuilder(ObjectConstructorInterface::class)->getMock();        $type = array('name' => Author::class, 'params' => array());        $class = new ClassMetadata(Author::class);        $constructor = new DoctrineObjectConstructor($this->registry, $fallback);        $authorFetched = $constructor->construct($this->visitor, $class, ['id' => 5], $type, $this->context);        $this->assertEquals($author, $authorFetched);    }    public function testFindManagedEntity()    {        $em = $this->registry->getManager();        $author = new Author('John', 5);        $em->persist($author);        $em->flush();        $fallback = $this->getMockBuilder(ObjectConstructorInterface::class)->getMock();        $type = array('name' => Author::class, 'params' => array());        $class = new ClassMetadata(Author::class);        $constructor = new DoctrineObjectConstructor($this->registry, $fallback);        $authorFetched = $constructor->construct($this->visitor, $class, ['id' => 5], $type, $this->context);        $this->assertSame($author, $authorFetched);    }    public function testMissingAuthor()    {        $fallback = $this->getMockBuilder(ObjectConstructorInterface::class)->getMock();        $type = array('name' => Author::class, 'params' => array());        $class = new ClassMetadata(Author::class);        $constructor = new DoctrineObjectConstructor($this->registry, $fallback);        $author = $constructor->construct($this->visitor, $class, ['id' => 5], $type, $this->context);        $this->assertNull($author);    }    public function testMissingAuthorFallback()    {        $author = new Author('John');        $fallback = $this->getMockBuilder(ObjectConstructorInterface::class)->getMock();        $fallback->expects($this->once())->method('construct')->willReturn($author);        $type = array('name' => Author::class, 'params' => array());        $class = new ClassMetadata(Author::class);        $constructor = new DoctrineObjectConstructor($this->registry, $fallback, DoctrineObjectConstructor::ON_MISSING_FALLBACK);        $authorFetched = $constructor->construct($this->visitor, $class, ['id' => 5], $type, $this->context);        $this->assertSame($author, $authorFetched);    }    public function testMissingNotManaged()    {        $author = new \JMS\Serializer\Tests\Fixtures\DoctrinePHPCR\Author('foo');        $fallback = $this->getMockBuilder(ObjectConstructorInterface::class)->getMock();        $fallback->expects($this->once())->method('construct')->willReturn($author);        $type = array('name' => Author::class, 'params' => array());        $class = new ClassMetadata(Author::class);        $constructor = new DoctrineObjectConstructor($this->registry, $fallback, DoctrineObjectConstructor::ON_MISSING_FALLBACK);        $authorFetched = $constructor->construct($this->visitor, $class, ['id' => 5], $type, $this->context);        $this->assertSame($author, $authorFetched);    }    public function testReference()    {        $em = $this->registry->getManager();        $author = new Author('John', 5);        $em->persist($author);        $em->flush();        $fallback = $this->getMockBuilder(ObjectConstructorInterface::class)->getMock();        $type = array('name' => Author::class, 'params' => array());        $class = new ClassMetadata(Author::class);        $constructor = new DoctrineObjectConstructor($this->registry, $fallback, DoctrineObjectConstructor::ON_MISSING_FALLBACK);        $authorFetched = $constructor->construct($this->visitor, $class, 5, $type, $this->context);        $this->assertSame($author, $authorFetched);    }    /**     * @expectedException \JMS\Serializer\Exception\ObjectConstructionException     */    public function testMissingAuthorException()    {        $fallback = $this->getMockBuilder(ObjectConstructorInterface::class)->getMock();        $type = array('name' => Author::class, 'params' => array());        $class = new ClassMetadata(Author::class);        $constructor = new DoctrineObjectConstructor($this->registry, $fallback, DoctrineObjectConstructor::ON_MISSING_EXCEPTION);        $constructor->construct($this->visitor, $class, ['id' => 5], $type, $this->context);    }    /**     * @expectedException \JMS\Serializer\Exception\InvalidArgumentException     */    public function testInvalidArg()    {        $fallback = $this->getMockBuilder(ObjectConstructorInterface::class)->getMock();        $type = array('name' => Author::class, 'params' => array());        $class = new ClassMetadata(Author::class);        $constructor = new DoctrineObjectConstructor($this->registry, $fallback, 'foo');        $constructor->construct($this->visitor, $class, ['id' => 5], $type, $this->context);    }    public function testMissingData()    {        $author = new Author('John');        $fallback = $this->getMockBuilder(ObjectConstructorInterface::class)->getMock();        $fallback->expects($this->once())->method('construct')->willReturn($author);        $type = array('name' => Author::class, 'params' => array());        $class = new ClassMetadata(Author::class);        $constructor = new DoctrineObjectConstructor($this->registry, $fallback, 'foo');        $authorFetched = $constructor->construct($this->visitor, $class, ['foo' => 5], $type, $this->context);        $this->assertSame($author, $authorFetched);    }    public function testNamingForIdentifierColumnIsConsidered()    {        $serializer = $this->createSerializerWithDoctrineObjectConstructor();        /** @var EntityManager $em */        $em = $this->registry->getManager();        $server = new Server('Linux', '127.0.0.1', 'home');        $em->persist($server);        $em->flush();        $em->clear();        $jsonData = '{"ip_address":"127.0.0.1", "server_id_extracted":"home", "name":"Windows"}';        /** @var Server $serverDeserialized */        $serverDeserialized = $serializer->deserialize($jsonData, Server::class, 'json');        static::assertSame(            $em->getUnitOfWork()->getEntityState($serverDeserialized),            UnitOfWork::STATE_MANAGED        );    }    protected function setUp()    {        $this->visitor = $this->getMockBuilder('JMS\Serializer\VisitorInterface')->getMock();        $this->context = $this->getMockBuilder('JMS\Serializer\DeserializationContext')->getMock();        $connection = $this->createConnection();        $entityManager = $this->createEntityManager($connection);        $this->registry = $registry = new SimpleBaseManagerRegistry(            function ($id) use ($connection, $entityManager) {                switch ($id) {                    case 'default_connection':                        return $connection;                    case 'default_manager':                        return $entityManager;                    default:                        throw new \RuntimeException(sprintf('Unknown service id "%s".', $id));                }            }        );        $this->serializer = SerializerBuilder::create()            ->setMetadataDriverFactory(new CallbackDriverFactory(                function (array $metadataDirs, Reader $annotationReader) use ($registry) {                    $defaultFactory = new DefaultDriverFactory();                    return new DoctrineTypeDriver($defaultFactory->createDriver($metadataDirs, $annotationReader), $registry);                }            ))            ->build();        $this->prepareDatabase();    }    private function prepareDatabase()    {        /** @var EntityManager $em */        $em = $this->registry->getManager();        $tool = new SchemaTool($em);        $tool->createSchema($em->getMetadataFactory()->getAllMetadata());    }    private function createConnection()    {        $con = DriverManager::getConnection(array(            'driver' => 'pdo_sqlite',            'memory' => true,        ));        return $con;    }    private function createEntityManager(Connection $con)    {        $cfg = new Configuration();        $cfg->setMetadataDriverImpl(new AnnotationDriver(new AnnotationReader(), array(            __DIR__ . '/../../Fixtures/Doctrine',        )));        $cfg->setAutoGenerateProxyClasses(true);        $cfg->setProxyNamespace('JMS\Serializer\DoctrineProxy');        $cfg->setProxyDir(sys_get_temp_dir() . '/serializer-test-proxies');        $em = EntityManager::create($con, $cfg);        return $em;    }    /**     * @return \JMS\Serializer\SerializerInterface     */    private function createSerializerWithDoctrineObjectConstructor()    {        return SerializerBuilder::create()            ->setObjectConstructor(                new DoctrineObjectConstructor(                    $this->registry,                    new UnserializeObjectConstructor(),                    DoctrineObjectConstructor::ON_MISSING_FALLBACK                )            )            ->addDefaultHandlers()            ->build();    }}\Doctrine\DBAL\Types\Type::addType('Author', 'Doctrine\DBAL\Types\StringType');\Doctrine\DBAL\Types\Type::addType('some_custom_type', 'Doctrine\DBAL\Types\StringType');class SimpleBaseManagerRegistry extends AbstractManagerRegistry{    private $services = array();    private $serviceCreator;    public function __construct($serviceCreator, $name = 'anonymous', array $connections = array('default' => 'default_connection'), array $managers = array('default' => 'default_manager'), $defaultConnection = null, $defaultManager = null, $proxyInterface = 'Doctrine\Common\Persistence\Proxy')    {        if (null === $defaultConnection) {            $defaultConnection = key($connections);        }        if (null === $defaultManager) {            $defaultManager = key($managers);        }        parent::__construct($name, $connections, $managers, $defaultConnection, $defaultManager, $proxyInterface);        if (!is_callable($serviceCreator)) {            throw new \InvalidArgumentException('$serviceCreator must be a valid callable.');        }        $this->serviceCreator = $serviceCreator;    }    public function getService($name)    {        if (isset($this->services[$name])) {            return $this->services[$name];        }        return $this->services[$name] = call_user_func($this->serviceCreator, $name);    }    public function resetService($name)    {        unset($this->services[$name]);    }    public function getAliasNamespace($alias)    {        foreach (array_keys($this->getManagers()) as $name) {            $manager = $this->getManager($name);            if ($manager instanceof EntityManager) {                try {                    return $manager->getConfiguration()->getEntityNamespace($alias);                } catch (ORMException $ex) {                    // Probably mapped by another entity manager, or invalid, just ignore this here.                }            } else {                throw new \LogicException(sprintf('Unsupported manager type "%s".', get_class($manager)));            }        }        throw new \RuntimeException(sprintf('The namespace alias "%s" is not known to any manager.', $alias));    }}
 |