123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526 |
- <?php
- /*
- * This file is part of the Symfony package.
- *
- * (c) Fabien Potencier <fabien@symfony.com>
- *
- * For the full copyright and license information, please view the LICENSE
- * file that was distributed with this source code.
- */
- namespace Symfony\Component\Serializer\Tests\Encoder;
- use Symfony\Component\Serializer\Tests\Fixtures\Dummy;
- use Symfony\Component\Serializer\Tests\Fixtures\NormalizableTraversableDummy;
- use Symfony\Component\Serializer\Tests\Fixtures\ScalarDummy;
- use Symfony\Component\Serializer\Encoder\XmlEncoder;
- use Symfony\Component\Serializer\Serializer;
- use Symfony\Component\Serializer\Exception\UnexpectedValueException;
- use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
- class XmlEncoderTest extends \PHPUnit_Framework_TestCase
- {
- private $encoder;
- protected function setUp()
- {
- $this->encoder = new XmlEncoder();
- $serializer = new Serializer(array(new CustomNormalizer()), array('xml' => new XmlEncoder()));
- $this->encoder->setSerializer($serializer);
- }
- public function testEncodeScalar()
- {
- $obj = new ScalarDummy();
- $obj->xmlFoo = 'foo';
- $expected = '<?xml version="1.0"?>'."\n".
- '<response>foo</response>'."\n";
- $this->assertEquals($expected, $this->encoder->encode($obj, 'xml'));
- }
- public function testSetRootNodeName()
- {
- $obj = new ScalarDummy();
- $obj->xmlFoo = 'foo';
- $this->encoder->setRootNodeName('test');
- $expected = '<?xml version="1.0"?>'."\n".
- '<test>foo</test>'."\n";
- $this->assertEquals($expected, $this->encoder->encode($obj, 'xml'));
- }
- /**
- * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
- * @expectedExceptionMessage Document types are not allowed.
- */
- public function testDocTypeIsNotAllowed()
- {
- $this->encoder->decode('<?xml version="1.0"?><!DOCTYPE foo><foo></foo>', 'foo');
- }
- public function testAttributes()
- {
- $obj = new ScalarDummy();
- $obj->xmlFoo = array(
- 'foo-bar' => array(
- '@id' => 1,
- '@name' => 'Bar',
- ),
- 'Foo' => array(
- 'Bar' => 'Test',
- '@Type' => 'test',
- ),
- 'föo_bär' => 'a',
- 'Bar' => array(1, 2, 3),
- 'a' => 'b',
- );
- $expected = '<?xml version="1.0"?>'."\n".
- '<response>'.
- '<foo-bar id="1" name="Bar"/>'.
- '<Foo Type="test"><Bar>Test</Bar></Foo>'.
- '<föo_bär>a</föo_bär>'.
- '<Bar>1</Bar>'.
- '<Bar>2</Bar>'.
- '<Bar>3</Bar>'.
- '<a>b</a>'.
- '</response>'."\n";
- $this->assertEquals($expected, $this->encoder->encode($obj, 'xml'));
- }
- public function testElementNameValid()
- {
- $obj = new ScalarDummy();
- $obj->xmlFoo = array(
- 'foo-bar' => 'a',
- 'foo_bar' => 'a',
- 'föo_bär' => 'a',
- );
- $expected = '<?xml version="1.0"?>'."\n".
- '<response>'.
- '<foo-bar>a</foo-bar>'.
- '<foo_bar>a</foo_bar>'.
- '<föo_bär>a</föo_bär>'.
- '</response>'."\n";
- $this->assertEquals($expected, $this->encoder->encode($obj, 'xml'));
- }
- public function testEncodeSimpleXML()
- {
- $xml = simplexml_load_string('<firstname>Peter</firstname>');
- $array = array('person' => $xml);
- $expected = '<?xml version="1.0"?>'."\n".
- '<response><person><firstname>Peter</firstname></person></response>'."\n";
- $this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
- }
- public function testEncodeXmlAttributes()
- {
- $xml = simplexml_load_string('<firstname>Peter</firstname>');
- $array = array('person' => $xml);
- $expected = '<?xml version="1.1" encoding="utf-8" standalone="yes"?>'."\n".
- '<response><person><firstname>Peter</firstname></person></response>'."\n";
- $context = array(
- 'xml_version' => '1.1',
- 'xml_encoding' => 'utf-8',
- 'xml_standalone' => true,
- );
- $this->assertSame($expected, $this->encoder->encode($array, 'xml', $context));
- }
- public function testContext()
- {
- $array = array('person' => array('name' => 'George Abitbol'));
- $expected = <<<'XML'
- <?xml version="1.0"?>
- <response>
- <person>
- <name>George Abitbol</name>
- </person>
- </response>
- XML;
- $context = array(
- 'xml_format_output' => true,
- );
- $this->assertSame($expected, $this->encoder->encode($array, 'xml', $context));
- }
- public function testEncodeScalarRootAttributes()
- {
- $array = array(
- '#' => 'Paul',
- '@gender' => 'm',
- );
- $expected = '<?xml version="1.0"?>'."\n".
- '<response gender="m">Paul</response>'."\n";
- $this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
- }
- public function testEncodeRootAttributes()
- {
- $array = array(
- 'firstname' => 'Paul',
- '@gender' => 'm',
- );
- $expected = '<?xml version="1.0"?>'."\n".
- '<response gender="m"><firstname>Paul</firstname></response>'."\n";
- $this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
- }
- public function testEncodeCdataWrapping()
- {
- $array = array(
- 'firstname' => 'Paul <or Me>',
- );
- $expected = '<?xml version="1.0"?>'."\n".
- '<response><firstname><![CDATA[Paul <or Me>]]></firstname></response>'."\n";
- $this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
- }
- public function testEncodeScalarWithAttribute()
- {
- $array = array(
- 'person' => array('@gender' => 'M', '#' => 'Peter'),
- );
- $expected = '<?xml version="1.0"?>'."\n".
- '<response><person gender="M">Peter</person></response>'."\n";
- $this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
- }
- public function testDecodeScalar()
- {
- $source = '<?xml version="1.0"?>'."\n".
- '<response>foo</response>'."\n";
- $this->assertEquals('foo', $this->encoder->decode($source, 'xml'));
- }
- public function testEncode()
- {
- $source = $this->getXmlSource();
- $obj = $this->getObject();
- $this->assertEquals($source, $this->encoder->encode($obj, 'xml'));
- }
- public function testEncodeWithNamespace()
- {
- $source = $this->getNamespacedXmlSource();
- $array = $this->getNamespacedArray();
- $this->assertEquals($source, $this->encoder->encode($array, 'xml'));
- }
- public function testEncodeSerializerXmlRootNodeNameOption()
- {
- $options = array('xml_root_node_name' => 'test');
- $this->encoder = new XmlEncoder();
- $serializer = new Serializer(array(), array('xml' => new XmlEncoder()));
- $this->encoder->setSerializer($serializer);
- $array = array(
- 'person' => array('@gender' => 'M', '#' => 'Peter'),
- );
- $expected = '<?xml version="1.0"?>'."\n".
- '<test><person gender="M">Peter</person></test>'."\n";
- $this->assertEquals($expected, $serializer->serialize($array, 'xml', $options));
- }
- public function testEncodeTraversableWhenNormalizable()
- {
- $this->encoder = new XmlEncoder();
- $serializer = new Serializer(array(new CustomNormalizer()), array('xml' => new XmlEncoder()));
- $this->encoder->setSerializer($serializer);
- $expected = <<<'XML'
- <?xml version="1.0"?>
- <response><foo>normalizedFoo</foo><bar>normalizedBar</bar></response>
- XML;
- $this->assertEquals($expected, $serializer->serialize(new NormalizableTraversableDummy(), 'xml'));
- }
- public function testDecode()
- {
- $source = $this->getXmlSource();
- $obj = $this->getObject();
- $this->assertEquals(get_object_vars($obj), $this->encoder->decode($source, 'xml'));
- }
- public function testDecodeCdataWrapping()
- {
- $expected = array(
- 'firstname' => 'Paul <or Me>',
- );
- $xml = '<?xml version="1.0"?>'."\n".
- '<response><firstname><![CDATA[Paul <or Me>]]></firstname></response>'."\n";
- $this->assertEquals($expected, $this->encoder->decode($xml, 'xml'));
- }
- public function testDecodeCdataWrappingAndWhitespace()
- {
- $expected = array(
- 'firstname' => 'Paul <or Me>',
- );
- $xml = '<?xml version="1.0"?>'."\n".
- '<response><firstname>'."\n".
- '<![CDATA[Paul <or Me>]]></firstname></response>'."\n";
- $this->assertEquals($expected, $this->encoder->decode($xml, 'xml'));
- }
- public function testDecodeWithNamespace()
- {
- $source = $this->getNamespacedXmlSource();
- $array = $this->getNamespacedArray();
- $this->assertEquals($array, $this->encoder->decode($source, 'xml'));
- }
- public function testDecodeScalarWithAttribute()
- {
- $source = '<?xml version="1.0"?>'."\n".
- '<response><person gender="M">Peter</person></response>'."\n";
- $expected = array(
- 'person' => array('@gender' => 'M', '#' => 'Peter'),
- );
- $this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
- }
- public function testDecodeScalarRootAttributes()
- {
- $source = '<?xml version="1.0"?>'."\n".
- '<person gender="M">Peter</person>'."\n";
- $expected = array(
- '#' => 'Peter',
- '@gender' => 'M',
- );
- $this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
- }
- public function testDecodeRootAttributes()
- {
- $source = '<?xml version="1.0"?>'."\n".
- '<person gender="M"><firstname>Peter</firstname><lastname>Mac Calloway</lastname></person>'."\n";
- $expected = array(
- 'firstname' => 'Peter',
- 'lastname' => 'Mac Calloway',
- '@gender' => 'M',
- );
- $this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
- }
- public function testDecodeArray()
- {
- $source = '<?xml version="1.0"?>'."\n".
- '<response>'.
- '<people>'.
- '<person><firstname>Benjamin</firstname><lastname>Alexandre</lastname></person>'.
- '<person><firstname>Damien</firstname><lastname>Clay</lastname></person>'.
- '</people>'.
- '</response>'."\n";
- $expected = array(
- 'people' => array('person' => array(
- array('firstname' => 'Benjamin', 'lastname' => 'Alexandre'),
- array('firstname' => 'Damien', 'lastname' => 'Clay'),
- )),
- );
- $this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
- }
- public function testDecodeIgnoreWhiteSpace()
- {
- $source = <<<'XML'
- <?xml version="1.0"?>
- <people>
- <person>
- <firstname>Benjamin</firstname>
- <lastname>Alexandre</lastname>
- </person>
- <person>
- <firstname>Damien</firstname>
- <lastname>Clay</lastname>
- </person>
- </people>
- XML;
- $expected = array('person' => array(
- array('firstname' => 'Benjamin', 'lastname' => 'Alexandre'),
- array('firstname' => 'Damien', 'lastname' => 'Clay'),
- ));
- $this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
- }
- public function testDecodeWithoutItemHash()
- {
- $obj = new ScalarDummy();
- $obj->xmlFoo = array(
- 'foo-bar' => array(
- '@key' => 'value',
- 'item' => array('@key' => 'key', 'key-val' => 'val'),
- ),
- 'Foo' => array(
- 'Bar' => 'Test',
- '@Type' => 'test',
- ),
- 'föo_bär' => 'a',
- 'Bar' => array(1, 2, 3),
- 'a' => 'b',
- );
- $expected = array(
- 'foo-bar' => array(
- '@key' => 'value',
- 'key' => array('@key' => 'key', 'key-val' => 'val'),
- ),
- 'Foo' => array(
- 'Bar' => 'Test',
- '@Type' => 'test',
- ),
- 'föo_bär' => 'a',
- 'Bar' => array(1, 2, 3),
- 'a' => 'b',
- );
- $xml = $this->encoder->encode($obj, 'xml');
- $this->assertEquals($expected, $this->encoder->decode($xml, 'xml'));
- }
- /**
- * @expectedException \Symfony\Component\Serializer\Exception\UnexpectedValueException
- */
- public function testDecodeInvalidXml()
- {
- $this->encoder->decode('<?xml version="1.0"?><invalid><xml>', 'xml');
- }
- public function testPreventsComplexExternalEntities()
- {
- $oldCwd = getcwd();
- chdir(__DIR__);
- try {
- $this->encoder->decode('<?xml version="1.0"?><!DOCTYPE scan[<!ENTITY test SYSTEM "php://filter/read=convert.base64-encode/resource=XmlEncoderTest.php">]><scan>&test;</scan>', 'xml');
- chdir($oldCwd);
- $this->fail('No exception was thrown.');
- } catch (\Exception $e) {
- chdir($oldCwd);
- if (!$e instanceof UnexpectedValueException) {
- $this->fail('Expected UnexpectedValueException');
- }
- }
- }
- public function testDecodeEmptyXml()
- {
- $this->setExpectedException('Symfony\Component\Serializer\Exception\UnexpectedValueException', 'Invalid XML data, it can not be empty.');
- $this->encoder->decode(' ', 'xml');
- }
- protected function getXmlSource()
- {
- return '<?xml version="1.0"?>'."\n".
- '<response>'.
- '<foo>foo</foo>'.
- '<bar>a</bar><bar>b</bar>'.
- '<baz><key>val</key><key2>val</key2><item key="A B">bar</item>'.
- '<item><title>title1</title></item><item><title>title2</title></item>'.
- '<Barry><FooBar id="1"><Baz>Ed</Baz></FooBar></Barry></baz>'.
- '<qux>1</qux>'.
- '</response>'."\n";
- }
- protected function getNamespacedXmlSource()
- {
- return '<?xml version="1.0"?>'."\n".
- '<response xmlns="http://www.w3.org/2005/Atom" xmlns:app="http://www.w3.org/2007/app" xmlns:media="http://search.yahoo.com/mrss/" xmlns:gd="http://schemas.google.com/g/2005" xmlns:yt="http://gdata.youtube.com/schemas/2007">'.
- '<qux>1</qux>'.
- '<app:foo>foo</app:foo>'.
- '<yt:bar>a</yt:bar><yt:bar>b</yt:bar>'.
- '<media:baz><media:key>val</media:key><media:key2>val</media:key2><item key="A B">bar</item>'.
- '<item><title>title1</title></item><item><title>title2</title></item>'.
- '<Barry size="large"><FooBar gd:id="1"><Baz>Ed</Baz></FooBar></Barry></media:baz>'.
- '</response>'."\n";
- }
- protected function getNamespacedArray()
- {
- return array(
- '@xmlns' => 'http://www.w3.org/2005/Atom',
- '@xmlns:app' => 'http://www.w3.org/2007/app',
- '@xmlns:media' => 'http://search.yahoo.com/mrss/',
- '@xmlns:gd' => 'http://schemas.google.com/g/2005',
- '@xmlns:yt' => 'http://gdata.youtube.com/schemas/2007',
- 'qux' => '1',
- 'app:foo' => 'foo',
- 'yt:bar' => array('a', 'b'),
- 'media:baz' => array(
- 'media:key' => 'val',
- 'media:key2' => 'val',
- 'A B' => 'bar',
- 'item' => array(
- array(
- 'title' => 'title1',
- ),
- array(
- 'title' => 'title2',
- ),
- ),
- 'Barry' => array(
- '@size' => 'large',
- 'FooBar' => array(
- 'Baz' => 'Ed',
- '@gd:id' => 1,
- ),
- ),
- ),
- );
- }
- protected function getObject()
- {
- $obj = new Dummy();
- $obj->foo = 'foo';
- $obj->bar = array('a', 'b');
- $obj->baz = array('key' => 'val', 'key2' => 'val', 'A B' => 'bar', 'item' => array(array('title' => 'title1'), array('title' => 'title2')), 'Barry' => array('FooBar' => array('Baz' => 'Ed', '@id' => 1)));
- $obj->qux = '1';
- return $obj;
- }
- }
|