XmlTest.php 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. <?php
  2. /**
  3. * XmlTest file
  4. *
  5. * PHP 5
  6. *
  7. * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
  8. * Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  9. *
  10. * Licensed under The MIT License
  11. * Redistributions of files must retain the above copyright notice
  12. *
  13. * @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
  14. * @link http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
  15. * @package Cake.Test.Case.Utility
  16. * @since CakePHP(tm) v 1.2.0.5432
  17. * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
  18. */
  19. App::uses('Xml', 'Utility');
  20. App::uses('CakeTestModel', 'TestSuite/Fixture');
  21. /**
  22. * Article class
  23. *
  24. * @package Cake.Test.Case.Utility
  25. */
  26. class XmlArticle extends CakeTestModel {
  27. /**
  28. * name property
  29. *
  30. * @var string 'Article'
  31. */
  32. public $name = 'Article';
  33. /**
  34. * belongsTo property
  35. *
  36. * @var array
  37. */
  38. public $belongsTo = array(
  39. 'User' => array(
  40. 'className' => 'XmlUser',
  41. 'foreignKey' => 'user_id'
  42. )
  43. );
  44. }
  45. /**
  46. * User class
  47. *
  48. * @package Cake.Test.Case.Utility
  49. */
  50. class XmlUser extends CakeTestModel {
  51. /**
  52. * name property
  53. *
  54. * @var string 'User'
  55. */
  56. public $name = 'User';
  57. /**
  58. * hasMany property
  59. *
  60. * @var array
  61. */
  62. public $hasMany = array(
  63. 'Article' => array(
  64. 'className' => 'XmlArticle'
  65. )
  66. );
  67. }
  68. /**
  69. * XmlTest class
  70. *
  71. * @package Cake.Test.Case.Utility
  72. */
  73. class XmlTest extends CakeTestCase {
  74. /**
  75. * autoFixtures property
  76. *
  77. * @var bool false
  78. */
  79. public $autoFixtures = false;
  80. /**
  81. * fixtures property
  82. * @var array
  83. */
  84. public $fixtures = array(
  85. 'core.article', 'core.user'
  86. );
  87. /**
  88. * setUp method
  89. *
  90. * @return void
  91. */
  92. public function setUp() {
  93. parent::setUp();
  94. $this->_appEncoding = Configure::read('App.encoding');
  95. Configure::write('App.encoding', 'UTF-8');
  96. }
  97. /**
  98. * tearDown method
  99. *
  100. * @return void
  101. */
  102. public function tearDown() {
  103. parent::tearDown();
  104. Configure::write('App.encoding', $this->_appEncoding);
  105. }
  106. /**
  107. * testBuild method
  108. *
  109. * @return void
  110. */
  111. public function testBuild() {
  112. $xml = '<tag>value</tag>';
  113. $obj = Xml::build($xml);
  114. $this->assertTrue($obj instanceof SimpleXMLElement);
  115. $this->assertEquals('tag', (string)$obj->getName());
  116. $this->assertEquals('value', (string)$obj);
  117. $xml = '<?xml version="1.0" encoding="UTF-8"?><tag>value</tag>';
  118. $this->assertEquals($obj, Xml::build($xml));
  119. $obj = Xml::build($xml, array('return' => 'domdocument'));
  120. $this->assertTrue($obj instanceof DOMDocument);
  121. $this->assertEquals('tag', $obj->firstChild->nodeName);
  122. $this->assertEquals('value', $obj->firstChild->nodeValue);
  123. $xml = CAKE . 'Test' . DS . 'Fixture' . DS . 'sample.xml';
  124. $obj = Xml::build($xml);
  125. $this->assertEquals('tags', $obj->getName());
  126. $this->assertEquals(2, count($obj));
  127. $this->assertEquals(Xml::build($xml), Xml::build(file_get_contents($xml)));
  128. $obj = Xml::build($xml, array('return' => 'domdocument'));
  129. $this->assertEquals('tags', $obj->firstChild->nodeName);
  130. $this->assertEquals(
  131. Xml::build($xml, array('return' => 'domdocument')),
  132. Xml::build(file_get_contents($xml), array('return' => 'domdocument'))
  133. );
  134. $this->assertEquals(
  135. Xml::build($xml, array('return' => 'simplexml')),
  136. Xml::build($xml, 'simplexml')
  137. );
  138. $xml = array('tag' => 'value');
  139. $obj = Xml::build($xml);
  140. $this->assertEquals('tag', $obj->getName());
  141. $this->assertEquals('value', (string)$obj);
  142. $obj = Xml::build($xml, array('return' => 'domdocument'));
  143. $this->assertEquals('tag', $obj->firstChild->nodeName);
  144. $this->assertEquals('value', $obj->firstChild->nodeValue);
  145. $obj = Xml::build($xml, array('return' => 'domdocument', 'encoding' => null));
  146. $this->assertNotRegExp('/encoding/', $obj->saveXML());
  147. }
  148. /**
  149. * data provider function for testBuildInvalidData
  150. *
  151. * @return array
  152. */
  153. public static function invalidDataProvider() {
  154. return array(
  155. array(null),
  156. array(false),
  157. array(''),
  158. array('http://localhost/notthere.xml'),
  159. );
  160. }
  161. /**
  162. * testBuildInvalidData
  163. *
  164. * @dataProvider invalidDataProvider
  165. * @expectedException XmlException
  166. * return void
  167. */
  168. public function testBuildInvalidData($value) {
  169. Xml::build($value);
  170. }
  171. /**
  172. * test build with a single empty tag
  173. *
  174. * return void
  175. */
  176. public function testBuildEmptyTag() {
  177. try {
  178. Xml::build('<tag>');
  179. $this->fail('No exception');
  180. } catch (Exception $e) {
  181. $this->assertTrue(true, 'An exception was raised');
  182. }
  183. }
  184. /**
  185. * testFromArray method
  186. *
  187. * @return void
  188. */
  189. public function testFromArray() {
  190. $xml = array('tag' => 'value');
  191. $obj = Xml::fromArray($xml);
  192. $this->assertEquals('tag', $obj->getName());
  193. $this->assertEquals('value', (string)$obj);
  194. $xml = array('tag' => null);
  195. $obj = Xml::fromArray($xml);
  196. $this->assertEquals('tag', $obj->getName());
  197. $this->assertEquals('', (string)$obj);
  198. $xml = array('tag' => array('@' => 'value'));
  199. $obj = Xml::fromArray($xml);
  200. $this->assertEquals('tag', $obj->getName());
  201. $this->assertEquals('value', (string)$obj);
  202. $xml = array(
  203. 'tags' => array(
  204. 'tag' => array(
  205. array(
  206. 'id' => '1',
  207. 'name' => 'defect'
  208. ),
  209. array(
  210. 'id' => '2',
  211. 'name' => 'enhancement'
  212. )
  213. )
  214. )
  215. );
  216. $obj = Xml::fromArray($xml, 'attributes');
  217. $this->assertTrue($obj instanceof SimpleXMLElement);
  218. $this->assertEquals('tags', $obj->getName());
  219. $this->assertEquals(2, count($obj));
  220. $xmlText = <<<XML
  221. <?xml version="1.0" encoding="UTF-8"?>
  222. <tags>
  223. <tag id="1" name="defect"/>
  224. <tag id="2" name="enhancement"/>
  225. </tags>
  226. XML;
  227. $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
  228. $obj = Xml::fromArray($xml);
  229. $this->assertTrue($obj instanceof SimpleXMLElement);
  230. $this->assertEquals('tags', $obj->getName());
  231. $this->assertEquals(2, count($obj));
  232. $xmlText = <<<XML
  233. <?xml version="1.0" encoding="UTF-8"?>
  234. <tags>
  235. <tag>
  236. <id>1</id>
  237. <name>defect</name>
  238. </tag>
  239. <tag>
  240. <id>2</id>
  241. <name>enhancement</name>
  242. </tag>
  243. </tags>
  244. XML;
  245. $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
  246. $xml = array(
  247. 'tags' => array(
  248. )
  249. );
  250. $obj = Xml::fromArray($xml);
  251. $this->assertEquals('tags', $obj->getName());
  252. $this->assertEquals('', (string)$obj);
  253. $xml = array(
  254. 'tags' => array(
  255. 'bool' => true,
  256. 'int' => 1,
  257. 'float' => 10.2,
  258. 'string' => 'ok',
  259. 'null' => null,
  260. 'array' => array()
  261. )
  262. );
  263. $obj = Xml::fromArray($xml, 'tags');
  264. $this->assertEquals(6, count($obj));
  265. $this->assertSame((string)$obj->bool, '1');
  266. $this->assertSame((string)$obj->int, '1');
  267. $this->assertSame((string)$obj->float, '10.2');
  268. $this->assertSame((string)$obj->string, 'ok');
  269. $this->assertSame((string)$obj->null, '');
  270. $this->assertSame((string)$obj->array, '');
  271. $xml = array(
  272. 'tags' => array(
  273. 'tag' => array(
  274. array(
  275. '@id' => '1',
  276. 'name' => 'defect'
  277. ),
  278. array(
  279. '@id' => '2',
  280. 'name' => 'enhancement'
  281. )
  282. )
  283. )
  284. );
  285. $obj = Xml::fromArray($xml, 'tags');
  286. $xmlText = <<<XML
  287. <?xml version="1.0" encoding="UTF-8"?>
  288. <tags>
  289. <tag id="1">
  290. <name>defect</name>
  291. </tag>
  292. <tag id="2">
  293. <name>enhancement</name>
  294. </tag>
  295. </tags>
  296. XML;
  297. $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
  298. $xml = array(
  299. 'tags' => array(
  300. 'tag' => array(
  301. array(
  302. '@id' => '1',
  303. 'name' => 'defect',
  304. '@' => 'Tag 1'
  305. ),
  306. array(
  307. '@id' => '2',
  308. 'name' => 'enhancement'
  309. ),
  310. ),
  311. '@' => 'All tags'
  312. )
  313. );
  314. $obj = Xml::fromArray($xml, 'tags');
  315. $xmlText = <<<XML
  316. <?xml version="1.0" encoding="UTF-8"?>
  317. <tags>All tags<tag id="1">Tag 1<name>defect</name></tag><tag id="2"><name>enhancement</name></tag></tags>
  318. XML;
  319. $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
  320. $xml = array(
  321. 'tags' => array(
  322. 'tag' => array(
  323. 'id' => 1,
  324. '@' => 'defect'
  325. )
  326. )
  327. );
  328. $obj = Xml::fromArray($xml, 'attributes');
  329. $xmlText = '<' . '?xml version="1.0" encoding="UTF-8"?><tags><tag id="1">defect</tag></tags>';
  330. $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
  331. }
  332. /**
  333. * Test non-sequential keys in list types.
  334. *
  335. * @return void
  336. */
  337. public function testFromArrayNonSequentialKeys() {
  338. $xmlArray = array(
  339. 'Event' => array(
  340. array(
  341. 'id' => '235',
  342. 'Attribute' => array(
  343. 0 => array(
  344. 'id' => '9646',
  345. ),
  346. 2 => array(
  347. 'id' => '9647',
  348. )
  349. )
  350. )
  351. )
  352. );
  353. $obj = Xml::fromArray($xmlArray);
  354. $expected = <<<XML
  355. <?xml version="1.0" encoding="UTF-8"?>
  356. <Event>
  357. <id>235</id>
  358. <Attribute>
  359. <id>9646</id>
  360. </Attribute>
  361. <Attribute>
  362. <id>9647</id>
  363. </Attribute>
  364. </Event>
  365. XML;
  366. $this->assertXmlStringEqualsXmlString($expected, $obj->asXML());
  367. }
  368. /**
  369. * data provider for fromArray() failures
  370. *
  371. * @return array
  372. */
  373. public static function invalidArrayDataProvider() {
  374. return array(
  375. array(''),
  376. array(null),
  377. array(false),
  378. array(array()),
  379. array(array('numeric key as root')),
  380. array(array('item1' => '', 'item2' => '')),
  381. array(array('items' => array('item1', 'item2'))),
  382. array(array(
  383. 'tags' => array(
  384. 'tag' => array(
  385. array(
  386. array(
  387. 'string'
  388. )
  389. )
  390. )
  391. )
  392. )),
  393. array(array(
  394. 'tags' => array(
  395. '@tag' => array(
  396. array(
  397. '@id' => '1',
  398. 'name' => 'defect'
  399. ),
  400. array(
  401. '@id' => '2',
  402. 'name' => 'enhancement'
  403. )
  404. )
  405. )
  406. )),
  407. array(new DateTime())
  408. );
  409. }
  410. /**
  411. * testFromArrayFail method
  412. *
  413. * @dataProvider invalidArrayDataProvider
  414. */
  415. public function testFromArrayFail($value) {
  416. try {
  417. Xml::fromArray($value);
  418. $this->fail('No exception.');
  419. } catch (Exception $e) {
  420. $this->assertTrue(true, 'Caught exception.');
  421. }
  422. }
  423. /**
  424. * testToArray method
  425. *
  426. * @return void
  427. */
  428. public function testToArray() {
  429. $xml = '<tag>name</tag>';
  430. $obj = Xml::build($xml);
  431. $this->assertEquals(array('tag' => 'name'), Xml::toArray($obj));
  432. $xml = CAKE . 'Test' . DS . 'Fixture' . DS . 'sample.xml';
  433. $obj = Xml::build($xml);
  434. $expected = array(
  435. 'tags' => array(
  436. 'tag' => array(
  437. array(
  438. '@id' => '1',
  439. 'name' => 'defect'
  440. ),
  441. array(
  442. '@id' => '2',
  443. 'name' => 'enhancement'
  444. )
  445. )
  446. )
  447. );
  448. $this->assertEquals($expected, Xml::toArray($obj));
  449. $array = array(
  450. 'tags' => array(
  451. 'tag' => array(
  452. array(
  453. 'id' => '1',
  454. 'name' => 'defect'
  455. ),
  456. array(
  457. 'id' => '2',
  458. 'name' => 'enhancement'
  459. )
  460. )
  461. )
  462. );
  463. $this->assertEquals(Xml::toArray(Xml::fromArray($array, 'tags')), $array);
  464. $expected = array(
  465. 'tags' => array(
  466. 'tag' => array(
  467. array(
  468. '@id' => '1',
  469. '@name' => 'defect'
  470. ),
  471. array(
  472. '@id' => '2',
  473. '@name' => 'enhancement'
  474. )
  475. )
  476. )
  477. );
  478. $this->assertEquals($expected, Xml::toArray(Xml::fromArray($array, 'attributes')));
  479. $this->assertEquals($expected, Xml::toArray(Xml::fromArray($array, array('return' => 'domdocument', 'format' => 'attributes'))));
  480. $this->assertEquals(Xml::toArray(Xml::fromArray($array)), $array);
  481. $this->assertEquals(Xml::toArray(Xml::fromArray($array, array('return' => 'domdocument'))), $array);
  482. $array = array(
  483. 'tags' => array(
  484. 'tag' => array(
  485. 'id' => '1',
  486. 'posts' => array(
  487. array('id' => '1'),
  488. array('id' => '2')
  489. )
  490. ),
  491. 'tagOther' => array(
  492. 'subtag' => array(
  493. 'id' => '1'
  494. )
  495. )
  496. )
  497. );
  498. $expected = array(
  499. 'tags' => array(
  500. 'tag' => array(
  501. '@id' => '1',
  502. 'posts' => array(
  503. array('@id' => '1'),
  504. array('@id' => '2')
  505. )
  506. ),
  507. 'tagOther' => array(
  508. 'subtag' => array(
  509. '@id' => '1'
  510. )
  511. )
  512. )
  513. );
  514. $this->assertEquals($expected, Xml::toArray(Xml::fromArray($array, 'attributes')));
  515. $this->assertEquals($expected, Xml::toArray(Xml::fromArray($array, array('format' => 'attributes', 'return' => 'domdocument'))));
  516. $xml = <<<XML
  517. <root>
  518. <tag id="1">defect</tag>
  519. </root>
  520. XML;
  521. $obj = Xml::build($xml);
  522. $expected = array(
  523. 'root' => array(
  524. 'tag' => array(
  525. '@id' => 1,
  526. '@' => 'defect'
  527. )
  528. )
  529. );
  530. $this->assertEquals($expected, Xml::toArray($obj));
  531. $xml = <<<XML
  532. <root>
  533. <table xmlns="http://www.w3.org/TR/html4/"><tr><td>Apples</td><td>Bananas</td></tr></table>
  534. <table xmlns="http://www.cakephp.org"><name>CakePHP</name><license>MIT</license></table>
  535. <table>The book is on the table.</table>
  536. </root>
  537. XML;
  538. $obj = Xml::build($xml);
  539. $expected = array(
  540. 'root' => array(
  541. 'table' => array(
  542. array('tr' => array('td' => array('Apples', 'Bananas'))),
  543. array('name' => 'CakePHP', 'license' => 'MIT'),
  544. 'The book is on the table.'
  545. )
  546. )
  547. );
  548. $this->assertEquals($expected, Xml::toArray($obj));
  549. $xml = <<<XML
  550. <root xmlns:cake="http://www.cakephp.org/">
  551. <tag>defect</tag>
  552. <cake:bug>1</cake:bug>
  553. </root>
  554. XML;
  555. $obj = Xml::build($xml);
  556. $expected = array(
  557. 'root' => array(
  558. 'tag' => 'defect',
  559. 'cake:bug' => 1
  560. )
  561. );
  562. $this->assertEquals($expected, Xml::toArray($obj));
  563. }
  564. /**
  565. * testRss
  566. *
  567. * @return void
  568. */
  569. public function testRss() {
  570. $rss = file_get_contents(CAKE . 'Test' . DS . 'Fixture' . DS . 'rss.xml');
  571. $rssAsArray = Xml::toArray(Xml::build($rss));
  572. $this->assertEquals('2.0', $rssAsArray['rss']['@version']);
  573. $this->assertEquals(2, count($rssAsArray['rss']['channel']['item']));
  574. $atomLink = array('@href' => 'http://bakery.cakephp.org/articles/rss', '@rel' => 'self', '@type' => 'application/rss+xml');
  575. $this->assertEquals($rssAsArray['rss']['channel']['atom:link'], $atomLink);
  576. $this->assertEquals('http://bakery.cakephp.org/', $rssAsArray['rss']['channel']['link']);
  577. $expected = array(
  578. 'title' => 'Alertpay automated sales via IPN',
  579. 'link' => 'http://bakery.cakephp.org/articles/view/alertpay-automated-sales-via-ipn',
  580. 'description' => 'I\'m going to show you how I implemented a payment module via the Alertpay payment processor.',
  581. 'pubDate' => 'Tue, 31 Aug 2010 01:42:00 -0500',
  582. 'guid' => 'http://bakery.cakephp.org/articles/view/alertpay-automated-sales-via-ipn'
  583. );
  584. $this->assertSame($rssAsArray['rss']['channel']['item'][1], $expected);
  585. $rss = array(
  586. 'rss' => array(
  587. 'xmlns:atom' => 'http://www.w3.org/2005/Atom',
  588. '@version' => '2.0',
  589. 'channel' => array(
  590. 'atom:link' => array(
  591. '@href' => 'http://bakery.cakephp.org/articles/rss',
  592. '@rel' => 'self',
  593. '@type' => 'application/rss+xml'
  594. ),
  595. 'title' => 'The Bakery: ',
  596. 'link' => 'http://bakery.cakephp.org/',
  597. 'description' => 'Recent Articles at The Bakery.',
  598. 'pubDate' => 'Sun, 12 Sep 2010 04:18:26 -0500',
  599. 'item' => array(
  600. array(
  601. 'title' => 'CakePHP 1.3.4 released',
  602. 'link' => 'http://bakery.cakephp.org/articles/view/cakephp-1-3-4-released'
  603. ),
  604. array(
  605. 'title' => 'Wizard Component 1.2 Tutorial',
  606. 'link' => 'http://bakery.cakephp.org/articles/view/wizard-component-1-2-tutorial'
  607. )
  608. )
  609. )
  610. )
  611. );
  612. $rssAsSimpleXML = Xml::fromArray($rss);
  613. $xmlText = <<<XML
  614. <?xml version="1.0" encoding="UTF-8"?>
  615. <rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
  616. <channel>
  617. <atom:link href="http://bakery.cakephp.org/articles/rss" rel="self" type="application/rss+xml"/>
  618. <title>The Bakery: </title>
  619. <link>http://bakery.cakephp.org/</link>
  620. <description>Recent Articles at The Bakery.</description>
  621. <pubDate>Sun, 12 Sep 2010 04:18:26 -0500</pubDate>
  622. <item>
  623. <title>CakePHP 1.3.4 released</title>
  624. <link>http://bakery.cakephp.org/articles/view/cakephp-1-3-4-released</link>
  625. </item>
  626. <item>
  627. <title>Wizard Component 1.2 Tutorial</title>
  628. <link>http://bakery.cakephp.org/articles/view/wizard-component-1-2-tutorial</link>
  629. </item>
  630. </channel>
  631. </rss>
  632. XML;
  633. $this->assertXmlStringEqualsXmlString($xmlText, $rssAsSimpleXML->asXML());
  634. }
  635. /**
  636. * testXmlRpc
  637. *
  638. * @return void
  639. */
  640. public function testXmlRpc() {
  641. $xml = Xml::build('<methodCall><methodName>test</methodName><params /></methodCall>');
  642. $expected = array(
  643. 'methodCall' => array(
  644. 'methodName' => 'test',
  645. 'params' => ''
  646. )
  647. );
  648. $this->assertSame(Xml::toArray($xml), $expected);
  649. $xml = Xml::build('<methodCall><methodName>test</methodName><params><param><value><array><data><value><int>12</int></value><value><string>Egypt</string></value><value><boolean>0</boolean></value><value><int>-31</int></value></data></array></value></param></params></methodCall>');
  650. $expected = array(
  651. 'methodCall' => array(
  652. 'methodName' => 'test',
  653. 'params' => array(
  654. 'param' => array(
  655. 'value' => array(
  656. 'array' => array(
  657. 'data' => array(
  658. 'value' => array(
  659. array('int' => '12'),
  660. array('string' => 'Egypt'),
  661. array('boolean' => '0'),
  662. array('int' => '-31')
  663. )
  664. )
  665. )
  666. )
  667. )
  668. )
  669. )
  670. );
  671. $this->assertSame(Xml::toArray($xml), $expected);
  672. $xmlText = <<<XML
  673. <?xml version="1.0" encoding="UTF-8"?>
  674. <methodResponse>
  675. <params>
  676. <param>
  677. <value>
  678. <array>
  679. <data>
  680. <value>
  681. <int>1</int>
  682. </value>
  683. <value>
  684. <string>testing</string>
  685. </value>
  686. </data>
  687. </array>
  688. </value>
  689. </param>
  690. </params>
  691. </methodResponse>
  692. XML;
  693. $xml = Xml::build($xmlText);
  694. $expected = array(
  695. 'methodResponse' => array(
  696. 'params' => array(
  697. 'param' => array(
  698. 'value' => array(
  699. 'array' => array(
  700. 'data' => array(
  701. 'value' => array(
  702. array('int' => '1'),
  703. array('string' => 'testing')
  704. )
  705. )
  706. )
  707. )
  708. )
  709. )
  710. )
  711. );
  712. $this->assertSame(Xml::toArray($xml), $expected);
  713. $xml = Xml::fromArray($expected, 'tags');
  714. $this->assertXmlStringEqualsXmlString($xmlText, $xml->asXML());
  715. }
  716. /**
  717. * testSoap
  718. *
  719. * @return void
  720. */
  721. public function testSoap() {
  722. $xmlRequest = Xml::build(CAKE . 'Test' . DS . 'Fixture' . DS . 'soap_request.xml');
  723. $expected = array(
  724. 'Envelope' => array(
  725. '@soap:encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding',
  726. 'soap:Body' => array(
  727. 'm:GetStockPrice' => array(
  728. 'm:StockName' => 'IBM'
  729. )
  730. )
  731. )
  732. );
  733. $this->assertEquals($expected, Xml::toArray($xmlRequest));
  734. $xmlResponse = Xml::build(CAKE . 'Test' . DS . 'Fixture' . DS . 'soap_response.xml');
  735. $expected = array(
  736. 'Envelope' => array(
  737. '@soap:encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding',
  738. 'soap:Body' => array(
  739. 'm:GetStockPriceResponse' => array(
  740. 'm:Price' => '34.5'
  741. )
  742. )
  743. )
  744. );
  745. $this->assertEquals($expected, Xml::toArray($xmlResponse));
  746. $xml = array(
  747. 'soap:Envelope' => array(
  748. 'xmlns:soap' => 'http://www.w3.org/2001/12/soap-envelope',
  749. '@soap:encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding',
  750. 'soap:Body' => array(
  751. 'xmlns:m' => 'http://www.example.org/stock',
  752. 'm:GetStockPrice' => array(
  753. 'm:StockName' => 'IBM'
  754. )
  755. )
  756. )
  757. );
  758. $xmlRequest = Xml::fromArray($xml, array('encoding' => null));
  759. $xmlText = <<<XML
  760. <?xml version="1.0"?>
  761. <soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
  762. <soap:Body xmlns:m="http://www.example.org/stock">
  763. <m:GetStockPrice><m:StockName>IBM</m:StockName></m:GetStockPrice>
  764. </soap:Body>
  765. </soap:Envelope>
  766. XML;
  767. $this->assertXmlStringEqualsXmlString($xmlText, $xmlRequest->asXML());
  768. }
  769. /**
  770. * testNamespace
  771. *
  772. * @return void
  773. */
  774. public function testNamespace() {
  775. $xml = <<<XML
  776. <root xmlns:ns="http://cakephp.org">
  777. <ns:tag id="1">
  778. <child>good</child>
  779. <otherchild>bad</otherchild>
  780. </ns:tag>
  781. <tag>Tag without ns</tag>
  782. </root>
  783. XML;
  784. $xmlResponse = Xml::build($xml);
  785. $expected = array(
  786. 'root' => array(
  787. 'ns:tag' => array(
  788. '@id' => '1',
  789. 'child' => 'good',
  790. 'otherchild' => 'bad'
  791. ),
  792. 'tag' => 'Tag without ns'
  793. )
  794. );
  795. $this->assertEquals($expected, Xml::toArray($xmlResponse));
  796. $xmlResponse = Xml::build('<root xmlns:ns="http://cakephp.org"><ns:tag id="1" /><tag><id>1</id></tag></root>');
  797. $expected = array(
  798. 'root' => array(
  799. 'ns:tag' => array(
  800. '@id' => '1'
  801. ),
  802. 'tag' => array(
  803. 'id' => '1'
  804. )
  805. )
  806. );
  807. $this->assertEquals($expected, Xml::toArray($xmlResponse));
  808. $xmlResponse = Xml::build('<root xmlns:ns="http://cakephp.org"><ns:attr>1</ns:attr></root>');
  809. $expected = array(
  810. 'root' => array(
  811. 'ns:attr' => '1'
  812. )
  813. );
  814. $this->assertEquals($expected, Xml::toArray($xmlResponse));
  815. $xmlResponse = Xml::build('<root><ns:attr xmlns:ns="http://cakephp.org">1</ns:attr></root>');
  816. $this->assertEquals($expected, Xml::toArray($xmlResponse));
  817. $xml = array(
  818. 'root' => array(
  819. 'ns:attr' => array(
  820. 'xmlns:ns' => 'http://cakephp.org',
  821. '@' => 1
  822. )
  823. )
  824. );
  825. $expected = '<' . '?xml version="1.0" encoding="UTF-8"?><root><ns:attr xmlns:ns="http://cakephp.org">1</ns:attr></root>';
  826. $xmlResponse = Xml::fromArray($xml);
  827. $this->assertEquals(str_replace(array("\r", "\n"), '', $xmlResponse->asXML()), $expected);
  828. $xml = array(
  829. 'root' => array(
  830. 'tag' => array(
  831. 'xmlns:pref' => 'http://cakephp.org',
  832. 'pref:item' => array(
  833. 'item 1',
  834. 'item 2'
  835. )
  836. )
  837. )
  838. );
  839. $expected = <<<XML
  840. <?xml version="1.0" encoding="UTF-8"?>
  841. <root>
  842. <tag xmlns:pref="http://cakephp.org">
  843. <pref:item>item 1</pref:item>
  844. <pref:item>item 2</pref:item>
  845. </tag>
  846. </root>
  847. XML;
  848. $xmlResponse = Xml::fromArray($xml);
  849. $this->assertXmlStringEqualsXmlString($expected, $xmlResponse->asXML());
  850. $xml = array(
  851. 'root' => array(
  852. 'tag' => array(
  853. 'xmlns:' => 'http://cakephp.org'
  854. )
  855. )
  856. );
  857. $expected = '<' . '?xml version="1.0" encoding="UTF-8"?><root><tag xmlns="http://cakephp.org"/></root>';
  858. $xmlResponse = Xml::fromArray($xml);
  859. $this->assertXmlStringEqualsXmlString($expected, $xmlResponse->asXML());
  860. $xml = array(
  861. 'root' => array(
  862. 'xmlns:' => 'http://cakephp.org'
  863. )
  864. );
  865. $expected = '<' . '?xml version="1.0" encoding="UTF-8"?><root xmlns="http://cakephp.org"/>';
  866. $xmlResponse = Xml::fromArray($xml);
  867. $this->assertXmlStringEqualsXmlString($expected, $xmlResponse->asXML());
  868. $xml = array(
  869. 'root' => array(
  870. 'xmlns:ns' => 'http://cakephp.org'
  871. )
  872. );
  873. $expected = '<' . '?xml version="1.0" encoding="UTF-8"?><root xmlns:ns="http://cakephp.org"/>';
  874. $xmlResponse = Xml::fromArray($xml);
  875. $this->assertXmlStringEqualsXmlString($expected, $xmlResponse->asXML());
  876. }
  877. /**
  878. * test that CDATA blocks don't get screwed up by SimpleXml
  879. *
  880. * @return void
  881. */
  882. public function testCdata() {
  883. $xml = '<' . '?xml version="1.0" encoding="UTF-8"?>' .
  884. '<people><name><![CDATA[ Mark ]]></name></people>';
  885. $result = Xml::build($xml);
  886. $this->assertEquals(' Mark ', (string)$result->name);
  887. }
  888. /**
  889. * data provider for toArray() failures
  890. *
  891. * @return array
  892. */
  893. public static function invalidToArrayDataProvider() {
  894. return array(
  895. array(new DateTime()),
  896. array(array())
  897. );
  898. }
  899. /**
  900. * testToArrayFail method
  901. *
  902. * @dataProvider invalidToArrayDataProvider
  903. * @expectedException XmlException
  904. */
  905. public function testToArrayFail($value) {
  906. Xml::toArray($value);
  907. }
  908. /**
  909. * testWithModel method
  910. *
  911. * @return void
  912. */
  913. public function testWithModel() {
  914. $this->loadFixtures('User', 'Article');
  915. $user = new XmlUser();
  916. $data = $user->read(null, 1);
  917. $obj = Xml::build(compact('data'));
  918. $expected = <<<XML
  919. <?xml version="1.0" encoding="UTF-8"?><data>
  920. <User><id>1</id><user>mariano</user><password>5f4dcc3b5aa765d61d8327deb882cf99</password>
  921. <created>2007-03-17 01:16:23</created><updated>2007-03-17 01:18:31</updated></User>
  922. <Article><id>1</id><user_id>1</user_id><title>First Article</title><body>First Article Body</body>
  923. <published>Y</published><created>2007-03-18 10:39:23</created><updated>2007-03-18 10:41:31</updated></Article>
  924. <Article><id>3</id><user_id>1</user_id><title>Third Article</title><body>Third Article Body</body>
  925. <published>Y</published><created>2007-03-18 10:43:23</created><updated>2007-03-18 10:45:31</updated></Article>
  926. </data>
  927. XML;
  928. $this->assertXmlStringEqualsXmlString($expected, $obj->asXML());
  929. //multiple model results - without a records key it would fatal error
  930. $data = $user->find('all', array('limit' => 2));
  931. $data = array('records' => $data);
  932. $obj = Xml::build(compact('data'));
  933. $expected = <<<XML
  934. <?xml version="1.0" encoding="UTF-8"?><data>
  935. <records>
  936. <User><id>1</id><user>mariano</user><password>5f4dcc3b5aa765d61d8327deb882cf99</password>
  937. <created>2007-03-17 01:16:23</created><updated>2007-03-17 01:18:31</updated></User>
  938. <Article><id>1</id><user_id>1</user_id><title>First Article</title><body>First Article Body</body>
  939. <published>Y</published><created>2007-03-18 10:39:23</created><updated>2007-03-18 10:41:31</updated></Article>
  940. <Article><id>3</id><user_id>1</user_id><title>Third Article</title><body>Third Article Body</body>
  941. <published>Y</published><created>2007-03-18 10:43:23</created><updated>2007-03-18 10:45:31</updated></Article>
  942. </records><records><User><id>2</id><user>nate</user><password>5f4dcc3b5aa765d61d8327deb882cf99</password>
  943. <created>2007-03-17 01:18:23</created><updated>2007-03-17 01:20:31</updated></User><Article/>
  944. </records>
  945. </data>
  946. XML;
  947. $obj->asXML();
  948. $this->assertXmlStringEqualsXmlString($expected, $obj->asXML());
  949. }
  950. /**
  951. * Test ampersand in text elements.
  952. *
  953. * @return void
  954. */
  955. public function testAmpInText() {
  956. $data = array(
  957. 'outer' => array(
  958. 'inner' => array('name' => 'mark & mark')
  959. )
  960. );
  961. $obj = Xml::build($data);
  962. $result = $obj->asXml();
  963. $this->assertContains('mark &amp; mark', $result);
  964. }
  965. /**
  966. * Test that entity loading is disabled by default.
  967. *
  968. * @return void
  969. */
  970. public function testNoEntityLoading() {
  971. $file = CAKE . 'VERSION.txt';
  972. $xml = <<<XML
  973. <!DOCTYPE cakephp [
  974. <!ENTITY payload SYSTEM "file://$file" >]>
  975. <request>
  976. <xxe>&payload;</xxe>
  977. </request>
  978. XML;
  979. try {
  980. $result = Xml::build($xml);
  981. $this->assertEquals('', (string)$result->xxe);
  982. } catch (Exception $e) {
  983. $this->assertTrue(true, 'A warning was raised meaning external entities were not loaded');
  984. }
  985. }
  986. }