統計
| ブランチ: | リビジョン:

pictcode / lib / Cake / Test / Case / Utility / XmlTest.php @ 0b1b8047

履歴 | 表示 | アノテート | ダウンロード (29.569 KB)

1
<?php
2
/**
3
 * XmlTest file
4
 *
5
 * CakePHP(tm) Tests <http://book.cakephp.org/2.0/en/development/testing.html>
6
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
7
 *
8
 * Licensed under The MIT License
9
 * For full copyright and license information, please see the LICENSE.txt
10
 * Redistributions of files must retain the above copyright notice
11
 *
12
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
13
 * @link          http://book.cakephp.org/2.0/en/development/testing.html CakePHP(tm) Tests
14
 * @package       Cake.Test.Case.Utility
15
 * @since         CakePHP(tm) v 1.2.0.5432
16
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
17
 */
18

    
19
App::uses('Xml', 'Utility');
20
App::uses('CakeTestModel', 'TestSuite/Fixture');
21

    
22
/**
23
 * Article class
24
 *
25
 * @package       Cake.Test.Case.Utility
26
 */
27
class XmlArticle extends CakeTestModel {
28

    
29
/**
30
 * name property
31
 *
32
 * @var string
33
 */
34
        public $name = 'Article';
35

    
36
/**
37
 * belongsTo property
38
 *
39
 * @var array
40
 */
41
        public $belongsTo = array(
42
                'User' => array(
43
                        'className' => 'XmlUser',
44
                        'foreignKey' => 'user_id'
45
                )
46
        );
47
}
48

    
49
/**
50
 * User class
51
 *
52
 * @package       Cake.Test.Case.Utility
53
 */
54
class XmlUser extends CakeTestModel {
55

    
56
/**
57
 * name property
58
 *
59
 * @var string
60
 */
61
        public $name = 'User';
62

    
63
/**
64
 * hasMany property
65
 *
66
 * @var array
67
 */
68
        public $hasMany = array(
69
                'Article' => array(
70
                        'className' => 'XmlArticle'
71
                )
72
        );
73
}
74

    
75
/**
76
 * XmlTest class
77
 *
78
 * @package       Cake.Test.Case.Utility
79
 */
