EscaperTest.php 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien.potencier@symfony-project.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Tests\Component\OutputEscaper;
  11. use Symfony\Component\OutputEscaper\Escaper;
  12. use Symfony\Component\OutputEscaper\SafeDecorator;
  13. use Symfony\Component\OutputEscaper\IteratorDecorator;
  14. use Symfony\Component\OutputEscaper\ArrayDecorator;
  15. use Symfony\Component\OutputEscaper\ObjectDecorator;
  16. class EscaperTest extends \PHPUnit_Framework_TestCase
  17. {
  18. public function testEscapeDoesNotEscapeSpecialValues()
  19. {
  20. $this->assertNull(Escaper::escape('entities', null), '::escape() returns null if the value to escape is null');
  21. $this->assertFalse(Escaper::escape('entities', false), '::escape() returns false if the value to escape is false');
  22. $this->assertTrue(Escaper::escape('entities', true), '::escape() returns true if the value to escape is true');
  23. }
  24. public function testEscapeDoesNotEscapeAValueWhenEscapingMethodIsRAW()
  25. {
  26. $this->assertEquals('<strong>escaped!</strong>', Escaper::escape('raw', '<strong>escaped!</strong>'), '::escape() takes an escaping strategy function name as its first argument');
  27. }
  28. public function testEscapeEscapesStrings()
  29. {
  30. $this->assertEquals('&lt;strong&gt;escaped!&lt;/strong&gt;', Escaper::escape('entities', '<strong>escaped!</strong>'), '::escape() returns an escaped string if the value to escape is a string');
  31. $this->assertEquals('&lt;strong&gt;&eacute;chapp&eacute;&lt;/strong&gt;', Escaper::escape('entities', '<strong>échappé</strong>'), '::escape() returns an escaped string if the value to escape is a string');
  32. }
  33. public function testEscapeEscapesArrays()
  34. {
  35. $input = array(
  36. 'foo' => '<strong>escaped!</strong>',
  37. 'bar' => array('foo' => '<strong>escaped!</strong>'),
  38. );
  39. $output = Escaper::escape('entities', $input);
  40. $this->assertInstanceOf('Symfony\Component\OutputEscaper\ArrayDecorator', $output, '::escape() returns a ArrayDecorator object if the value to escape is an array');
  41. $this->assertEquals('&lt;strong&gt;escaped!&lt;/strong&gt;', $output['foo'], '::escape() escapes all elements of the original array');
  42. $this->assertEquals('&lt;strong&gt;escaped!&lt;/strong&gt;', $output['bar']['foo'], '::escape() is recursive');
  43. $this->assertEquals($input, $output->getRawValue(), '->getRawValue() returns the unescaped value');
  44. }
  45. public function testEscapeEscapesObjects()
  46. {
  47. $input = new OutputEscaperTestClass();
  48. $output = Escaper::escape('entities', $input);
  49. $this->assertInstanceOf('Symfony\Component\OutputEscaper\ObjectDecorator', $output, '::escape() returns a ObjectDecorator object if the value to escape is an object');
  50. $this->assertEquals('&lt;strong&gt;escaped!&lt;/strong&gt;', $output->getTitle(), '::escape() escapes all methods of the original object');
  51. $this->assertEquals('&lt;strong&gt;escaped!&lt;/strong&gt;', $output->title, '::escape() escapes all properties of the original object');
  52. $this->assertEquals('&lt;strong&gt;escaped!&lt;/strong&gt;', $output->getTitleTitle(), '::escape() is recursive');
  53. $this->assertEquals($input, $output->getRawValue(), '->getRawValue() returns the unescaped value');
  54. $this->assertEquals('&lt;strong&gt;escaped!&lt;/strong&gt;', Escaper::escape('entities', $output)->getTitle(), '::escape() does not double escape an object');
  55. $this->assertInstanceOf('Symfony\Component\OutputEscaper\IteratorDecorator', Escaper::escape('entities', new \DirectoryIterator('.')), '::escape() returns a IteratorDecorator object if the value to escape is an object that implements the ArrayAccess interface');
  56. }
  57. public function testEscapeDoesNotEscapeObjectMarkedAsBeingSafe()
  58. {
  59. $this->assertInstanceOf('Symfony\Tests\Component\OutputEscaper\OutputEscaperTestClass', Escaper::escape('entities', new SafeDecorator(new OutputEscaperTestClass())), '::escape() returns the original value if it is marked as being safe');
  60. Escaper::markClassAsSafe('Symfony\Tests\Component\OutputEscaper\OutputEscaperTestClass');
  61. $this->assertInstanceOf('Symfony\Tests\Component\OutputEscaper\OutputEscaperTestClass', Escaper::escape('entities', new OutputEscaperTestClass()), '::escape() returns the original value if the object class is marked as being safe');
  62. $this->assertInstanceOf('Symfony\Tests\Component\OutputEscaper\OutputEscaperTestClass', Escaper::escape('entities', new OutputEscaperTestClassChild()), '::escape() returns the original value if one of the object parent class is marked as being safe');
  63. }
  64. public function testEscapeCannotEscapeResources()
  65. {
  66. $fh = fopen(__FILE__, 'r');
  67. try {
  68. Escaper::escape('entities', $fh);
  69. $this->fail('::escape() throws an InvalidArgumentException if the value cannot be escaped');
  70. } catch (\InvalidArgumentException $e) {
  71. }
  72. fclose($fh);
  73. }
  74. public function testUnescapeDoesNotUnescapeSpecialValues()
  75. {
  76. $this->assertNull(Escaper::unescape(null), '::unescape() returns null if the value to unescape is null');
  77. $this->assertFalse(Escaper::unescape(false), '::unescape() returns false if the value to unescape is false');
  78. $this->assertTrue(Escaper::unescape(true), '::unescape() returns true if the value to unescape is true');
  79. }
  80. public function testUnescapeUnescapesStrings()
  81. {
  82. $this->assertEquals('<strong>escaped!</strong>', Escaper::unescape('&lt;strong&gt;escaped!&lt;/strong&gt;'), '::unescape() returns an unescaped string if the value to unescape is a string');
  83. $this->assertEquals('<strong>échappé</strong>', Escaper::unescape('&lt;strong&gt;&eacute;chapp&eacute;&lt;/strong&gt;'), '::unescape() returns an unescaped string if the value to unescape is a string');
  84. }
  85. public function testUnescapeUnescapesArrays()
  86. {
  87. $input = Escaper::escape('entities', array(
  88. 'foo' => '<strong>escaped!</strong>',
  89. 'bar' => array('foo' => '<strong>escaped!</strong>'),
  90. ));
  91. $output = Escaper::unescape($input);
  92. $this->assertType('array', $output, '::unescape() returns an array if the input is a ArrayDecorator object');
  93. $this->assertEquals('<strong>escaped!</strong>', $output['foo'], '::unescape() unescapes all elements of the original array');
  94. $this->assertEquals('<strong>escaped!</strong>', $output['bar']['foo'], '::unescape() is recursive');
  95. }
  96. public function testUnescapeUnescapesObjects()
  97. {
  98. $object = new OutputEscaperTestClass();
  99. $input = Escaper::escape('entities', $object);
  100. $output = Escaper::unescape($input);
  101. $this->assertInstanceOf('Symfony\Tests\Component\OutputEscaper\OutputEscaperTestClass', $output, '::unescape() returns the original object when a ObjectDecorator object is passed');
  102. $this->assertEquals('<strong>escaped!</strong>', $output->getTitle(), '::unescape() unescapes all methods of the original object');
  103. $this->assertEquals('<strong>escaped!</strong>', $output->title, '::unescape() unescapes all properties of the original object');
  104. $this->assertEquals('<strong>escaped!</strong>', $output->getTitleTitle(), '::unescape() is recursive');
  105. $this->assertInstanceOf('\DirectoryIterator', IteratorDecorator::unescape(Escaper::escape('entities', new \DirectoryIterator('.'))), '::unescape() unescapes IteratorDecorator objects');
  106. }
  107. public function testUnescapeDoesNotUnescapeObjectMarkedAsBeingSafe()
  108. {
  109. $this->assertInstanceOf('Symfony\Tests\Component\OutputEscaper\OutputEscaperTestClass', Escaper::unescape(Escaper::escape('entities', new SafeDecorator(new OutputEscaperTestClass()))), '::unescape() returns the original value if it is marked as being safe');
  110. Escaper::markClassAsSafe('OutputEscaperTestClass');
  111. $this->assertInstanceOf('Symfony\Tests\Component\OutputEscaper\OutputEscaperTestClass', Escaper::unescape(Escaper::escape('entities', new OutputEscaperTestClass())), '::unescape() returns the original value if the object class is marked as being safe');
  112. $this->assertInstanceOf('Symfony\Tests\Component\OutputEscaper\OutputEscaperTestClass', Escaper::unescape(Escaper::escape('entities', new OutputEscaperTestClassChild())), '::unescape() returns the original value if one of the object parent class is marked as being safe');
  113. }
  114. public function testUnescapeDoesNothingToResources()
  115. {
  116. $fh = fopen(__FILE__, 'r');
  117. $this->assertEquals($fh, Escaper::unescape($fh), '::unescape() do nothing to resources');
  118. }
  119. public function testUnescapeUnescapesMixedArrays()
  120. {
  121. $object = new OutputEscaperTestClass();
  122. $input = array(
  123. 'foo' => 'bar',
  124. 'bar' => Escaper::escape('entities', '<strong>bar</strong>'),
  125. 'foobar' => Escaper::escape('entities', $object),
  126. );
  127. $output = array(
  128. 'foo' => 'bar',
  129. 'bar' => '<strong>bar</strong>',
  130. 'foobar' => $object,
  131. );
  132. $this->assertEquals($output, Escaper::unescape($input), '::unescape() unescapes values with some escaped and unescaped values');
  133. }
  134. }
  135. class OutputEscaperTestClass
  136. {
  137. public $title = '<strong>escaped!</strong>';
  138. public function getTitle()
  139. {
  140. return $this->title;
  141. }
  142. public function getTitleTitle()
  143. {
  144. $o = new self;
  145. return $o->getTitle();
  146. }
  147. }
  148. class OutputEscaperTestClassChild extends OutputEscaperTestClass
  149. {
  150. }