/iti-note-rest-client-php/vendor/guzzle/guzzle/tests/Guzzle/Tests/Service/Command/LocationVisitor/Request/XmlVisitorTest.php

https://bitbucket.org/alessandro-aglietti/itis-leonardo-da-vinci · PHP · 540 lines · 500 code · 23 blank · 17 comment · 2 complexity · 216f201286c9beaa6664d7a55fce8dfc MD5 · raw file

  1. <?php
  2. namespace Guzzle\Tests\Service\Command\LocationVisitor\Request;
  3. use Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor;
  4. use Guzzle\Service\Client;
  5. use Guzzle\Service\Description\Parameter;
  6. use Guzzle\Service\Description\Operation;
  7. use Guzzle\Http\Message\EntityEnclosingRequest;
  8. /**
  9. * @covers Guzzle\Service\Command\LocationVisitor\Request\XmlVisitor
  10. */
  11. class XmlVisitorTest extends AbstractVisitorTestCase
  12. {
  13. public function xmlProvider()
  14. {
  15. return array(
  16. array(
  17. array(
  18. 'data' => array(
  19. 'xmlRoot' => array(
  20. 'name' => 'test',
  21. 'namespaces' => 'http://foo.com'
  22. )
  23. ),
  24. 'parameters' => array(
  25. 'Foo' => array('location' => 'xml', 'type' => 'string'),
  26. 'Baz' => array('location' => 'xml', 'type' => 'string')
  27. )
  28. ),
  29. array('Foo' => 'test', 'Baz' => 'bar'),
  30. '<test xmlns="http://foo.com"><Foo>test</Foo><Baz>bar</Baz></test>'
  31. ),
  32. // Ensure that the content-type is not added
  33. array(array('parameters' => array('Foo' => array('location' => 'xml', 'type' => 'string'))), array(), ''),
  34. // Test with adding attributes and no namespace
  35. array(
  36. array(
  37. 'data' => array(
  38. 'xmlRoot' => array(
  39. 'name' => 'test'
  40. )
  41. ),
  42. 'parameters' => array(
  43. 'Foo' => array('location' => 'xml', 'type' => 'string', 'data' => array('xmlAttribute' => true))
  44. )
  45. ),
  46. array('Foo' => 'test', 'Baz' => 'bar'),
  47. '<test Foo="test"/>'
  48. ),
  49. // Test adding with an array
  50. array(
  51. array(
  52. 'parameters' => array(
  53. 'Foo' => array('location' => 'xml', 'type' => 'string'),
  54. 'Baz' => array(
  55. 'type' => 'array',
  56. 'location' => 'xml',
  57. 'items' => array(
  58. 'type' => 'numeric',
  59. 'sentAs' => 'Bar'
  60. )
  61. )
  62. )
  63. ),
  64. array('Foo' => 'test', 'Baz' => array(1, 2)),
  65. '<Request><Foo>test</Foo><Baz><Bar>1</Bar><Bar>2</Bar></Baz></Request>'
  66. ),
  67. // Test adding an object
  68. array(
  69. array(
  70. 'parameters' => array(
  71. 'Foo' => array('location' => 'xml', 'type' => 'string'),
  72. 'Baz' => array(
  73. 'type' => 'object',
  74. 'location' => 'xml',
  75. 'properties' => array(
  76. 'Bar' => array('type' => 'string'),
  77. 'Bam' => array()
  78. )
  79. )
  80. )
  81. ),
  82. array('Foo' => 'test', 'Baz' => array('Bar' => 'abc', 'Bam' => 'foo')),
  83. '<Request><Foo>test</Foo><Baz><Bar>abc</Bar><Bam>foo</Bam></Baz></Request>'
  84. ),
  85. // Add an array that contains an object
  86. array(
  87. array(
  88. 'parameters' => array(
  89. 'Baz' => array(
  90. 'type' => 'array',
  91. 'location' => 'xml',
  92. 'items' => array(
  93. 'type' => 'object',
  94. 'sentAs' => 'Bar',
  95. 'properties' => array('A' => array(), 'B' => array())
  96. )
  97. )
  98. )
  99. ),
  100. array('Baz' => array(
  101. array('A' => '1', 'B' => '2'),
  102. array('A' => '3', 'B' => '4')
  103. )),
  104. '<Request><Baz><Bar><A>1</A><B>2</B></Bar><Bar><A>3</A><B>4</B></Bar></Baz></Request>'
  105. ),
  106. // Add an object of attributes
  107. array(
  108. array(
  109. 'parameters' => array(
  110. 'Foo' => array('location' => 'xml', 'type' => 'string'),
  111. 'Baz' => array(
  112. 'type' => 'object',
  113. 'location' => 'xml',
  114. 'properties' => array(
  115. 'Bar' => array('type' => 'string', 'data' => array('xmlAttribute' => true)),
  116. 'Bam' => array()
  117. )
  118. )
  119. )
  120. ),
  121. array('Foo' => 'test', 'Baz' => array('Bar' => 'abc', 'Bam' => 'foo')),
  122. '<Request><Foo>test</Foo><Baz Bar="abc"><Bam>foo</Bam></Baz></Request>'
  123. ),
  124. // Add values with custom namespaces
  125. array(
  126. array(
  127. 'parameters' => array(
  128. 'Foo' => array(
  129. 'location' => 'xml',
  130. 'type' => 'string',
  131. 'data' => array(
  132. 'xmlNamespace' => 'http://foo.com'
  133. )
  134. )
  135. )
  136. ),
  137. array('Foo' => 'test'),
  138. '<Request><Foo xmlns="http://foo.com">test</Foo></Request>'
  139. ),
  140. // Add attributes with custom namespace prefix
  141. array(
  142. array(
  143. 'parameters' => array(
  144. 'Wrap' => array(
  145. 'type' => 'object',
  146. 'location' => 'xml',
  147. 'properties' => array(
  148. 'Foo' => array(
  149. 'type' => 'string',
  150. 'sentAs' => 'xsi:baz',
  151. 'data' => array(
  152. 'xmlNamespace' => 'http://foo.com',
  153. 'xmlAttribute' => true
  154. )
  155. )
  156. )
  157. ),
  158. )
  159. ),
  160. array('Wrap' => array(
  161. 'Foo' => 'test'
  162. )),
  163. '<Request><Wrap xsi:baz="test" xmlns:xsi="http://foo.com"/></Request>'
  164. ),
  165. // Add nodes with custom namespace prefix
  166. array(
  167. array(
  168. 'parameters' => array(
  169. 'Wrap' => array(
  170. 'type' => 'object',
  171. 'location' => 'xml',
  172. 'properties' => array(
  173. 'Foo' => array(
  174. 'type' => 'string',
  175. 'sentAs' => 'xsi:Foo',
  176. 'data' => array(
  177. 'xmlNamespace' => 'http://foobar.com'
  178. )
  179. )
  180. )
  181. ),
  182. )
  183. ),
  184. array('Wrap' => array(
  185. 'Foo' => 'test'
  186. )),
  187. '<Request><Wrap><xsi:Foo xmlns:xsi="http://foobar.com">test</xsi:Foo></Wrap></Request>'
  188. ),
  189. array(
  190. array(
  191. 'parameters' => array(
  192. 'Foo' => array(
  193. 'location' => 'xml',
  194. 'type' => 'string',
  195. 'data' => array(
  196. 'xmlNamespace' => 'http://foo.com'
  197. )
  198. )
  199. )
  200. ),
  201. array('Foo' => '<h1>This is a title</h1>'),
  202. '<Request><Foo xmlns="http://foo.com"><![CDATA[<h1>This is a title</h1>]]></Foo></Request>'
  203. ),
  204. // Flat array at top level
  205. array(
  206. array(
  207. 'parameters' => array(
  208. 'Bars' => array(
  209. 'type' => 'array',
  210. 'data' => array('xmlFlattened' => true),
  211. 'location' => 'xml',
  212. 'items' => array(
  213. 'type' => 'object',
  214. 'sentAs' => 'Bar',
  215. 'properties' => array(
  216. 'A' => array(),
  217. 'B' => array()
  218. )
  219. )
  220. ),
  221. 'Boos' => array(
  222. 'type' => 'array',
  223. 'data' => array('xmlFlattened' => true),
  224. 'location' => 'xml',
  225. 'items' => array(
  226. 'sentAs' => 'Boo',
  227. 'type' => 'string'
  228. )
  229. )
  230. )
  231. ),
  232. array(
  233. 'Bars' => array(
  234. array('A' => '1', 'B' => '2'),
  235. array('A' => '3', 'B' => '4')
  236. ),
  237. 'Boos' => array('test', '123')
  238. ),
  239. '<Request><Bar><A>1</A><B>2</B></Bar><Bar><A>3</A><B>4</B></Bar><Boo>test</Boo><Boo>123</Boo></Request>'
  240. ),
  241. // Nested flat arrays
  242. array(
  243. array(
  244. 'parameters' => array(
  245. 'Delete' => array(
  246. 'type' => 'object',
  247. 'location' => 'xml',
  248. 'properties' => array(
  249. 'Items' => array(
  250. 'type' => 'array',
  251. 'data' => array('xmlFlattened' => true),
  252. 'items' => array(
  253. 'type' => 'object',
  254. 'sentAs' => 'Item',
  255. 'properties' => array(
  256. 'A' => array(),
  257. 'B' => array()
  258. )
  259. )
  260. )
  261. )
  262. )
  263. )
  264. ),
  265. array(
  266. 'Delete' => array(
  267. 'Items' => array(
  268. array('A' => '1', 'B' => '2'),
  269. array('A' => '3', 'B' => '4')
  270. )
  271. )
  272. ),
  273. '<Request><Delete><Item><A>1</A><B>2</B></Item><Item><A>3</A><B>4</B></Item></Delete></Request>'
  274. )
  275. );
  276. }
  277. /**
  278. * @dataProvider xmlProvider
  279. */
  280. public function testSerializesXml(array $operation, array $input, $xml)
  281. {
  282. $operation = new Operation($operation);
  283. $command = $this->getMockBuilder('Guzzle\Service\Command\OperationCommand')
  284. ->setConstructorArgs(array($input, $operation))
  285. ->getMockForAbstractClass();
  286. $command->setClient(new Client());
  287. $request = $command->prepare();
  288. if (!empty($input)) {
  289. $this->assertEquals('application/xml', (string) $request->getHeader('Content-Type'));
  290. } else {
  291. $this->assertNull($request->getHeader('Content-Type'));
  292. }
  293. $body = str_replace(array("\n", "<?xml version=\"1.0\"?>"), '', (string) $request->getBody());
  294. $this->assertEquals($xml, $body);
  295. }
  296. public function testAddsContentTypeAndTopLevelValues()
  297. {
  298. $operation = new Operation(array(
  299. 'data' => array(
  300. 'xmlRoot' => array(
  301. 'name' => 'test',
  302. 'namespaces' => array(
  303. 'xsi' => 'http://foo.com'
  304. )
  305. )
  306. ),
  307. 'parameters' => array(
  308. 'Foo' => array('location' => 'xml', 'type' => 'string'),
  309. 'Baz' => array('location' => 'xml', 'type' => 'string')
  310. )
  311. ));
  312. $command = $this->getMockBuilder('Guzzle\Service\Command\OperationCommand')
  313. ->setConstructorArgs(array(array(
  314. 'Foo' => 'test',
  315. 'Baz' => 'bar'
  316. ), $operation))
  317. ->getMockForAbstractClass();
  318. $command->setClient(new Client());
  319. $request = $command->prepare();
  320. $this->assertEquals('application/xml', (string) $request->getHeader('Content-Type'));
  321. $this->assertEquals(
  322. '<?xml version="1.0"?>' . "\n"
  323. . '<test xmlns:xsi="http://foo.com"><Foo>test</Foo><Baz>bar</Baz></test>' . "\n",
  324. (string) $request->getBody()
  325. );
  326. }
  327. public function testCanChangeContentType()
  328. {
  329. $visitor = new XmlVisitor();
  330. $visitor->setContentTypeHeader('application/foo');
  331. $this->assertEquals('application/foo', $this->readAttribute($visitor, 'contentType'));
  332. }
  333. public function testCanAddArrayOfSimpleTypes()
  334. {
  335. $request = new EntityEnclosingRequest('POST', 'http://foo.com');
  336. $visitor = new XmlVisitor();
  337. $param = new Parameter(array(
  338. 'type' => 'object',
  339. 'location' => 'xml',
  340. 'name' => 'Out',
  341. 'properties' => array(
  342. 'Nodes' => array(
  343. 'required' => true,
  344. 'type' => 'array',
  345. 'min' => 1,
  346. 'items' => array('type' => 'string', 'sentAs' => 'Node')
  347. )
  348. )
  349. ));
  350. $param->setParent(new Operation(array(
  351. 'data' => array(
  352. 'xmlRoot' => array(
  353. 'name' => 'Test',
  354. 'namespaces' => array(
  355. 'https://foo/'
  356. )
  357. )
  358. )
  359. )));
  360. $value = array('Nodes' => array('foo', 'baz'));
  361. $this->assertTrue($this->validator->validate($param, $value));
  362. $visitor->visit($this->command, $request, $param, $value);
  363. $visitor->after($this->command, $request);
  364. $this->assertEquals(
  365. "<?xml version=\"1.0\"?>\n"
  366. . "<Test xmlns=\"https://foo/\"><Out><Nodes><Node>foo</Node><Node>baz</Node></Nodes></Out></Test>\n",
  367. (string) $request->getBody()
  368. );
  369. }
  370. public function testCanAddMultipleNamespacesToRoot()
  371. {
  372. $operation = new Operation(array(
  373. 'data' => array(
  374. 'xmlRoot' => array(
  375. 'name' => 'Hi',
  376. 'namespaces' => array(
  377. 'xsi' => 'http://foo.com',
  378. 'foo' => 'http://foobar.com'
  379. )
  380. )
  381. ),
  382. 'parameters' => array(
  383. 'Foo' => array('location' => 'xml', 'type' => 'string')
  384. )
  385. ));
  386. $command = $this->getMockBuilder('Guzzle\Service\Command\OperationCommand')
  387. ->setConstructorArgs(array(array(
  388. 'Foo' => 'test'
  389. ), $operation))
  390. ->getMockForAbstractClass();
  391. $command->setClient(new Client());
  392. $request = $command->prepare();
  393. $this->assertEquals('application/xml', (string) $request->getHeader('Content-Type'));
  394. $this->assertEquals(
  395. '<?xml version="1.0"?>' . "\n"
  396. . '<Hi xmlns:xsi="http://foo.com" xmlns:foo="http://foobar.com"><Foo>test</Foo></Hi>' . "\n",
  397. (string) $request->getBody()
  398. );
  399. }
  400. public function testValuesAreFiltered()
  401. {
  402. $operation = new Operation(array(
  403. 'parameters' => array(
  404. 'Foo' => array(
  405. 'location' => 'xml',
  406. 'type' => 'string',
  407. 'filters' => array('strtoupper')
  408. ),
  409. 'Bar' => array(
  410. 'location' => 'xml',
  411. 'type' => 'object',
  412. 'properties' => array(
  413. 'Baz' => array(
  414. 'filters' => array('strtoupper')
  415. )
  416. )
  417. )
  418. )
  419. ));
  420. $command = $this->getMockBuilder('Guzzle\Service\Command\OperationCommand')
  421. ->setConstructorArgs(array(array(
  422. 'Foo' => 'test',
  423. 'Bar' => array(
  424. 'Baz' => 'abc'
  425. )
  426. ), $operation))
  427. ->getMockForAbstractClass();
  428. $command->setClient(new Client());
  429. $request = $command->prepare();
  430. $this->assertEquals(
  431. '<?xml version="1.0"?>' . "\n"
  432. . '<Request><Foo>TEST</Foo><Bar><Baz>ABC</Baz></Bar></Request>' . "\n",
  433. (string) $request->getBody()
  434. );
  435. }
  436. public function testSkipsNullValues()
  437. {
  438. $operation = new Operation(array(
  439. 'parameters' => array(
  440. 'Foo' => array(
  441. 'location' => 'xml',
  442. 'type' => 'string'
  443. ),
  444. 'Bar' => array(
  445. 'location' => 'xml',
  446. 'type' => 'object',
  447. 'properties' => array(
  448. 'Baz' => array(),
  449. 'Bam' => array(),
  450. )
  451. ),
  452. 'Arr' => array(
  453. 'type' => 'array',
  454. 'items' => array(
  455. 'type' => 'string'
  456. )
  457. )
  458. )
  459. ));
  460. $command = $this->getMockBuilder('Guzzle\Service\Command\OperationCommand')
  461. ->setConstructorArgs(array(array(
  462. 'Foo' => null,
  463. 'Bar' => array(
  464. 'Bar' => null,
  465. 'Bam' => 'test'
  466. ),
  467. 'Arr' => array(null)
  468. ), $operation))
  469. ->getMockForAbstractClass();
  470. $command->setClient(new Client());
  471. $request = $command->prepare();
  472. $this->assertEquals(
  473. '<?xml version="1.0"?>' . "\n"
  474. . '<Request><Bar><Bam>test</Bam></Bar></Request>' . "\n",
  475. (string) $request->getBody()
  476. );
  477. }
  478. public function testAllowsXmlEncoding()
  479. {
  480. $operation = new Operation(array(
  481. 'data' => array(
  482. 'xmlEncoding' => 'UTF-8'
  483. ),
  484. 'parameters' => array(
  485. 'Foo' => array('location' => 'xml')
  486. )
  487. ));
  488. $command = $this->getMockBuilder('Guzzle\Service\Command\OperationCommand')
  489. ->setConstructorArgs(array(array('Foo' => 'test'), $operation))
  490. ->getMockForAbstractClass();
  491. $command->setClient(new Client());
  492. $request = $command->prepare();
  493. $this->assertEquals(
  494. '<?xml version="1.0" encoding="UTF-8"?>' . "\n"
  495. . '<Request><Foo>test</Foo></Request>' . "\n",
  496. (string) $request->getBody()
  497. );
  498. }
  499. public function testAllowsSendingXmlPayloadIfNoXmlParamsWereSet()
  500. {
  501. $operation = new Operation(array(
  502. 'httpMethod' => 'POST',
  503. 'data' => array('xmlAllowEmpty' => true),
  504. 'parameters' => array('Foo' => array('location' => 'xml'))
  505. ));
  506. $command = $this->getMockBuilder('Guzzle\Service\Command\OperationCommand')
  507. ->setConstructorArgs(array(array(), $operation))
  508. ->getMockForAbstractClass();
  509. $command->setClient(new Client('http://foo.com'));
  510. $request = $command->prepare();
  511. $this->assertEquals(
  512. '<?xml version="1.0"?>' . "\n"
  513. . '<Request/>' . "\n",
  514. (string) $request->getBody()
  515. );
  516. }
  517. }