80
class XmlTest extends CakeTestCase {
81

    
82
/**
83
 * autoFixtures property
84
 *
85
 * @var bool
86
 */
87
        public $autoFixtures = false;
88

    
89
/**
90
 * fixtures property
91
 * @var array
92
 */
93
        public $fixtures = array(
94
                'core.article', 'core.user'
95
        );
96

    
97
/**
98
 * setUp method
99
 *
100
 * @return void
101
 */
102
        public function setUp() {
103
                parent::setUp();
104
                $this->_appEncoding = Configure::read('App.encoding');
105
                Configure::write('App.encoding', 'UTF-8');
106
        }
107

    
108
/**
109
 * tearDown method
110
 *
111
 * @return void
112
 */
113
        public function tearDown() {
114
                parent::tearDown();
115
                Configure::write('App.encoding', $this->_appEncoding);
116
        }
117

    
118
/**
119
 * testBuild method
120
 *
121
 * @return void
122
 */
123
        public function testBuild() {
124
                $xml = '<tag>value</tag>';
125
                $obj = Xml::build($xml);
126
                $this->assertTrue($obj instanceof SimpleXMLElement);
127
                $this->assertEquals('tag', (string)$obj->getName());
128
                $this->assertEquals('value', (string)$obj);
129

    
130
                $xml = '<?xml version="1.0" encoding="UTF-8"?><tag>value</tag>';
131
                $this->assertEquals($obj, Xml::build($xml));
132

    
133
                $obj = Xml::build($xml, array('return' => 'domdocument'));
134
                $this->assertTrue($obj instanceof DOMDocument);
135
                $this->assertEquals('tag', $obj->firstChild->nodeName);
136
                $this->assertEquals('value', $obj->firstChild->nodeValue);
137

    
138
                $xml = CAKE . 'Test' . DS . 'Fixture' . DS . 'sample.xml';
139
                $obj = Xml::build($xml);
140
                $this->assertEquals('tags', $obj->getName());
141
                $this->assertEquals(2, count($obj));
142

    
143
                $this->assertEquals(Xml::build($xml), Xml::build(file_get_contents($xml)));
144

    
145
                $obj = Xml::build($xml, array('return' => 'domdocument'));
146
                $this->assertEquals('tags', $obj->firstChild->nodeName);
147

    
148
                $this->assertEquals(
149
                        Xml::build($xml, array('return' => 'domdocument')),
150
                        Xml::build(file_get_contents($xml), array('return' => 'domdocument'))
151
                );
152
                $this->assertEquals(
153
                        Xml::build($xml, array('return' => 'simplexml')),
154
                        Xml::build($xml, 'simplexml')
155
                );
156

    
157
                $xml = array('tag' => 'value');
158
                $obj = Xml::build($xml);
159
                $this->assertEquals('tag', $obj->getName());
160
                $this->assertEquals('value', (string)$obj);
161

    
162
                $obj = Xml::build($xml, array('return' => 'domdocument'));
163
                $this->assertEquals('tag', $obj->firstChild->nodeName);
164
                $this->assertEquals('value', $obj->firstChild->nodeValue);
165

    
166
                $obj = Xml::build($xml, array('return' => 'domdocument', 'encoding' => null));
167
                $this->assertNotRegExp('/encoding/', $obj->saveXML());
168
        }
169

    
170
/**
171
 * Test that the readFile option disables local file parsing.
172
 *
173
 * @expectedException XmlException
174
 * @return void
175
 */
176
        public function testBuildFromFileWhenDisabled() {
177
                $xml = CAKE . 'Test' . DS . 'Fixture' . DS . 'sample.xml';
178
                Xml::build($xml, array('readFile' => false));
179
        }
180

    
181
/**
182
 * Test that the readFile option disables local file parsing.
183
 *
184
 * @expectedException XmlException
185
 * @return void
186
 */
187
        public function testBuildFromUrlWhenDisabled() {
188
                $xml = 'http://www.google.com';
189
                Xml::build($xml, array('readFile' => false));
190
        }
191

    
192
/**
193
 * data provider function for testBuildInvalidData
194
 *
195
 * @return array
196
 */
197
        public static function invalidDataProvider() {
198
                return array(
199
                        array(null),
200
                        array(false),
201
                        array(''),
202
                        array('http://localhost/notthere.xml'),
203
                );
204
        }
205

    
206
/**
207
 * testBuildInvalidData
208
 *
209
 * @dataProvider invalidDataProvider
210
 * @expectedException XmlException
211
 * @return void
212
 */
213
        public function testBuildInvalidData($value) {
214
                Xml::build($value);
215
        }
216

    
217
/**
218
 * Test that building SimpleXmlElement with invalid XML causes the right exception.
219
 *
220
 * @expectedException XmlException
221
 * @return void
222
 */
223
        public function testBuildInvalidDataSimpleXml() {
224
                $input = '<derp';
225
                Xml::build($input, array('return' => 'simplexml'));
226
        }
227

    
228
/**
229
 * test build with a single empty tag
230
 *
231
 * @return void
232
 */
233
        public function testBuildEmptyTag() {
234
                try {
235
                        Xml::build('<tag>');
236
                        $this->fail('No exception');
237
                } catch (Exception $e) {
238
                        $this->assertTrue(true, 'An exception was raised');
239
                }
240
        }
241

    
242
/**
243
 * testFromArray method
244
 *
245
 * @return void
246
 */
247
        public function testFromArray() {
248
                $xml = array('tag' => 'value');
249
                $obj = Xml::fromArray($xml);
250
                $this->assertEquals('tag', $obj->getName());
251
                $this->assertEquals('value', (string)$obj);
252

    
253
                $xml = array('tag' => null);
254
                $obj = Xml::fromArray($xml);
255
                $this->assertEquals('tag', $obj->getName());
256
                $this->assertEquals('', (string)$obj);
257

    
258
                $xml = array('tag' => array('@' => 'value'));
259
                $obj = Xml::fromArray($xml);
260
                $this->assertEquals('tag', $obj->getName());
261
                $this->assertEquals('value', (string)$obj);
262

    
263
                $xml = array(
264
                        'tags' => array(
265
                                'tag' => array(
266
                                        array(
267
                                                'id' => '1',
268
                                                'name' => 'defect'
269
                                        ),
270
                                        array(
271
                                                'id' => '2',
272
                                                'name' => 'enhancement'
273
                                        )
274
                                )
275
                        )
276
                );
277
                $obj = Xml::fromArray($xml, 'attributes');
278
                $this->assertTrue($obj instanceof SimpleXMLElement);
279
                $this->assertEquals('tags', $obj->getName());
280
                $this->assertEquals(2, count($obj));
281
                $xmlText = <<<XML
282
<?xml version="1.0" encoding="UTF-8"?>
283
<tags>
284
        <tag id="1" name="defect"/>
285
        <tag id="2" name="enhancement"/>
286
</tags>
287
XML;
288
                $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
289

    
290
                $obj = Xml::fromArray($xml);
291
                $this->assertTrue($obj instanceof SimpleXMLElement);
292
                $this->assertEquals('tags', $obj->getName());
293
                $this->assertEquals(2, count($obj));
294
                $xmlText = <<<XML
295
<?xml version="1.0" encoding="UTF-8"?>
296
<tags>
297
        <tag>
298
                <id>1</id>
299
                <name>defect</name>
300
        </tag>
301
        <tag>
302
                <id>2</id>
303
                <name>enhancement</name>
304
        </tag>
305
</tags>
306
XML;
307
                $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
308

    
309
                $xml = array(
310
                        'tags' => array(
311
                        )
312
                );
313
                $obj = Xml::fromArray($xml);
314
                $this->assertEquals('tags', $obj->getName());
315
                $this->assertEquals('', (string)$obj);
316

    
317
                $xml = array(
318
                        'tags' => array(
319
                                'bool' => true,
320
                                'int' => 1,
321
                                'float' => 10.2,
322
                                'string' => 'ok',
323
                                'null' => null,
324
                                'array' => array()
325
                        )
326
                );
327
                $obj = Xml::fromArray($xml, 'tags');
328
                $this->assertEquals(6, count($obj));
329
                $this->assertSame((string)$obj->bool, '1');
330
                $this->assertSame((string)$obj->int, '1');
331
                $this->assertSame((string)$obj->float, '10.2');
332
                $this->assertSame((string)$obj->string, 'ok');
333
                $this->assertSame((string)$obj->null, '');
334
                $this->assertSame((string)$obj->array, '');
335

    
336
                $xml = array(
337
                        'tags' => array(
338
                                'tag' => array(
339
                                        array(
340
                                                '@id' => '1',
341
                                                'name' => 'defect'
342
                                        ),
343
                                        array(
344
                                                '@id' => '2',
345
                                                'name' => 'enhancement'
346
                                        )
347
                                )
348
                        )
349
                );
350
                $obj = Xml::fromArray($xml, 'tags');
351
                $xmlText = <<<XML
352
<?xml version="1.0" encoding="UTF-8"?>
353
<tags>
354
        <tag id="1">
355
                <name>defect</name>
356
        </tag>
357
        <tag id="2">
358
                <name>enhancement</name>
359
        </tag>
360
</tags>
361
XML;
362
                $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
363

    
364
                $xml = array(
365
                        'tags' => array(
366
                                'tag' => array(
367
                                        array(
368
                                                '@id' => '1',
369
                                                'name' => 'defect',
370
                                                '@' => 'Tag 1'
371
                                        ),
372
                                        array(
373
                                                '@id' => '2',
374
                                                'name' => 'enhancement'
375
                                        ),
376
                                ),
377
                                '@' => 'All tags'
378
                        )
379
                );
380
                $obj = Xml::fromArray($xml, 'tags');
381
                $xmlText = <<<XML
382
<?xml version="1.0" encoding="UTF-8"?>
383
<tags>All tags<tag id="1">Tag 1<name>defect</name></tag><tag id="2"><name>enhancement</name></tag></tags>
384
XML;
385
                $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
386

    
387
                $xml = array(
388
                        'tags' => array(
389
                                'tag' => array(
390
                                        'id' => 1,
391
                                        '@' => 'defect'
392
                                )
393
                        )
394
                );
395
                $obj = Xml::fromArray($xml, 'attributes');
396
                $xmlText = '<' . '?xml version="1.0" encoding="UTF-8"?><tags><tag id="1">defect</tag></tags>';
397
                $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
398

    
399
                $xml = array(
400
                        'tag' => array(
401
                                '@' => 0,
402
                                '@test' => 'A test'
403
                        )
404
                );
405
                $obj = Xml::fromArray($xml);
406
                $xmlText = <<<XML
407
<?xml version="1.0" encoding="UTF-8"?>
408
<tag test="A test">0</tag>
409
XML;
410
                $this->assertXmlStringEqualsXmlString($xmlText, $obj->asXML());
411
        }
412

    
413
/**
414
 * Test non-sequential keys in list types.
415
 *
416
 * @return void
417
 */
418
        public function testFromArrayNonSequentialKeys() {
419
                $xmlArray = array(
420
                        'Event' => array(
421
                                array(
422
                                        'id' => '235',
423
                                        'Attribute' => array(
424
                                                0 => array(
425
                                                        'id' => '9646',
426
                                                ),
427
                                                2 => array(
428
                                                        'id' => '9647',
429
                                                )
430
                                        )
431
                                )
432
                        )
433
                );
434
                $obj = Xml::fromArray($xmlArray);
435
                $expected = <<<XML
436
<?xml version="1.0" encoding="UTF-8"?>
437
<Event>
438
        <id>235</id>
439
        <Attribute>
440
                <id>9646</id>
441
        </Attribute>
442
        <Attribute>
443
                <id>9647</id>
444
        </Attribute>
445
</Event>
446
XML;
447
                $this->assertXmlStringEqualsXmlString($expected, $obj->asXML());
448
        }
449

    
450
/**
451
 * testFromArrayPretty method
452
 *
453
 * @return void
454
 */
455
        public function testFromArrayPretty() {
456
                $xml = array(
457
                        'tags' => array(
458
                                'tag' => array(
459
                                        array(
460
                                                'id' => '1',
461
                                                'name' => 'defect'
462
                                        ),
463
                                        array(
464
                                                'id' => '2',
465
                                                'name' => 'enhancement'
466
                                        )
467
                                )
468
                        )
469
                );
470

    
471
                $expected = <<<XML
472
<?xml version="1.0" encoding="UTF-8"?>
473
<tags><tag><id>1</id><name>defect</name></tag><tag><id>2</id><name>enhancement</name></tag></tags>
474

475
XML;
476
                $xmlResponse = Xml::fromArray($xml, array('pretty' => false));
477
                $this->assertTextEquals($expected, $xmlResponse->asXML());
478

    
479
                $expected = <<<XML
480
<?xml version="1.0" encoding="UTF-8"?>
481
<tags>
482
  <tag>
483
    <id>1</id>
484
    <name>defect</name>
485
  </tag>
486
  <tag>
487
    <id>2</id>
488
    <name>enhancement</name>
489
  </tag>
490
</tags>
491

492
XML;
493
                $xmlResponse = Xml::fromArray($xml, array('pretty' => true));
494
                $this->assertTextEquals($expected, $xmlResponse->asXML());
495

    
496
                                $xml = array(
497
                        'tags' => array(
498
                                'tag' => array(
499
                                        array(
500
                                                'id' => '1',
501
                                                'name' => 'defect'
502
                                        ),
503
                                        array(
504
                                                'id' => '2',
505
                                                'name' => 'enhancement'
506
                                        )
507
                                )
508
                        )
509
                );
510

    
511
                $expected = <<<XML
512
<?xml version="1.0" encoding="UTF-8"?>
513
<tags><tag id="1" name="defect"/><tag id="2" name="enhancement"/></tags>
514

515
XML;
516
                $xmlResponse = Xml::fromArray($xml, array('pretty' => false, 'format' => 'attributes'));
517
                $this->assertTextEquals($expected, $xmlResponse->asXML());
518

    
519
                $expected = <<<XML
520
<?xml version="1.0" encoding="UTF-8"?>
521
<tags>
522
  <tag id="1" name="defect"/>
523
  <tag id="2" name="enhancement"/>
524
</tags>
525

526
XML;
527
                $xmlResponse = Xml::fromArray($xml, array('pretty' => true, 'format' => 'attributes'));
528
                $this->assertTextEquals($expected, $xmlResponse->asXML());
529
        }
530

    
531
/**
532
 * data provider for fromArray() failures
533
 *
534
 * @return array
535
 */
536
        public static function invalidArrayDataProvider() {
537
                return array(
538
                        array(''),
539
                        array(null),
540
                        array(false),
541
                        array(array()),
542
                        array(array('numeric key as root')),
543
                        array(array('item1' => '', 'item2' => '')),
544
                        array(array('items' => array('item1', 'item2'))),
545
                        array(array(
546
                                'tags' => array(
547
                                        'tag' => array(
548
                                                array(
549
                                                        array(
550
                                                                'string'
551
                                                        )
552
                                                )
553
                                        )
554
                                )
555
                        )),
556
                        array(array(
557
                                'tags' => array(
558
                                        '@tag' => array(
559
                                                array(
560
                                                        '@id' => '1',
561
                                                        'name' => 'defect'
562
                                                ),
563
                                                array(
564
                                                        '@id' => '2',
565
                                                        'name' => 'enhancement'
566
                                                )
567
                                        )
568
                                )
569
                        )),
570
                        array(new DateTime())
571
                );
572
        }
573

    
574
/**
575
 * testFromArrayFail method
576
 *
577
 * @dataProvider invalidArrayDataProvider
578
 * @return void
579
 */
580
        public function testFromArrayFail($value) {
581
                try {
582
                        Xml::fromArray($value);
583
                        $this->fail('No exception.');
584
                } catch (Exception $e) {
585
                        $this->assertTrue(true, 'Caught exception.');
586
                }
587
        }
588

    
589
/**
590
 * Test that there are not unterminated errors when building xml
591
 *
592
 * @return void
593
 */
594
        public function testFromArrayUnterminatedError() {
595
                $data = array(
596
                        'product_ID' => 'GENERT-DL',
597
                        'deeplink' => 'http://example.com/deep',
598
                        'image_URL' => 'http://example.com/image',
599
                        'thumbnail_image_URL' => 'http://example.com/thumb',
600
                        'brand' => 'Malte Lange & Co',
601
                        'availability' => 'in stock',
602
                        'authors' => array(
603
                                'author' => array('Malte Lange & Co')
604
                        )
605
                );
606
                $xml = Xml::fromArray(array('products' => $data), 'tags');
607
                $expected = <<<XML
608
<?xml version="1.0" encoding="UTF-8"?>
609
<products>
610
        <product_ID>GENERT-DL</product_ID>
611
        <deeplink>http://example.com/deep</deeplink>
612
        <image_URL>http://example.com/image</image_URL>
613
        <thumbnail_image_URL>http://example.com/thumb</thumbnail_image_URL>
614
        <brand>Malte Lange &amp; Co</brand>
615
        <availability>in stock</availability>
616
        <authors>
617
                <author>Malte Lange &amp; Co</author>
618
        </authors>
619
</products>
620
XML;
621
                $this->assertXmlStringEqualsXmlString($expected, $xml->asXML());
622
        }
623

    
624
/**
625
 * testToArray method
626
 *
627
 * @return void
628
 */
629
        public function testToArray() {
630
                $xml = '<tag>name</tag>';
631
                $obj = Xml::build($xml);
632
                $this->assertEquals(array('tag' => 'name'), Xml::toArray($obj));
633

    
634
                $xml = CAKE . 'Test' . DS . 'Fixture' . DS . 'sample.xml';
635
                $obj = Xml::build($xml);
636
                $expected = array(
637
                        'tags' => array(
638
                                'tag' => array(
639
                                        array(
640
                                                '@id' => '1',
641
                                                'name' => 'defect'
642
                                        ),
643
                                        array(
644
                                                '@id' => '2',
645
                                                'name' => 'enhancement'
646
                                        )
647
                                )
648
                        )
649
                );
650
                $this->assertEquals($expected, Xml::toArray($obj));
651

    
652
                $array = array(
653
                        'tags' => array(
654
                                'tag' => array(
655
                                        array(
656
                                                'id' => '1',
657
                                                'name' => 'defect'
658
                                        ),
659
                                        array(
660
                                                'id' => '2',
661
                                                'name' => 'enhancement'
662
                                        )
663
                                )
664
                        )
665
                );
666
                $this->assertEquals(Xml::toArray(Xml::fromArray($array, 'tags')), $array);
667

    
668
                $expected = array(
669
                        'tags' => array(
670
                                'tag' => array(
671
                                        array(
672
                                                '@id' => '1',
673
                                                '@name' => 'defect'
674
                                        ),
675
                                        array(
676
                                                '@id' => '2',
677
                                                '@name' => 'enhancement'
678
                                        )
679
                                )
680
                        )
681
                );
682
                $this->assertEquals($expected, Xml::toArray(Xml::fromArray($array, 'attributes')));
683
                $this->assertEquals($expected, Xml::toArray(Xml::fromArray($array, array('return' => 'domdocument', 'format' => 'attributes'))));
684
                $this->assertEquals(Xml::toArray(Xml::fromArray($array)), $array);
685
                $this->assertEquals(Xml::toArray(Xml::fromArray($array, array('return' => 'domdocument'))), $array);
686

    
687
                $array = array(
688
                        'tags' => array(
689
                                'tag' => array(
690
                                        'id' => '1',
691
                                        'posts' => array(
692
                                                array('id' => '1'),
693
                                                array('id' => '2')
694
                                        )
695
                                ),
696
                                'tagOther' => array(
697
                                        'subtag' => array(
698
                                                'id' => '1'
699
                                        )
700
                                )
701
                        )
702
                );
703
                $expected = array(
704
                        'tags' => array(
705
                                'tag' => array(
706
                                        '@id' => '1',
707
                                        'posts' => array(
708
                                                array('@id' => '1'),
709
                                                array('@id' => '2')
710
                                        )
711
                                ),
712
                                'tagOther' => array(
713
                                        'subtag' => array(
714
                                                '@id' => '1'
715
                                        )
716
                                )
717
                        )
718
                );
719
                $this->assertEquals($expected, Xml::toArray(Xml::fromArray($array, 'attributes')));
720
                $this->assertEquals($expected, Xml::toArray(Xml::fromArray($array, array('format' => 'attributes', 'return' => 'domdocument'))));
721

    
722
                $xml = <<<XML
723
<root>
724
<tag id="1">defect</tag>
725
</root>
726
XML;
727
                $obj = Xml::build($xml);
728

    
729
                $expected = array(
730
                        'root' => array(
731
                                'tag' => array(
732
                                        '@id' => 1,
733
                                        '@' => 'defect'
734
                                )
735
                        )
736
                );
737
                $this->assertEquals($expected, Xml::toArray($obj));
738

    
739
                $xml = <<<XML
740
<root>
741
        <table xmlns="http://www.w3.org/TR/html4/"><tr><td>Apples</td><td>Bananas</td></tr></table>
742
        <table xmlns="http://www.cakephp.org"><name>CakePHP</name><license>MIT</license></table>
743
        <table>The book is on the table.</table>
744
</root>
745
XML;
746
                $obj = Xml::build($xml);
747

    
748
                $expected = array(
749
                        'root' => array(
750
                                'table' => array(
751
                                        array('tr' => array('td' => array('Apples', 'Bananas'))),
752
                                        array('name' => 'CakePHP', 'license' => 'MIT'),
753
                                        'The book is on the table.'
754
                                )
755
                        )
756
                );
757
                $this->assertEquals($expected, Xml::toArray($obj));
758

    
759
                $xml = <<<XML
760
<root xmlns:cake="http://www.cakephp.org/">
761
<tag>defect</tag>
762
<cake:bug>1</cake:bug>
763
</root>
764
XML;
765
                $obj = Xml::build($xml);
766

    
767
                $expected = array(
768
                        'root' => array(
769
                                'tag' => 'defect',
770
                                'cake:bug' => 1
771
                        )
772
                );
773
                $this->assertEquals($expected, Xml::toArray($obj));
774

    
775
                $xml = '<tag type="myType">0</tag>';
776
                $obj = Xml::build($xml);
777
                $expected = array(
778
                        'tag' => array(
779
                                '@type' => 'myType',
780
                                '@' => 0
781
                        )
782
                );
783
                $this->assertEquals($expected, Xml::toArray($obj));
784
        }
785

    
786
/**
787
 * testRss
788
 *
789
 * @return void
790
 */
791
        public function testRss() {
792
                $rss = file_get_contents(CAKE . 'Test' . DS . 'Fixture' . DS . 'rss.xml');
793
                $rssAsArray = Xml::toArray(Xml::build($rss));
794
                $this->assertEquals('2.0', $rssAsArray['rss']['@version']);
795
                $this->assertEquals(2, count($rssAsArray['rss']['channel']['item']));
796

    
797
                $atomLink = array('@href' => 'http://bakery.cakephp.org/articles/rss', '@rel' => 'self', '@type' => 'application/rss+xml');
798
                $this->assertEquals($rssAsArray['rss']['channel']['atom:link'], $atomLink);
799
                $this->assertEquals('http://bakery.cakephp.org/', $rssAsArray['rss']['channel']['link']);
800

    
801
                $expected = array(
802
                        'title' => 'Alertpay automated sales via IPN',
803
                        'link' => 'http://bakery.cakephp.org/articles/view/alertpay-automated-sales-via-ipn',
804
                        'description' => 'I\'m going to show you how I implemented a payment module via the Alertpay payment processor.',
805
                        'pubDate' => 'Tue, 31 Aug 2010 01:42:00 -0500',
806
                        'guid' => 'http://bakery.cakephp.org/articles/view/alertpay-automated-sales-via-ipn'
807
                );
808
                $this->assertSame($expected, $rssAsArray['rss']['channel']['item'][1]);
809

    
810
                $rss = array(
811
                        'rss' => array(
812
                                'xmlns:atom' => 'http://www.w3.org/2005/Atom',
813
                                '@version' => '2.0',
814
                                'channel' => array(
815
                                        'atom:link' => array(
816
                                                '@href' => 'http://bakery.cakephp.org/articles/rss',
817
                                                '@rel' => 'self',
818
                                                '@type' => 'application/rss+xml'
819
                                        ),
820
                                        'title' => 'The Bakery: ',
821
                                        'link' => 'http://bakery.cakephp.org/',
822
                                        'description' => 'Recent  Articles at The Bakery.',
823
                                        'pubDate' => 'Sun, 12 Sep 2010 04:18:26 -0500',
824
                                        'item' => array(
825
                                                array(
826
                                                        'title' => 'CakePHP 1.3.4 released',
827
                                                        'link' => 'http://bakery.cakephp.org/articles/view/cakephp-1-3-4-released'
828
                                                ),
829
                                                array(
830
                                                        'title' => 'Wizard Component 1.2 Tutorial',
831
                                                        'link' => 'http://bakery.cakephp.org/articles/view/wizard-component-1-2-tutorial'
832
                                                )
833
                                        )
834
                                )
835
                        )
836
                );
837
                $rssAsSimpleXML = Xml::fromArray($rss);
838
                $xmlText = <<<XML
839
<?xml version="1.0" encoding="UTF-8"?>
840
<rss xmlns:atom="http://www.w3.org/2005/Atom" version="2.0">
841
<channel>
842
        <atom:link href="http://bakery.cakephp.org/articles/rss" rel="self" type="application/rss+xml"/>
843
        <title>The Bakery: </title>
844
        <link>http://bakery.cakephp.org/</link>
845
        <description>Recent  Articles at The Bakery.</description>
846
        <pubDate>Sun, 12 Sep 2010 04:18:26 -0500</pubDate>
847
        <item>
848
                <title>CakePHP 1.3.4 released</title>
849
                <link>http://bakery.cakephp.org/articles/view/cakephp-1-3-4-released</link>
850
        </item>
851
        <item>
852
                <title>Wizard Component 1.2 Tutorial</title>
853
                <link>http://bakery.cakephp.org/articles/view/wizard-component-1-2-tutorial</link>
854
        </item>
855
</channel>
856
</rss>
857
XML;
858
                $this->assertXmlStringEqualsXmlString($xmlText, $rssAsSimpleXML->asXML());
859
        }
860

    
861
/**
862
 * testXmlRpc
863
 *
864
 * @return void
865
 */
866
        public function testXmlRpc() {
867
                $xml = Xml::build('<methodCall><methodName>test</methodName><params /></methodCall>');
868
                $expected = array(
869
                        'methodCall' => array(
870
                                'methodName' => 'test',
871
                                'params' => ''
872
                        )
873
                );
874
                $this->assertSame($expected, Xml::toArray($xml));
875

    
876
                $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>');
877
                $expected = array(
878
                        'methodCall' => array(
879
                                'methodName' => 'test',
880
                                'params' => array(
881
                                        'param' => array(
882
                                                'value' => array(
883
                                                        'array' => array(
884
                                                                'data' => array(
885
                                                                        'value' => array(
886
                                                                                array('int' => '12'),
887
                                                                                array('string' => 'Egypt'),
888
                                                                                array('boolean' => '0'),
889
                                                                                array('int' => '-31')
890
                                                                        )
891
                                                                )
892
                                                        )
893
                                                )
894
                                        )
895
                                )
896
                        )
897
                );
898
                $this->assertSame($expected, Xml::toArray($xml));
899

    
900
                $xmlText = <<<XML
901
<?xml version="1.0" encoding="UTF-8"?>
902
<methodResponse>
903
        <params>
904
                <param>
905
                        <value>
906
                                <array>
907
                                        <data>
908
                                                <value>
909
                                                        <int>1</int>
910
                                                </value>
911
                                                <value>
912
                                                        <string>testing</string>
913
                                                </value>
914
                                        </data>
915
                                </array>
916
                        </value>
917
                </param>
918
        </params>
919
</methodResponse>
920
XML;
921
                $xml = Xml::build($xmlText);
922
                $expected = array(
923
                        'methodResponse' => array(
924
                                'params' => array(
925
                                        'param' => array(
926
                                                'value' => array(
927
                                                        'array' => array(
928
                                                                'data' => array(
929
                                                                        'value' => array(
930
                                                                                array('int' => '1'),
931
                                                                                array('string' => 'testing')
932
                                                                        )
933
                                                                )
934
                                                        )
935
                                                )
936
                                        )
937
                                )
938
                        )
939
                );
940
                $this->assertSame($expected, Xml::toArray($xml));
941

    
942
                $xml = Xml::fromArray($expected, 'tags');
943
                $this->assertXmlStringEqualsXmlString($xmlText, $xml->asXML());
944
        }
945

    
946
/**
947
 * testSoap
948
 *
949
 * @return void
950
 */
951
        public function testSoap() {
952
                $xmlRequest = Xml::build(CAKE . 'Test' . DS . 'Fixture' . DS . 'soap_request.xml');
953
                $expected = array(
954
                        'Envelope' => array(
955
                                '@soap:encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding',
956
                                'soap:Body' => array(
957
                                        'm:GetStockPrice' => array(
958
                                                'm:StockName' => 'IBM'
959
                                        )
960
                                )
961
                        )
962
                );
963
                $this->assertEquals($expected, Xml::toArray($xmlRequest));
964

    
965
                $xmlResponse = Xml::build(CAKE . 'Test' . DS . 'Fixture' . DS . 'soap_response.xml');
966
                $expected = array(
967
                        'Envelope' => array(
968
                                '@soap:encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding',
969
                                'soap:Body' => array(
970
                                        'm:GetStockPriceResponse' => array(
971
                                                'm:Price' => '34.5'
972
                                        )
973
                                )
974
                        )
975
                );
976
                $this->assertEquals($expected, Xml::toArray($xmlResponse));
977

    
978
                $xml = array(
979
                        'soap:Envelope' => array(
980
                                'xmlns:soap' => 'http://www.w3.org/2001/12/soap-envelope',
981
                                '@soap:encodingStyle' => 'http://www.w3.org/2001/12/soap-encoding',
982
                                'soap:Body' => array(
983
                                        'xmlns:m' => 'http://www.example.org/stock',
984
                                        'm:GetStockPrice' => array(
985
                                                'm:StockName' => 'IBM'
986
                                        )
987
                                )
988
                        )
989
                );
990
                $xmlRequest = Xml::fromArray($xml, array('encoding' => null));
991
                $xmlText = <<<XML
992
<?xml version="1.0"?>
993
<soap:Envelope xmlns:soap="http://www.w3.org/2001/12/soap-envelope" soap:encodingStyle="http://www.w3.org/2001/12/soap-encoding">
994
        <soap:Body xmlns:m="http://www.example.org/stock">
995
        <m:GetStockPrice><m:StockName>IBM</m:StockName></m:GetStockPrice>
996
        </soap:Body>
997
</soap:Envelope>
998
XML;
999
                $this->assertXmlStringEqualsXmlString($xmlText, $xmlRequest->asXML());
1000
        }
1001

    
1002
/**
1003
 * testNamespace
1004
 *
1005
 * @return void
1006
 */
1007
        public function testNamespace() {
1008
                $xml = <<<XML
1009
<root xmlns:ns="http://cakephp.org">
1010
        <ns:tag id="1">
1011
                <child>good</child>
1012
                <otherchild>bad</otherchild>
1013
        </ns:tag>
1014
        <tag>Tag without ns</tag>
1015
</root>
1016
XML;
1017
                $xmlResponse = Xml::build($xml);
1018
                $expected = array(
1019
                        'root' => array(
1020
                                'ns:tag' => array(
1021
                                        '@id' => '1',
1022
                                        'child' => 'good',
1023
                                        'otherchild' => 'bad'
1024
                                ),
1025
                                'tag' => 'Tag without ns'
1026
                        )
1027
                );
1028
                $this->assertEquals($expected, Xml::toArray($xmlResponse));
1029

    
1030
                $xmlResponse = Xml::build('<root xmlns:ns="http://cakephp.org"><ns:tag id="1" /><tag><id>1</id></tag></root>');
1031
                $expected = array(
1032
                        'root' => array(
1033
                                'ns:tag' => array(
1034
                                        '@id' => '1'
1035
                                ),
1036
                                'tag' => array(
1037
                                        'id' => '1'
1038
                                )
1039
                        )
1040
                );
1041
                $this->assertEquals($expected, Xml::toArray($xmlResponse));
1042

    
1043
                $xmlResponse = Xml::build('<root xmlns:ns="http://cakephp.org"><ns:attr>1</ns:attr></root>');
1044
                $expected = array(
1045
                        'root' => array(
1046
                                'ns:attr' => '1'
1047
                        )
1048
                );
1049
                $this->assertEquals($expected, Xml::toArray($xmlResponse));
1050

    
1051
                $xmlResponse = Xml::build('<root><ns:attr xmlns:ns="http://cakephp.org">1</ns:attr></root>');
1052
                $this->assertEquals($expected, Xml::toArray($xmlResponse));
1053

    
1054
                $xml = array(
1055
                        'root' => array(
1056
                                'ns:attr' => array(
1057
                                        'xmlns:ns' => 'http://cakephp.org',
1058
                                        '@' => 1
1059
                                )
1060
                        )
1061
                );
1062
                $expected = '<' . '?xml version="1.0" encoding="UTF-8"?><root><ns:attr xmlns:ns="http://cakephp.org">1</ns:attr></root>';
1063
                $xmlResponse = Xml::fromArray($xml);
1064
                $this->assertEquals($expected, str_replace(array("\r", "\n"), '', $xmlResponse->asXML()));
1065

    
1066
                $xml = array(
1067
                        'root' => array(
1068
                                'tag' => array(
1069
                                        'xmlns:pref' => 'http://cakephp.org',
1070
                                        'pref:item' => array(
1071
                                                'item 1',
1072
                                                'item 2'
1073
                                        )
1074
                                )
1075
                        )
1076
                );
1077
                $expected = <<<XML
1078
<?xml version="1.0" encoding="UTF-8"?>
1079
<root>
1080
        <tag xmlns:pref="http://cakephp.org">
1081
                <pref:item>item 1</pref:item>
1082
                <pref:item>item 2</pref:item>
1083
        </tag>
1084
</root>
1085
XML;
1086
                $xmlResponse = Xml::fromArray($xml);
1087
                $this->assertXmlStringEqualsXmlString($expected, $xmlResponse->asXML());
1088

    
1089
                $xml = array(
1090
                        'root' => array(
1091
                                'tag' => array(
1092
                                        'xmlns:' => 'http://cakephp.org'
1093
                                )
1094
                        )
1095
                );
1096
                $expected = '<' . '?xml version="1.0" encoding="UTF-8"?><root><tag xmlns="http://cakephp.org"/></root>';
1097
                $xmlResponse = Xml::fromArray($xml);
1098
                $this->assertXmlStringEqualsXmlString($expected, $xmlResponse->asXML());
1099

    
1100
                $xml = array(
1101
                        'root' => array(
1102
                                'xmlns:' => 'http://cakephp.org'
1103
                        )
1104
                );
1105
                $expected = '<' . '?xml version="1.0" encoding="UTF-8"?><root xmlns="http://cakephp.org"/>';
1106
                $xmlResponse = Xml::fromArray($xml);
1107
                $this->assertXmlStringEqualsXmlString($expected, $xmlResponse->asXML());
1108

    
1109
                $xml = array(
1110
                        'root' => array(
1111
                                'xmlns:ns' => 'http://cakephp.org'
1112
                        )
1113
                );
1114
                $expected = '<' . '?xml version="1.0" encoding="UTF-8"?><root xmlns:ns="http://cakephp.org"/>';
1115
                $xmlResponse = Xml::fromArray($xml);
1116
                $this->assertXmlStringEqualsXmlString($expected, $xmlResponse->asXML());
1117
        }
1118

    
1119
/**
1120
 * test that CDATA blocks don't get screwed up by SimpleXml
1121
 *
1122
 * @return void
1123
 */
1124
        public function testCdata() {
1125
                $xml = '<' . '?xml version="1.0" encoding="UTF-8"?>' .
1126
                        '<people><name><![CDATA[ Mark ]]></name></people>';
1127

    
1128
                $result = Xml::build($xml);
1129
                $this->assertEquals(' Mark ', (string)$result->name);
1130
        }
1131

    
1132
/**
1133
 * data provider for toArray() failures
1134
 *
1135
 * @return array
1136
 */
1137
        public static function invalidToArrayDataProvider() {
1138
                return array(
1139
                        array(new DateTime()),
1140
                        array(array())
1141
                );
1142
        }
1143

    
1144
/**
1145
 * testToArrayFail method
1146
 *
1147
 * @dataProvider invalidToArrayDataProvider
1148
 * @expectedException XmlException
1149
 * @return void
1150
 */
1151
        public function testToArrayFail($value) {
1152
                Xml::toArray($value);
1153
        }
1154

    
1155
/**
1156
 * testWithModel method
1157
 *
1158
 * @return void
1159
 */
1160
        public function testWithModel() {
1161
                $this->loadFixtures('User', 'Article');
1162

    
1163
                $user = new XmlUser();
1164
                $data = $user->read(null, 1);
1165

    
1166
                $obj = Xml::build(compact('data'));
1167
                $expected = <<<XML
1168
<?xml version="1.0" encoding="UTF-8"?><data>
1169
<User><id>1</id><user>mariano</user><password>5f4dcc3b5aa765d61d8327deb882cf99</password>
1170
<created>2007-03-17 01:16:23</created><updated>2007-03-17 01:18:31</updated></User>
1171
<Article><id>1</id><user_id>1</user_id><title>First Article</title><body>First Article Body</body>
1172
<published>Y</published><created>2007-03-18 10:39:23</created><updated>2007-03-18 10:41:31</updated></Article>
1173
<Article><id>3</id><user_id>1</user_id><title>Third Article</title><body>Third Article Body</body>
1174
<published>Y</published><created>2007-03-18 10:43:23</created><updated>2007-03-18 10:45:31</updated></Article>
1175
</data>
1176
XML;
1177
                $this->assertXmlStringEqualsXmlString($expected, $obj->asXML());
1178

    
1179
                //multiple model results - without a records key it would fatal error
1180
                $data = $user->find('all', array('limit' => 2));
1181
                $data = array('records' => $data);
1182
                $obj = Xml::build(compact('data'));
1183
                $expected = <<<XML
1184
<?xml version="1.0" encoding="UTF-8"?><data>
1185
<records>
1186
<User><id>1</id><user>mariano</user><password>5f4dcc3b5aa765d61d8327deb882cf99</password>
1187
<created>2007-03-17 01:16:23</created><updated>2007-03-17 01:18:31</updated></User>
1188
<Article><id>1</id><user_id>1</user_id><title>First Article</title><body>First Article Body</body>
1189
<published>Y</published><created>2007-03-18 10:39:23</created><updated>2007-03-18 10:41:31</updated></Article>
1190
<Article><id>3</id><user_id>1</user_id><title>Third Article</title><body>Third Article Body</body>
1191
<published>Y</published><created>2007-03-18 10:43:23</created><updated>2007-03-18 10:45:31</updated></Article>
1192
</records><records><User><id>2</id><user>nate</user><password>5f4dcc3b5aa765d61d8327deb882cf99</password>
1193
<created>2007-03-17 01:18:23</created><updated>2007-03-17 01:20:31</updated></User><Article/>
1194
</records>
1195
</data>
1196
XML;
1197
                $obj->asXML();
1198
                $this->assertXmlStringEqualsXmlString($expected, $obj->asXML());
1199
        }
1200

    
1201
/**
1202
 * Test ampersand in text elements.
1203
 *
1204
 * @return void
1205
 */
1206
        public function testAmpInText() {
1207
                $data = array(
1208
                        'outer' => array(
1209
                                'inner' => array('name' => 'mark & mark')
1210
                        )
1211
                );
1212
                $obj = Xml::build($data);
1213
                $result = $obj->asXml();
1214
                $this->assertContains('mark &amp; mark', $result);
1215
        }
1216

    
1217
/**
1218
 * Test that entity loading is disabled by default.
1219
 *
1220
 * @return void
1221
 */
1222
        public function testNoEntityLoading() {
1223
                $file = CAKE . 'VERSION.txt';
1224
                $xml = <<<XML
1225
<!DOCTYPE cakephp [
1226
  <!ENTITY payload SYSTEM "file://$file" >]>
1227
<request>
1228
  <xxe>&payload;</xxe>
1229
</request>
1230
XML;
1231
                try {
1232
                        $result = Xml::build($xml);
1233
                        $this->assertEquals('', (string)$result->xxe);
1234
                } catch (Exception $e) {
1235
                        $this->assertTrue(true, 'A warning was raised meaning external entities were not loaded');
1236
                }
1237
        }
1238

    
1239
}